bug#81537: 32.0.50; Fixing icomplete-in-buffer requiring users to advice-add
Sean Whitton <[email protected]> Sun, 02 Aug 2026 12:02:34 +0100
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <[email protected]> |
X-debbugs-cc: [email protected], [email protected], [email protected] I wrote these entries for NEWS.30: ** 'completion-auto-help' now affects 'icomplete-in-buffer'. Previously, 'completion-auto-help' mostly affected only minibuffer completion. Now, if 'completion-auto-help' has the value 'lazy', then Icomplete's in-buffer display of possible completions will only appear after the 'completion-at-point' command has been invoked twice, and if 'completion-auto-help' is nil, then Icomplete's in-buffer display is completely suppressed. Thus, if you use 'icomplete-in-buffer', ensure 'completion-auto-help' is not customized to 'lazy' or nil. ** The "*Completions*" buffer now always accompanies 'icomplete-in-buffer'. Previously, it was not consistent whether the "*Completions*" buffer would appear when using 'icomplete-in-buffer'. Now the "*Completions*" buffer and Icomplete's in-buffer display of possible completions always appear together. If you would prefer to see only Icomplete's in-buffer display, and not the "*Completions*" buffer, you can add this to your init file: (advice-add 'completion-at-point :after #'minibuffer-hide-completions) We say "If you would prefer ..." but really all users would not want to see both displays. Someone who really wants to see both should be the one who has to add some advice to *show* the completions. Also, populating the *Completions* buffer only to then hide it is a performance hit. We've discussed this before and Eshel and Juri suggested that the thing to do is make icomplete-in-buffer a proper completion-in-region-function value, instead of hanging off the default completion infrastructure as it does now. I've been looking into this over the weekend and I think that it would not be a good idea to try to do that. Icomplete is heavily dependent on the default completion process in a couple of senses: - it relies on various completion- and completion-- functions and variables, and some of the state changes - in its primary mode, in the minibuffer, it is architected as a pure supplement to the default completion, instead of a whole completions interface of its own. So, if we were to try to rearchitect Icomplete to work as a bona fide completion-in-region-function, we would likely break various subtle behavioural tweaks that have gone into Icomplete over the years that make it work as well as it does, and also invalidate code in people's initialisation files. For example, I found while trying things out that some Icomplete code in my initialization file was relying on the value of completion-all-sorted-completions in a way that subtly broke once I tried moving away from the default completion infrastructure. The code would surely be fixable, but I wouldn't want to make users do that. I haven't got much experience in this area so perhaps the above contains some misconceptions. Let me know how it seems to you all. Otherwise, I propose the following patch for master. -- etc/NEWS | 10 ++++++++++ lisp/icomplete.el | 10 +--------- lisp/minibuffer.el | 20 ++++++++++++++++---- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 23b97971105..ead3f7fb72c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -97,6 +97,16 @@ You can restore the previous behavior by removing --- *** The variable 'completion-ignore-case' is now customizable. +--- +*** 'icomplete-in-buffer' users need no longer advise 'completion-at-point'. +The "*Completions*" buffer no longer pops up in addition to Icomplete's +in-buffer display of completions, by default. +Therefore, the instructions in the NEWS file for Emacs 30.1 to add + + (advice-add 'completion-at-point :after #'minibuffer-hide-completions) + +to your initialization file no longer apply, and you may remove it. + * Editing Changes in Emacs 32.1 diff --git a/lisp/icomplete.el b/lisp/icomplete.el index 9a1202c30af..c8da0e9bf9b 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -154,15 +154,7 @@ icomplete-max-delay-chars (defcustom icomplete-in-buffer nil "If non-nil, use Icomplete when completing in buffers other than minibuffer. This affects commands like `completion-in-region', but not commands -that use their own completions setup. - -If you would prefer to see only Icomplete's in-buffer display, but do -not want the \"*Completions*\" buffer to pop up in those cases, add -this advice to your init file: - - (advice-add \\='completion-at-point - :after #\\='minibuffer-hide-completions) -" +that use their own completions setup." :type 'boolean) (defcustom icomplete-minibuffer-setup-hook nil diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 6c13fcabe54..c96de7e4ec1 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1581,6 +1581,9 @@ completion--in-boundaries-p (end (+ (length string) (cdr boundaries)))) (>= start pos end))) +(defun completion--icomplete-in-buffer-p () + (eq (bound-and-true-p icomplete--in-region-buffer) (current-buffer))) + (defun completion--do-completion (beg end &optional try-completion-function expect-exact) "Do the completion and return a summary of what happened. @@ -1689,7 +1692,8 @@ completion--do-completion ((pcase completion-auto-help ('visible (minibuffer--completions-visible)) ('always t)) - (minibuffer-completion-help beg end)) + (unless (completion--icomplete-in-buffer-p) + (minibuffer-completion-help beg end))) (t (minibuffer-hide-completions) (when exact ;; If completion did not put point at end of field, @@ -1702,13 +1706,15 @@ completion--do-completion (if (pcase completion-auto-help ('lazy (eq this-command last-command)) (_ completion-auto-help)) - (minibuffer-completion-help beg end) + (unless (completion--icomplete-in-buffer-p) + (minibuffer-completion-help beg end)) (completion--message "Next char not unique"))) ;; If the last exact completion and this one were the same, it ;; means we've already given a "Complete, but not unique" message ;; and the user's hit TAB again, so now we give him help. (t - (when (and (eq this-command last-command) completion-auto-help) + (when (and (eq this-command last-command) completion-auto-help + (not (completion--icomplete-in-buffer-p))) (minibuffer-completion-help beg end)) (completion--done completion 'exact (unless (or expect-exact @@ -1774,7 +1780,13 @@ completion--in-region-1 (t (prog1 (pcase (completion--do-completion beg end) (#b000 nil) (_ t)) - (if (window-live-p minibuffer-scroll-window) + (if (or (window-live-p minibuffer-scroll-window) + ;; FIXME: This reintroduces bug#67001 for + ;; `icomplete-in-region' users. It's not as bad for + ;; them, because Icomplete users probably expect to have + ;; to C-g out of completion before using other bindings, + ;; but it would still be better to fix it. --spwhitton + (completion--icomplete-in-buffer-p)) (and (eq completion-auto-select t) (eq t (frame-visible-p (window-frame minibuffer-scroll-window))) ;; When the completion list window was displayed, select it. -- Sean Whitton