]> git.eshelyaron.com Git - emacs.git/commitdiff
New commands for navigating completions from the minibuffer.
authorJuri Linkov <juri@linkov.net>
Tue, 5 Apr 2022 19:20:16 +0000 (22:20 +0300)
committerJuri Linkov <juri@linkov.net>
Tue, 5 Apr 2022 19:20:16 +0000 (22:20 +0300)
* lisp/simple.el (minibuffer-local-shell-command-map):
* lisp/minibuffer.el (minibuffer-local-completion-map):
Bind "M-<up>" to minibuffer-choose-previous-completion,
"M-<down>" to minibuffer-choose-next-completion,
"M-S-<up>" to minibuffer-previous-completion,
"M-S-<down>" to minibuffer-next-completion,
"M-RET" to minibuffer-choose-completion.
(with-minibuffer-completions-window): New macro.
(minibuffer-previous-completion, minibuffer-next-completion)
(minibuffer-choose-previous-completion)
(minibuffer-choose-next-completion)
(minibuffer-choose-completion): New commands.

https://lists.gnu.org/archive/html/emacs-devel/2022-03/msg00335.html

etc/NEWS
lisp/minibuffer.el
lisp/simple.el

index b567caedb355ec103fca293d7144e65d4a3379d9..6b7bb7a18eb25046b16c493b13b59d1ea56b056a 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -601,6 +601,17 @@ value.
 
 ** Minibuffer and Completions
 
+*** New commands for navigating completions from the minibuffer.
+When the minibuffer is the current buffer, typing 'M-<up>' or
+'M-<down>' selects a previous/next completion candidate from the
+"*Completions*" buffer and inserts it to the minibuffer.
+'M-S-<up>' and 'M-S-<down>' do the same, but without inserting
+a completion candidate to the minibuffer, then 'M-RET' can be used
+to choose the currently active candidate from the "*Completions*"
+buffer and exit the minibuffer.  With a prefix argument, 'C-u M-RET'
+inserts the currently active candidate to the minibuffer, but doesn't
+exit the minibuffer.
+
 +++
 *** The "*Completions*" buffer can now be automatically selected.
 To enable this behavior, customize the user option
index 393555fc62f19e4a3ec0a8a17e8c5f96d3ebc646..8a0e15ce05d25b5efb3629607e86ad8e02446423 100644 (file)
@@ -2748,7 +2748,12 @@ The completion method is determined by `completion-at-point-functions'."
   "?"         #'minibuffer-completion-help
   "<prior>"   #'switch-to-completions
   "M-v"       #'switch-to-completions
-  "M-g M-c"   #'switch-to-completions)
+  "M-g M-c"   #'switch-to-completions
+  "M-<up>"    #'minibuffer-choose-previous-completion
+  "M-<down>"  #'minibuffer-choose-next-completion
+  "M-S-<up>"   #'minibuffer-previous-completion
+  "M-S-<down>" #'minibuffer-next-completion
+  "M-RET"      #'minibuffer-choose-completion)
 
 (defvar-keymap minibuffer-local-must-match-map
   :doc "Local keymap for minibuffer input with completion, for exact match."
@@ -4338,6 +4343,64 @@ the minibuffer was activated, and execute the forms."
   (with-minibuffer-selected-window
     (scroll-other-window-down arg)))
 
+(defmacro with-minibuffer-completions-window (&rest body)
+  "Execute the forms in BODY from the minibuffer in its completions window.
+When used in a minibuffer window, select the window with completions,
+and execute the forms."
+  (declare (indent 0) (debug t))
+  `(let ((window (or (get-buffer-window "*Completions*" 0)
+                     ;; Make sure we have a completions window.
+                     (progn (minibuffer-completion-help)
+                            (get-buffer-window "*Completions*" 0)))))
+     (when window
+       (with-selected-window window
+         ,@body))))
+
+(defun minibuffer-previous-completion (&optional n)
+  "Run `previous-completion' from the minibuffer in its completions window."
+  (interactive "p")
+  (with-minibuffer-completions-window
+    (let ((completion-wrap-movement nil))
+      (when completions-highlight-face
+        (setq-local cursor-face-highlight-nonselected-window t))
+      (previous-completion n))))
+
+(defun minibuffer-next-completion (&optional n)
+  "Run `next-completion' from the minibuffer in its completions window."
+  (interactive "p")
+  (with-minibuffer-completions-window
+    (let ((completion-wrap-movement nil))
+      (when completions-highlight-face
+        (setq-local cursor-face-highlight-nonselected-window t))
+      (next-completion n))))
+
+(defun minibuffer-choose-previous-completion (&optional n)
+  "Run `previous-completion' from the minibuffer in its completions window.
+Also insert the selected completion to the minibuffer."
+  (interactive "p")
+  (minibuffer-previous-completion n)
+  (minibuffer-choose-completion t t))
+
+(defun minibuffer-choose-next-completion (&optional n)
+  "Run `next-completion' from the minibuffer in its completions window.
+Also insert the selected completion to the minibuffer."
+  (interactive "p")
+  (minibuffer-next-completion n)
+  (minibuffer-choose-completion t t))
+
+(defun minibuffer-choose-completion (&optional no-exit no-quit)
+  "Run `choose-completion' from the minibuffer in its completions window.
+With prefix argument NO-EXIT, insert the completion at point to the
+minibuffer, but don't exit the minibuffer.  When the prefix argument
+is not provided, then whether to exit the minibuffer depends on the value
+of `completion-no-auto-exit'.
+If NO-QUIT is non-nil, insert the completion at point to the
+minibuffer, but don't quit the completions window."
+  (interactive "P")
+  (with-minibuffer-completions-window
+    (let ((completion-use-base-affixes t))
+      (choose-completion nil no-exit no-quit))))
+
 (defcustom minibuffer-default-prompt-format " (default %s)"
   "Format string used to output \"default\" values.
 When prompting for input, there will often be a default value,
index 5bf1c32e1db9dab49819d6353455af0d0d3d0e26..ef5200650114eae53f1e10bb8097bd2907e3a281 100644 (file)
@@ -3892,6 +3892,11 @@ to the end of the list of defaults just after the default value."
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map minibuffer-local-map)
     (define-key map "\t" 'completion-at-point)
+    (define-key map [M-up]   'minibuffer-choose-previous-completion)
+    (define-key map [M-down] 'minibuffer-choose-next-completion)
+    (define-key map [M-S-up]   'minibuffer-previous-completion)
+    (define-key map [M-S-down] 'minibuffer-next-completion)
+    (define-key map [?\M-\r]   'minibuffer-choose-completion)
     map)
   "Keymap used for completing shell commands in minibuffer.")