aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c32
1 files changed, 14 insertions, 18 deletions
diff --git a/src/eval.c b/src/eval.c
index 3aff3b56d52..91fc4e68377 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1165,21 +1165,23 @@ usage: (catch TAG BODY...) */)
1165 FUNC should return a Lisp_Object. 1165 FUNC should return a Lisp_Object.
1166 This is how catches are done from within C code. */ 1166 This is how catches are done from within C code. */
1167 1167
1168/* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by
1169 throwing t to tag `exit'.
1170 0 means there is no (throw 'exit t) in progress, or it wasn't from
1171 a minibuffer which isn't the most nested;
1172 N > 0 means the `throw' was done from the minibuffer at level N which
1173 wasn't the most nested. */
1174EMACS_INT minibuffer_quit_level = 0;
1175
1168Lisp_Object 1176Lisp_Object
1169internal_catch (Lisp_Object tag, 1177internal_catch (Lisp_Object tag,
1170 Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) 1178 Lisp_Object (*func) (Lisp_Object), Lisp_Object arg)
1171{ 1179{
1172 /* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by
1173 throwing t to tag `exit'.
1174 Value -1 means there is no (throw 'exit t) in progress;
1175 0 means the `throw' wasn't done from an active minibuffer;
1176 N > 0 means the `throw' was done from the minibuffer at level N. */
1177 static EMACS_INT minibuffer_quit_level = -1;
1178 /* This structure is made part of the chain `catchlist'. */ 1180 /* This structure is made part of the chain `catchlist'. */
1179 struct handler *c = push_handler (tag, CATCHER); 1181 struct handler *c = push_handler (tag, CATCHER);
1180 1182
1181 if (EQ (tag, Qexit)) 1183 if (EQ (tag, Qexit))
1182 minibuffer_quit_level = -1; 1184 minibuffer_quit_level = 0;
1183 1185
1184 /* Call FUNC. */ 1186 /* Call FUNC. */
1185 if (! sys_setjmp (c->jmp)) 1187 if (! sys_setjmp (c->jmp))
@@ -1194,22 +1196,16 @@ internal_catch (Lisp_Object tag,
1194 Lisp_Object val = handlerlist->val; 1196 Lisp_Object val = handlerlist->val;
1195 clobbered_eassert (handlerlist == c); 1197 clobbered_eassert (handlerlist == c);
1196 handlerlist = handlerlist->next; 1198 handlerlist = handlerlist->next;
1197 if (EQ (tag, Qexit) && EQ (val, Qt)) 1199 if (EQ (tag, Qexit) && EQ (val, Qt) && minibuffer_quit_level > 0)
1198 /* If we've thrown t to tag `exit' from within a minibuffer, we 1200 /* If we've thrown t to tag `exit' from within a minibuffer, we
1199 exit all minibuffers more deeply nested than the current 1201 exit all minibuffers more deeply nested than the current
1200 one. */ 1202 one. */
1201 { 1203 {
1202 EMACS_INT mini_depth = this_minibuffer_depth (Qnil); 1204 if (minibuf_level > minibuffer_quit_level
1203 if (mini_depth && mini_depth != minibuffer_quit_level) 1205 && !NILP (Fminibuffer_innermost_command_loop_p (Qnil)))
1204 { 1206 Fthrow (Qexit, Qt);
1205 if (minibuffer_quit_level == -1)
1206 minibuffer_quit_level = mini_depth;
1207 if (minibuffer_quit_level
1208 && (minibuf_level > minibuffer_quit_level))
1209 Fthrow (Qexit, Qt);
1210 }
1211 else 1207 else
1212 minibuffer_quit_level = -1; 1208 minibuffer_quit_level = 0;
1213 } 1209 }
1214 return val; 1210 return val;
1215 } 1211 }