Subject: bug#19032: bug#43120: 28.0.50; fido-mode: M-j before completions appear selects wrong choice

From: João Távora <[email-masked]>
Date: Sun, 06 Sep 2020 19:26:47 +0100

Lars Ingebrigtsen <[email-masked]> writes:

> Sean Whitton <[email-masked]> writes:
>
>> On Sat 05 Sep 2020 at 02:25PM +02, Lars Ingebrigtsen wrote:
>>
>>> In which case -- does the following fix this problem?
>>
>> It does indeed.  Hope this patch can be applied.
>
> Thanks for testing; I've now applied the patch.

I've had a look at the original problem that triggered this, and I
wonder if this much simpler patch wouldn't be preferable.  For one, it
doesn't touch the minibuffer.el machinery (which is complicated as it
is) or has any kind of complicated caching semantics.  It just binds a
different command to RET in icomplete-minibuffer-map, presumably solving
19032 (in my limited testing).  It's also guaranteed not to affect
fido-mode.

I think something like this is the way to go for a behaviour change such
as this.

João

>From f4dc81e0c7be75ace3766ca16e2be8bdcc8f0627 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= <[email-masked]>
Date: Sun, 6 Sep 2020 19:03:52 +0100
Subject: [PATCH] Change icomplete-show-matches-on-no-input behaviour for
 Icomplete only

Fixes: bug#19032, bug#43120

Previous fixes to bug#19032 introduced bugs in Fido mode.  This fix
relies on a new command bound to RET.

* etc/NEWS (Miscellaneous): Mention icomplete-show-matches-on-no-input.

* lisp/icomplete.el (icomplete-show-matches-on-no-input): Add comment.
(icomplete-minibuffer-map): Bind icomplete-ret.
(icomplete-ret): New command.
---
 etc/NEWS          |  6 ++++++
 lisp/icomplete.el | 16 +++++++++++++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/etc/NEWS b/etc/NEWS
index 749b28ac3f..d40a4807ec 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -938,6 +938,12 @@ window after starting).  This variable defaults to nil.
 
 ** Miscellaneous
 
+---
+*** 'icomplete-show-matches-on-no-input' behavior change
+Previously, choosing a different completion with commands like 'C-.'
+and then hitting enter would choose the default completion.  Doing
+this will now choose the completion under point.
+
 +++
 *** The user can now customize how "default" values are prompted for.
 The new utility function 'format-prompt' has been added which uses the
diff --git a/lisp/icomplete.el b/lisp/icomplete.el
index f76ab28fb8..c4d5012af9 100644
--- a/lisp/icomplete.el
+++ b/lisp/icomplete.el
@@ -75,7 +75,11 @@ icomplete-tidy-shadowed-file-names
 selection process starts again from the user's $HOME.")
 
 (defcustom icomplete-show-matches-on-no-input nil
-  "When non-nil, show completions when first prompting for input."
+  "When non-nil, show completions when first prompting for input.
+This also means that if you traverse the list of completions with
+commands like `C-.' and just hit RET without typing any
+characters, the match under point will be chosen instead of the
+default."
   :type 'boolean
   :version "24.4")
 
@@ -153,12 +157,22 @@ icomplete-post-command-hook
 (defvar icomplete-minibuffer-map
   (let ((map (make-sparse-keymap)))
     (define-key map [?\M-\t] 'icomplete-force-complete)
+    (define-key map (kbd "RET") 'icomplete-ret)
     (define-key map [?\C-j]  'icomplete-force-complete-and-exit)
     (define-key map [?\C-.]  'icomplete-forward-completions)
     (define-key map [?\C-,]  'icomplete-backward-completions)
     map)
   "Keymap used by `icomplete-mode' in the minibuffer.")
 
+(defun icomplete-ret ()
+  "Exit minibuffer for icomplete."
+  (interactive)
+  (if (and icomplete-show-matches-on-no-input
+           (car completion-all-sorted-completions)
+           (eql (icomplete--field-end) (icomplete--field-beg)))
+      (icomplete-force-complete-and-exit)
+    (exit-minibuffer)))
+
 (defun icomplete-force-complete-and-exit ()
   "Complete the minibuffer with the longest possible match and exit.
 Use the first of the matches if there are any displayed, and use
-- 
2.25.1