diff options
| author | Alan Mackenzie | 2021-01-10 20:32:40 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2021-01-10 20:32:40 +0000 |
| commit | c7c154bb5756e0ae71d342c5d8aabf725877f186 (patch) | |
| tree | 4db61dff837b5e5f5b864c2e1b53a1051ec536bf /src | |
| parent | a583c72305530f7d3ecc9ba50eefa70b6ddecdd9 (diff) | |
| download | emacs-c7c154bb5756e0ae71d342c5d8aabf725877f186.tar.gz emacs-c7c154bb5756e0ae71d342c5d8aabf725877f186.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval.c | 26 | ||||
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/minibuf.c | 182 | ||||
| -rw-r--r-- | src/window.c | 5 | ||||
| -rw-r--r-- | src/window.h | 4 |
5 files changed, 193 insertions, 26 deletions
diff --git a/src/eval.c b/src/eval.c index 706aafdf509..5bf3faebc85 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1167,9 +1167,18 @@ Lisp_Object | |||
| 1167 | internal_catch (Lisp_Object tag, | 1167 | internal_catch (Lisp_Object tag, |
| 1168 | Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) | 1168 | Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) |
| 1169 | { | 1169 | { |
| 1170 | /* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by | ||
| 1171 | throwing t to tag `exit'. | ||
| 1172 | Value -1 means there is no (throw 'exit t) in progress; | ||
| 1173 | 0 means the `throw' wasn't done from an active minibuffer; | ||
| 1174 | N > 0 means the `throw' was done from the minibuffer at level N. */ | ||
| 1175 | static EMACS_INT minibuffer_quit_level = -1; | ||
| 1170 | /* This structure is made part of the chain `catchlist'. */ | 1176 | /* This structure is made part of the chain `catchlist'. */ |
| 1171 | struct handler *c = push_handler (tag, CATCHER); | 1177 | struct handler *c = push_handler (tag, CATCHER); |
| 1172 | 1178 | ||
| 1179 | if (EQ (tag, Qexit)) | ||
| 1180 | minibuffer_quit_level = -1; | ||
| 1181 | |||
| 1173 | /* Call FUNC. */ | 1182 | /* Call FUNC. */ |
| 1174 | if (! sys_setjmp (c->jmp)) | 1183 | if (! sys_setjmp (c->jmp)) |
| 1175 | { | 1184 | { |
| @@ -1183,6 +1192,23 @@ internal_catch (Lisp_Object tag, | |||
| 1183 | Lisp_Object val = handlerlist->val; | 1192 | Lisp_Object val = handlerlist->val; |
| 1184 | clobbered_eassert (handlerlist == c); | 1193 | clobbered_eassert (handlerlist == c); |
| 1185 | handlerlist = handlerlist->next; | 1194 | handlerlist = handlerlist->next; |
| 1195 | if (EQ (tag, Qexit) && EQ (val, Qt)) | ||
| 1196 | /* If we've thrown t to tag `exit' from within a minibuffer, we | ||
| 1197 | exit all minibuffers more deeply nested than the current | ||
| 1198 | one. */ | ||
| 1199 | { | ||
| 1200 | EMACS_INT mini_depth = this_minibuffer_depth (Qnil); | ||
| 1201 | if (mini_depth && mini_depth != minibuffer_quit_level) | ||
| 1202 | { | ||
| 1203 | if (minibuffer_quit_level == -1) | ||
| 1204 | minibuffer_quit_level = mini_depth; | ||
| 1205 | if (minibuffer_quit_level | ||
| 1206 | && (minibuf_level > minibuffer_quit_level)) | ||
| 1207 | Fthrow (Qexit, Qt); | ||
| 1208 | } | ||
| 1209 | else | ||
| 1210 | minibuffer_quit_level = -1; | ||
| 1211 | } | ||
| 1186 | return val; | 1212 | return val; |
| 1187 | } | 1213 | } |
| 1188 | } | 1214 | } |
diff --git a/src/lisp.h b/src/lisp.h index d139df93424..86be25852a6 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4346,6 +4346,8 @@ extern Lisp_Object Vminibuffer_list; | |||
| 4346 | extern Lisp_Object last_minibuf_string; | 4346 | extern Lisp_Object last_minibuf_string; |
| 4347 | extern void move_minibuffer_onto_frame (void); | 4347 | extern void move_minibuffer_onto_frame (void); |
| 4348 | extern bool is_minibuffer (EMACS_INT, Lisp_Object); | 4348 | extern bool is_minibuffer (EMACS_INT, Lisp_Object); |
| 4349 | extern EMACS_INT this_minibuffer_depth (Lisp_Object); | ||
| 4350 | extern EMACS_INT minibuf_level; | ||
| 4349 | extern Lisp_Object get_minibuffer (EMACS_INT); | 4351 | extern Lisp_Object get_minibuffer (EMACS_INT); |
| 4350 | extern void init_minibuf_once (void); | 4352 | extern void init_minibuf_once (void); |
| 4351 | extern void syms_of_minibuf (void); | 4353 | extern void syms_of_minibuf (void); |
diff --git a/src/minibuf.c b/src/minibuf.c index 5ee440f6622..c527e2bc9c6 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -63,10 +63,31 @@ static Lisp_Object minibuf_prompt; | |||
| 63 | 63 | ||
| 64 | static ptrdiff_t minibuf_prompt_width; | 64 | static ptrdiff_t minibuf_prompt_width; |
| 65 | 65 | ||
| 66 | static Lisp_Object nth_minibuffer (EMACS_INT depth); | ||
| 67 | |||
| 66 | 68 | ||
| 69 | /* Return TRUE when a frame switch causes a minibuffer on the old | ||
| 70 | frame to move onto the new one. */ | ||
| 67 | static bool | 71 | static bool |
| 68 | minibuf_follows_frame (void) | 72 | minibuf_follows_frame (void) |
| 69 | { | 73 | { |
| 74 | return EQ (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame), | ||
| 75 | Qt); | ||
| 76 | } | ||
| 77 | |||
| 78 | /* Return TRUE when a minibuffer always remains on the frame where it | ||
| 79 | was first invoked. */ | ||
| 80 | static bool | ||
| 81 | minibuf_stays_put (void) | ||
| 82 | { | ||
| 83 | return NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame)); | ||
| 84 | } | ||
| 85 | |||
| 86 | /* Return TRUE when opening a (recursive) minibuffer causes | ||
| 87 | minibuffers on other frames to move to the selected frame. */ | ||
| 88 | static bool | ||
| 89 | minibuf_moves_frame_when_opened (void) | ||
| 90 | { | ||
| 70 | return !NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame)); | 91 | return !NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame)); |
| 71 | } | 92 | } |
| 72 | 93 | ||
| @@ -90,7 +111,7 @@ choose_minibuf_frame (void) | |||
| 90 | minibuf_window = sf->minibuffer_window; | 111 | minibuf_window = sf->minibuffer_window; |
| 91 | /* If we've still got another minibuffer open, use its mini-window | 112 | /* If we've still got another minibuffer open, use its mini-window |
| 92 | instead. */ | 113 | instead. */ |
| 93 | if (minibuf_level && !minibuf_follows_frame ()) | 114 | if (minibuf_level > 1 && minibuf_stays_put ()) |
| 94 | { | 115 | { |
| 95 | Lisp_Object buffer = get_minibuffer (minibuf_level); | 116 | Lisp_Object buffer = get_minibuffer (minibuf_level); |
| 96 | Lisp_Object tail, frame; | 117 | Lisp_Object tail, frame; |
| @@ -105,26 +126,40 @@ choose_minibuf_frame (void) | |||
| 105 | } | 126 | } |
| 106 | } | 127 | } |
| 107 | 128 | ||
| 108 | if (minibuf_follows_frame ()) | 129 | if (minibuf_moves_frame_when_opened () |
| 130 | && FRAMEP (selected_frame) | ||
| 131 | && FRAME_LIVE_P (XFRAME (selected_frame))) | ||
| 109 | /* Make sure no other frame has a minibuffer as its selected window, | 132 | /* Make sure no other frame has a minibuffer as its selected window, |
| 110 | because the text would not be displayed in it, and that would be | 133 | because the text would not be displayed in it, and that would be |
| 111 | confusing. Only allow the selected frame to do this, | 134 | confusing. Only allow the selected frame to do this, |
| 112 | and that only if the minibuffer is active. */ | 135 | and that only if the minibuffer is active. */ |
| 113 | { | 136 | { |
| 114 | Lisp_Object tail, frame; | 137 | Lisp_Object tail, frame; |
| 115 | 138 | struct frame *of; | |
| 116 | FOR_EACH_FRAME (tail, frame) | 139 | |
| 117 | if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (XFRAME (frame)))) | 140 | FOR_EACH_FRAME (tail, frame) |
| 118 | && !(EQ (frame, selected_frame) | 141 | if (!EQ (frame, selected_frame) |
| 119 | && minibuf_level > 0)) | 142 | && minibuf_level > 1 |
| 120 | Fset_frame_selected_window (frame, Fframe_first_window (frame), | 143 | /* The frame's minibuffer can be on a different frame. */ |
| 121 | Qnil); | 144 | && XWINDOW ((of = XFRAME (frame))->minibuffer_window)->frame |
| 122 | } | 145 | != selected_frame) |
| 146 | { | ||
| 147 | if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (of)))) | ||
| 148 | Fset_frame_selected_window (frame, Fframe_first_window (frame), | ||
| 149 | Qnil); | ||
| 150 | |||
| 151 | if (!EQ (XWINDOW (of->minibuffer_window)->contents, | ||
| 152 | nth_minibuffer (0))) | ||
| 153 | set_window_buffer (of->minibuffer_window, | ||
| 154 | nth_minibuffer (0), 0, 0); | ||
| 155 | } | ||
| 156 | } | ||
| 123 | } | 157 | } |
| 124 | 158 | ||
| 125 | /* If `minibuffer_follows_selected_frame' and we have a minibuffer, move it | 159 | /* If `minibuffer_follows_selected_frame' is t and we have a |
| 126 | from its current frame to the selected frame. This function is | 160 | minibuffer, move it from its current frame to the selected frame. |
| 127 | intended to be called from `do_switch_frame' in frame.c. */ | 161 | This function is intended to be called from `do_switch_frame' in |
| 162 | frame.c. */ | ||
| 128 | void move_minibuffer_onto_frame (void) | 163 | void move_minibuffer_onto_frame (void) |
| 129 | { | 164 | { |
| 130 | if (!minibuf_level) | 165 | if (!minibuf_level) |
| @@ -135,14 +170,18 @@ void move_minibuffer_onto_frame (void) | |||
| 135 | && FRAME_LIVE_P (XFRAME (selected_frame)) | 170 | && FRAME_LIVE_P (XFRAME (selected_frame)) |
| 136 | && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window)) | 171 | && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window)) |
| 137 | { | 172 | { |
| 173 | EMACS_INT i; | ||
| 138 | struct frame *sf = XFRAME (selected_frame); | 174 | struct frame *sf = XFRAME (selected_frame); |
| 139 | Lisp_Object old_frame = XWINDOW (minibuf_window)->frame; | 175 | Lisp_Object old_frame = XWINDOW (minibuf_window)->frame; |
| 140 | struct frame *of = XFRAME (old_frame); | 176 | struct frame *of = XFRAME (old_frame); |
| 141 | Lisp_Object buffer = XWINDOW (minibuf_window)->contents; | ||
| 142 | 177 | ||
| 143 | set_window_buffer (sf->minibuffer_window, buffer, 0, 0); | 178 | /* Stack up all the (recursively) open minibuffers on the selected |
| 179 | mini_window. */ | ||
| 180 | for (i = 1; i <= minibuf_level; i++) | ||
| 181 | set_window_buffer (sf->minibuffer_window, nth_minibuffer (i), 0, 0); | ||
| 144 | minibuf_window = sf->minibuffer_window; | 182 | minibuf_window = sf->minibuffer_window; |
| 145 | set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0); | 183 | if (of != sf) |
| 184 | set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0); | ||
| 146 | } | 185 | } |
| 147 | } | 186 | } |
| 148 | 187 | ||
| @@ -336,6 +375,63 @@ return t only if BUFFER is an active minibuffer. */) | |||
| 336 | ? Qt : Qnil; | 375 | ? Qt : Qnil; |
| 337 | } | 376 | } |
| 338 | 377 | ||
| 378 | DEFUN ("innermost-minibuffer-p", Finnermost_minibuffer_p, | ||
| 379 | Sinnermost_minibuffer_p, 0, 1, 0, | ||
| 380 | doc: /* Return t if BUFFER is the most nested active minibuffer. | ||
| 381 | No argument or nil as argument means use the current buffer as BUFFER. */) | ||
| 382 | (Lisp_Object buffer) | ||
| 383 | { | ||
| 384 | if (NILP (buffer)) | ||
| 385 | buffer = Fcurrent_buffer (); | ||
| 386 | return EQ (buffer, (Fcar (Fnthcdr (make_fixnum (minibuf_level), | ||
| 387 | Vminibuffer_list)))) | ||
| 388 | ? Qt | ||
| 389 | : Qnil; | ||
| 390 | } | ||
| 391 | |||
| 392 | /* Return the nesting depth of the active minibuffer BUFFER, or 0 if | ||
| 393 | BUFFER isn't such a thing. If BUFFER is nil, this means use the current | ||
| 394 | buffer. */ | ||
| 395 | EMACS_INT | ||
| 396 | this_minibuffer_depth (Lisp_Object buffer) | ||
| 397 | { | ||
| 398 | EMACS_INT i; | ||
| 399 | Lisp_Object bufs; | ||
| 400 | |||
| 401 | if (NILP (buffer)) | ||
| 402 | buffer = Fcurrent_buffer (); | ||
| 403 | for (i = 1, bufs = Fcdr (Vminibuffer_list); | ||
| 404 | i <= minibuf_level; | ||
| 405 | i++, bufs = Fcdr (bufs)) | ||
| 406 | if (EQ (Fcar (bufs), buffer)) | ||
| 407 | return i; | ||
| 408 | return 0; | ||
| 409 | } | ||
| 410 | |||
| 411 | DEFUN ("abort-minibuffers", Fabort_minibuffers, Sabort_minibuffers, 0, 0, "", | ||
| 412 | doc: /* Abort the current minibuffer. | ||
| 413 | If we are not currently in the innermost minibuffer, prompt the user to | ||
| 414 | confirm the aborting of the current minibuffer and all contained ones. */) | ||
| 415 | (void) | ||
| 416 | { | ||
| 417 | EMACS_INT minibuf_depth = this_minibuffer_depth (Qnil); | ||
| 418 | Lisp_Object array[2]; | ||
| 419 | AUTO_STRING (fmt, "Abort %s minibuffer levels? "); | ||
| 420 | |||
| 421 | if (!minibuf_depth) | ||
| 422 | error ("Not in a minibuffer"); | ||
| 423 | if (minibuf_depth < minibuf_level) | ||
| 424 | { | ||
| 425 | array[0] = fmt; | ||
| 426 | array[1] = make_fixnum (minibuf_level - minibuf_depth + 1); | ||
| 427 | if (!NILP (Fyes_or_no_p (Fformat (2, array)))) | ||
| 428 | Fthrow (Qexit, Qt); | ||
| 429 | } | ||
| 430 | else | ||
| 431 | Fthrow (Qexit, Qt); | ||
| 432 | return Qnil; | ||
| 433 | } | ||
| 434 | |||
| 339 | DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end, | 435 | DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end, |
| 340 | Sminibuffer_prompt_end, 0, 0, 0, | 436 | Sminibuffer_prompt_end, 0, 0, 0, |
| 341 | doc: /* Return the buffer position of the end of the minibuffer prompt. | 437 | 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, | |||
| 411 | Lisp_Object val; | 507 | Lisp_Object val; |
| 412 | ptrdiff_t count = SPECPDL_INDEX (); | 508 | ptrdiff_t count = SPECPDL_INDEX (); |
| 413 | Lisp_Object mini_frame, ambient_dir, minibuffer, input_method; | 509 | Lisp_Object mini_frame, ambient_dir, minibuffer, input_method; |
| 510 | Lisp_Object calling_frame = selected_frame; | ||
| 414 | Lisp_Object enable_multibyte; | 511 | Lisp_Object enable_multibyte; |
| 415 | EMACS_INT pos = 0; | 512 | EMACS_INT pos = 0; |
| 416 | /* String to add to the history. */ | 513 | /* String to add to the history. */ |
| @@ -648,6 +745,17 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 648 | } | 745 | } |
| 649 | } | 746 | } |
| 650 | 747 | ||
| 748 | if (minibuf_moves_frame_when_opened ()) | ||
| 749 | { | ||
| 750 | EMACS_INT i; | ||
| 751 | |||
| 752 | /* Stack up all the (recursively) open minibuffers on the selected | ||
| 753 | mini_window. */ | ||
| 754 | for (i = 1; i < minibuf_level; i++) | ||
| 755 | set_window_buffer (XFRAME (mini_frame)->minibuffer_window, | ||
| 756 | nth_minibuffer (i), 0, 0); | ||
| 757 | } | ||
| 758 | |||
| 651 | /* Display this minibuffer in the proper window. */ | 759 | /* Display this minibuffer in the proper window. */ |
| 652 | /* Use set_window_buffer instead of Fset_window_buffer (see | 760 | /* Use set_window_buffer instead of Fset_window_buffer (see |
| 653 | discussion of bug#11984, bug#12025, bug#12026). */ | 761 | discussion of bug#11984, bug#12025, bug#12026). */ |
| @@ -729,6 +837,20 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 729 | 837 | ||
| 730 | recursive_edit_1 (); | 838 | recursive_edit_1 (); |
| 731 | 839 | ||
| 840 | /* We've exited the recursive edit without an error, so switch the | ||
| 841 | current window away from the expired minibuffer window. */ | ||
| 842 | { | ||
| 843 | Lisp_Object prev = Fprevious_window (minibuf_window, Qnil, Qnil); | ||
| 844 | /* PREV can be on a different frame when we have a minibuffer only | ||
| 845 | frame, the other frame's minibuffer window is MINIBUF_WINDOW, | ||
| 846 | and its "focus window" is also MINIBUF_WINDOW. */ | ||
| 847 | while (!EQ (prev, minibuf_window) | ||
| 848 | && !EQ (selected_frame, WINDOW_FRAME (XWINDOW (prev)))) | ||
| 849 | prev = Fprevious_window (prev, Qnil, Qnil); | ||
| 850 | if (!EQ (prev, minibuf_window)) | ||
| 851 | Fset_frame_selected_window (selected_frame, prev, Qnil); | ||
| 852 | } | ||
| 853 | |||
| 732 | /* If cursor is on the minibuffer line, | 854 | /* If cursor is on the minibuffer line, |
| 733 | show the user we have exited by putting it in column 0. */ | 855 | show the user we have exited by putting it in column 0. */ |
| 734 | if (XWINDOW (minibuf_window)->cursor.vpos >= 0 | 856 | if (XWINDOW (minibuf_window)->cursor.vpos >= 0 |
| @@ -767,6 +889,12 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, | |||
| 767 | in set-window-configuration. */ | 889 | in set-window-configuration. */ |
| 768 | unbind_to (count, Qnil); | 890 | unbind_to (count, Qnil); |
| 769 | 891 | ||
| 892 | /* Switch the frame back to the calling frame. */ | ||
| 893 | if (!EQ (selected_frame, calling_frame) | ||
| 894 | && FRAMEP (calling_frame) | ||
| 895 | && FRAME_LIVE_P (XFRAME (calling_frame))) | ||
| 896 | call2 (intern ("select-frame-set-input-focus"), calling_frame, Qnil); | ||
| 897 | |||
| 770 | /* Add the value to the appropriate history list, if any. This is | 898 | /* Add the value to the appropriate history list, if any. This is |
| 771 | done after the previous buffer has been made current again, in | 899 | done after the previous buffer has been made current again, in |
| 772 | case the history variable is buffer-local. */ | 900 | case the history variable is buffer-local. */ |
| @@ -790,6 +918,14 @@ is_minibuffer (EMACS_INT depth, Lisp_Object buf) | |||
| 790 | && EQ (Fcar (tail), buf); | 918 | && EQ (Fcar (tail), buf); |
| 791 | } | 919 | } |
| 792 | 920 | ||
| 921 | /* Return the DEPTHth minibuffer, or nil if such does not yet exist. */ | ||
| 922 | static Lisp_Object | ||
| 923 | nth_minibuffer (EMACS_INT depth) | ||
| 924 | { | ||
| 925 | Lisp_Object tail = Fnthcdr (make_fixnum (depth), Vminibuffer_list); | ||
| 926 | return XCAR (tail); | ||
| 927 | } | ||
| 928 | |||
| 793 | /* Return a buffer to be used as the minibuffer at depth `depth'. | 929 | /* Return a buffer to be used as the minibuffer at depth `depth'. |
| 794 | depth = 0 is the lowest allowed argument, and that is the value | 930 | depth = 0 is the lowest allowed argument, and that is the value |
| 795 | used for nonrecursive minibuffer invocations. */ | 931 | used for nonrecursive minibuffer invocations. */ |
| @@ -2032,13 +2168,15 @@ For example, `eval-expression' uses this. */); | |||
| 2032 | The function is called with the arguments passed to `read-buffer'. */); | 2168 | The function is called with the arguments passed to `read-buffer'. */); |
| 2033 | Vread_buffer_function = Qnil; | 2169 | Vread_buffer_function = Qnil; |
| 2034 | 2170 | ||
| 2035 | DEFVAR_BOOL ("minibuffer-follows-selected-frame", minibuffer_follows_selected_frame, | 2171 | DEFVAR_LISP ("minibuffer-follows-selected-frame", minibuffer_follows_selected_frame, |
| 2036 | doc: /* Non-nil means the active minibuffer always displays on the selected frame. | 2172 | doc: /* t means the active minibuffer always displays on the selected frame. |
| 2037 | Nil means that a minibuffer will appear only in the frame which created it. | 2173 | Nil means that a minibuffer will appear only in the frame which created it. |
| 2174 | Any other value means the minibuffer will move onto another frame, but | ||
| 2175 | only when the user starts using a minibuffer there. | ||
| 2038 | 2176 | ||
| 2039 | Any buffer local or dynamic binding of this variable is ignored. Only the | 2177 | Any buffer local or dynamic binding of this variable is ignored. Only the |
| 2040 | default top level value is used. */); | 2178 | default top level value is used. */); |
| 2041 | minibuffer_follows_selected_frame = 1; | 2179 | minibuffer_follows_selected_frame = Qt; |
| 2042 | 2180 | ||
| 2043 | DEFVAR_BOOL ("read-buffer-completion-ignore-case", | 2181 | DEFVAR_BOOL ("read-buffer-completion-ignore-case", |
| 2044 | read_buffer_completion_ignore_case, | 2182 | read_buffer_completion_ignore_case, |
| @@ -2196,6 +2334,8 @@ uses to hide passwords. */); | |||
| 2196 | defsubr (&Sminibuffer_prompt); | 2334 | defsubr (&Sminibuffer_prompt); |
| 2197 | 2335 | ||
| 2198 | defsubr (&Sminibufferp); | 2336 | defsubr (&Sminibufferp); |
| 2337 | defsubr (&Sinnermost_minibuffer_p); | ||
| 2338 | defsubr (&Sabort_minibuffers); | ||
| 2199 | defsubr (&Sminibuffer_prompt_end); | 2339 | defsubr (&Sminibuffer_prompt_end); |
| 2200 | defsubr (&Sminibuffer_contents); | 2340 | defsubr (&Sminibuffer_contents); |
| 2201 | defsubr (&Sminibuffer_contents_no_properties); | 2341 | defsubr (&Sminibuffer_contents_no_properties); |
diff --git a/src/window.c b/src/window.c index 5e78aa400b5..e025e0b0821 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -2663,12 +2663,15 @@ static void | |||
| 2663 | decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames) | 2663 | decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames) |
| 2664 | { | 2664 | { |
| 2665 | struct window *w = decode_live_window (*window); | 2665 | struct window *w = decode_live_window (*window); |
| 2666 | Lisp_Object miniwin = XFRAME (w->frame)->minibuffer_window; | ||
| 2666 | 2667 | ||
| 2667 | XSETWINDOW (*window, w); | 2668 | XSETWINDOW (*window, w); |
| 2668 | /* MINIBUF nil may or may not include minibuffers. Decide if it | 2669 | /* MINIBUF nil may or may not include minibuffers. Decide if it |
| 2669 | does. */ | 2670 | does. */ |
| 2670 | if (NILP (*minibuf)) | 2671 | if (NILP (*minibuf)) |
| 2671 | *minibuf = minibuf_level ? minibuf_window : Qlambda; | 2672 | *minibuf = this_minibuffer_depth (XWINDOW (miniwin)->contents) |
| 2673 | ? miniwin | ||
| 2674 | : Qlambda; | ||
| 2672 | else if (!EQ (*minibuf, Qt)) | 2675 | else if (!EQ (*minibuf, Qt)) |
| 2673 | *minibuf = Qlambda; | 2676 | *minibuf = Qlambda; |
| 2674 | 2677 | ||
diff --git a/src/window.h b/src/window.h index 332cb3091fd..79eb44e7a38 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -1124,10 +1124,6 @@ extern Lisp_Object echo_area_window; | |||
| 1124 | 1124 | ||
| 1125 | extern EMACS_INT command_loop_level; | 1125 | extern EMACS_INT command_loop_level; |
| 1126 | 1126 | ||
| 1127 | /* Depth in minibuffer invocations. */ | ||
| 1128 | |||
| 1129 | extern EMACS_INT minibuf_level; | ||
| 1130 | |||
| 1131 | /* Non-zero if we should redraw the mode lines on the next redisplay. | 1127 | /* Non-zero if we should redraw the mode lines on the next redisplay. |
| 1132 | Usually set to a unique small integer so we can track the main causes of | 1128 | Usually set to a unique small integer so we can track the main causes of |
| 1133 | full redisplays in `redisplay--mode-lines-cause'. */ | 1129 | full redisplays in `redisplay--mode-lines-cause'. */ |