From 9a47b630b82dbd02f9164260d0dda26a5ab69182 Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Thu, 23 Mar 2023 08:00:19 -0700 Subject: spw/icomplete-tab: exit completion when only one candidate remains --- .emacs.d/init.el | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.emacs.d/init.el b/.emacs.d/init.el index ba7d662c..54d86c55 100644 --- a/.emacs.d/init.el +++ b/.emacs.d/init.el @@ -1239,8 +1239,8 @@ To be used only when it seems to be necessary." (when-let* ((current (car completion-all-sorted-completions))) ;; For in-buffer completion it should always be fine to just call ;; `icomplete-force-complete', and not exit, because of how in-buffer - ;; completion uses a transient map. An alternative would be to guess - ;; whether completing a file name, e.g. (string-suffix-p "/" current). + ;; completion uses a transient map (an alternative would be to guess + ;; whether completing a file name, e.g. (string-suffix-p "/" current)) ... (if (or (not (window-minibuffer-p)) (and (spw/minibuffer-completing-file-name-p) (let ((dir (file-name-directory (minibuffer-contents)))) @@ -1248,7 +1248,19 @@ To be used only when it seems to be necessary." (if dir (expand-file-name (directory-file-name current) (substitute-env-vars dir)) current))))) - (icomplete-force-complete) + (progn + (icomplete-force-complete) + (unless (window-minibuffer-p) + ;; ... but if there is now only one candidate remaining, then it's + ;; the one we just selected, so do exit completion. + (letrec ((buf (current-buffer)) + (fun + (lambda () + (advice-remove 'icomplete-post-command-hook fun) + (with-current-buffer buf + (when (atom (cdr completion-all-sorted-completions)) + (completion-in-region-mode -1)))))) + (advice-add 'icomplete-post-command-hook :after fun)))) (icomplete-force-complete-and-exit)))) (define-key icomplete-minibuffer-map [?\t] #'spw/icomplete-tab) -- cgit v1.2.3