diff options
| author | Daniel Mendler | 2024-12-08 20:05:07 +0100 |
|---|---|---|
| committer | Eli Zaretskii | 2024-12-14 14:38:29 +0200 |
| commit | fd021c07606264a73cd4c1f6fa6fe80a756defe0 (patch) | |
| tree | 2be0e0fa6f9aeed73a4c79d63c71a58d3f4477c6 | |
| parent | 64981660c912e5ab79c1143d9879d9ee7a0b93bf (diff) | |
| download | emacs-fd021c07606264a73cd4c1f6fa6fe80a756defe0.tar.gz emacs-fd021c07606264a73cd4c1f6fa6fe80a756defe0.zip | |
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.
| -rw-r--r-- | etc/NEWS | 8 | ||||
| -rw-r--r-- | lisp/ffap.el | 17 | ||||
| -rw-r--r-- | lisp/imenu.el | 40 | ||||
| -rw-r--r-- | lisp/minibuffer.el | 67 | ||||
| -rw-r--r-- | lisp/tmm.el | 19 |
5 files changed, 101 insertions, 50 deletions
| @@ -103,6 +103,14 @@ files and features. | |||
| 103 | ** Minibuffer and Completions | 103 | ** Minibuffer and Completions |
| 104 | 104 | ||
| 105 | +++ | 105 | +++ |
| 106 | *** New user option 'completion-eager-display'. | ||
| 107 | This option configures whether completion commands should display | ||
| 108 | the *Completions* buffer immediately. When the variable is set to t all | ||
| 109 | completion commands show *Completions* immediately, respectively nil | ||
| 110 | disables the eager display for all commands. The default setting auto | ||
| 111 | enables eager completion only if requested by the command. | ||
| 112 | |||
| 113 | +++ | ||
| 106 | *** New user option 'completion-pcm-leading-wildcard'. | 114 | *** New user option 'completion-pcm-leading-wildcard'. |
| 107 | This option configures how the partial-completion style does completion. | 115 | This option configures how the partial-completion style does completion. |
| 108 | It defaults to nil, which preserves the existing behavior. When it is set | 116 | It defaults to nil, which preserves the existing behavior. When it is set |
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 @@ Function CONT is applied to the entry chosen by the user." | |||
| 1739 | alist)))))) | 1739 | alist)))))) |
| 1740 | ;; minibuffer with completion buffer: | 1740 | ;; minibuffer with completion buffer: |
| 1741 | (t | 1741 | (t |
| 1742 | (let ((minibuffer-setup-hook 'minibuffer-completion-help)) | 1742 | ;; Bug: prompting may assume unique strings, no "". |
| 1743 | ;; Bug: prompting may assume unique strings, no "". | 1743 | (setq choice |
| 1744 | (setq choice | 1744 | (completing-read |
| 1745 | (completing-read | 1745 | (format-prompt title (car (car alist))) |
| 1746 | (format-prompt title (car (car alist))) | 1746 | (completion-table-with-metadata |
| 1747 | alist nil t | 1747 | alist '((category . ffap-menu) (eager-display . t))) |
| 1748 | ;; (cons (car (car alist)) 0) | 1748 | nil t |
| 1749 | nil))) | 1749 | ;; (cons (car (car alist)) 0) |
| 1750 | nil)) | ||
| 1750 | (sit-for 0) ; redraw original screen | 1751 | (sit-for 0) ; redraw original screen |
| 1751 | ;; Convert string to its entry, or else the default: | 1752 | ;; Convert string to its entry, or else the default: |
| 1752 | (setq choice (or (assoc choice alist) (car alist))))) | 1753 | (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 @@ If `on-mouse' use a popup menu when `imenu' was invoked with the mouse." | |||
| 100 | (other :tag "Always" t))) | 100 | (other :tag "Always" t))) |
| 101 | 101 | ||
| 102 | (defcustom imenu-eager-completion-buffer t | 102 | (defcustom imenu-eager-completion-buffer t |
| 103 | "If non-nil, eagerly pop up the completion buffer." | 103 | "If nil, eagerly pop up the completion buffer." |
| 104 | :type 'boolean | 104 | :type 'boolean |
| 105 | :version "22.1") | 105 | :version "22.1") |
| 106 | 106 | ||
| @@ -767,27 +767,25 @@ Return one of the entries in index-alist or nil." | |||
| 767 | (imenu--in-alist name prepared-index-alist) | 767 | (imenu--in-alist name prepared-index-alist) |
| 768 | ;; Default to `name' if it's in the alist. | 768 | ;; Default to `name' if it's in the alist. |
| 769 | name)))) | 769 | name)))) |
| 770 | ;; Display the completion buffer. | ||
| 771 | (minibuffer-with-setup-hook | 770 | (minibuffer-with-setup-hook |
| 772 | (lambda () | 771 | (lambda () (setq-local minibuffer-allow-text-properties t)) |
| 773 | (setq-local minibuffer-allow-text-properties t) | 772 | (setq name (completing-read |
| 774 | (setq-local completion-extra-properties | 773 | prompt |
| 775 | `( :category imenu | 774 | (completion-table-with-metadata |
| 776 | ,@(when (eq imenu-flatten 'annotation) | 775 | prepared-index-alist |
| 777 | `(:annotation-function | 776 | `((category . imenu) |
| 778 | ,(lambda (s) (get-text-property | 777 | (eager-display . ,(not imenu-eager-completion-buffer)) |
| 779 | 0 'imenu-section s)))) | 778 | ,@(when (eq imenu-flatten 'annotation) |
| 780 | ,@(when (eq imenu-flatten 'group) | 779 | `((annotation-function |
| 781 | `(:group-function | 780 | . ,(lambda (s) (get-text-property |
| 782 | ,(lambda (s transform) | 781 | 0 'imenu-section s))))) |
| 783 | (if transform s | 782 | ,@(when (eq imenu-flatten 'group) |
| 784 | (get-text-property | 783 | `((group-function |
| 785 | 0 'imenu-section s))))))) | 784 | . ,(lambda (s transform) |
| 786 | (unless imenu-eager-completion-buffer | 785 | (if transform s |
| 787 | (minibuffer-completion-help))) | 786 | (get-text-property |
| 788 | (setq name (completing-read prompt | 787 | 0 'imenu-section s)))))))) |
| 789 | prepared-index-alist | 788 | nil t nil 'imenu--history-list name))) |
| 790 | nil t nil 'imenu--history-list name))) | ||
| 791 | 789 | ||
| 792 | (when (stringp name) | 790 | (when (stringp name) |
| 793 | (or (get-text-property 0 'imenu-choice name) | 791 | (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 @@ This metadata is an alist. Currently understood keys are: | |||
| 138 | of completions. Can operate destructively. | 138 | of completions. Can operate destructively. |
| 139 | - `cycle-sort-function': function to sort entries when cycling. | 139 | - `cycle-sort-function': function to sort entries when cycling. |
| 140 | Works like `display-sort-function'. | 140 | Works like `display-sort-function'. |
| 141 | - `eager-display': non-nil to request eager display of the | ||
| 142 | completion candidates. Can also be a function which is invoked | ||
| 143 | after minibuffer setup. | ||
| 141 | The metadata of a completion table should be constant between two boundaries." | 144 | The metadata of a completion table should be constant between two boundaries." |
| 142 | (let ((metadata (if (functionp table) | 145 | (let ((metadata (if (functionp table) |
| 143 | (funcall table string pred 'metadata)))) | 146 | (funcall table string pred 'metadata)))) |
| @@ -277,6 +280,15 @@ case sensitive instead." | |||
| 277 | (let ((completion-ignore-case (not dont-fold))) | 280 | (let ((completion-ignore-case (not dont-fold))) |
| 278 | (complete-with-action action table string pred)))) | 281 | (complete-with-action action table string pred)))) |
| 279 | 282 | ||
| 283 | (defun completion-table-with-metadata (table metadata) | ||
| 284 | "Return new completion TABLE with METADATA. | ||
| 285 | METADATA should be an alist of completion metadata. See | ||
| 286 | `completion-metadata' for a list of supported metadata." | ||
| 287 | (lambda (string pred action) | ||
| 288 | (if (eq action 'metadata) | ||
| 289 | `(metadata . ,metadata) | ||
| 290 | (complete-with-action action table string pred)))) | ||
| 291 | |||
| 280 | (defun completion-table-subvert (table s1 s2) | 292 | (defun completion-table-subvert (table s1 s2) |
| 281 | "Return a completion table from TABLE with S1 replaced by S2. | 293 | "Return a completion table from TABLE with S1 replaced by S2. |
| 282 | The result is a completion table which completes strings of the | 294 | The result is a completion table which completes strings of the |
| @@ -1031,6 +1043,25 @@ If the current buffer is not a minibuffer, erase its entire contents." | |||
| 1031 | (defvar completion-show-inline-help t | 1043 | (defvar completion-show-inline-help t |
| 1032 | "If non-nil, print helpful inline messages during completion.") | 1044 | "If non-nil, print helpful inline messages during completion.") |
| 1033 | 1045 | ||
| 1046 | (defcustom completion-eager-display 'auto | ||
| 1047 | "Whether completion commands should display *Completions* buffer eagerly. | ||
| 1048 | |||
| 1049 | If the variable is set to t, completion commands show the *Completions* | ||
| 1050 | buffer always immediately. Setting the variable to nil disables the | ||
| 1051 | eager *Completions* display for all commands. | ||
| 1052 | |||
| 1053 | For the value `auto', completion commands show the *Completions* buffer | ||
| 1054 | immediately only if requested by the completion command. Completion | ||
| 1055 | tables can request eager display via the `eager-display' metadata. | ||
| 1056 | |||
| 1057 | See also the variables `completion-category-overrides' and | ||
| 1058 | `completion-extra-properties' for the `eager-display' completion | ||
| 1059 | metadata." | ||
| 1060 | :type '(choice (const :tag "Never show *Completions* eagerly" nil) | ||
| 1061 | (const :tag "Always show *Completions* eagerly" t) | ||
| 1062 | (const :tag "If requested by the completion command" auto)) | ||
| 1063 | :version "31.1") | ||
| 1064 | |||
| 1034 | (defcustom completion-auto-help t | 1065 | (defcustom completion-auto-help t |
| 1035 | "Non-nil means automatically provide help for invalid completion input. | 1066 | "Non-nil means automatically provide help for invalid completion input. |
| 1036 | If the value is t, the *Completions* buffer is displayed whenever completion | 1067 | If the value is t, the *Completions* buffer is displayed whenever completion |
| @@ -1247,7 +1278,11 @@ overrides the default specified in `completion-category-defaults'." | |||
| 1247 | (cons :tag "Completion Affixation" | 1278 | (cons :tag "Completion Affixation" |
| 1248 | (const :tag "Select one value from the menu." | 1279 | (const :tag "Select one value from the menu." |
| 1249 | affixation-function) | 1280 | affixation-function) |
| 1250 | (choice (function :tag "Custom function")))))) | 1281 | (choice (function :tag "Custom function"))) |
| 1282 | (cons :tag "Eager display" | ||
| 1283 | (const :tag "Select one value from the menu." | ||
| 1284 | eager-display) | ||
| 1285 | boolean)))) | ||
| 1251 | 1286 | ||
| 1252 | (defun completion--category-override (category tag) | 1287 | (defun completion--category-override (category tag) |
| 1253 | (or (assq tag (cdr (assq category completion-category-overrides))) | 1288 | (or (assq tag (cdr (assq category completion-category-overrides))) |
| @@ -2499,6 +2534,8 @@ These include: | |||
| 2499 | 2534 | ||
| 2500 | `:cycle-sort-function': Function to sort entries when cycling. | 2535 | `:cycle-sort-function': Function to sort entries when cycling. |
| 2501 | 2536 | ||
| 2537 | `:eager-display': Show the *Completions* buffer eagerly. | ||
| 2538 | |||
| 2502 | See more information about these functions above | 2539 | See more information about these functions above |
| 2503 | in `completion-metadata'. | 2540 | in `completion-metadata'. |
| 2504 | 2541 | ||
| @@ -4815,7 +4852,17 @@ See `completing-read' for the meaning of the arguments." | |||
| 4815 | (setq-local minibuffer--require-match require-match) | 4852 | (setq-local minibuffer--require-match require-match) |
| 4816 | (setq-local minibuffer--original-buffer buffer) | 4853 | (setq-local minibuffer--original-buffer buffer) |
| 4817 | ;; Copy the value from original buffer to the minibuffer. | 4854 | ;; Copy the value from original buffer to the minibuffer. |
| 4818 | (setq-local completion-ignore-case c-i-c)) | 4855 | (setq-local completion-ignore-case c-i-c) |
| 4856 | ;; Show the completion help eagerly if | ||
| 4857 | ;; `completion-eager-display' is t or if eager display | ||
| 4858 | ;; has been requested by the completion table. | ||
| 4859 | (when completion-eager-display | ||
| 4860 | (let* ((md (completion-metadata (or initial-input "") | ||
| 4861 | collection predicate)) | ||
| 4862 | (fun (completion-metadata-get md 'eager-display))) | ||
| 4863 | (when (or fun (eq completion-eager-display t)) | ||
| 4864 | (funcall (if (functionp fun) | ||
| 4865 | fun #'minibuffer-completion-help)))))) | ||
| 4819 | (read-from-minibuffer prompt initial-input keymap | 4866 | (read-from-minibuffer prompt initial-input keymap |
| 4820 | nil hist def inherit-input-method)))) | 4867 | nil hist def inherit-input-method)))) |
| 4821 | (when (and (equal result "") def) | 4868 | (when (and (equal result "") def) |
| @@ -5005,11 +5052,9 @@ instead of the default completion table." | |||
| 5005 | (lambda () (get-buffer-window "*Completions*" 0)))) | 5052 | (lambda () (get-buffer-window "*Completions*" 0)))) |
| 5006 | (completion-in-region | 5053 | (completion-in-region |
| 5007 | (minibuffer--completion-prompt-end) (point-max) | 5054 | (minibuffer--completion-prompt-end) (point-max) |
| 5008 | (lambda (string pred action) | 5055 | (completion-table-with-metadata |
| 5009 | (if (eq action 'metadata) | 5056 | completions '((display-sort-function . identity) |
| 5010 | '(metadata (display-sort-function . identity) | 5057 | (cycle-sort-function . identity))))))) |
| 5011 | (cycle-sort-function . identity)) | ||
| 5012 | (complete-with-action action completions string pred))))))) | ||
| 5013 | 5058 | ||
| 5014 | (defun minibuffer-complete-defaults () | 5059 | (defun minibuffer-complete-defaults () |
| 5015 | "Complete minibuffer defaults as far as possible. | 5060 | "Complete minibuffer defaults as far as possible. |
| @@ -5025,11 +5070,9 @@ instead of the completion table." | |||
| 5025 | (lambda () (get-buffer-window "*Completions*" 0)))) | 5070 | (lambda () (get-buffer-window "*Completions*" 0)))) |
| 5026 | (completion-in-region | 5071 | (completion-in-region |
| 5027 | (minibuffer--completion-prompt-end) (point-max) | 5072 | (minibuffer--completion-prompt-end) (point-max) |
| 5028 | (lambda (string pred action) | 5073 | (completion-table-with-metadata |
| 5029 | (if (eq action 'metadata) | 5074 | completions '((display-sort-function . identity) |
| 5030 | '(metadata (display-sort-function . identity) | 5075 | (cycle-sort-function . identity)))))) |
| 5031 | (cycle-sort-function . identity)) | ||
| 5032 | (complete-with-action action completions string pred)))))) | ||
| 5033 | 5076 | ||
| 5034 | (define-key minibuffer-local-map [?\C-x up] 'minibuffer-complete-history) | 5077 | (define-key minibuffer-local-map [?\C-x up] 'minibuffer-complete-history) |
| 5035 | (define-key minibuffer-local-map [?\C-x down] 'minibuffer-complete-defaults) | 5078 | (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 @@ is displayed with the `highlight' face to help identify it. The | |||
| 119 | '((t :inherit shadow)) | 119 | '((t :inherit shadow)) |
| 120 | "Face used for inactive menu items.") | 120 | "Face used for inactive menu items.") |
| 121 | 121 | ||
| 122 | (defun tmm--completion-table (items) | ||
| 123 | (lambda (string pred action) | ||
| 124 | (if (eq action 'metadata) | ||
| 125 | '(metadata (display-sort-function . identity)) | ||
| 126 | (complete-with-action action items string pred)))) | ||
| 127 | |||
| 128 | (defvar tmm--history nil) | 122 | (defvar tmm--history nil) |
| 129 | 123 | ||
| 130 | ;;;###autoload | 124 | ;;;###autoload |
| @@ -222,7 +216,9 @@ is used to go back through those sub-menus." | |||
| 222 | (setq out | 216 | (setq out |
| 223 | (if default-item | 217 | (if default-item |
| 224 | (car (nth index-of-default tmm-km-list)) | 218 | (car (nth index-of-default tmm-km-list)) |
| 225 | (minibuffer-with-setup-hook #'tmm-add-prompt | 219 | (minibuffer-with-setup-hook |
| 220 | (lambda () | ||
| 221 | (setq tmm-old-mb-map (tmm-define-keys t))) | ||
| 226 | ;; tmm-km-list is reversed, because history | 222 | ;; tmm-km-list is reversed, because history |
| 227 | ;; needs it in LIFO order. But default list | 223 | ;; needs it in LIFO order. But default list |
| 228 | ;; needs it in non-reverse order, so that the | 224 | ;; needs it in non-reverse order, so that the |
| @@ -233,7 +229,12 @@ is used to go back through those sub-menus." | |||
| 233 | (completing-read-default | 229 | (completing-read-default |
| 234 | (concat gl-str | 230 | (concat gl-str |
| 235 | " (up/down to change, PgUp to menu): ") | 231 | " (up/down to change, PgUp to menu): ") |
| 236 | (tmm--completion-table tmm-km-list) nil t nil | 232 | (completion-table-with-metadata |
| 233 | tmm-km-list '((category . tmm) | ||
| 234 | (eager-display . tmm-add-prompt) | ||
| 235 | (display-sort-function . identity) | ||
| 236 | (cycle-sort-function . identity))) | ||
| 237 | nil t nil | ||
| 237 | 'tmm--history (reverse tmm--history))))))) | 238 | 'tmm--history (reverse tmm--history))))))) |
| 238 | (if (and (stringp out) (string= "^" out)) | 239 | (if (and (stringp out) (string= "^" out)) |
| 239 | ;; A fake choice to please the destructuring later. | 240 | ;; A fake choice to please the destructuring later. |
| @@ -402,7 +403,6 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'." | |||
| 402 | (defun tmm-add-prompt () | 403 | (defun tmm-add-prompt () |
| 403 | (unless tmm-c-prompt | 404 | (unless tmm-c-prompt |
| 404 | (error "No active menu entries")) | 405 | (error "No active menu entries")) |
| 405 | (setq tmm-old-mb-map (tmm-define-keys t)) | ||
| 406 | (or tmm-completion-prompt | 406 | (or tmm-completion-prompt |
| 407 | (add-hook 'completion-setup-hook | 407 | (add-hook 'completion-setup-hook |
| 408 | #'tmm-completion-delete-prompt 'append)) | 408 | #'tmm-completion-delete-prompt 'append)) |
| @@ -458,6 +458,7 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'." | |||
| 458 | (defun tmm-goto-completions () | 458 | (defun tmm-goto-completions () |
| 459 | "Jump to the completions buffer." | 459 | "Jump to the completions buffer." |
| 460 | (interactive) | 460 | (interactive) |
| 461 | (tmm-add-prompt) | ||
| 461 | (setq tmm-c-prompt (buffer-substring (minibuffer-prompt-end) (point-max))) | 462 | (setq tmm-c-prompt (buffer-substring (minibuffer-prompt-end) (point-max))) |
| 462 | ;; Clear minibuffer old contents before using *Completions* buffer for | 463 | ;; Clear minibuffer old contents before using *Completions* buffer for |
| 463 | ;; selection. | 464 | ;; selection. |