emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 49e06183f5 1/3: Allow REQUIRE-MATCH to be a function


From: Lars Ingebrigtsen
Subject: master 49e06183f5 1/3: Allow REQUIRE-MATCH to be a function
Date: Fri, 10 Jun 2022 04:22:40 -0400 (EDT)

branch: master
commit 49e06183f5972817d93dad6acf5351c204e61cc5
Author: Lars Ingebrigtsen <larsi@gnus.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    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.
---
 doc/lispref/minibuf.texi |  5 +++
 lisp/minibuffer.el       | 93 ++++++++++++++++++++++++++----------------------
 src/minibuf.c            |  2 ++
 3 files changed, 57 insertions(+), 43 deletions(-)

diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi
index be81b5b3fb..86e601f8c0 100644
--- a/doc/lispref/minibuf.texi
+++ b/doc/lispref/minibuf.texi
@@ -1121,6 +1121,11 @@ completion command (i.e., one of the commands in
 @code{minibuffer-confirm-exit-commands}) and the resulting input is
 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.
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index cdbde2d340..332e3fcce9 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 79985b8d2b..3e984d163d 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.
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]