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/eval.c | |
| 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/eval.c')
| -rw-r--r-- | src/eval.c | 26 |
1 files changed, 26 insertions, 0 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 | } |