GNU bug report logs - #80024
30.1.90; minibuffer-visible-completions always rebinds left/right

Previous Next

Package: emacs;

Reported by: Spencer Baugh <sbaugh <at> janestreet.com>

Date: Wed, 17 Dec 2025 17:31:02 UTC

Severity: normal

Found in version 30.1.90

To reply to this bug, email your comments to 80024 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


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):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.1.90; minibuffer-visible-completions always rebinds left/right
Date: Wed, 17 Dec 2025 12:30:03 -0500
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):

From: Juri Linkov <juri <at> linkov.net>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: 80024 <at> debbugs.gnu.org
Subject: Re: bug#80024: 30.1.90; minibuffer-visible-completions always
 rebinds left/right
Date: Thu, 18 Dec 2025 18:38:41 +0200
[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.

This bug report was last modified 1 day ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.