Fix incompleteness in the implementation of minibuffer-follows-selected-frame
In particular, add a new value to the variable, and fix several bugs apparent with the implementation up till now. * doc/emacs/mini.texi (Basic Minibuffer): Add a description of the new non-nil, non-t value of minibuffer-follows-selected-frame. * doc/emacs/trouble.texi (Quitting): Add a description of how C-g handles recursive minibuffers when typed in one which isn't the most nested. * doc/lispref/minibuf.texi (Intro to Minibuffers): Add an @dfn for "active minibuffer". (Minibuffer Commands): Document that exit-minibuffer throws an error when not invoked from the innermost Minibuffer. (Recursive Mini): Amend the description of the visibility of outer level minibuffers. (Minibuffer Misc): In the description of the minibuffer hooks, replace "the minibuffer" with "a minibuffer". * etc/NEWS (Entry announcing minibuffer-follows-selected-frame): Add a description of the new non-nil, non-t value. * lisp/cus-start.el (top level): make the customize entry for minibuffer-follows-selected-frame a choice between three entries. * lisp/minibuffer.el (exit-minibuffer): throw an error when we're not in the most nested minibuffer. (top level): Bind C-g to abort-minibuffers in minibuffer-local-map. * lisp/window.el (window-deletable-p): return the symbol `frame' when (amongst other things) minibuffer-follows-selected-frame is t. * src/eval.c (internal_catch): Add a mechanism to (throw 'exit t) repeatedly when the throw currently being processed doesn't terminate the current minibuffer. * src/lisp.h (this_minibuffer_depth): New extern declaration (minibuf_level): extern declaration moved here from window.h. * src/minibuf.c (minibuffer_follows_frame, minibuf_stays_put) (minibuf_moves_frame_when_opened): New and amended functions to query the value of minibuffer-follows-selected-frame. (choose_minibuf_frame): check (minibuf > 1) in place of (minibufer > 0) at a particular place. At another place, check that an alleged frame is so and is live. Before selecting a non-miniwindow on a different frame, ensure it really is a different frame. (move_minibuffer_onto_frame): Stack up all recursive minibuffers on the target frame. Check the minibuf_window isn't in the old frame before setting that frame's miniwindow to an inactive minibuffer. (Finnermost_minibuffer_p, Fabort_minibuffers): New primitives. (this_minibuffer_depth): New function. (read_minibuf): Record the calling frame in a variable, and switch back to it after the recursive edit has terminated normally, using select-frame-set-input-focus. Stack up all the recursive minibuffers on the miniwindow where a new minibuffer is being opened. After the recursive edit, switch the selected window away from the expired minibuffer's window. (nth_minibuffer): New function. (minibuffer-follows-selected-frame): Change from a DEFVAR_BOOL to a DEFVAR_LISP. * src/window.c (decode_next_window_args): Set *minibuf to w's mini-window's content when that content is a minibuffer. * src/window.h (minibuf_level) Declaration moved from here to lisp.h.
This commit is contained in:
parent
a583c72305
commit
c7c154bb57
12 changed files with 242 additions and 48 deletions
|
@ -76,9 +76,13 @@ default, the active minibuffer moves to this new frame. If you set
|
|||
the user option @code{minibuffer-follows-selected-frame} to
|
||||
@code{nil}, then the minibuffer stays in the frame where you opened
|
||||
it, and you must switch back to that frame in order to complete (or
|
||||
abort) the current command. Note that the effect of the command, when
|
||||
you finally finish using the minibuffer, always takes place in the
|
||||
frame where you first opened it.
|
||||
abort) the current command. If you set that option to a value which
|
||||
is neither @code{nil} nor @code{t}, the minibuffer moves frame only
|
||||
after a recursive minibuffer has been opened in the current command
|
||||
(@pxref{Recursive Mini,,, elisp}). This option is mainly to retain
|
||||
(approximately) the behavior prior to Emacs 28.1. Note that the
|
||||
effect of the command, when you finally finish using the minibuffer,
|
||||
always takes place in the frame where you first opened it.
|
||||
|
||||
@node Minibuffer File
|
||||
@section Minibuffers for File Names
|
||||
|
|
|
@ -57,6 +57,13 @@ incremental search, @kbd{C-g} behaves specially; it may take two
|
|||
successive @kbd{C-g} characters to get out of a search.
|
||||
@xref{Incremental Search}, for details.
|
||||
|
||||
If you type @kbd{C-g} in a minibuffer, this quits the command that
|
||||
opened that minibuffer, closing it. If that minibuffer is not the
|
||||
most recently opened one (which can happen when
|
||||
@code{minibuffer-follows-selected-frame} is @code{nil} (@pxref{Basic
|
||||
Minibuffer})), @kbd{C-g} also closes the more recently opened ones,
|
||||
quitting their associated commands, after asking you for confirmation.
|
||||
|
||||
On MS-DOS, the character @kbd{C-@key{Break}} serves as a quit character
|
||||
like @kbd{C-g}. The reason is that it is not feasible, on MS-DOS, to
|
||||
recognize @kbd{C-g} while a command is running, between interactions
|
||||
|
|
|
@ -82,10 +82,12 @@ there is an active minibuffer; such a minibuffer is called a
|
|||
incrementing the number at the end of the name. (The names begin with
|
||||
a space so that they won't show up in normal buffer lists.) Of
|
||||
several recursive minibuffers, the innermost (or most recently
|
||||
entered) is the active minibuffer. We usually call this @emph{the}
|
||||
minibuffer. You can permit or forbid recursive minibuffers by setting
|
||||
the variable @code{enable-recursive-minibuffers}, or by putting
|
||||
properties of that name on command symbols (@xref{Recursive Mini}.)
|
||||
entered) is the @dfn{active minibuffer}--it is the one you can
|
||||
terminate by typing @key{RET} (@code{exit-minibuffer}) in. We usually
|
||||
call this @emph{the} minibuffer. You can permit or forbid recursive
|
||||
minibuffers by setting the variable
|
||||
@code{enable-recursive-minibuffers}, or by putting properties of that
|
||||
name on command symbols (@xref{Recursive Mini}.)
|
||||
|
||||
Like other buffers, a minibuffer uses a local keymap
|
||||
(@pxref{Keymaps}) to specify special key bindings. The function that
|
||||
|
@ -2380,7 +2382,8 @@ minibuffer.
|
|||
|
||||
@deffn Command exit-minibuffer
|
||||
This command exits the active minibuffer. It is normally bound to
|
||||
keys in minibuffer local keymaps.
|
||||
keys in minibuffer local keymaps. The command throws an error if the
|
||||
current buffer is not the active minibuffer.
|
||||
@end deffn
|
||||
|
||||
@deffn Command self-insert-and-exit
|
||||
|
@ -2594,8 +2597,11 @@ returns zero.
|
|||
If this variable is non-@code{nil}, you can invoke commands (such as
|
||||
@code{find-file}) that use minibuffers even while the minibuffer is
|
||||
active. Such invocation produces a recursive editing level for a new
|
||||
minibuffer. The outer-level minibuffer is invisible while you are
|
||||
editing the inner one.
|
||||
minibuffer. By default, the outer-level minibuffer is invisible while
|
||||
you are editing the inner one. If you have
|
||||
@code{minibuffer-follows-selected-frame} set to @code{nil}, you can
|
||||
have minibuffers visible on several frames at the same time.
|
||||
@xref{Basic Minibuffer,,, emacs}.
|
||||
|
||||
If this variable is @code{nil}, you cannot invoke minibuffer commands
|
||||
when the minibuffer is active, not even if you switch to another window
|
||||
|
@ -2623,7 +2629,7 @@ active minibuffer.
|
|||
@end defun
|
||||
|
||||
@defvar minibuffer-setup-hook
|
||||
This is a normal hook that is run whenever the minibuffer is entered.
|
||||
This is a normal hook that is run whenever a minibuffer is entered.
|
||||
@xref{Hooks}.
|
||||
@end defvar
|
||||
|
||||
|
@ -2641,7 +2647,7 @@ called once, for the outermost use of the minibuffer.
|
|||
@end defmac
|
||||
|
||||
@defvar minibuffer-exit-hook
|
||||
This is a normal hook that is run whenever the minibuffer is exited.
|
||||
This is a normal hook that is run whenever a minibuffer is exited.
|
||||
@xref{Hooks}.
|
||||
@end defvar
|
||||
|
||||
|
|
13
etc/NEWS
13
etc/NEWS
|
@ -102,12 +102,13 @@ effect should be negligible in the vast majority of cases anyway.
|
|||
By default, when you switch to another frame, an active minibuffer now
|
||||
moves to the newly selected frame. Nevertheless, the effect of what
|
||||
you type in the minibuffer happens in the frame where the minibuffer
|
||||
was first activated, even if it moved to another frame. An
|
||||
alternative behavior is available by customizing
|
||||
'minibuffer-follows-selected-frame' to nil. Here, the minibuffer
|
||||
stays in the frame where you first opened it, and you must switch back
|
||||
to this frame to continue or abort its command. The old, somewhat
|
||||
unsystematic behavior, which mixed these two is no longer available.
|
||||
was first activated. An alternative behavior is available by
|
||||
customizing 'minibuffer-follows-selected-frame' to nil. Here, the
|
||||
minibuffer stays in the frame where you first opened it, and you must
|
||||
switch back to this frame to continue or abort its command. The old
|
||||
behavior, which mixed these two, can be approximated by customizing
|
||||
'minibuffer-follows-selected-frame' to a value which is neither nil
|
||||
nor t.
|
||||
|
||||
+++
|
||||
** New system for displaying documentation for groups of functions.
|
||||
|
|
|
@ -394,7 +394,11 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
|
|||
;; (directory :format "%v"))))
|
||||
(load-prefer-newer lisp boolean "24.4")
|
||||
;; minibuf.c
|
||||
(minibuffer-follows-selected-frame minibuffer boolean "28.1")
|
||||
(minibuffer-follows-selected-frame
|
||||
minibuffer (choice (const :tag "Always" t)
|
||||
(const :tag "When used" hybrid)
|
||||
(const :tag "Never" nil))
|
||||
"28.1")
|
||||
(enable-recursive-minibuffers minibuffer boolean)
|
||||
(history-length minibuffer
|
||||
(choice (const :tag "Infinite" t) integer)
|
||||
|
|
|
@ -2125,8 +2125,10 @@ variables.")
|
|||
;; A better solution would be to make deactivate-mark buffer-local
|
||||
;; (or to turn it into a list of buffers, ...), but in the mean time,
|
||||
;; this should do the trick in most cases.
|
||||
(setq deactivate-mark nil)
|
||||
(throw 'exit nil))
|
||||
(when (innermost-minibuffer-p)
|
||||
(setq deactivate-mark nil)
|
||||
(throw 'exit nil))
|
||||
(error "%s" "Not in most nested minibuffer"))
|
||||
|
||||
(defun self-insert-and-exit ()
|
||||
"Terminate minibuffer input."
|
||||
|
@ -2394,7 +2396,7 @@ The completion method is determined by `completion-at-point-functions'."
|
|||
;;; Key bindings.
|
||||
|
||||
(let ((map minibuffer-local-map))
|
||||
(define-key map "\C-g" 'abort-recursive-edit)
|
||||
(define-key map "\C-g" 'abort-minibuffers)
|
||||
(define-key map "\M-<" 'minibuffer-beginning-of-buffer)
|
||||
|
||||
(define-key map "\r" 'exit-minibuffer)
|
||||
|
|
|
@ -4116,7 +4116,10 @@ frame can be safely deleted."
|
|||
frame))
|
||||
(throw 'other t))))
|
||||
(let ((minibuf (active-minibuffer-window)))
|
||||
(and minibuf (eq frame (window-frame minibuf)))))
|
||||
(and minibuf (eq frame (window-frame minibuf))
|
||||
(not (eq (default-toplevel-value
|
||||
minibuffer-follows-selected-frame)
|
||||
t)))))
|
||||
'frame))
|
||||
((window-minibuffer-p window)
|
||||
;; If WINDOW is the minibuffer window of a non-minibuffer-only
|
||||
|
|
26
src/eval.c
26
src/eval.c
|
@ -1167,9 +1167,18 @@ Lisp_Object
|
|||
internal_catch (Lisp_Object tag,
|
||||
Lisp_Object (*func) (Lisp_Object), Lisp_Object arg)
|
||||
{
|
||||
/* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by
|
||||
throwing t to tag `exit'.
|
||||
Value -1 means there is no (throw 'exit t) in progress;
|
||||
0 means the `throw' wasn't done from an active minibuffer;
|
||||
N > 0 means the `throw' was done from the minibuffer at level N. */
|
||||
static EMACS_INT minibuffer_quit_level = -1;
|
||||
/* This structure is made part of the chain `catchlist'. */
|
||||
struct handler *c = push_handler (tag, CATCHER);
|
||||
|
||||
if (EQ (tag, Qexit))
|
||||
minibuffer_quit_level = -1;
|
||||
|
||||
/* Call FUNC. */
|
||||
if (! sys_setjmp (c->jmp))
|
||||
{
|
||||
|
@ -1183,6 +1192,23 @@ internal_catch (Lisp_Object tag,
|
|||
Lisp_Object val = handlerlist->val;
|
||||
clobbered_eassert (handlerlist == c);
|
||||
handlerlist = handlerlist->next;
|
||||
if (EQ (tag, Qexit) && EQ (val, Qt))
|
||||
/* If we've thrown t to tag `exit' from within a minibuffer, we
|
||||
exit all minibuffers more deeply nested than the current
|
||||
one. */
|
||||
{
|
||||
EMACS_INT mini_depth = this_minibuffer_depth (Qnil);
|
||||
if (mini_depth && mini_depth != minibuffer_quit_level)
|
||||
{
|
||||
if (minibuffer_quit_level == -1)
|
||||
minibuffer_quit_level = mini_depth;
|
||||
if (minibuffer_quit_level
|
||||
&& (minibuf_level > minibuffer_quit_level))
|
||||
Fthrow (Qexit, Qt);
|
||||
}
|
||||
else
|
||||
minibuffer_quit_level = -1;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4346,6 +4346,8 @@ extern Lisp_Object Vminibuffer_list;
|
|||
extern Lisp_Object last_minibuf_string;
|
||||
extern void move_minibuffer_onto_frame (void);
|
||||
extern bool is_minibuffer (EMACS_INT, Lisp_Object);
|
||||
extern EMACS_INT this_minibuffer_depth (Lisp_Object);
|
||||
extern EMACS_INT minibuf_level;
|
||||
extern Lisp_Object get_minibuffer (EMACS_INT);
|
||||
extern void init_minibuf_once (void);
|
||||
extern void syms_of_minibuf (void);
|
||||
|
|
180
src/minibuf.c
180
src/minibuf.c
|
@ -63,9 +63,30 @@ static Lisp_Object minibuf_prompt;
|
|||
|
||||
static ptrdiff_t minibuf_prompt_width;
|
||||
|
||||
static Lisp_Object nth_minibuffer (EMACS_INT depth);
|
||||
|
||||
|
||||
/* Return TRUE when a frame switch causes a minibuffer on the old
|
||||
frame to move onto the new one. */
|
||||
static bool
|
||||
minibuf_follows_frame (void)
|
||||
{
|
||||
return EQ (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame),
|
||||
Qt);
|
||||
}
|
||||
|
||||
/* Return TRUE when a minibuffer always remains on the frame where it
|
||||
was first invoked. */
|
||||
static bool
|
||||
minibuf_stays_put (void)
|
||||
{
|
||||
return NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame));
|
||||
}
|
||||
|
||||
/* Return TRUE when opening a (recursive) minibuffer causes
|
||||
minibuffers on other frames to move to the selected frame. */
|
||||
static bool
|
||||
minibuf_moves_frame_when_opened (void)
|
||||
{
|
||||
return !NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame));
|
||||
}
|
||||
|
@ -90,7 +111,7 @@ choose_minibuf_frame (void)
|
|||
minibuf_window = sf->minibuffer_window;
|
||||
/* If we've still got another minibuffer open, use its mini-window
|
||||
instead. */
|
||||
if (minibuf_level && !minibuf_follows_frame ())
|
||||
if (minibuf_level > 1 && minibuf_stays_put ())
|
||||
{
|
||||
Lisp_Object buffer = get_minibuffer (minibuf_level);
|
||||
Lisp_Object tail, frame;
|
||||
|
@ -105,26 +126,40 @@ choose_minibuf_frame (void)
|
|||
}
|
||||
}
|
||||
|
||||
if (minibuf_follows_frame ())
|
||||
if (minibuf_moves_frame_when_opened ()
|
||||
&& FRAMEP (selected_frame)
|
||||
&& FRAME_LIVE_P (XFRAME (selected_frame)))
|
||||
/* Make sure no other frame has a minibuffer as its selected window,
|
||||
because the text would not be displayed in it, and that would be
|
||||
confusing. Only allow the selected frame to do this,
|
||||
and that only if the minibuffer is active. */
|
||||
{
|
||||
Lisp_Object tail, frame;
|
||||
{
|
||||
Lisp_Object tail, frame;
|
||||
struct frame *of;
|
||||
|
||||
FOR_EACH_FRAME (tail, frame)
|
||||
if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (XFRAME (frame))))
|
||||
&& !(EQ (frame, selected_frame)
|
||||
&& minibuf_level > 0))
|
||||
Fset_frame_selected_window (frame, Fframe_first_window (frame),
|
||||
Qnil);
|
||||
}
|
||||
FOR_EACH_FRAME (tail, frame)
|
||||
if (!EQ (frame, selected_frame)
|
||||
&& minibuf_level > 1
|
||||
/* The frame's minibuffer can be on a different frame. */
|
||||
&& XWINDOW ((of = XFRAME (frame))->minibuffer_window)->frame
|
||||
!= selected_frame)
|
||||
{
|
||||
if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (of))))
|
||||
Fset_frame_selected_window (frame, Fframe_first_window (frame),
|
||||
Qnil);
|
||||
|
||||
if (!EQ (XWINDOW (of->minibuffer_window)->contents,
|
||||
nth_minibuffer (0)))
|
||||
set_window_buffer (of->minibuffer_window,
|
||||
nth_minibuffer (0), 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If `minibuffer_follows_selected_frame' and we have a minibuffer, move it
|
||||
from its current frame to the selected frame. This function is
|
||||
intended to be called from `do_switch_frame' in frame.c. */
|
||||
/* If `minibuffer_follows_selected_frame' is t and we have a
|
||||
minibuffer, move it from its current frame to the selected frame.
|
||||
This function is intended to be called from `do_switch_frame' in
|
||||
frame.c. */
|
||||
void move_minibuffer_onto_frame (void)
|
||||
{
|
||||
if (!minibuf_level)
|
||||
|
@ -135,14 +170,18 @@ void move_minibuffer_onto_frame (void)
|
|||
&& FRAME_LIVE_P (XFRAME (selected_frame))
|
||||
&& !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window))
|
||||
{
|
||||
EMACS_INT i;
|
||||
struct frame *sf = XFRAME (selected_frame);
|
||||
Lisp_Object old_frame = XWINDOW (minibuf_window)->frame;
|
||||
struct frame *of = XFRAME (old_frame);
|
||||
Lisp_Object buffer = XWINDOW (minibuf_window)->contents;
|
||||
|
||||
set_window_buffer (sf->minibuffer_window, buffer, 0, 0);
|
||||
/* Stack up all the (recursively) open minibuffers on the selected
|
||||
mini_window. */
|
||||
for (i = 1; i <= minibuf_level; i++)
|
||||
set_window_buffer (sf->minibuffer_window, nth_minibuffer (i), 0, 0);
|
||||
minibuf_window = sf->minibuffer_window;
|
||||
set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0);
|
||||
if (of != sf)
|
||||
set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,6 +375,63 @@ return t only if BUFFER is an active minibuffer. */)
|
|||
? Qt : Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("innermost-minibuffer-p", Finnermost_minibuffer_p,
|
||||
Sinnermost_minibuffer_p, 0, 1, 0,
|
||||
doc: /* Return t if BUFFER is the most nested active minibuffer.
|
||||
No argument or nil as argument means use the current buffer as BUFFER. */)
|
||||
(Lisp_Object buffer)
|
||||
{
|
||||
if (NILP (buffer))
|
||||
buffer = Fcurrent_buffer ();
|
||||
return EQ (buffer, (Fcar (Fnthcdr (make_fixnum (minibuf_level),
|
||||
Vminibuffer_list))))
|
||||
? Qt
|
||||
: Qnil;
|
||||
}
|
||||
|
||||
/* Return the nesting depth of the active minibuffer BUFFER, or 0 if
|
||||
BUFFER isn't such a thing. If BUFFER is nil, this means use the current
|
||||
buffer. */
|
||||
EMACS_INT
|
||||
this_minibuffer_depth (Lisp_Object buffer)
|
||||
{
|
||||
EMACS_INT i;
|
||||
Lisp_Object bufs;
|
||||
|
||||
if (NILP (buffer))
|
||||
buffer = Fcurrent_buffer ();
|
||||
for (i = 1, bufs = Fcdr (Vminibuffer_list);
|
||||
i <= minibuf_level;
|
||||
i++, bufs = Fcdr (bufs))
|
||||
if (EQ (Fcar (bufs), buffer))
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFUN ("abort-minibuffers", Fabort_minibuffers, Sabort_minibuffers, 0, 0, "",
|
||||
doc: /* Abort the current minibuffer.
|
||||
If we are not currently in the innermost minibuffer, prompt the user to
|
||||
confirm the aborting of the current minibuffer and all contained ones. */)
|
||||
(void)
|
||||
{
|
||||
EMACS_INT minibuf_depth = this_minibuffer_depth (Qnil);
|
||||
Lisp_Object array[2];
|
||||
AUTO_STRING (fmt, "Abort %s minibuffer levels? ");
|
||||
|
||||
if (!minibuf_depth)
|
||||
error ("Not in a minibuffer");
|
||||
if (minibuf_depth < minibuf_level)
|
||||
{
|
||||
array[0] = fmt;
|
||||
array[1] = make_fixnum (minibuf_level - minibuf_depth + 1);
|
||||
if (!NILP (Fyes_or_no_p (Fformat (2, array))))
|
||||
Fthrow (Qexit, Qt);
|
||||
}
|
||||
else
|
||||
Fthrow (Qexit, Qt);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end,
|
||||
Sminibuffer_prompt_end, 0, 0, 0,
|
||||
doc: /* Return the buffer position of the end of the minibuffer prompt.
|
||||
|
@ -411,6 +507,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
|
|||
Lisp_Object val;
|
||||
ptrdiff_t count = SPECPDL_INDEX ();
|
||||
Lisp_Object mini_frame, ambient_dir, minibuffer, input_method;
|
||||
Lisp_Object calling_frame = selected_frame;
|
||||
Lisp_Object enable_multibyte;
|
||||
EMACS_INT pos = 0;
|
||||
/* String to add to the history. */
|
||||
|
@ -648,6 +745,17 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
|
|||
}
|
||||
}
|
||||
|
||||
if (minibuf_moves_frame_when_opened ())
|
||||
{
|
||||
EMACS_INT i;
|
||||
|
||||
/* Stack up all the (recursively) open minibuffers on the selected
|
||||
mini_window. */
|
||||
for (i = 1; i < minibuf_level; i++)
|
||||
set_window_buffer (XFRAME (mini_frame)->minibuffer_window,
|
||||
nth_minibuffer (i), 0, 0);
|
||||
}
|
||||
|
||||
/* Display this minibuffer in the proper window. */
|
||||
/* Use set_window_buffer instead of Fset_window_buffer (see
|
||||
discussion of bug#11984, bug#12025, bug#12026). */
|
||||
|
@ -729,6 +837,20 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
|
|||
|
||||
recursive_edit_1 ();
|
||||
|
||||
/* We've exited the recursive edit without an error, so switch the
|
||||
current window away from the expired minibuffer window. */
|
||||
{
|
||||
Lisp_Object prev = Fprevious_window (minibuf_window, Qnil, Qnil);
|
||||
/* PREV can be on a different frame when we have a minibuffer only
|
||||
frame, the other frame's minibuffer window is MINIBUF_WINDOW,
|
||||
and its "focus window" is also MINIBUF_WINDOW. */
|
||||
while (!EQ (prev, minibuf_window)
|
||||
&& !EQ (selected_frame, WINDOW_FRAME (XWINDOW (prev))))
|
||||
prev = Fprevious_window (prev, Qnil, Qnil);
|
||||
if (!EQ (prev, minibuf_window))
|
||||
Fset_frame_selected_window (selected_frame, prev, Qnil);
|
||||
}
|
||||
|
||||
/* If cursor is on the minibuffer line,
|
||||
show the user we have exited by putting it in column 0. */
|
||||
if (XWINDOW (minibuf_window)->cursor.vpos >= 0
|
||||
|
@ -767,6 +889,12 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
|
|||
in set-window-configuration. */
|
||||
unbind_to (count, Qnil);
|
||||
|
||||
/* Switch the frame back to the calling frame. */
|
||||
if (!EQ (selected_frame, calling_frame)
|
||||
&& FRAMEP (calling_frame)
|
||||
&& FRAME_LIVE_P (XFRAME (calling_frame)))
|
||||
call2 (intern ("select-frame-set-input-focus"), calling_frame, Qnil);
|
||||
|
||||
/* Add the value to the appropriate history list, if any. This is
|
||||
done after the previous buffer has been made current again, in
|
||||
case the history variable is buffer-local. */
|
||||
|
@ -790,6 +918,14 @@ is_minibuffer (EMACS_INT depth, Lisp_Object buf)
|
|||
&& EQ (Fcar (tail), buf);
|
||||
}
|
||||
|
||||
/* Return the DEPTHth minibuffer, or nil if such does not yet exist. */
|
||||
static Lisp_Object
|
||||
nth_minibuffer (EMACS_INT depth)
|
||||
{
|
||||
Lisp_Object tail = Fnthcdr (make_fixnum (depth), Vminibuffer_list);
|
||||
return XCAR (tail);
|
||||
}
|
||||
|
||||
/* Return a buffer to be used as the minibuffer at depth `depth'.
|
||||
depth = 0 is the lowest allowed argument, and that is the value
|
||||
used for nonrecursive minibuffer invocations. */
|
||||
|
@ -2032,13 +2168,15 @@ For example, `eval-expression' uses this. */);
|
|||
The function is called with the arguments passed to `read-buffer'. */);
|
||||
Vread_buffer_function = Qnil;
|
||||
|
||||
DEFVAR_BOOL ("minibuffer-follows-selected-frame", minibuffer_follows_selected_frame,
|
||||
doc: /* Non-nil means the active minibuffer always displays on the selected frame.
|
||||
DEFVAR_LISP ("minibuffer-follows-selected-frame", minibuffer_follows_selected_frame,
|
||||
doc: /* t means the active minibuffer always displays on the selected frame.
|
||||
Nil means that a minibuffer will appear only in the frame which created it.
|
||||
Any other value means the minibuffer will move onto another frame, but
|
||||
only when the user starts using a minibuffer there.
|
||||
|
||||
Any buffer local or dynamic binding of this variable is ignored. Only the
|
||||
default top level value is used. */);
|
||||
minibuffer_follows_selected_frame = 1;
|
||||
minibuffer_follows_selected_frame = Qt;
|
||||
|
||||
DEFVAR_BOOL ("read-buffer-completion-ignore-case",
|
||||
read_buffer_completion_ignore_case,
|
||||
|
@ -2196,6 +2334,8 @@ uses to hide passwords. */);
|
|||
defsubr (&Sminibuffer_prompt);
|
||||
|
||||
defsubr (&Sminibufferp);
|
||||
defsubr (&Sinnermost_minibuffer_p);
|
||||
defsubr (&Sabort_minibuffers);
|
||||
defsubr (&Sminibuffer_prompt_end);
|
||||
defsubr (&Sminibuffer_contents);
|
||||
defsubr (&Sminibuffer_contents_no_properties);
|
||||
|
|
|
@ -2663,12 +2663,15 @@ static void
|
|||
decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames)
|
||||
{
|
||||
struct window *w = decode_live_window (*window);
|
||||
Lisp_Object miniwin = XFRAME (w->frame)->minibuffer_window;
|
||||
|
||||
XSETWINDOW (*window, w);
|
||||
/* MINIBUF nil may or may not include minibuffers. Decide if it
|
||||
does. */
|
||||
if (NILP (*minibuf))
|
||||
*minibuf = minibuf_level ? minibuf_window : Qlambda;
|
||||
*minibuf = this_minibuffer_depth (XWINDOW (miniwin)->contents)
|
||||
? miniwin
|
||||
: Qlambda;
|
||||
else if (!EQ (*minibuf, Qt))
|
||||
*minibuf = Qlambda;
|
||||
|
||||
|
|
|
@ -1124,10 +1124,6 @@ extern Lisp_Object echo_area_window;
|
|||
|
||||
extern EMACS_INT command_loop_level;
|
||||
|
||||
/* Depth in minibuffer invocations. */
|
||||
|
||||
extern EMACS_INT minibuf_level;
|
||||
|
||||
/* Non-zero if we should redraw the mode lines on the next redisplay.
|
||||
Usually set to a unique small integer so we can track the main causes of
|
||||
full redisplays in `redisplay--mode-lines-cause'. */
|
||||
|
|
Loading…
Add table
Reference in a new issue