diff options
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 | } |