>> Let-binding enable-recursive-minibuffers temporarily to t was necessary
>> to fix bug#17272/bug#19064.
>> So when the minibuffer is already activated, and a minibuffer command
>> wants to ask a question, displaying another recursive minibuffer with
>> such question should override the value of enable-recursive-minibuffers.
> Those bugs are about an echo-area message overwriting the minibuffer
> prompt, are they not? If so, doesn't the set-message-function feature
> we now have fixed those bugs indirectly, this removing the need for
> let-binding enable-recursive-minibuffers?
This problem is not fixed by set-message-function that only improves
messaging. The problem was reported by João in the same bug report
C-k ;; to kill the Messages buffer
This affects yes-or-no-p that C-k needs to use from the minibuffer
> From: Juri Linkov <[hidden email]>
> Cc: [hidden email], [hidden email] > Date: Wed, 17 Feb 2021 22:20:01 +0200
> >> Let-binding enable-recursive-minibuffers temporarily to t was necessary
> >> to fix bug#17272/bug#19064.
> >> So when the minibuffer is already activated, and a minibuffer command
> >> wants to ask a question, displaying another recursive minibuffer with
> >> such question should override the value of enable-recursive-minibuffers.
> > Those bugs are about an echo-area message overwriting the minibuffer
> > prompt, are they not? If so, doesn't the set-message-function feature
> > we now have fixed those bugs indirectly, this removing the need for
> > let-binding enable-recursive-minibuffers?
> This problem is not fixed by set-message-function that only improves
It prevents messages from overwriting minibuffer prompts. And both of
the bugs you mentioned seem to be about messages that overwrite such
prompts. So what am I missing?
> The problem was reported by João in the same bug report
> https://debbugs.gnu.org/17272#114 >
> Emacs -Q
> M-x fido-mode
> C-x b
> C-k ;; to kill the Messages buffer
> This affects yes-or-no-p that C-k needs to use from the minibuffer
> in fido-mode.
Sorry, I don't understand: how is this related to what I asked about?
>> I could send a patch that fixes this bug.
> Thanks. I hoped first to understand why we bind
> enable-recursive-minibuffers in these cases, but if you prefer to
> begin with a patch, please do, and let's take it from there.
To understand the problem, it's better to start from the manual.
The node (info "(elisp) Recursive Mini") says:
If a command name has a property ‘enable-recursive-minibuffers’ that
is non-‘nil’, then the command can use the minibuffer to read arguments
even if it is invoked from the minibuffer. A command can also achieve
this by binding ‘enable-recursive-minibuffers’ to ‘t’ in the interactive
declaration (*note Using Interactive::). The minibuffer command
‘next-matching-history-element’ (normally ‘M-s’ in the minibuffer) does
And indeed the command ‘next-matching-history-element’ (‘M-s’)
mentioned as an example in the documentation, exhibits the same
problem reported by Richard:
One possible solution is to support an additional value ‘transient’
for the variable ‘enable-recursive-minibuffers’. Then this value
could have its effect only for the next invocation of
read-from-minibuffer. Afterwards it will be set to ‘nil’
for any further recursive calls of read-from-minibuffer.
PS: Such transient value is similar to the value ‘lambda’ of
‘transient-mark-mode’ described in (info "(elisp) The Mark").
Currently this patch fixes the reported problem only
for the commands yes-or-no-p and next-matching-history-element:
+ if (EQ (Venable_recursive_minibuffers, Qtransient))
+ specbind (Qenable_recursive_minibuffers, Qnil);
/* In case we are running as a daemon, only do this before
detaching from the terminal. */
@@ -2242,6 +2245,7 @@ syms_of_minibuf (void)
DEFSYM (Qcase_fold_search, "case-fold-search");
DEFSYM (Qmetadata, "metadata");
DEFSYM (Qcycle_sort_function, "cycle-sort-function");
+ DEFSYM (Qtransient, "transient");
/* A frame parameter. */
DEFSYM (Qminibuffer_exit, "minibuffer-exit");
@@ -2311,12 +2315,12 @@ syms_of_minibuf (void)
controls the behavior, rather than this variable. */);
completion_ignore_case = 0;
- DEFVAR_BOOL ("enable-recursive-minibuffers", enable_recursive_minibuffers,
+ DEFVAR_LISP ("enable-recursive-minibuffers", Venable_recursive_minibuffers,
doc: /* Non-nil means to allow minibuffer commands while in the minibuffer.
This variable makes a difference whenever the minibuffer window is active.
Also see `minibuffer-depth-indicate-mode', which may be handy if this
variable is non-nil. */);
- enable_recursive_minibuffers = 0;
+ Venable_recursive_minibuffers = Qnil;
DEFVAR_LISP ("minibuffer-completion-table", Vminibuffer_completion_table,
doc: /* Alist or obarray used for completion in the minibuffer.
diff --git a/src/fns.c b/src/fns.c
index f51ef2781d..4744fddf27 100644
@@ -2882,7 +2882,8 @@ DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, 1, 0,
prompt = CALLN (Fconcat, prompt, yes_or_no);