emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 4e2c70272f 2/2: New commands for navigating completions from the


From: Juri Linkov
Subject: master 4e2c70272f 2/2: New commands for navigating completions from the minibuffer.
Date: Tue, 5 Apr 2022 15:21:58 -0400 (EDT)

branch: master
commit 4e2c70272f4fbb686fd9aa4168b058ca1ad6f922
Author: Juri Linkov <juri@linkov.net>
Commit: Juri Linkov <juri@linkov.net>

    New commands for navigating completions from the minibuffer.
    
    * 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           | 11 +++++++++
 lisp/minibuffer.el | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 lisp/simple.el     |  5 +++++
 3 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/etc/NEWS b/etc/NEWS
index b567caedb3..6b7bb7a18e 100644
--- 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
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 393555fc62..8a0e15ce05 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -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,
diff --git a/lisp/simple.el b/lisp/simple.el
index 5bf1c32e1d..ef52006501 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -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.")
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]