From edd46c1a2df6dea2154eb893da51eca1abd2da83 Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Thu, 22 Apr 2021 20:51:52 +0000 Subject: [PATCH] Make it possible to disable a completion backend in recursive minibuffers --- lisp/minibuffer.el | 3 ++- lisp/subr.el | 34 ++++++++++++++++++++++++++++++++++ src/fns.c | 6 +++--- src/minibuf.c | 20 ++++++++++++++------ 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 7da3c39e6b..379dadef9d 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -3884,7 +3884,8 @@ completing-read-default ;; `read-from-minibuffer' uses 1-based index. (1+ (cdr initial-input))))) - (let* ((minibuffer-completion-table collection) + (let* ((minibuffer-local-completion t) + (minibuffer-completion-table collection) (minibuffer-completion-predicate predicate) ;; FIXME: Remove/rename this var, see the next one. (minibuffer-completion-confirm (unless (eq require-match t) diff --git a/lisp/subr.el b/lisp/subr.el index c2be26a15f..972422f343 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2791,6 +2791,40 @@ read-passwd ;; And of course, don't keep the sensitive data around. (erase-buffer)))))))) +(defvar minibuffer-local-completion nil + "Whether minibuffer completion elements should become buffer-local. +The default is nil for Emacs 28. Setting this variable in Emacs 29 will +have no effect; the value t will be assumed. +When t, `minibuffer-completion-table', `minibuffer-completion-predicate' +and `minibuffer-completion-confirm' become buffer-local upon entering the +minibuffer, and are nil in recursive invocations of the minibuffer, unless +they have been let-bound to a value. +When nil, their values is shared between the recursive invocations of the +minibuffer, unless they have been let-bound to another value.") + +(defmacro read-from-minibuffer (&rest body) + "Read a string from the minibuffer with `internal-read-from-minibuffer'. +See `internal-read-from-minibuffer' for a description of the arguments. +This macro exists only in Emacs 28, for the transition period during which +the default value of `minibuffer-local-completion' is nil, and will be +removed in Emacs 29. Likewise, `internal-read-from-minibuffer' will be +removed in Emacs 29, please do not use it directly." + `(if minibuffer-local-completion + (let ((minibuffer-local-c-t minibuffer-completion-table) + (minibuffer-local-c-p minibuffer-completion-predicate) + (minibuffer-local-c-c minibuffer-completion-confirm)) + (let ((minibuffer-completion-table nil) + (minibuffer-completion-predicate nil) + (minibuffer-completion-confirm nil)) + (minibuffer-with-setup-hook + (lambda () + (setq-local minibuffer-completion-table minibuffer-local-c-t + minibuffer-completion-predicate minibuffer-local-c-p + minibuffer-completion-confirm minibuffer-local-c-c) + (setq minibuffer-local-completion nil)) + (internal-read-from-minibuffer ,@body)))) + (internal-read-from-minibuffer ,@body))) + (defvar read-number-history nil "The default history for the `read-number' function.") diff --git a/src/fns.c b/src/fns.c index 1758148ff2..db6679a847 100644 --- a/src/fns.c +++ b/src/fns.c @@ -2985,9 +2985,9 @@ DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, 1, 0, while (1) { - ans = Fdowncase (Fread_from_minibuffer (prompt, Qnil, Qnil, Qnil, - Qyes_or_no_p_history, Qnil, - Qnil)); + ans = Fdowncase (Finternal_read_from_minibuffer (prompt, Qnil, Qnil, Qnil, + Qyes_or_no_p_history, Qnil, + Qnil)); if (SCHARS (ans) == 3 && !strcmp (SSDATA (ans), "yes")) return unbind_to (count, Qt); if (SCHARS (ans) == 2 && !strcmp (SSDATA (ans), "no")) diff --git a/src/minibuf.c b/src/minibuf.c index 1a637c86ad..90f329ddb2 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1231,9 +1231,17 @@ barf_if_interaction_inhibited (void) xsignal0 (Qinhibited_interaction); } -DEFUN ("read-from-minibuffer", Fread_from_minibuffer, - Sread_from_minibuffer, 1, 7, 0, +DEFUN ("internal-read-from-minibuffer", Finternal_read_from_minibuffer, + Sinternal_read_from_minibuffer, 1, 7, 0, doc: /* Read a string from the minibuffer, prompting with string PROMPT. + +Warning: Do not use this function directly, use `read-from-minibuffer' +instead, with the arguments described below. The `read-from-minibuffer' +macro exists only in Emacs 28 for the transition period during which the +default value of `minibuffer-local-completion' is nil, it will be removed +in Emacs 29, and `internal--read-from-minibuffer' will become +`read-from-minibuffer' again. + The optional second arg INITIAL-CONTENTS is an obsolete alternative to DEFAULT-VALUE. It normally should be nil in new code, except when HIST is a cons. It is discussed in more detail below. @@ -1352,9 +1360,9 @@ DEFUN ("read-string", Fread_string, Sread_string, 1, 5, 0, FIXME: `minibuffer-completion-table' should be buffer-local instead. */ specbind (Qminibuffer_completion_table, Qnil); - val = Fread_from_minibuffer (prompt, initial_input, Qnil, - Qnil, history, default_value, - inherit_input_method); + val = Finternal_read_from_minibuffer (prompt, initial_input, Qnil, + Qnil, history, default_value, + inherit_input_method); if (STRINGP (val) && SCHARS (val) == 0 && ! NILP (default_value)) val = CONSP (default_value) ? XCAR (default_value) : default_value; return unbind_to (count, val); @@ -2487,7 +2495,7 @@ syms_of_minibuf (void) defsubr (&Sactive_minibuffer_window); defsubr (&Sset_minibuffer_window); - defsubr (&Sread_from_minibuffer); + defsubr (&Sinternal_read_from_minibuffer); defsubr (&Sread_string); defsubr (&Sread_command); defsubr (&Sread_variable); -- 2.30.2