update magit
[emacs.git] / .emacs.d / elisp / magit / magit-key-mode.el
index 8976883..2fcf296 100644 (file)
@@ -1,50 +1,19 @@
-;;; magit-key-mode.el --- interactively tune git invocation
-
-;; Copyright (C) 2010  Phil Jackson
-
-;; Magit is free software; you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-;;
-;; Magit is distributed in the hope that it will be useful, but WITHOUT
-;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-;; License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with Magit.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This library implements `magit-key-mode' which is used throughout
-;; Magit to let the user interactively select the command, switches
-;; and options to call Git with.  It can be though of as a way to
-;; provide "postfix" arguments.
-
-;;; Code:
-
 (require 'magit)
 
-(eval-when-compile (require 'cl-lib))
+(eval-when-compile (require 'cl))
 
 (defvar magit-key-mode-key-maps '()
   "This will be filled lazily with proper `define-key' built
-keymaps as they're requested.")
+  keymaps as they're requested.")
 
-(defvar magit-key-mode-buf-name "*magit-key: %s*"
-  "Format string to create the name of the magit-key buffer.")
+(defvar magit-key-mode-buf-name "*magit-key*"
+  "Name of the buffer.")
 
-(defvar magit-key-mode-last-buffer nil
-  "Store the last magit-key buffer used.")
-
-(defvar magit-key-mode-current-args nil
-  "A hash-table of current argument set (which will eventually
-make it to the git command-line).")
+(defvar magit-key-mode-current-args '()
+  "Will contain the arguments to be passed to git.")
 
 (defvar magit-key-mode-current-options '()
-  "Current option set (which will eventually make it to the git
-command-line).")
+  "Will contain the arguments to be passed to git.")
 
 (defvar magit-log-mode-window-conf nil
   "Will hold the pre-menu configuration of magit.")
@@ -61,7 +30,6 @@ command-line).")
       ("rh" "Ranged reflog" magit-reflog-ranged))
      (switches
       ("-m" "Only merge commits" "--merges")
-      ("-do" "Date Order" "--date-order")
       ("-f" "First parent" "--first-parent")
       ("-i" "Case insensitive patterns" "-i")
       ("-pr" "Pickaxe regex" "--pickaxe-regex")
@@ -108,7 +76,6 @@ command-line).")
      (actions
       ("F" "Pull" magit-pull))
      (switches
-      ("-f" "Force" "--force")
       ("-r" "Rebase" "--rebase")))
 
     (branching
@@ -118,21 +85,12 @@ command-line).")
       ("c" "Create" magit-create-branch)
       ("r" "Rename" magit-move-branch)
       ("k" "Delete" magit-delete-branch)
-      ("b" "Checkout" magit-checkout))
-     (switches
-      ("-m" "Merged to HEAD" "--merged")
-      ("-M" "Merged to master" "--merged=master")
-      ("-n" "Not merged to HEAD" "--no-merged")
-      ("-N" "Not merged to master" "--no-merged=master"))
-     (arguments
-      ("=c" "Contains" "--contains=" magit-read-rev-with-default)
-      ("=m" "Merged" "--merged=" magit-read-rev-with-default)
-      ("=n" "Not merged" "--no-merged=" magit-read-rev-with-default)))
+      ("b" "Checkout" magit-checkout)))
 
     (remoting
      (man-page "git-remote")
      (actions
-      ("v" "Remote manager" magit-branch-manager)
+      ("v" "Branch manager" magit-branch-manager)
       ("a" "Add" magit-add-remote)
       ("r" "Rename" magit-rename-remote)
       ("k" "Remove" magit-remove-remote)))
@@ -194,9 +152,9 @@ command-line).")
       ("s" "Start" magit-bisect-start)
       ("u" "Run" magit-bisect-run)
       ("v" "Visualize" magit-bisect-visualize))))
