GNU bug report logs -
#80024
30.1.90; minibuffer-visible-completions always rebinds left/right
Previous Next
To reply to this bug, email your comments to 80024 AT debbugs.gnu.org.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
juri <at> linkov.net, bug-gnu-emacs <at> gnu.org:
bug#80024; Package
emacs.
(Wed, 17 Dec 2025 17:31:03 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Spencer Baugh <sbaugh <at> janestreet.com>:
New bug report received and forwarded. Copy sent to
juri <at> linkov.net, bug-gnu-emacs <at> gnu.org.
(Wed, 17 Dec 2025 17:31:03 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
It would be nice to have a version of minibuffer-visible-completions
which did not rebind <left>/<right> so that they could be used to
navigate in the minibuffer. This would in turn mean that <up>/<down>
would need to be bound to minibuffer-{previous,next}-completion so that
users can still navigate between all completions.
The motivation is just that novice users find the rebinding of
<left>/<right> confusing, and don't find it intuitive to use C-g to
dismiss *Completions* and be able to use <left>/<right> again.
While we're at it, I think it would be good for <up>/<down> to navigate
between completions when point is on the first/last line of the
minibuffer, respectively. Then all the usual arrow key bindings would
work for minibuffer navigation, while <up> and <down> are still usable
for navigating completions.
In GNU Emacs 30.1.90 (build 90, x86_64-pc-linux-gnu, X toolkit, cairo
version 1.15.12, Xaw scroll bars) of 2025-12-04 built on
igm-qws-u22796a
Repository revision: 88878f209ee0f1699952b1ba5fb829c502f5959f
Repository branch: HEAD
Windowing system distributor 'The X.Org Foundation', version 11.0.12011000
System Description: Rocky Linux 8.10 (Green Obsidian)
Configured using:
'configure --with-x-toolkit=lucid --without-gpm --without-gconf
--without-selinux --without-imagemagick --with-modules --with-gif=no
--with-cairo --with-rsvg --without-compress-install --with-tree-sitter
--with-native-compilation=aot
PKG_CONFIG_PATH=/usr/local/home/garnish/libtree-sitter/0.22.6-1/lib/pkgconfig/'
Configured features:
CAIRO DBUS FREETYPE GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG LIBSYSTEMD
LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP
SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER X11 XDBE XIM
XINPUT2 XPM LUCID ZLIB
Information forwarded
to
bug-gnu-emacs <at> gnu.org:
bug#80024; Package
emacs.
(Thu, 18 Dec 2025 16:41:02 GMT)
Full text and
rfc822 format available.
Message #8 received at 80024 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
> It would be nice to have a version of minibuffer-visible-completions
> which did not rebind <left>/<right> so that they could be used to
> navigate in the minibuffer. This would in turn mean that <up>/<down>
> would need to be bound to minibuffer-{previous,next}-completion so that
> users can still navigate between all completions.
>
> The motivation is just that novice users find the rebinding of
> <left>/<right> confusing, and don't find it intuitive to use C-g to
> dismiss *Completions* and be able to use <left>/<right> again.
>
> While we're at it, I think it would be good for <up>/<down> to navigate
> between completions when point is on the first/last line of the
> minibuffer, respectively. Then all the usual arrow key bindings would
> work for minibuffer navigation, while <up> and <down> are still usable
> for navigating completions.
Finding the most convenient behavior requires a lot of experimenting.
I tried to implement all parts above, but the last part doesn't feel intuitive.
For example, when completion is required in the middle of the multi-line
minibuffer, it's expected that up/down will navigate the completions
instead of navigating lines in the minibuffer.
Anyway here is the current implementation. It would be nice
if you try and possibly rearrange the conditions inside
'minibuffer-visible-completions--filter' to find the most
intuitive behavior.
[minibuffer-visible-completions-up-down.patch (text/x-diff, inline)]
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 5727cf9f479..b82e92e60e4 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -3458,7 +3458,9 @@ minibuffer-visible-completions
If the *Completions* buffer is not displayed on the screen, or this
variable is nil, the arrow keys move point in the minibuffer as usual,
and `RET' accepts the input typed into the minibuffer."
- :type 'boolean
+ :type '(choice (const :tag "Disable completions navigation" nil)
+ (const :tag "Enable up/down/left/right" t)
+ (const :tag "Enable only up/down" up-down))
:version "30.1")
(defvar minibuffer-visible-completions--always-bind nil
@@ -3486,7 +3488,21 @@ minibuffer-visible-completions--filter
(if minibuffer-visible-completions--always-bind
cmd
(when-let* ((window (minibuffer--completions-visible)))
- cmd)))
+ (cond ((eq minibuffer-visible-completions 'up-down)
+ (when (and (or (not (eq (buffer-local-value
+ 'completions-format
+ (window-buffer window))
+ 'one-column))
+ (member (key-description
+ (vector last-input-event))
+ '("<up>" "<down>")))
+ (or
+ ;; On the first line
+ (not (zerop (save-excursion (forward-line -1))))
+ ;; On the last line
+ (not (zerop (save-excursion (forward-line 1))))))
+ cmd))
+ (t cmd)))))
(defun minibuffer-visible-completions--bind (binding)
"Use BINDING when completions are visible.
Information forwarded
to
bug-gnu-emacs <at> gnu.org:
bug#80024; Package
emacs.
(Mon, 22 Dec 2025 21:44:02 GMT)
Full text and
rfc822 format available.
Message #11 received at 80024 <at> debbugs.gnu.org (full text, mbox):
Juri Linkov <juri <at> linkov.net> writes:
>> It would be nice to have a version of minibuffer-visible-completions
>> which did not rebind <left>/<right> so that they could be used to
>> navigate in the minibuffer. This would in turn mean that <up>/<down>
>> would need to be bound to minibuffer-{previous,next}-completion so that
>> users can still navigate between all completions.
>>
>> The motivation is just that novice users find the rebinding of
>> <left>/<right> confusing, and don't find it intuitive to use C-g to
>> dismiss *Completions* and be able to use <left>/<right> again.
>>
>> While we're at it, I think it would be good for <up>/<down> to navigate
>> between completions when point is on the first/last line of the
>> minibuffer, respectively. Then all the usual arrow key bindings would
>> work for minibuffer navigation, while <up> and <down> are still usable
>> for navigating completions.
>
> Finding the most convenient behavior requires a lot of experimenting.
> I tried to implement all parts above, but the last part doesn't feel intuitive.
> For example, when completion is required in the middle of the multi-line
> minibuffer, it's expected that up/down will navigate the completions
> instead of navigating lines in the minibuffer.
Ah, that makes sense to me, right.
> Anyway here is the current implementation. It would be nice
> if you try and possibly rearrange the conditions inside
> 'minibuffer-visible-completions--filter' to find the most
> intuitive behavior.
Actually on reflection I feel like just
(keymap-set minibuffer-local-completion-map "<up>" #'minibuffer-previous-completion)
(keymap-set minibuffer-local-completion-map "<down>" #'minibuffer-next-completion)
provides the best behavior. (with null minibuffer-visible-completions)
It is unfortunate that this loses the ability to use up/down to navigate
history. But I guess all the non-default completion frontends lose that
ability too, so maybe it's fine. M-n and M-p are perfectly good ways to
navigate history. Hmm.
Information forwarded
to
bug-gnu-emacs <at> gnu.org:
bug#80024; Package
emacs.
(Tue, 23 Dec 2025 07:37:02 GMT)
Full text and
rfc822 format available.
Message #14 received at 80024 <at> debbugs.gnu.org (full text, mbox):
>> Anyway here is the current implementation. It would be nice
>> if you try and possibly rearrange the conditions inside
>> 'minibuffer-visible-completions--filter' to find the most
>> intuitive behavior.
>
> Actually on reflection I feel like just
>
> (keymap-set minibuffer-local-completion-map "<up>" #'minibuffer-previous-completion)
> (keymap-set minibuffer-local-completion-map "<down>" #'minibuffer-next-completion)
>
> provides the best behavior. (with null minibuffer-visible-completions)
>
> It is unfortunate that this loses the ability to use up/down to navigate
> history. But I guess all the non-default completion frontends lose that
> ability too, so maybe it's fine. M-n and M-p are perfectly good ways to
> navigate history. Hmm.
Mnemonically <up> looks like the right key to pop up the completions buffer,
but after displaying the buffer <up> moves to the last completion
at the end of the buffer that would be confusing to users.
Requesting to display the buffer explicitly with e.g <TAB> before navigating it
would be more intuitive for users. And also up/down will retain
their ability to navigate history before the completions are displayed.
So we could still add an option 'up-down' to 'minibuffer-visible-completions'.
Information forwarded
to
bug-gnu-emacs <at> gnu.org:
bug#80024; Package
emacs.
(Tue, 23 Dec 2025 16:23:02 GMT)
Full text and
rfc822 format available.
Message #17 received at 80024 <at> debbugs.gnu.org (full text, mbox):
Juri Linkov <juri <at> linkov.net> writes:
>>> Anyway here is the current implementation. It would be nice
>>> if you try and possibly rearrange the conditions inside
>>> 'minibuffer-visible-completions--filter' to find the most
>>> intuitive behavior.
>>
>> Actually on reflection I feel like just
>>
>> (keymap-set minibuffer-local-completion-map "<up>" #'minibuffer-previous-completion)
>> (keymap-set minibuffer-local-completion-map "<down>" #'minibuffer-next-completion)
>>
>> provides the best behavior. (with null minibuffer-visible-completions)
>>
>> It is unfortunate that this loses the ability to use up/down to navigate
>> history. But I guess all the non-default completion frontends lose that
>> ability too, so maybe it's fine. M-n and M-p are perfectly good ways to
>> navigate history. Hmm.
>
> Mnemonically <up> looks like the right key to pop up the completions buffer,
> but after displaying the buffer <up> moves to the last completion
> at the end of the buffer that would be confusing to users.
I'm mostly inspired by the completions available in other software like
the Firefox address bar, which I also think is the inspiration for most
other Emacs completion frontends. In such UIs:
- the completions are automatically shown, they don't need to be requested
- up/down navigates between the completions
For Emacs completions, the first part is done by
completion-eager-display. The second part is done by this change to the
<up>/<down> bindings.
> Requesting to display the buffer explicitly with e.g <TAB> before navigating it
> would be more intuitive for users. And also up/down will retain
> their ability to navigate history before the completions are displayed.
>
> So we could still add an option 'up-down' to 'minibuffer-visible-completions'.
With completion-eager-display, I find that the completions are basically
always displayed. So the minibuffer-visible-completions bindings are
always in effect, even though they're bound conditionally on
*Completions* being displayed. So the conditinal binding doesn't end up
being useful, it's just occasionally confusing.
Information forwarded
to
bug-gnu-emacs <at> gnu.org:
bug#80024; Package
emacs.
(Tue, 23 Dec 2025 17:18:03 GMT)
Full text and
rfc822 format available.
Message #20 received at 80024 <at> debbugs.gnu.org (full text, mbox):
>> Mnemonically <up> looks like the right key to pop up the completions buffer,
>> but after displaying the buffer <up> moves to the last completion
>> at the end of the buffer that would be confusing to users.
>
> I'm mostly inspired by the completions available in other software like
> the Firefox address bar, which I also think is the inspiration for most
> other Emacs completion frontends. In such UIs:
>
> - the completions are automatically shown, they don't need to be requested
> - up/down navigates between the completions
>
> For Emacs completions, the first part is done by
> completion-eager-display. The second part is done by this change to the
> <up>/<down> bindings.
Indeed. Although there is still one difference with Firefox where
the list of completions mixes various types of suggestions: from history,
from bookmarks, etc. However, in Emacs these lists are separate:
1. TAB - list of completions
2. C-x up - list of history items
3. C-x down - list of suggestions
Information forwarded
to
bug-gnu-emacs <at> gnu.org:
bug#80024; Package
emacs.
(Wed, 07 Jan 2026 14:47:02 GMT)
Full text and
rfc822 format available.
Message #23 received at 80024 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Spencer Baugh <sbaugh <at> janestreet.com> writes:
> With completion-eager-display, I find that the completions are basically
> always displayed. So the minibuffer-visible-completions bindings are
> always in effect, even though they're bound conditionally on
> *Completions* being displayed. So the conditinal binding doesn't end up
> being useful, it's just occasionally confusing.
Well, I was a bit too hasty in thinking this. I did:
(keymap-set minibuffer-local-completion-map "<up>" #'minibuffer-previous-completion)
(keymap-set minibuffer-local-completion-map "<down>" #'minibuffer-next-completion)
But this is annoying to users that don't have
completion-eager-display=t. They, of course, were using <up> and <down>
for history navigation and don't want to have to learn to use M-p and
M-n instead.
So I guess I still want conditional bindings which depend on whether the
*Completions* buffer is displayed.
How about this?
[0001-minibuffer-visible-completions-up-down.patch (text/x-patch, inline)]
From e641b80f89c8f45c6b0c3589dc57a42a08aa3979 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh <at> janestreet.com>
Date: Wed, 7 Jan 2026 09:45:37 -0500
Subject: [PATCH] minibuffer-visible-completions up-down
---
lisp/emacs-lisp/crm.el | 6 +-----
lisp/minibuffer.el | 30 +++++++++++++++++++-----------
lisp/simple.el | 2 +-
3 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el
index b91fa165986..6bd763d2ea2 100644
--- a/lisp/emacs-lisp/crm.el
+++ b/lisp/emacs-lisp/crm.el
@@ -254,11 +254,7 @@ completing-read-multiple
(let* ((map (if require-match
crm-local-must-match-map
crm-local-completion-map))
- (map (if minibuffer-visible-completions
- (make-composed-keymap
- (list minibuffer-visible-completions-map
- map))
- map))
+ (map (minibuffer-visible-completions--maybe-compose-map map))
(buffer (current-buffer))
input)
(minibuffer-with-setup-hook
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 89e6f1430b5..418e58bd5c4 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -3195,11 +3195,7 @@ completion-in-region-mode
(setq-local minibuffer-completion-auto-choose nil)
(add-hook 'post-command-hook #'completion-in-region--postch)
(let* ((keymap completion-in-region-mode-map)
- (keymap (if minibuffer-visible-completions
- (make-composed-keymap
- (list minibuffer-visible-completions-map
- keymap))
- keymap)))
+ (keymap (minibuffer-visible-completions--maybe-compose-map keymap)))
(push `(completion-in-region-mode . ,keymap)
minor-mode-overriding-map-alist))))
@@ -3472,7 +3468,9 @@ minibuffer-visible-completions
If the *Completions* buffer is not displayed on the screen, or this
variable is nil, the arrow keys move point in the minibuffer as usual,
and `RET' accepts the input typed into the minibuffer."
- :type 'boolean
+ :type '(choice (const :tag "Disable completions navigation" nil)
+ (const :tag "Enable up/down/left/right" t)
+ (const :tag "Enable only up/down" up-down))
:version "30.1")
(defvar minibuffer-visible-completions--always-bind nil
@@ -3517,6 +3515,20 @@ minibuffer-visible-completions-map
"<up>" (minibuffer-visible-completions--bind #'minibuffer-previous-line-completion)
"<down>" (minibuffer-visible-completions--bind #'minibuffer-next-line-completion)
"C-g" (minibuffer-visible-completions--bind #'minibuffer-hide-completions))
+
+(defvar-keymap minibuffer-visible-completions-up-down-map
+ :doc "Local keymap for minibuffer input with visible completions, just binding up/down."
+ "<up>" (minibuffer-visible-completions--bind #'minibuffer-previous-completion)
+ "<down>" (minibuffer-visible-completions--bind #'minibuffer-next-completion))
+
+(defun minibuffer-visible-completions--maybe-compose-map (map)
+ (cond
+ ((eq minibuffer-visible-completions 'up-down)
+ (make-composed-keymap (list minibuffer-visible-completions-up-down-map map)))
+ ((eq minibuffer-visible-completions t)
+ (make-composed-keymap (list minibuffer-visible-completions-map map)))
+ (t map)))
+
;;; Completion tables.
@@ -5172,11 +5184,7 @@ completing-read-default
;; in minibuffer-local-filename-completion-map can
;; override bindings in base-keymap.
base-keymap)))
- (keymap (if minibuffer-visible-completions
- (make-composed-keymap
- (list minibuffer-visible-completions-map
- keymap))
- keymap))
+ (keymap (minibuffer-visible-completions--maybe-compose-map keymap))
(buffer (current-buffer))
(c-i-c completion-ignore-case)
(result
diff --git a/lisp/simple.el b/lisp/simple.el
index d79aa2d3046..f06e473d383 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -10730,7 +10730,7 @@ completion-setup-function
(if (display-mouse-p)
"Click or type \\[minibuffer-choose-completion] on a completion to select it.\n"
"Type \\[minibuffer-choose-completion] on a completion to select it.\n"))
- (if minibuffer-visible-completions
+ (if (eq minibuffer-visible-completions t)
(substitute-command-keys
"Type \\[minibuffer-next-completion], \\[minibuffer-previous-completion], \
\\[minibuffer-next-line-completion], \\[minibuffer-previous-line-completion] \
--
2.43.7
Information forwarded
to
bug-gnu-emacs <at> gnu.org:
bug#80024; Package
emacs.
(Wed, 07 Jan 2026 18:18:02 GMT)
Full text and
rfc822 format available.
Message #26 received at 80024 <at> debbugs.gnu.org (full text, mbox):
> Well, I was a bit too hasty in thinking this. I did:
>
> (keymap-set minibuffer-local-completion-map "<up>" #'minibuffer-previous-completion)
> (keymap-set minibuffer-local-completion-map "<down>" #'minibuffer-next-completion)
>
> But this is annoying to users that don't have
> completion-eager-display=t. They, of course, were using <up> and <down>
> for history navigation and don't want to have to learn to use M-p and
> M-n instead.
>
> So I guess I still want conditional bindings which depend on whether the
> *Completions* buffer is displayed.
>
> How about this?
It's nice that this option will match the default keys
'M-<up>' and 'M-<down>' in 'minibuffer-local-completion-map'.
BTW, there is one compilation warning:
minibuffer.el:3505:16: Warning: defvar
`minibuffer-visible-completions-up-down-map'
docstring wider than 80 characters
This bug report was last modified 4 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.