aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
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}