summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Ingebrigtsen <larsi@gnus.org>2022-06-10 10:16:57 +0200
committerLars Ingebrigtsen <larsi@gnus.org>2022-06-10 10:22:33 +0200
commit49e06183f5972817d93dad6acf5351c204e61cc5 (patch)
treeb2398f211b1ff12f9f590dd4585b0c526cf6cac4
parent32aa5c76bdb0236f159f24a7d8a7698b88fcb712 (diff)
downloademacs-49e06183f5972817d93dad6acf5351c204e61cc5.tar.gz
Allow REQUIRE-MATCH to be a function
* doc/lispref/minibuf.texi (Minibuffer Completion): Document it. * lisp/minibuffer.el (completion--complete-and-exit): Allow REQUIRE-MATCH to be a function. (read-file-name): Mention it. * src/minibuf.c (Fcompleting_read): Mention it.
-rw-r--r--doc/lispref/minibuf.texi5
-rw-r--r--lisp/minibuffer.el93
-rw-r--r--src/minibuf.c2
3 files changed, 57 insertions, 43 deletions
diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi
index be81b5b3fbb..86e601f8c0f 100644
--- a/doc/lispref/minibuf.texi
+++ b/doc/lispref/minibuf.texi
@@ -1122,6 +1122,11 @@ completion command (i.e., one of the commands in
not an element of @var{collection}. @xref{Completion Commands}.
@item
+If a function, the function is called with the input as the only
+argument. The function should return a non-@code{nil} value of the
+input is acceptable.
+
+@item
Any other value of @var{require-match} behaves like @code{t}, except
that the exit commands won't exit if it performs completion.
@end itemize
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index cdbde2d3405..332e3fcce97 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -1726,52 +1726,57 @@ If `minibuffer-completion-confirm' is `confirm-after-completion',
"Exit from `require-match' minibuffer.
COMPLETION-FUNCTION is called if the current buffer's content does not
appear to be a match."
- (cond
- ;; Allow user to specify null string
+ (cond
+ ;; Allow user to specify null string
((= beg end) (funcall exit-function))
- ((test-completion (buffer-substring beg end)
- minibuffer-completion-table
- minibuffer-completion-predicate)
- ;; FIXME: completion-ignore-case has various slightly
- ;; incompatible meanings. E.g. it can reflect whether the user
- ;; wants completion to pay attention to case, or whether the
- ;; string will be used in a context where case is significant.
- ;; E.g. usually try-completion should obey the first, whereas
- ;; test-completion should obey the second.
- (when completion-ignore-case
- ;; Fixup case of the field, if necessary.
- (let* ((string (buffer-substring beg end))
- (compl (try-completion
- string
- minibuffer-completion-table
- minibuffer-completion-predicate)))
- (when (and (stringp compl) (not (equal string compl))
- ;; If it weren't for this piece of paranoia, I'd replace
- ;; the whole thing with a call to do-completion.
- ;; This is important, e.g. when the current minibuffer's
- ;; content is a directory which only contains a single
- ;; file, so `try-completion' actually completes to
- ;; that file.
- (= (length string) (length compl)))
- (completion--replace beg end compl))))
- (funcall exit-function))
-
- ((memq minibuffer-completion-confirm '(confirm confirm-after-completion))
- ;; The user is permitted to exit with an input that's rejected
- ;; by test-completion, after confirming her choice.
- (if (or (eq last-command this-command)
- ;; For `confirm-after-completion' we only ask for confirmation
- ;; if trying to exit immediately after typing TAB (this
- ;; catches most minibuffer typos).
- (and (eq minibuffer-completion-confirm 'confirm-after-completion)
- (not (memq last-command minibuffer-confirm-exit-commands))))
+ ;; The CONFIRM argument is a predicate.
+ ((and (functionp minibuffer-completion-confirm)
+ (funcall minibuffer-completion-confirm
+ (buffer-substring beg end)))
+ (funcall exit-function))
+ ;; See if we have a completion from the table.
+ ((test-completion (buffer-substring beg end)
+ minibuffer-completion-table
+ minibuffer-completion-predicate)
+ ;; FIXME: completion-ignore-case has various slightly
+ ;; incompatible meanings. E.g. it can reflect whether the user
+ ;; wants completion to pay attention to case, or whether the
+ ;; string will be used in a context where case is significant.
+ ;; E.g. usually try-completion should obey the first, whereas
+ ;; test-completion should obey the second.
+ (when completion-ignore-case
+ ;; Fixup case of the field, if necessary.
+ (let* ((string (buffer-substring beg end))
+ (compl (try-completion
+ string
+ minibuffer-completion-table
+ minibuffer-completion-predicate)))
+ (when (and (stringp compl) (not (equal string compl))
+ ;; If it weren't for this piece of paranoia, I'd replace
+ ;; the whole thing with a call to do-completion.
+ ;; This is important, e.g. when the current minibuffer's
+ ;; content is a directory which only contains a single
+ ;; file, so `try-completion' actually completes to
+ ;; that file.
+ (= (length string) (length compl)))
+ (completion--replace beg end compl))))
+ (funcall exit-function))
+ ;; The user is permitted to exit with an input that's rejected
+ ;; by test-completion, after confirming her choice.
+ ((memq minibuffer-completion-confirm '(confirm confirm-after-completion))
+ (if (or (eq last-command this-command)
+ ;; For `confirm-after-completion' we only ask for confirmation
+ ;; if trying to exit immediately after typing TAB (this
+ ;; catches most minibuffer typos).
+ (and (eq minibuffer-completion-confirm 'confirm-after-completion)
+ (not (memq last-command minibuffer-confirm-exit-commands))))
(funcall exit-function)
- (minibuffer-message "Confirm")
- nil))
+ (minibuffer-message "Confirm")
+ nil))
- (t
- ;; Call do-completion, but ignore errors.
- (funcall completion-function))))
+ (t
+ ;; Call do-completion, but ignore errors.
+ (funcall completion-function))))
(defun completion--try-word-completion (string table predicate point md)
(let ((comp (completion-try-completion string table predicate point md)))
@@ -3156,6 +3161,8 @@ Fourth arg MUSTMATCH can take the following values:
input, but she needs to confirm her choice if she called
`minibuffer-complete' right before `minibuffer-complete-and-exit'
and the input is not an existing file.
+- a function, which will be called with the input as the parameter.
+ If it returns a non-nil value, we exit with that value.
- anything else behaves like t except that typing RET does not exit if it
does non-null completion.
diff --git a/src/minibuf.c b/src/minibuf.c
index 79985b8d2bb..3e984d163d1 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -2009,6 +2009,8 @@ REQUIRE-MATCH can take the following values:
input, but she needs to confirm her choice if she called
`minibuffer-complete' right before `minibuffer-complete-and-exit'
and the input is not an element of COLLECTION.
+- a function, which will be called with the input as the parameter.
+ If it returns a non-nil value, we exit with that value.
- anything else behaves like t except that typing RET does not exit if it
does non-null completion.