-  "Holds the key, help, function mapping for the log-mode.
-If you modify this make sure you reset `magit-key-mode-key-maps'
-to nil.")
+  "Holds the key, help, function mapping for the log-mode. If you
+  modify this make sure you reset `magit-key-mode-key-maps' to
+  nil.")
 
 (defun magit-key-mode-delete-group (group)
   "Delete a group from `magit-key-mode-key-maps'."
@@ -212,18 +170,17 @@ to nil.")
     magit-key-mode-groups))
 
 (defun magit-key-mode-add-group (group)
-  "Add a new group to `magit-key-mode-key-maps'.
-If there already is a group of that name then this will
-completely remove it and put in its place an empty one of the
-same name."
+  "Add a new group to `magit-key-mode-key-maps'. If there's
+already a group of that name then this will completely remove it
+and put in its place an empty one of the same name."
   (when (assoc group magit-key-mode-groups)
     (magit-key-mode-delete-group group))
   (setq magit-key-mode-groups
-        (cons (list group (list 'actions) (list 'switches)) magit-key-mode-groups)))
+        (cons (list group (list 'actions)) magit-key-mode-groups)))
 
 (defun magit-key-mode-key-defined-p (for-group key)
-  "Return t if KEY is defined as any option within FOR-GROUP.
-The option may be a switch, argument or action."
+  "If KEY is defined as any of switch, argument or action within
+FOR-GROUP then return t"
   (catch 'result
     (let ((options (magit-key-mode-options-for-group for-group)))
       (dolist (type '(actions switches arguments))
@@ -244,31 +201,31 @@ The option may be a switch, argument or action."
     things))
 
 (defun magit-key-mode-insert-argument (for-group key desc arg read-func)
-  "Add a new binding KEY in FOR-GROUP which will use READ-FUNC
-to receive input to apply to argument ARG git is run.  DESC should
+  "Add a new binding (KEY) in FOR-GROUP which will use READ-FUNC
+to receive input to apply to argument ARG git is run. DESC should
 be a brief description of the binding."
   (magit-key-mode-update-group for-group 'arguments key desc arg read-func))
 
 (defun magit-key-mode-insert-switch (for-group key desc switch)
-  "Add a new binding KEY in FOR-GROUP which will add SWITCH to git's
-command line when it runs.  DESC should be a brief description of
+  "Add a new binding (KEY) in FOR-GROUP which will add SWITCH to git's
+command line when it runs. DESC should be a brief description of
 the binding."
   (magit-key-mode-update-group for-group 'switches key desc switch))
 
 (defun magit-key-mode-insert-action (for-group key desc func)
-  "Add a new binding KEY in FOR-GROUP which will run command FUNC.
-DESC should be a brief description of the binding."
+  "Add a new binding (KEY) in FOR-GROUP which will run command
+FUNC. DESC should be a brief description of the binding."
   (magit-key-mode-update-group for-group 'actions key desc func))
 
 (defun magit-key-mode-options-for-group (for-group)
-  "Retrieve the options for the group FOR-GROUP.
-This includes switches, commands and arguments."
+  "Retrieve the options (switches, commands and arguments) for
+the group FOR-GROUP."
   (or (cdr (assoc for-group magit-key-mode-groups))
       (error "Unknown group '%s'" for-group)))
 
 (defun magit-key-mode-help (for-group)
-  "Provide help for a key within FOR-GROUP.
-The user is prompted for the key."
+  "Provide help for a key (which the user is prompted for) within
+FOR-GROUP."
   (let* ((opts (magit-key-mode-options-for-group for-group))
          (man-page (cadr (assoc 'man-page opts)))
          (seq (read-key-sequence
@@ -283,28 +240,17 @@ The user is prompted for the key."
       ;; if there is "?" show a man page if there is one
       ((equal seq "?")
        (if man-page
-           (man man-page)
+         (man man-page)
          (error "No man page associated with `%s'" for-group)))
       (t (error "No help associated with `%s'" seq)))))
 
 (defun magit-key-mode-exec-at-point ()
   "Run action/args/option at point."
   (interactive)
-  (let ((key (or (get-text-property (point) 'key-group-executor)
-                 (error "Nothing at point to do."))))
-    (call-interactively (lookup-key (current-local-map) key))))
-
-(defun magit-key-mode-build-exec-point-alist ()
-  (save-excursion
-    (goto-char (point-min))
-    (let* ((exec (get-text-property (point) 'key-group-executor))
-           (exec-alist (if exec `((,exec . ,(point))) nil)))
-      (cl-do nil ((eobp) (nreverse exec-alist))
-        (when (not (eq exec (get-text-property (point) 'key-group-executor)))
-          (setq exec (get-text-property (point) 'key-group-executor))
-          (when exec (push (cons exec (point)) exec-alist)))
-        (forward-char)))))
-
+  (let* ((key (or (get-text-property (point) 'key-group-executor)
+                  (error "Nothing at point to do.")))
+         (def (lookup-key (current-local-map) key)))
+    (call-interactively def)))
 (defun magit-key-mode-jump-to-next-exec ()
   "Jump to the next action/args/option point."
   (interactive)
@@ -318,8 +264,8 @@ The user is prompted for the key."
     (skip-chars-forward " ")))
 
 (defun magit-key-mode-build-keymap (for-group)
-  "Construct a normal looking keymap for the key mode to use.
-Put it in `magit-key-mode-key-maps' for fast lookup."
+  "Construct a normal looking keymap for the key mode to use and
+put it in magit-key-mode-key-maps for fast lookup."
   (let* ((options (magit-key-mode-options-for-group for-group))
          (actions (cdr (assoc 'actions options)))
          (switches (cdr (assoc 'switches options)))
@@ -343,22 +289,25 @@ Put it in `magit-key-mode-key-maps' for fast lookup."
                                  (interactive)
                                  (magit-key-mode-help ',for-group)))
 
-    (let ((defkey (lambda (k action)
-                    (when (and (lookup-key map (car k))
-                               (not (numberp (lookup-key map (car k)))))
-                      (message "Warning: overriding binding for `%s' in %S"
-                               (car k) for-group)
-                      (ding)
-                      (sit-for 2))
-                    (define-key map (car k)
-                      `(lambda () (interactive) ,action)))))
-      (dolist (k actions)
-        (funcall defkey k `(magit-key-mode-command ',(nth 2 k))))
-      (dolist (k switches)
-        (funcall defkey k `(magit-key-mode-add-option ',for-group ,(nth 2 k))))
-      (dolist (k arguments)
-        (funcall defkey k `(magit-key-mode-add-argument
-                            ',for-group ,(nth 2 k) ',(nth 3 k)))))
+    (flet ((defkey (k action)
+             (when (and (lookup-key map (car k))
+                        (not (numberp (lookup-key map (car k)))))
+               (message "Warning: overriding binding for `%s' in %S"
+                        (car k) for-group)
+               (ding)
+               (sit-for 2))
+             (define-key map (car k)
+               `(lambda () (interactive) ,action))))
+      (when actions
+        (dolist (k actions)
+          (defkey k `(magit-key-mode-command ',(nth 2 k)))))
+      (when switches
+        (dolist (k switches)
+          (defkey k `(magit-key-mode-add-option ',for-group ,(nth 2 k)))))
+      (when arguments
+        (dolist (k arguments)
+          (defkey k `(magit-key-mode-add-argument
+                      ',for-group ,(nth 2 k) ',(nth 3 k))))))
 
     (push (cons for-group map) magit-key-mode-key-maps)
     map))
@@ -381,13 +330,22 @@ command that's eventually invoked.")
         (call-interactively func))
       (magit-key-mode-kill-buffer))))
 
+(defvar magit-key-mode-current-args nil
+  "A hash-table of current argument set (which will eventually
+  make it to the git command-line).")
+
 (defun magit-key-mode-add-argument (for-group arg-name input-func)
   (let ((input (funcall input-func (concat arg-name ": "))))
     (puthash arg-name input magit-key-mode-current-args)
-    (magit-key-mode-redraw for-group)))
+   (magit-key-mode-redraw for-group)))
+
+(defvar magit-key-mode-current-options '()
+  "Current option set (which will eventually make it to the git
+  command-line).")
 
 (defun magit-key-mode-add-option (for-group option-name)
-  "Toggles the appearance of OPTION-NAME in `magit-key-mode-current-options'."
+  "Toggles the appearance of OPTION-NAME in
+`magit-key-mode-current-options'."
   (if (not (member option-name magit-key-mode-current-options))
       (add-to-list 'magit-key-mode-current-options option-name)
     (setq magit-key-mode-current-options
@@ -396,21 +354,22 @@ command that's eventually invoked.")
 
 (defun magit-key-mode-kill-buffer ()
   (interactive)
-  (kill-buffer magit-key-mode-last-buffer))
+  (kill-buffer magit-key-mode-buf-name))
+
+(defvar magit-log-mode-window-conf nil
+  "Pre-popup window configuration.")
 
 (defun magit-key-mode (for-group &optional original-opts)
-  "Mode for magit key selection.
-All commands, switches and options can be toggled/actioned with
-the key combination highlighted before the description."
+  "Mode for magit key selection. All commands, switches and
+options can be toggled/actioned with the key combination
+highlighted before the description."
   (interactive)
   ;; save the window config to restore it as was (no need to make this
   ;; buffer local)
   (setq magit-log-mode-window-conf
         (current-window-configuration))
   ;; setup the mode, draw the buffer
-  (let ((buf (get-buffer-create (format magit-key-mode-buf-name
-                                        (symbol-name for-group)))))
-    (setq magit-key-mode-last-buffer buf)
+  (let ((buf (get-buffer-create magit-key-mode-buf-name)))
     (delete-other-windows)
     (split-window-vertically)
     (other-window 1)
@@ -437,8 +396,6 @@ the key combination highlighted before the description."
 (defun magit-key-mode-redraw (for-group)
   "(re)draw the magit key buffer."
   (let ((buffer-read-only nil)
-        (current-exec (get-text-property (point) 'key-group-executor))
-        (new-exec-pos)
         (old-point (point))
         (is-first (zerop (buffer-size)))
         (actions-p nil))
@@ -448,15 +405,10 @@ the key combination highlighted before the description."
     (setq actions-p (magit-key-mode-draw for-group))
     (delete-trailing-whitespace)
     (setq mode-name "magit-key-mode" major-mode 'magit-key-mode)
-    (when current-exec
-      (setq new-exec-pos (cdr (assoc current-exec (magit-key-mode-build-exec-point-alist)))))
     (if (and is-first actions-p)
       (progn (goto-char actions-p)
              (magit-key-mode-jump-to-next-exec))
-      (if new-exec-pos
-          (progn (goto-char new-exec-pos)
-                 (skip-chars-forward " "))
-          (goto-char old-point))))
+      (goto-char old-point)))
   (setq buffer-read-only t)
   (fit-window-to-buffer))
 
@@ -465,7 +417,8 @@ the key combination highlighted before the description."
   (insert (propertize header 'face 'font-lock-keyword-face) "\n"))
 
 (defvar magit-key-mode-args-in-cols nil
-  "When true, draw arguments in columns as with switches and options.")
+  "When true, draw arguments in columns as with switches and
+  options.")
 
 (defun magit-key-mode-draw-args (args)
   "Draw the args part of the menu."
@@ -510,9 +463,9 @@ the key combination highlighted before the description."
      one-col-each)))
 
 (defun magit-key-mode-draw-in-cols (strings one-col-each)
-  "Given a list of strings, print in columns (using `insert').
-If ONE-COL-EACH is true then don't columify, but rather, draw
-each item on one line."
+  "Given a list of strings, print in columns (using `insert'). If
+ONE-COL-EACH is true then don't columify, but rather, draw each
+item on one line."
   (let ((longest-act (apply 'max (mapcar 'length strings))))
     (while strings
       (let ((str (car strings)))
@@ -530,8 +483,9 @@ each item on one line."
   (insert "\n"))
 
 (defun magit-key-mode-draw (for-group)
-  "Draw actions, switches and parameters.
-Return the point before the actions part, if any, nil otherwise."
+  "Function used to draw actions, switches and parameters.
+
+Returns the point before the actions part, if any."
   (let* ((options (magit-key-mode-options-for-group for-group))
          (switches (cdr (assoc 'switches options)))
          (arguments (cdr (assoc 'arguments options)))
@@ -550,7 +504,7 @@ Return the point before the actions part, if any, nil otherwise."
    (intern (concat "magit-key-mode-popup-" (symbol-name group)))))
 
 (defun magit-key-mode-generate (group)
-  "Generate the key-group menu for GROUP."
+  "Generate the key-group menu for GROUP"
   (let ((opts (magit-key-mode-options-for-group group)))
     (eval
      `(defun ,(intern (concat "magit-key-mode-popup-" (symbol-name group))) nil
@@ -565,4 +519,3 @@ Return the point before the actions part, if any, nil otherwise."
       magit-key-mode-groups)
 
 (provide 'magit-key-mode)
-;;; magit-key-mode.el ends here