From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Daniel Mendler via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#74616: 30.0.92; tmm always displays the *Completions* buffer Date: Sat, 14 Dec 2024 12:44:48 +0100 Message-ID: <87pllusd3j.fsf@daniel-mendler.de> References: <878qt1w7c6.fsf@daniel-mendler.de> <86wmgl9mfz.fsf@gnu.org> <86ldwrirf1.fsf@gnu.org> <87wmgbftih.fsf@daniel-mendler.de> <87jzca2bg5.fsf@daniel-mendler.de> <87wmg8llw1.fsf@mail.linkov.net> <877c88k51i.fsf@daniel-mendler.de> <868qsod3h3.fsf@gnu.org> <87o71kfvgu.fsf@daniel-mendler.de> <86zfl3btx0.fsf@gnu.org> <87ikrqb58x.fsf@daniel-mendler.de> <86ldwiv9mn.fsf@gnu.org> Reply-To: Daniel Mendler Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="17378"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: 74616@debbugs.gnu.org, monnier@iro.umontreal.ca, juri@linkov.net To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Dec 14 12:48:15 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1tMQd4-0004Pr-Dw for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 14 Dec 2024 12:48:14 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tMQcv-0004Io-TG; Sat, 14 Dec 2024 06:48:06 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tMQcs-0004IX-Ic for bug-gnu-emacs@gnu.org; Sat, 14 Dec 2024 06:48:02 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tMQcs-00087y-AO for bug-gnu-emacs@gnu.org; Sat, 14 Dec 2024 06:48:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:Date:References:In-Reply-To:From:To:Subject; bh=5KzVYFQADjQsf7RcR7jXllKTzLy/pfnblWuTrzeQgig=; b=uacVEivCE3TFPkXDP/yLWmO1X5hXnpg4f5E4t7oQISN/aBfEk6Wa6rRx+rNlEj7s0H5ahH/L2uSqDFa6COnLwSVMA/WFE276i2Sw0EpD6l71z/S4XCNI2xZyOHqm8/akf2aV9KH74zbM3SfE70EU3MKi/fK/Ccb0/BZmqw+FzD6juwBhPAel/z9b9AIBS2xfTN+f351WV0Cl0WET68dp+331ByNMqAfQ1n88wbrX08UL3RQ7Bclra05TzqBPxoGou8kRoHOkQPqtqZ54Yy8CNvuZ13CQsmTGlDpS9730Rb9p4VqUgj07HUO4QcOUvZL+/6WvZxQMR9b+07vmW7G5bA==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tMQcr-0004it-RP for bug-gnu-emacs@gnu.org; Sat, 14 Dec 2024 06:48:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Daniel Mendler Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 14 Dec 2024 11:48:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74616 X-GNU-PR-Package: emacs Original-Received: via spool by 74616-submit@debbugs.gnu.org id=B74616.173417683818091 (code B ref 74616); Sat, 14 Dec 2024 11:48:01 +0000 Original-Received: (at 74616) by debbugs.gnu.org; 14 Dec 2024 11:47:18 +0000 Original-Received: from localhost ([127.0.0.1]:45759 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tMQc8-0004hh-I3 for submit@debbugs.gnu.org; Sat, 14 Dec 2024 06:47:17 -0500 Original-Received: from server.qxqx.de ([49.12.34.165]:54689 helo=mail.qxqx.de) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tMQc1-0004hI-GQ for 74616@debbugs.gnu.org; Sat, 14 Dec 2024 06:47:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=daniel-mendler.de; s=key; h=Content-Type:MIME-Version:Message-ID:Date: References:In-Reply-To:Subject:Cc:To:From:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=5KzVYFQADjQsf7RcR7jXllKTzLy/pfnblWuTrzeQgig=; b=lzQbcC91fKjlK2FsscarBL1Pku wIOacCT83Dp2bVusc1eu3d9rRLkJzro8X33DSUe1Rr2kvL45qgRCG0E2XqwovHNKGj4dYoruBqhHw 7i+u+K+RIV+Tc54Ifz0JnmfCHNlCItaWIHeCX+UcCpa/vOancCTCzA0OssoLitXU3tfc=; In-Reply-To: <86ldwiv9mn.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 14 Dec 2024 12:31:28 +0200") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:297039 Archived-At: --=-=-= Content-Type: text/plain Eli Zaretskii writes: >> From: Daniel Mendler >> Cc: juri@linkov.net, monnier@iro.umontreal.ca, 74616@debbugs.gnu.org >> Date: Wed, 11 Dec 2024 16:37:18 +0100 >> >> > Thanks. This LGTM (but let's leave some time for others to chime in), >> > with the following nit: >> > >> >> ++++ >> >> +*** New user option 'completion-eager-display'. >> >> +This option configures whether completion commands should display >> >> +the *Completions* buffer immediately. When the variable is set to t all >> >> +completion commands show *Completions* immediately, respectively nil >> >> +disables the eager display for all commands. The default setting auto >> > ^^ >> > Two spaces there, please. >> >> Thanks. Updated patch attached. > > Thanks. I was about to install this, but it turns out it breaks > minibuffer-tests: Thanks for finding this. The problem was that `initial-input' was passed directly to `completion-metadata'. I replaced `initial-input' with `(or initial-input "")'. See the updated patch attached to this mail. Daniel --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-New-customization-variable-completion-eager-display.patch >From f8f93c078dbcc598dac87e7451bdae3e9f80e92b Mon Sep 17 00:00:00 2001 From: Daniel Mendler Date: Sun, 8 Dec 2024 20:05:07 +0100 Subject: [PATCH 1/4] New customization variable `completion-eager-display' The customization option can be set to t or nil, to respectively always or never show the *Completions* buffer eagerly at the beginning of a completion session. Furthermore the option can be set to the value auto. In this case the *Completions* buffer will only be shown if requested by the completion table. Completion tables can use the `eager-display' completion metadata to do so. (Bug#74616, Bug#74617) * lisp/minibuffer.el (completion-eager-display): New customization variable. (completion-metadata): Update docstring, document the new `eager-display' completion metadata. (completion-extra-properties): Update docstring, document the new `:eager-display' completion metadata. (completion-category-overrides): Add `eager-display' to the custom type specification. (completing-read-default): Handle the `completion-eager-display' customization variable and the `eager-display' completion metadata. (completion-table-with-metadata): New function to create a completion table with metadata. (minibuffer-complete-defaults, minibuffer-complete-history): Use it. * lisp/ffap.el (ffap-menu-ask): Add `ffap-menu' completion category and `eager-display' completion metadata. Use `completion-table-with-metadata'. * lisp/imenu.el (imenu-eager-completion-buffer): Correct docstring, which had been inverted. (imenu--completion-buffer): Add `eager-display' completion metadata. Use `completion-table-with-metadata'. * lisp/tmm.el (tmm-prompt): Add `tmm' completion category and `eager-display' completion metadata. Use `completion-table-with-metadata'. Add keymap setup. (tmm-add-prompt): Remove keymap setup. (tmm-goto-completions): Call `tmm-add-prompt' to ensure that a *Completions* buffer is shown. (tmm--completion-table): Remove unused internal function. * etc/NEWS: Announce the change. --- etc/NEWS | 8 ++++++ lisp/ffap.el | 17 ++++++------ lisp/imenu.el | 40 +++++++++++++-------------- lisp/minibuffer.el | 67 +++++++++++++++++++++++++++++++++++++--------- lisp/tmm.el | 19 ++++++------- 5 files changed, 101 insertions(+), 50 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index d96e49402ba..b847a76f741 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -102,6 +102,14 @@ files and features. ** Minibuffer and Completions ++++ +*** New user option 'completion-eager-display'. +This option configures whether completion commands should display +the *Completions* buffer immediately. When the variable 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. + +++ *** New user option 'completion-pcm-leading-wildcard'. This option configures how the partial-completion style does completion. diff --git a/lisp/ffap.el b/lisp/ffap.el index 180fe408104..d3110f824a6 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el @@ -1739,14 +1739,15 @@ ffap-menu-ask alist)))))) ;; minibuffer with completion buffer: (t - (let ((minibuffer-setup-hook 'minibuffer-completion-help)) - ;; Bug: prompting may assume unique strings, no "". - (setq choice - (completing-read - (format-prompt title (car (car alist))) - alist nil t - ;; (cons (car (car alist)) 0) - nil))) + ;; Bug: prompting may assume unique strings, no "". + (setq choice + (completing-read + (format-prompt title (car (car alist))) + (completion-table-with-metadata + alist '((category . ffap-menu) (eager-display . t))) + nil t + ;; (cons (car (car alist)) 0) + nil)) (sit-for 0) ; redraw original screen ;; Convert string to its entry, or else the default: (setq choice (or (assoc choice alist) (car alist))))) diff --git a/lisp/imenu.el b/lisp/imenu.el index 2d64970bfcf..ba1ba5fcd00 100644 --- a/lisp/imenu.el +++ b/lisp/imenu.el @@ -100,7 +100,7 @@ imenu-use-popup-menu (other :tag "Always" t))) (defcustom imenu-eager-completion-buffer t - "If non-nil, eagerly pop up the completion buffer." + "If nil, eagerly pop up the completion buffer." :type 'boolean :version "22.1") @@ -767,27 +767,25 @@ imenu--completion-buffer (imenu--in-alist name prepared-index-alist) ;; Default to `name' if it's in the alist. name)))) - ;; Display the completion buffer. (minibuffer-with-setup-hook - (lambda () - (setq-local minibuffer-allow-text-properties t) - (setq-local completion-extra-properties - `( :category imenu - ,@(when (eq imenu-flatten 'annotation) - `(:annotation-function - ,(lambda (s) (get-text-property - 0 'imenu-section s)))) - ,@(when (eq imenu-flatten 'group) - `(:group-function - ,(lambda (s transform) - (if transform s - (get-text-property - 0 'imenu-section s))))))) - (unless imenu-eager-completion-buffer - (minibuffer-completion-help))) - (setq name (completing-read prompt - prepared-index-alist - nil t nil 'imenu--history-list name))) + (lambda () (setq-local minibuffer-allow-text-properties t)) + (setq name (completing-read + prompt + (completion-table-with-metadata + prepared-index-alist + `((category . imenu) + (eager-display . ,(not imenu-eager-completion-buffer)) + ,@(when (eq imenu-flatten 'annotation) + `((annotation-function + . ,(lambda (s) (get-text-property + 0 'imenu-section s))))) + ,@(when (eq imenu-flatten 'group) + `((group-function + . ,(lambda (s transform) + (if transform s + (get-text-property + 0 'imenu-section s)))))))) + nil t nil 'imenu--history-list name))) (when (stringp name) (or (get-text-property 0 'imenu-choice name) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 1337fbe17ea..dfc62c25f38 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -138,6 +138,9 @@ completion-metadata of completions. Can operate destructively. - `cycle-sort-function': function to sort entries when cycling. Works like `display-sort-function'. +- `eager-display': non-nil to request eager display of the + completion candidates. Can also be a function which is invoked + after minibuffer setup. The metadata of a completion table should be constant between two boundaries." (let ((metadata (if (functionp table) (funcall table string pred 'metadata)))) @@ -277,6 +280,15 @@ completion-table-case-fold (let ((completion-ignore-case (not dont-fold))) (complete-with-action action table string pred)))) +(defun completion-table-with-metadata (table metadata) + "Return new completion TABLE with METADATA. +METADATA should be an alist of completion metadata. See +`completion-metadata' for a list of supported metadata." + (lambda (string pred action) + (if (eq action 'metadata) + `(metadata . ,metadata) + (complete-with-action action table string pred)))) + (defun completion-table-subvert (table s1 s2) "Return a completion table from TABLE with S1 replaced by S2. The result is a completion table which completes strings of the @@ -1031,6 +1043,25 @@ minibuffer--completion-prompt-end (defvar completion-show-inline-help t "If non-nil, print helpful inline messages during completion.") +(defcustom completion-eager-display 'auto + "Whether completion commands should display *Completions* buffer eagerly. + +If the variable is set to t, completion commands show the *Completions* +buffer always immediately. Setting the variable to nil disables the +eager *Completions* display for all commands. + +For the value `auto', completion commands show the *Completions* buffer +immediately only if requested by the completion command. Completion +tables can request eager display via the `eager-display' metadata. + +See also the variables `completion-category-overrides' and +`completion-extra-properties' for the `eager-display' completion +metadata." + :type '(choice (const :tag "Never show *Completions* eagerly" nil) + (const :tag "Always show *Completions* eagerly" t) + (const :tag "If requested by the completion command" auto)) + :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 @@ -1247,7 +1278,11 @@ completion-category-overrides (cons :tag "Completion Affixation" (const :tag "Select one value from the menu." affixation-function) - (choice (function :tag "Custom function")))))) + (choice (function :tag "Custom function"))) + (cons :tag "Eager display" + (const :tag "Select one value from the menu." + eager-display) + boolean)))) (defun completion--category-override (category tag) (or (assq tag (cdr (assq category completion-category-overrides))) @@ -2499,6 +2534,8 @@ completion-extra-properties `:cycle-sort-function': Function to sort entries when cycling. +`:eager-display': Show the *Completions* buffer eagerly. + See more information about these functions above in `completion-metadata'. @@ -4815,7 +4852,17 @@ completing-read-default (setq-local minibuffer--require-match require-match) (setq-local minibuffer--original-buffer buffer) ;; Copy the value from original buffer to the minibuffer. - (setq-local completion-ignore-case c-i-c)) + (setq-local completion-ignore-case c-i-c) + ;; Show the completion help eagerly if + ;; `completion-eager-display' is t or if eager display + ;; has been requested by the completion table. + (when completion-eager-display + (let* ((md (completion-metadata (or initial-input "") + collection predicate)) + (fun (completion-metadata-get md 'eager-display))) + (when (or fun (eq completion-eager-display t)) + (funcall (if (functionp fun) + fun #'minibuffer-completion-help)))))) (read-from-minibuffer prompt initial-input keymap nil hist def inherit-input-method)))) (when (and (equal result "") def) @@ -5005,11 +5052,9 @@ minibuffer-complete-history (lambda () (get-buffer-window "*Completions*" 0)))) (completion-in-region (minibuffer--completion-prompt-end) (point-max) - (lambda (string pred action) - (if (eq action 'metadata) - '(metadata (display-sort-function . identity) - (cycle-sort-function . identity)) - (complete-with-action action completions string pred))))))) + (completion-table-with-metadata + completions '((display-sort-function . identity) + (cycle-sort-function . identity))))))) (defun minibuffer-complete-defaults () "Complete minibuffer defaults as far as possible. @@ -5025,11 +5070,9 @@ minibuffer-complete-defaults (lambda () (get-buffer-window "*Completions*" 0)))) (completion-in-region (minibuffer--completion-prompt-end) (point-max) - (lambda (string pred action) - (if (eq action 'metadata) - '(metadata (display-sort-function . identity) - (cycle-sort-function . identity)) - (complete-with-action action completions string pred)))))) + (completion-table-with-metadata + completions '((display-sort-function . identity) + (cycle-sort-function . identity)))))) (define-key minibuffer-local-map [?\C-x up] 'minibuffer-complete-history) (define-key minibuffer-local-map [?\C-x down] 'minibuffer-complete-defaults) diff --git a/lisp/tmm.el b/lisp/tmm.el index 632e55e47a8..45afbe4a3c2 100644 --- a/lisp/tmm.el +++ b/lisp/tmm.el @@ -119,12 +119,6 @@ tmm-inactive '((t :inherit shadow)) "Face used for inactive menu items.") -(defun tmm--completion-table (items) - (lambda (string pred action) - (if (eq action 'metadata) - '(metadata (display-sort-function . identity)) - (complete-with-action action items string pred)))) - (defvar tmm--history nil) ;;;###autoload @@ -222,7 +216,9 @@ tmm-prompt (setq out (if default-item (car (nth index-of-default tmm-km-list)) - (minibuffer-with-setup-hook #'tmm-add-prompt + (minibuffer-with-setup-hook + (lambda () + (setq tmm-old-mb-map (tmm-define-keys t))) ;; tmm-km-list is reversed, because history ;; needs it in LIFO order. But default list ;; needs it in non-reverse order, so that the @@ -233,7 +229,12 @@ tmm-prompt (completing-read-default (concat gl-str " (up/down to change, PgUp to menu): ") - (tmm--completion-table tmm-km-list) nil t nil + (completion-table-with-metadata + tmm-km-list '((category . tmm) + (eager-display . tmm-add-prompt) + (display-sort-function . identity) + (cycle-sort-function . identity))) + nil t nil 'tmm--history (reverse tmm--history))))))) (if (and (stringp out) (string= "^" out)) ;; A fake choice to please the destructuring later. @@ -402,7 +403,6 @@ tmm-remove-inactive-mouse-face (defun tmm-add-prompt () (unless tmm-c-prompt (error "No active menu entries")) - (setq tmm-old-mb-map (tmm-define-keys t)) (or tmm-completion-prompt (add-hook 'completion-setup-hook #'tmm-completion-delete-prompt 'append)) @@ -458,6 +458,7 @@ tmm-shortcut (defun tmm-goto-completions () "Jump to the completions buffer." (interactive) + (tmm-add-prompt) (setq tmm-c-prompt (buffer-substring (minibuffer-prompt-end) (point-max))) ;; Clear minibuffer old contents before using *Completions* buffer for ;; selection. -- 2.45.2 --=-=-=--