aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Mendler2025-02-03 16:39:49 +0100
committerEli Zaretskii2025-02-15 13:39:33 +0200
commita8a4c3a091bc6ebab40db3b33f4d15bb1040dbcb (patch)
tree14a0306910f9d7c0db671b9d6f2d66a827bf2010
parent6491fee366f58a831689c57aa31493dd70bc2245 (diff)
downloademacs-a8a4c3a091bc6ebab40db3b33f4d15bb1040dbcb.tar.gz
emacs-a8a4c3a091bc6ebab40db3b33f4d15bb1040dbcb.zip
completing-read-multiple: CRM indication and prompt customization
The `completing-read-multiple' prompt indicates multi completion. The customization option `crm-prompt' configures the formatting of the prompt. The variable can be set to "%p" in order to only display the original prompt, to "[%d] %p" to display the separator description and the prompt, or to "[CRM%s] %p" to display a shorter indicator of only the separator string and the prompt. * lisp/emacs-lisp/crm.el (crm-prompt): New user option. (crm-separator): Update value and docstring. (completing-read-multiple): Use `crm-prompt' to format the prompt. * etc/NEWS: Announce the change. (Bug#76028)
-rw-r--r--etc/NEWS8
-rw-r--r--lisp/emacs-lisp/crm.el30
2 files changed, 34 insertions, 4 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 51f481c763c..6d934b2029c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -176,6 +176,14 @@ will still be on that candidate after "*Completions*" is updated with a
176new list of completions. The candidate is automatically deselected when 176new list of completions. The candidate is automatically deselected when
177the "*Completions*" buffer is hidden. 177the "*Completions*" buffer is hidden.
178 178
179---
180*** New user option 'crm-prompt' for 'completing-read-multiple'.
181This option configures the prompt format of 'completing-read-multiple'.
182By default the prompt indicates to the user that the completion command
183accepts a comma-separated list. The prompt format can include the
184separator description and the separator string, which are both stored as
185text properties of the 'crm-separator' regular expression.
186
179** Windows 187** Windows
180 188
181+++ 189+++
diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el
index a371a8e14de..676252ae126 100644
--- a/lisp/emacs-lisp/crm.el
+++ b/lisp/emacs-lisp/crm.el
@@ -79,9 +79,25 @@
79 79
80(define-obsolete-variable-alias 'crm-default-separator 'crm-separator "29.1") 80(define-obsolete-variable-alias 'crm-default-separator 'crm-separator "29.1")
81 81
82(defvar crm-separator "[ \t]*,[ \t]*" 82(defvar crm-separator
83 (propertize "[ \t]*,[ \t]*" 'separator "," 'description "comma-separated list")
83 "Separator regexp used for separating strings in `completing-read-multiple'. 84 "Separator regexp used for separating strings in `completing-read-multiple'.
84It should be a regexp that does not match the list of completion candidates.") 85It should be a regexp that does not match the list of completion
86candidates. The regexp string can carry the text properties `separator'
87and `description', which if present `completing-read-multiple' will show
88as part of the prompt. See the user option `crm-prompt'.")
89
90(defcustom crm-prompt "[%d] %p"
91 "Prompt format for `completing-read-multiple'.
92The prompt is formatted by `format-spec' with the keys %d, %s and %p
93standing for the separator description, the separator itself and the
94original prompt respectively."
95 :type '(choice (const :tag "Original prompt" "%p")
96 (const :tag "Description and prompt" "[%d] %p")
97 (const :tag "Short CRM indication" "[CRM%s] %p")
98 (string :tag "Custom string"))
99 :group 'minibuffer
100 :version "31.1")
85 101
86(defvar-keymap crm-local-completion-map 102(defvar-keymap crm-local-completion-map
87 :doc "Local keymap for minibuffer multiple input with completion. 103 :doc "Local keymap for minibuffer multiple input with completion.
@@ -266,8 +282,14 @@ with empty strings removed."
266 (unless (eq require-match t) require-match)) 282 (unless (eq require-match t) require-match))
267 (setq-local crm-completion-table table)) 283 (setq-local crm-completion-table table))
268 (setq input (read-from-minibuffer 284 (setq input (read-from-minibuffer
269 prompt initial-input map 285 (format-spec
270 nil hist def inherit-input-method))) 286 crm-prompt
287 (let* ((sep (or (get-text-property 0 'separator crm-separator)
288 (string-replace "[ \t]*" "" crm-separator)))
289 (desc (or (get-text-property 0 'description crm-separator)
290 (concat "list separated by " sep))))
291 `((?s . ,sep) (?d . ,desc) (?p . ,prompt))))
292 initial-input map nil hist def inherit-input-method)))
271 ;; If the user enters empty input, `read-from-minibuffer' 293 ;; If the user enters empty input, `read-from-minibuffer'
272 ;; returns the empty string, not DEF. 294 ;; returns the empty string, not DEF.
273 (when (and def (string-equal input "")) 295 (when (and def (string-equal input ""))