Subject: bug#53935: 27.2; [PATCH] ecomplete.el: Auto-select when there is only a single option

From: Phil Sainty <[email-masked]>
Date: Fri, 11 Feb 2022 23:24:15 +1300

I realised this would be better with some minor refactoring of
the existing code, so I'm attaching a new version of that patch.

I've used "git diff --ignore-space-change" for clarity (hence the
indentation isn't correct).
diff --git a/lisp/ecomplete.el b/lisp/ecomplete.el
index 260657e0f7..ad3cf199e7 100644
--- a/lisp/ecomplete.el
+++ b/lisp/ecomplete.el
@@ -149,10 +149,14 @@ ecomplete-get-matches
 (defun ecomplete-display-matches (type word &optional choose)
   "Display the top-rated elements TYPE that match WORD.
 If CHOOSE, allow the user to choose interactively between the
-matches."
+matches.
+
+Auto-select when `ecomplete-message-display-abbrev-auto-select' is
+non-nil and there is only a single completion option available."
   (let* ((matches (ecomplete-get-matches type word))
+         (match-list (and matches (split-string matches "\n")))
+         (max-lines (and matches (- (length match-list) 2)))
          (line 0)
-	 (max-lines (when matches (- (length (split-string matches "\n")) 2)))
          (message-log-max nil)
          command highlight)
     (if (not matches)
@@ -163,25 +167,30 @@ ecomplete-display-matches
 	  (progn
 	    (message "%s" matches)
 	    nil)
-	(setq highlight (ecomplete-highlight-match-line matches line))
+        (if (and ecomplete-message-display-abbrev-auto-select
+                 (eql 0 max-lines))
+            ;; Auto-select when only one option is available.
+            (nth 0 match-list)
+          ;; Interactively choose from the filtered completions.
           (let ((local-map (make-sparse-keymap))
                 (prev-func (lambda () (setq line (max (1- line) 0))))
                 (next-func (lambda () (setq line (min (1+ line) max-lines))))
                 selected)
             (define-key local-map (kbd "RET")
-	    (lambda () (setq selected (nth line (split-string matches "\n")))))
+              (lambda () (setq selected (nth line match-list))))
 	    (define-key local-map (kbd "M-n") next-func)
 	    (define-key local-map (kbd "<down>") next-func)
 	    (define-key local-map (kbd "M-p") prev-func)
 	    (define-key local-map (kbd "<up>") prev-func)
             (let ((overriding-local-map local-map))
+              (setq highlight (ecomplete-highlight-match-line matches line))
               (while (and (null selected)
 			  (setq command (read-key-sequence highlight))
 			  (lookup-key local-map command))
 	        (apply (key-binding command) nil)
 	        (setq highlight (ecomplete-highlight-match-line matches line))))
 	    (message (or selected "Abort"))
-	  selected)))))
+            selected))))))
 
 (defun ecomplete-highlight-match-line (matches line)
   (with-temp-buffer