GNU bug report logs - #62700
29.0.60; minibuffer-{previous,next,choose}-completion behave unintuitively when point is not at end of buffer

Previous Next

Package: emacs;

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

Date: Thu, 6 Apr 2023 17:57:01 UTC

Severity: normal

Found in version 29.0.60

Fixed in version 30.0.50

Done: Juri Linkov <juri <at> linkov.net>

Bug is archived. No further changes may be made.

Full log


Message #77 received at 62700 <at> debbugs.gnu.org (full text, mbox):

From: sbaugh <at> catern.com
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 62700 <at> debbugs.gnu.org, Spencer Baugh <sbaugh <at> janestreet.com>,
 juri <at> linkov.net
Subject: Re: bug#62700: 29.0.60; minibuffer-{previous,next,choose}-completion
 behave unintuitively when point is not at end of buffer
Date: Fri, 21 Apr 2023 18:56:35 +0000 (UTC)
[Message part 1 (text/plain, inline)]
Eli Zaretskii <eliz <at> gnu.org> writes:

>> Cc: 62700 <at> debbugs.gnu.org, Spencer Baugh <sbaugh <at> catern.com>
>> From: Spencer Baugh <sbaugh <at> janestreet.com>
>> Date: Thu, 20 Apr 2023 14:46:45 -0400
>> 
>> Juri Linkov <juri <at> linkov.net> writes:
>> >>>>> It just needs more testing for different categories of completion.
>> >>>>
>> >>>> Which categories do you have in mind?
>> >>>
>> >>> Actually, I can't find categories where it could fail.
>> >>> So your patch looks safe to push.
>> >>
>> >> Can we go ahead and push it to Emacs master, then?  I will work on the
>> >> changing-only-new-code backport for Emacs 29 as Eli requested.
>> >
>> > But your patch changes only new code.
>> 
>> Ah, I thought Eli still wanted a backport version because this changes
>> code which has been on Emacs 29 for over a year.
>
> Indeed, that's what I would like to see on the release branch.  Mainly
> because even if this is deemed a bug, it happens in a relatively rare
> situation, so I'd like to avoid risking breakage in code which affects
> other situations.

Here's the backport for the release branch.  (FYI, my papers have been
signed and the FSF copyright clerk has approved accepting my
contributions again)

[0001-Handle-point-not-at-EOB-in-minibuffer-choose-complet.patch (text/x-patch, inline)]
From a159cfb8ee80e24de180d002caa61119edc7afc1 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh <at> catern.com>
Date: Fri, 21 Apr 2023 14:55:00 -0400
Subject: [PATCH] Handle point not at EOB in minibuffer-choose-completion

Without this change, only the minibuffer contents before point are
cleared when a completion is chosen, which results in stray text when
point is in the middle of the minibuffer.

After this change, we heuristically decide either to clear the whole
buffer or only part of it, taking into account the location of point.

This is a backport for the Emacs 29 release branch of a simpler fix in
minibuffer-completion-help.

* lisp/minibuffer.el (minibuffer-next-completion):
(minibuffer-choose-completion):
Recalculate completion-base-affixes with point
---
 lisp/minibuffer.el | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index dfb06b5b88f..86946ec9ce1 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -4464,13 +4464,21 @@ minibuffer-next-completion
 When `minibuffer-completion-auto-choose' is non-nil, then also
 insert the selected completion to the minibuffer."
   (interactive "p")
-  (let ((auto-choose minibuffer-completion-auto-choose))
+  (let* ((auto-choose minibuffer-completion-auto-choose)
+         ;; Backported fix for bug#62700
+         (md (completion--field-metadata (minibuffer--completion-prompt-end)))
+         (base-suffix
+          (if (eq (alist-get 'category (cdr md)) 'file)
+              (buffer-substring (save-excursion (search-forward "/" nil t) (point))
+                                (point-max))
+            "")))
     (with-minibuffer-completions-window
       (when completions-highlight-face
         (setq-local cursor-face-highlight-nonselected-window t))
       (next-completion (or n 1))
       (when auto-choose
-        (let ((completion-use-base-affixes t))
+        (let ((completion-use-base-affixes t)
+              (completion-base-affixes (list (car completion-base-affixes) base-suffix)))
           (choose-completion nil t t))))))
 
 (defun minibuffer-previous-completion (&optional n)
@@ -4489,9 +4497,17 @@ minibuffer-choose-completion
 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))))
+  ;; Backported fix for bug#62700
+  (let* ((md (completion--field-metadata (minibuffer--completion-prompt-end)))
+         (base-suffix
+          (if (eq (alist-get 'category (cdr md)) 'file)
+              (buffer-substring (save-excursion (search-forward "/" nil t) (point))
+                                (point-max))
+            "")))
+    (with-minibuffer-completions-window
+      (let ((completion-use-base-affixes t)
+            (completion-base-affixes (list (car completion-base-affixes) base-suffix)))
+        (choose-completion nil no-exit no-quit)))))
 
 (defun minibuffer-complete-history ()
   "Complete the minibuffer history as far as possible.
-- 
2.38.0


This bug report was last modified 1 year and 39 days ago.

Previous Next


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