aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorAlan Mackenzie2021-01-10 20:32:40 +0000
committerAlan Mackenzie2021-01-10 20:32:40 +0000
commitc7c154bb5756e0ae71d342c5d8aabf725877f186 (patch)
tree4db61dff837b5e5f5b864c2e1b53a1051ec536bf /src/eval.c
parenta583c72305530f7d3ecc9ba50eefa70b6ddecdd9 (diff)
downloademacs-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.c26
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
1167internal_catch (Lisp_Object tag, 1167internal_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}