emacs-devel
[Top][All Lists]
Advanced

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

Re: Stop frames stealing eachothers' minibuffers!


From: Alan Mackenzie
Subject: Re: Stop frames stealing eachothers' minibuffers!
Date: Tue, 3 Nov 2020 21:08:53 +0000

Hello, Eli.

On Mon, Nov 02, 2020 at 21:19:40 +0200, Eli Zaretskii wrote:
> > Date: Mon, 2 Nov 2020 18:51:47 +0000
> > Cc: emacs-devel@gnu.org
> > From: Alan Mackenzie <acm@muc.de

> > > Please just use the guts of Fminibufferp; the tests it does on its
> > > argument are not needed here.

> > Sorry, I can't follow you, here.  What do you mean by "the guts" of
> > Fminibufferp?  What things do you mean that the word "just" should
> > exclude?

> I meant to exclude these tests that Fminibufferp does:

>   if (NILP (buffer))
>     buffer = Fcurrent_buffer ();
>   else if (STRINGP (buffer))
>     buffer = Fget_buffer (buffer);
>   else
>     CHECK_BUFFER (buffer);

OK, I've extracted a new function `live_minibuffer_p'  from Fminibufferp,
and call that directly from the mini-window emptying code.  (The new
second parameter in Fminibufferp is still needed, since it is used in
minibuffer.el.)

Here's a patch of the subset of changes to minibuf.c which are relevant
to our discussions of the last two or three days.  Perhaps we are close
to the stage when this could be committed to master.



diff --git a/src/minibuf.c b/src/minibuf.c
index f957b2ae17..ebc00ae4e4 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -261,15 +302,31 @@ read_minibuf_noninteractive (Lisp_Object prompt, bool 
expflag,
   return val;
 }
 
+/* Return true when BUFFER is an active minibuffer.  */
+static bool
+live_minibuffer_p (Lisp_Object buffer)
+{
+  Lisp_Object tem;
+  EMACS_INT i;
+
+  if (EQ (buffer, Fcar (Vminibuffer_list)))
+    /*  *Minibuf-0* is never active.  */
+    return false;
+  tem = Fcdr (Vminibuffer_list);
+  for (i = 1; i <= minibuf_level; i++, tem = Fcdr (tem))
+    if (EQ (Fcar (tem), buffer))
+      return true;
+  return false;
+}
+
 DEFUN ("minibufferp", Fminibufferp,
-       Sminibufferp, 0, 1, 0,
+       Sminibufferp, 0, 2, 0,
        doc: /* Return t if BUFFER is a minibuffer.
 No argument or nil as argument means use current buffer as BUFFER.
-BUFFER can be a buffer or a buffer name.  */)
-  (Lisp_Object buffer)
+BUFFER can be a buffer or a buffer name.  If LIVE is non-nil, then
+return t only if BUFFER is an active minibuffer.  */)
+  (Lisp_Object buffer, Lisp_Object live)
 {
-  Lisp_Object tem;
-
   if (NILP (buffer))
     buffer = Fcurrent_buffer ();
   else if (STRINGP (buffer))
@@ -277,8 +334,10 @@ BUFFER can be a buffer or a buffer name.  */)
   else
     CHECK_BUFFER (buffer);
 
-  tem = Fmemq (buffer, Vminibuffer_list);
-  return ! NILP (tem) ? Qt : Qnil;
+  return (NILP (live)
+          ? !NILP (Fmemq (buffer, Vminibuffer_list))
+          : live_minibuffer_p (buffer))
+    ? Qt : Qnil;
 }
 
 DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end,
@@ -566,8 +626,8 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, 
Lisp_Object prompt,
   if (minibuf_level == 1 || !EQ (minibuf_window, selected_window))
     minibuf_selected_window = selected_window;
 
-  /* Empty out the minibuffers of all frames other than the one
-     where we are going to display one now.
+  /* Empty out the minibuffers of all frames, except those frames
+     where there is an active minibuffer.
      Set them to point to ` *Minibuf-0*', which is always empty.  */
   empty_minibuf = get_minibuffer (0);
 
@@ -575,12 +635,17 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, 
Lisp_Object prompt,
     {
       Lisp_Object root_window = Fframe_root_window (frame);
       Lisp_Object mini_window = XWINDOW (root_window)->next;
+      Lisp_Object buffer;
 
-      if (! NILP (mini_window) && ! EQ (mini_window, minibuf_window)
-         && !NILP (Fwindow_minibuffer_p (mini_window)))
-       /* Use set_window_buffer instead of Fset_window_buffer (see
-          discussion of bug#11984, bug#12025, bug#12026).  */
-       set_window_buffer (mini_window, empty_minibuf, 0, 0);
+      if (!NILP (mini_window) && !EQ (mini_window, minibuf_window)
+          && !NILP (Fwindow_minibuffer_p (mini_window)))
+        {
+          buffer = XWINDOW (mini_window)->contents;
+          if (!live_minibuffer_p (buffer))
+            /* Use set_window_buffer instead of Fset_window_buffer (see
+               discussion of bug#11984, bug#12025, bug#12026).  */
+            set_window_buffer (mini_window, empty_minibuf, 0, 0);
+        }
     }
 
   /* Display this minibuffer in the proper window.  */


-- 
Alan Mackenzie (Nuremberg, Germany).



reply via email to

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