aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuri Linkov2023-11-05 19:52:33 +0200
committerJuri Linkov2023-11-05 19:52:33 +0200
commitf0c0ff6bf23ec667ff5487fd94b7f46803ea00ac (patch)
treebec9c209603174eeece0297a772e722fa255ba65
parentad82bc9b29eacad29a441bbb4e87bd09ef1ff1c4 (diff)
downloademacs-f0c0ff6bf23ec667ff5487fd94b7f46803ea00ac.tar.gz
emacs-f0c0ff6bf23ec667ff5487fd94b7f46803ea00ac.zip
New option to use arrows in the minibuffer to select completions (bug#59486)
* lisp/minibuffer.el (minibuffer-visible-completions): New defcustom. (minibuffer-visible-completions-bind): New function. (minibuffer-visible-completions-map): New defvar-keymap. (minibuffer-mode): Set buffer-local minibuffer-completion-auto-choose to nil for minibuffer-visible-completions. (completing-read-default, completion-in-region-mode): Use minibuffer-visible-completions to compose keymap with minibuffer-visible-completions-map. (minibuffer-next-completion): Add new arg VERTICAL, and use next-line-completion. (minibuffer-next-line-completion) (minibuffer-previous-line-completion): New commands.
-rw-r--r--etc/NEWS8
-rw-r--r--lisp/minibuffer.el92
2 files changed, 90 insertions, 10 deletions
diff --git a/etc/NEWS b/etc/NEWS
index c06a013466f..94bcb75835b 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1013,6 +1013,14 @@ Bound to '<UP>' and '<DOWN>' arrow keys, respectively, they navigate
1013the "*Completions*" buffer vertically by lines, wrapping at the 1013the "*Completions*" buffer vertically by lines, wrapping at the
1014top/bottom when 'completion-auto-wrap' is non-nil. 1014top/bottom when 'completion-auto-wrap' is non-nil.
1015 1015
1016*** New user option 'minibuffer-visible-completions'.
1017When customized to non-nil, you can use arrow key in the minibuffer
1018to navigate the completions displayed in the *Completions* window.
1019Typing 'RET' selects the highlighted candidate. 'C-g' hides the
1020completions window. When the completions window is not visible,
1021then all these keys have their usual meaning in the minibuffer.
1022This option is supported for in-buffer completion as well.
1023
1016+++ 1024+++
1017*** New global minor mode 'minibuffer-regexp-mode'. 1025*** New global minor mode 'minibuffer-regexp-mode'.
1018This is a minor mode for editing regular expressions in the minibuffer. 1026This is a minor mode for editing regular expressions in the minibuffer.
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 2120e31775e..45d9a113d0b 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -2707,8 +2707,14 @@ Also respects the obsolete wrapper hook `completion-in-region-functions'.
2707 completion-in-region-mode-predicate) 2707 completion-in-region-mode-predicate)
2708 (setq-local minibuffer-completion-auto-choose nil) 2708 (setq-local minibuffer-completion-auto-choose nil)
2709 (add-hook 'post-command-hook #'completion-in-region--postch) 2709 (add-hook 'post-command-hook #'completion-in-region--postch)
2710 (push `(completion-in-region-mode . ,completion-in-region-mode-map) 2710 (let* ((keymap completion-in-region-mode-map)
2711 minor-mode-overriding-map-alist))) 2711 (keymap (if minibuffer-visible-completions
2712 (make-composed-keymap
2713 (list minibuffer-visible-completions-map
2714 keymap))
2715 keymap)))
2716 (push `(completion-in-region-mode . ,keymap)
2717 minor-mode-overriding-map-alist))))
2712 2718
2713;; Define-minor-mode added our keymap to minor-mode-map-alist, but we want it 2719;; Define-minor-mode added our keymap to minor-mode-map-alist, but we want it
2714;; on minor-mode-overriding-map-alist instead. 2720;; on minor-mode-overriding-map-alist instead.
@@ -2953,8 +2959,46 @@ the mode hook of this mode."
2953 :interactive nil 2959 :interactive nil
2954 ;; Enable text conversion, but always make sure `RET' does 2960 ;; Enable text conversion, but always make sure `RET' does
2955 ;; something. 2961 ;; something.
2956 (setq text-conversion-style 'action)) 2962 (setq text-conversion-style 'action)
2963 (when minibuffer-visible-completions
2964 (setq-local minibuffer-completion-auto-choose nil)))
2965
2966(defcustom minibuffer-visible-completions nil
2967 "When non-nil, visible completions can be navigated from the minibuffer.
2968This means that when the *Completions* buffer is visible in a window,
2969then you can use the arrow keys in the minibuffer to move the cursor
2970in the *Completions* buffer. Then you can type `RET',
2971and the candidate highlighted in the *Completions* buffer
2972will be accepted.
2973But when the *Completions* buffer is not displayed on the screen,
2974then the arrow keys move point in the minibuffer as usual, and
2975`RET' accepts the input typed in the minibuffer."
2976 :type 'boolean
2977 :version "30.1")
2978
2979(defun minibuffer-visible-completions-bind (binding)
2980 "Use BINDING when completions are visible.
2981Return an item that is enabled only when a window
2982displaying the *Completions* buffer exists."
2983 `(menu-item
2984 "" ,binding
2985 :filter ,(lambda (cmd)
2986 (when-let ((window (get-buffer-window "*Completions*" 0)))
2987 (when (eq (buffer-local-value 'completion-reference-buffer
2988 (window-buffer window))
2989 (window-buffer (active-minibuffer-window)))
2990 cmd)))))
2991
2992(defvar-keymap minibuffer-visible-completions-map
2993 :doc "Local keymap for minibuffer input with visible completions."
2994 "<left>" (minibuffer-visible-completions-bind #'minibuffer-previous-completion)
2995 "<right>" (minibuffer-visible-completions-bind #'minibuffer-next-completion)
2996 "<up>" (minibuffer-visible-completions-bind #'minibuffer-previous-line-completion)
2997 "<down>" (minibuffer-visible-completions-bind #'minibuffer-next-line-completion)
2998 "RET" (minibuffer-visible-completions-bind #'minibuffer-choose-completion)
2999 "C-g" (minibuffer-visible-completions-bind #'minibuffer-hide-completions))
2957 3000
3001
2958;;; Completion tables. 3002;;; Completion tables.
2959 3003
2960(defun minibuffer--double-dollars (str) 3004(defun minibuffer--double-dollars (str)
@@ -4370,6 +4414,11 @@ See `completing-read' for the meaning of the arguments."
4370 ;; in minibuffer-local-filename-completion-map can 4414 ;; in minibuffer-local-filename-completion-map can
4371 ;; override bindings in base-keymap. 4415 ;; override bindings in base-keymap.
4372 base-keymap))) 4416 base-keymap)))
4417 (keymap (if minibuffer-visible-completions
4418 (make-composed-keymap
4419 (list minibuffer-visible-completions-map
4420 keymap))
4421 keymap))
4373 (buffer (current-buffer)) 4422 (buffer (current-buffer))
4374 (c-i-c completion-ignore-case) 4423 (c-i-c completion-ignore-case)
4375 (result 4424 (result
@@ -4489,16 +4538,21 @@ selected by these commands to the minibuffer."
4489 :type 'boolean 4538 :type 'boolean
4490 :version "29.1") 4539 :version "29.1")
4491 4540
4492(defun minibuffer-next-completion (&optional n) 4541(defun minibuffer-next-completion (&optional n vertical)
4493 "Move to the next item in its completions window from the minibuffer. 4542 "Move to the next item in its completions window from the minibuffer.
4543When the optional argument VERTICAL is non-nil, move vertically
4544to the next item on the next line using `next-line-completion'.
4545Otherwise, move to the next item horizontally using `next-completion'.
4494When `minibuffer-completion-auto-choose' is non-nil, then also 4546When `minibuffer-completion-auto-choose' is non-nil, then also
4495insert the selected completion to the minibuffer." 4547insert the selected completion candidate to the minibuffer."
4496 (interactive "p") 4548 (interactive "p")
4497 (let ((auto-choose minibuffer-completion-auto-choose)) 4549 (let ((auto-choose minibuffer-completion-auto-choose))
4498 (with-minibuffer-completions-window 4550 (with-minibuffer-completions-window
4499 (when completions-highlight-face 4551 (when completions-highlight-face
4500 (setq-local cursor-face-highlight-nonselected-window t)) 4552 (setq-local cursor-face-highlight-nonselected-window t))
4501 (next-completion (or n 1)) 4553 (if vertical
4554 (next-line-completion (or n 1))
4555 (next-completion (or n 1)))
4502 (when auto-choose 4556 (when auto-choose
4503 (let ((completion-use-base-affixes t)) 4557 (let ((completion-use-base-affixes t))
4504 (choose-completion nil t t)))))) 4558 (choose-completion nil t t))))))
@@ -4506,17 +4560,35 @@ insert the selected completion to the minibuffer."
4506(defun minibuffer-previous-completion (&optional n) 4560(defun minibuffer-previous-completion (&optional n)
4507 "Move to the previous item in its completions window from the minibuffer. 4561 "Move to the previous item in its completions window from the minibuffer.
4508When `minibuffer-completion-auto-choose' is non-nil, then also 4562When `minibuffer-completion-auto-choose' is non-nil, then also
4509insert the selected completion to the minibuffer." 4563insert the selected completion candidate to the minibuffer."
4510 (interactive "p") 4564 (interactive "p")
4511 (minibuffer-next-completion (- (or n 1)))) 4565 (minibuffer-next-completion (- (or n 1))))
4512 4566
4567(defun minibuffer-next-line-completion (&optional n)
4568 "Move to the next completion line from the minibuffer.
4569This means to move to the completion candidate on the next line
4570in the *Completions* buffer while point stays in the minibuffer.
4571When `minibuffer-completion-auto-choose' is non-nil, then also
4572insert the selected completion candidate to the minibuffer."
4573 (interactive "p")
4574 (minibuffer-next-completion (or n 1) t))
4575
4576(defun minibuffer-previous-line-completion (&optional n)
4577 "Move to the previous completion line from the minibuffer.
4578This means to move to the completion candidate on the previous line
4579in the *Completions* buffer while point stays in the minibuffer.
4580When `minibuffer-completion-auto-choose' is non-nil, then also
4581insert the selected completion candidate to the minibuffer."
4582 (interactive "p")
4583 (minibuffer-next-completion (- (or n 1)) t))
4584
4513(defun minibuffer-choose-completion (&optional no-exit no-quit) 4585(defun minibuffer-choose-completion (&optional no-exit no-quit)
4514 "Run `choose-completion' from the minibuffer in its completions window. 4586 "Run `choose-completion' from the minibuffer in its completions window.
4515With prefix argument NO-EXIT, insert the completion at point to the 4587With prefix argument NO-EXIT, insert the completion candidate at point to
4516minibuffer, but don't exit the minibuffer. When the prefix argument 4588the minibuffer, but don't exit the minibuffer. When the prefix argument
4517is not provided, then whether to exit the minibuffer depends on the value 4589is not provided, then whether to exit the minibuffer depends on the value
4518of `completion-no-auto-exit'. 4590of `completion-no-auto-exit'.
4519If NO-QUIT is non-nil, insert the completion at point to the 4591If NO-QUIT is non-nil, insert the completion candidate at point to the
4520minibuffer, but don't quit the completions window." 4592minibuffer, but don't quit the completions window."
4521 (interactive "P") 4593 (interactive "P")
4522 (with-minibuffer-completions-window 4594 (with-minibuffer-completions-window