Package: emacs;
Reported by: Spencer Baugh <sbaugh <at> janestreet.com>
Date: Tue, 8 Apr 2025 15:18:01 UTC
Severity: normal
Tags: patch
View this message in rfc822 format
From: Spencer Baugh <sbaugh <at> janestreet.com> To: Juri Linkov <juri <at> linkov.net> Cc: sbaugh <at> catern.com, 77649 <at> debbugs.gnu.org, Daniel Mendler <mail <at> daniel-mendler.de> Subject: bug#77649: [PATCH] Add support for updating *Completions* as you type Date: Mon, 21 Jul 2025 12:43:56 -0400
[Message part 1 (text/plain, inline)]
Juri Linkov <juri <at> linkov.net> writes: >>>>> Add support for updating the *Completions* buffer as you type, >>>>> controlled by a new completion metadata symbol 'eager-update and >>>>> new defcustom completion-eager-update. >>>>> >>>>> You can configure a completion category to update *Completions* >>>>> as you type by setting completion-category-overrides >>>>> appropriately; or set completion-eager-update to t to always >>>>> update *Completions* as you type. >>>>> >>>>> This is similar to the recently added completion-eager-display. >>>> >>>> Thanks, now finally we'll have this long-needed feature. >> >> Hi, have you gotten a chance to try this out? > > Yes, I tried it out, and everything worked nicely. > >> I have been running this for several completion categories at my site >> and have had no complaints. > > Could you send a complete patch with a NEWS entry? Yes, attached.
[0001-Add-support-for-updating-Completions-as-you-type.patch (text/x-patch, inline)]
From 5c8290de611710c1859c65c37daf961507b20e62 Mon Sep 17 00:00:00 2001 From: Spencer Baugh <sbaugh <at> janestreet.com> Date: Thu, 3 Apr 2025 15:38:22 -0400 Subject: [PATCH] Add support for updating *Completions* as you type Add support for updating the *Completions* buffer as you type, controlled by a new completion metadata symbol 'eager-update and new defcustom completion-eager-update. You can configure a completion category to update *Completions* as you type by setting completion-category-overrides appropriately; or set completion-eager-update to t to always update *Completions* as you type. This is similar to the recently added completion-eager-display. * lisp/minibuffer.el (completion-eager-update): Add new defcustom defaulting to 'auto. (bug#77649) (completion--eager-update-p, completions--background-update) (completions--post-command-update): Add. (completions--after-change): Call completions--post-command-update via post-command-hook. (minibuffer-completion-help): Check completion-eager-update and install completions--after-change. (completion-help-at-point): Call completion--eager-update-p if ONLY-IF-EAGER is non-nil. * etc/NEWS: Announce completion-eager-update. Slightly reword the announcement of completion-eager-display for consistency. --- etc/NEWS | 13 +++++++++- lisp/minibuffer.el | 59 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index b469b22aacf..0c0f333319a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -167,11 +167,22 @@ This option configures whether completion commands should display the "*Completions*" buffer immediately. When the option is set to t, all completion commands show "*Completions*" immediately, respectively nil disables the eager display for all commands. The default setting auto -enables eager completion only if requested by the command. +enables eager display only if requested by the command. For more fine-grained control you can also toggle this feature by category using the symbol 'eager-display' in the user option 'completion-category-overrides'. ++++ +*** New user option 'completion-eager-update. +This option configures whether typing should update the contents of the +"*Completions*" buffer, if it is shown. When the option is set to t, +typing will always update the "*Completions*" buffer. Note that for +large or inefficient completion tables, this can slow down typing. The +default setting enables eager updating only if requested by the command. +For more fine-grained control you can also toggle this feature by +category using the symbol 'eager-update in the user option +'completion-category-overrides'. + +++ *** New user option 'completion-pcm-leading-wildcard'. This option configures how the partial-completion style does completion. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 571c4174537..12f66f57747 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1072,6 +1072,21 @@ completion-eager-display (const :tag "If requested by the completion command" auto)) :version "31.1") +(defcustom completion-eager-update 'auto + "Whether typing should update the *Completions* buffer eagerly. + +If `t', always update as you type. + +If `auto', only update if the completion table has requested it or +`eager-update' is set in in `completion-category-defaults'. + +This only affects the *Completions* buffer if it is already +displayed." + :type '(choice (const :tag "Do nothing when you type" nil) + (const :tag "Auto-update based on the category" auto) + (const :tag "Always update as you type" t)) + :version "31.1") + (defcustom completion-auto-help t "Non-nil means automatically provide help for invalid completion input. If the value is t, the *Completions* buffer is displayed whenever completion @@ -2648,12 +2663,43 @@ completions--deselect (goto-char (or (next-single-property-change (point) 'completion--string) (point-max))))) +(defun completion--eager-update-p (start) + "Return non-nil if *Completions* should be automatically updated. + +If `completion-eager-update' is the symbol `auto', checks completion +metadata for the string from START to point." + (if (eq completion-eager-update 'auto) + (completion-metadata-get (completion--field-metadata start) 'eager-update) + completion-eager-update)) + +(defun completions--background-update () + "Try to update *Completions* without blocking input. + +This function uses `while-no-input' and sets `non-essential' to t +so that the update is less likely to interfere with user typing." + (while-no-input + (let ((non-essential t)) + (redisplay) + (cond + (completion-in-region-mode (completion-help-at-point t)) + ((completion--eager-update-p (minibuffer-prompt-end)) + (minibuffer-completion-help)))))) + +(defun completions--post-command-update () + "Update displayed *Completions* buffer after command, once." + (remove-hook 'post-command-hook #'completions--post-command-update) + (when (and completion-eager-update (get-buffer-window "*Completions*" 0)) + (completions--background-update))) + (defun completions--after-change (_start _end _old-len) "Update displayed *Completions* buffer after change in buffer contents." - (when completion-auto-deselect + (when (or completion-auto-deselect completion-eager-update) (when-let* ((window (get-buffer-window "*Completions*" 0))) - (with-selected-window window - (completions--deselect))))) + (when completion-auto-deselect + (with-selected-window window + (completions--deselect))) + (when completion-eager-update + (add-hook 'post-command-hook #'completions--post-command-update))))) (defun minibuffer-completion-help (&optional start end) "Display a list of possible completions of the current minibuffer contents." @@ -2744,7 +2790,7 @@ minibuffer-completion-help (body-function . ,#'(lambda (window) (with-current-buffer mainbuf - (when completion-auto-deselect + (when (or completion-auto-deselect completion-eager-update) (add-hook 'after-change-functions #'completions--after-change nil t)) ;; Remove the base-size tail because `sort' requires a properly ;; nil-terminated list. @@ -3133,7 +3179,7 @@ completion-at-point (car res))) (cdr res))))) -(defun completion-help-at-point () +(defun completion-help-at-point (&optional only-if-eager) "Display the completions on the text around point. The completion method is determined by `completion-at-point-functions'." (interactive) @@ -3160,7 +3206,8 @@ completion-help-at-point `(,start ,(copy-marker end t) ,collection ,(plist-get plist :predicate))) (completion-in-region-mode 1) - (minibuffer-completion-help start end))) + (when (or (not only-if-eager) (completion--eager-update-p start)) + (minibuffer-completion-help start end)))) (`(,hookfun . ,_) ;; The hook function already performed completion :-( ;; Not much we can do at this point. -- 2.39.3
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.