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: Sun, 08 Dec 2024 20:59:06 +0100 Message-ID: <87jzca2bg5.fsf@daniel-mendler.de> References: <878qt1w7c6.fsf@daniel-mendler.de> <86wmgl9mfz.fsf@gnu.org> <86ldwrirf1.fsf@gnu.org> <87wmgbftih.fsf@daniel-mendler.de> 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="5485"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: Eli Zaretskii , 74616@debbugs.gnu.org, Juri Linkov To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Dec 08 21:02:24 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 1tKNU0-0001J6-3z for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 08 Dec 2024 21:02:24 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tKNTh-00077W-4S; Sun, 08 Dec 2024 15:02:05 -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 1tKNTf-00077G-2W for bug-gnu-emacs@gnu.org; Sun, 08 Dec 2024 15:02:03 -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 1tKNTe-0005eA-Q9 for bug-gnu-emacs@gnu.org; Sun, 08 Dec 2024 15:02: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=AAlNUTBPzt+qV8kqrjFJFHnh0n7AufhM/GXBXuQpzBw=; b=Pvc5N18WQLdZZlnRX0BLZ7gDxcNn05qNERcsGk5xkJRPxHHWK+sjVwHr8QcU3AceufNogylUi+GAOuZFd311HNLZbN7BXtMp43mKlXl5OTRlfLvBdOzL6qkOIymLJSEbJ4IvDKnQgYv3cP6tjZKyUzU+jDd4J01v+TXH/mzI8GXoUqyBN+HIYF9FBrmmBbiyzLo6AULI8Me/dK1FRtRn17d3BXww+dhXVizrJf8pV1PJLMpGoNfxg1Jjn+VMqn72qNY0Ie4o3jTejUAVzb8PmU1tsMnFOsyHQblHUTukIbBUDqFs2rY4xx6NdLInS7Np9ZZVYLjwoFy8q/0hUR4V2Q==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tKNTe-00042R-Lo for bug-gnu-emacs@gnu.org; Sun, 08 Dec 2024 15:02:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Daniel Mendler Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 08 Dec 2024 20:02:02 +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.173368809015452 (code B ref 74616); Sun, 08 Dec 2024 20:02:02 +0000 Original-Received: (at 74616) by debbugs.gnu.org; 8 Dec 2024 20:01:30 +0000 Original-Received: from localhost ([127.0.0.1]:51767 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tKNT7-000419-D0 for submit@debbugs.gnu.org; Sun, 08 Dec 2024 15:01:30 -0500 Original-Received: from server.qxqx.de ([49.12.34.165]:45245 helo=mail.qxqx.de) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tKNT5-00040n-7M for 74616@debbugs.gnu.org; Sun, 08 Dec 2024 15:01:28 -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=AAlNUTBPzt+qV8kqrjFJFHnh0n7AufhM/GXBXuQpzBw=; b=AR3o/i2WHdLBQ7xbFpAY0aNlit i7TGR66R9BtrdUL8JDZbKsIrrr8A7rHflHoYWLiP+IkP+LsBh6ul6KYHxjvEZ+uVCJ1cBNidI7Ao6 gKjibvcN/TJsew4dmul2yA3ta0k+mdOiGb+hq6IhzTNXHwDXcR2UUOehBM34ISAd5QHc=; In-Reply-To: (Stefan Monnier's message of "Sun, 08 Dec 2024 10:33:53 -0500") 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:296663 Archived-At: --=-=-= Content-Type: text/plain Stefan Monnier writes: >> So is the plan to add a completion metadata `eager-display' such that >> completion tables can request immediate display? This completion >> metadata can then be overridden by the user via >> `completion-category-overrides'. The patch would include changes to tmm, >> ffap-menu and imenu (obsoleting `imenu-eager-completion-buffer'). > > That sounds good, except that in order for > `completion-category-overrides` to work reliably, the `eager-display` > should not be in the metadata but in `completion-category-defaults`. Okay. Can you please clarify why you assume that overriding isn't reliably possible if the metadata is specified directly? In `completion-metadata-get' the `completion-category-defaults' and `completion-category-overrides' take precedence over the completion table metadata. I attached a patch which adds a customization option `completion-eager-display' and an `eager-display' completion table metadata. The customization option can be set to nil (never), t (always) or to auto, which means that the *Completions* buffer will only be shown if the completion table requests eager display via the `eager-display' metadata. I updated ffap.el, tmm.el and imenu.el to take advantage of the new `eager-display' metadata. I added completion categories where missing such that overriding the metadata becomes possible. If desired, the metadata can be moved to `completion-category-defaults' instead. Daniel --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-New-customization-variable-completion-eager-display.patch >From 2a4f2c04a880c6a66207a0717f5ba79bbfe109ef Mon Sep 17 00:00:00 2001 From: Daniel Mendler Date: Sun, 8 Dec 2024 20:05:07 +0100 Subject: [PATCH] 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. * 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. (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'. (tmm-goto-completions): Ensure that a *Completions* buffer is available. (tmm--completion-table): Remove unused internal function. --- lisp/ffap.el | 17 ++++++++------- lisp/imenu.el | 40 ++++++++++++++++------------------ lisp/minibuffer.el | 54 ++++++++++++++++++++++++++++++++++++---------- lisp/tmm.el | 38 ++++++++++++++++---------------- 4 files changed, 90 insertions(+), 59 deletions(-) diff --git a/lisp/ffap.el b/lisp/ffap.el index 6a4915fb5a3..c869e234140 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el @@ -1738,14 +1738,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 405ee21cdb2..1dfe450a35c 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,18 @@ minibuffer--completion-prompt-end (defvar completion-show-inline-help t "If non-nil, print helpful inline messages during completion.") +(defcustom completion-eager-display 'auto + "Display the *Completions* buffer eagerly. + +If the variable is set to t or nil, respectively show the *Completions* +buffer always or never eagerly. The value `auto' shows the +*Completions* buffer eagerly only if requested by the completion +command. Completion tables can request eager display via the +`eager-display' 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))) + (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 @@ -2493,6 +2517,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'. @@ -4809,7 +4835,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 + 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) @@ -4999,11 +5035,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. @@ -5019,11 +5053,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..01912916a6d 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,19 +216,23 @@ tmm-prompt (setq out (if default-item (car (nth index-of-default tmm-km-list)) - (minibuffer-with-setup-hook #'tmm-add-prompt - ;; tmm-km-list is reversed, because history - ;; needs it in LIFO order. But default list - ;; needs it in non-reverse order, so that the - ;; menu items are displayed by M-n as default - ;; values in the order they are shown on - ;; the menu bar. So pass the DEFAULT arg the - ;; reversed copy of the list. - (completing-read-default - (concat gl-str - " (up/down to change, PgUp to menu): ") - (tmm--completion-table tmm-km-list) nil t nil - 'tmm--history (reverse tmm--history))))))) + ;; tmm-km-list is reversed, because history + ;; needs it in LIFO order. But default list + ;; needs it in non-reverse order, so that the + ;; menu items are displayed by M-n as default + ;; values in the order they are shown on + ;; the menu bar. So pass the DEFAULT arg the + ;; reversed copy of the list. + (completing-read-default + (concat gl-str + " (up/down to change, PgUp to menu): ") + (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. (setq choice (cons out out)) @@ -458,6 +456,8 @@ tmm-shortcut (defun tmm-goto-completions () "Jump to the completions buffer." (interactive) + (unless (get-buffer "*Completions*") + (minibuffer-completion-help)) (setq tmm-c-prompt (buffer-substring (minibuffer-prompt-end) (point-max))) ;; Clear minibuffer old contents before using *Completions* buffer for ;; selection. -- 2.45.2 --=-=-=--