From 93a257cf50f1210f8b31487f892ea6bf8ba450db Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Tue, 20 Apr 2021 18:46:33 +0000 Subject: [PATCH] Make it possible to disable a completion backend in recursive minibuffers --- lisp/minibuffer.el | 1 + lisp/subr.el | 13 +++++++++++++ src/fns.c | 6 +++--- src/minibuf.c | 37 +++++++++++++++++++++++++++++++------ 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index c900b0d7ce..20103b5191 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -3825,6 +3825,7 @@ completing-read-default (1+ (cdr initial-input))))) (let* ((minibuffer-completion-table collection) + (minibuffer-local-completion-table t) (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..28b42fa398 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2791,6 +2791,19 @@ read-passwd ;; And of course, don't keep the sensitive data around. (erase-buffer)))))))) +(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-table' 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-table + (let ((minibuffer-local-completion-table minibuffer-completion-table)) + (let ((minibuffer-completion-table 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 c9831fd50f..6d4c2848f6 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -862,6 +862,12 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, if (STRINGP (input_method) && !NILP (Ffboundp (Qactivate_input_method))) call1 (Qactivate_input_method, input_method); + if (! EQ (Vminibuffer_local_completion_table, Qnil)) { + Fmake_local_variable (Qminibuffer_completion_table); + Fset (Qminibuffer_completion_table, Vminibuffer_local_completion_table); + specbind (Qminibuffer_local_completion_table, Qnil); + } + run_hook (Qminibuffer_setup_hook); /* Don't allow the user to undo past this point. */ @@ -1223,9 +1229,16 @@ 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. + +Note: Do not use this function directly, use `read-from-minibuffer' instead, +whith 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-table' 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. @@ -1344,9 +1357,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); @@ -2297,6 +2310,7 @@ syms_of_minibuf (void) Fset (Qminibuffer_default, Qnil); DEFSYM (Qminibuffer_completion_table, "minibuffer-completion-table"); + DEFSYM (Qminibuffer_local_completion_table, "minibuffer-local-completion-table"); staticpro (&last_minibuf_string); @@ -2409,6 +2423,17 @@ syms_of_minibuf (void) lambda -- return t if STRING is a valid completion as it stands. */); Vminibuffer_completion_table = Qnil; + DEFVAR_LISP ("minibuffer-local-completion-table", Vminibuffer_local_completion_table, + doc: /* Whether `minibuffer-completion-table' 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' becomes buffer-local upon entering the minibuffer, +and is nil in recursive invocations of the minibuffer, unless it has been let-bound to +a value. +When nil, `minibuffer-completion-table' is shared between the recursive invocations of +the minibuffer, unless it has been let-bound to another value. */); + Vminibuffer_local_completion_table = Qnil; + DEFVAR_LISP ("minibuffer-completion-predicate", Vminibuffer_completion_predicate, doc: /* Within call to `completing-read', this holds the PREDICATE argument. */); Vminibuffer_completion_predicate = Qnil; @@ -2496,7 +2521,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