diff options
| author | Andrea Corallo | 2021-01-16 13:26:10 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2021-01-16 13:26:10 +0100 |
| commit | 0a7ac0b5504e75275699a3d8d2d5d94bcfda8708 (patch) | |
| tree | bb6158c8a9edeb1e716718abfc98dca16aef9e9e /src/eval.c | |
| parent | f1efac1f9efbfa15b6434ebef507c00c1277633f (diff) | |
| parent | 0732fc31932c75c682c8b65b4dcb4376ca63e8fd (diff) | |
| download | emacs-0a7ac0b5504e75275699a3d8d2d5d94bcfda8708.tar.gz emacs-0a7ac0b5504e75275699a3d8d2d5d94bcfda8708.zip | |
Merge remote-tracking branch 'savannah/master' into native-comp
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 f77f07e1711..cef9407dbfa 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1176,9 +1176,18 @@ Lisp_Object | |||
| 1176 | internal_catch (Lisp_Object tag, | 1176 | internal_catch (Lisp_Object tag, |
| 1177 | Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) | 1177 | Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) |
| 1178 | { | 1178 | { |
| 1179 | /* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by | ||
| 1180 | throwing t to tag `exit'. | ||
| 1181 | Value -1 means there is no (throw 'exit t) in progress; | ||
| 1182 | 0 means the `throw' wasn't done from an active minibuffer; | ||
| 1183 | N > 0 means the `throw' was done from the minibuffer at level N. */ | ||
| 1184 | static EMACS_INT minibuffer_quit_level = -1; | ||
| 1179 | /* This structure is made part of the chain `catchlist'. */ | 1185 | /* This structure is made part of the chain `catchlist'. */ |
| 1180 | struct handler *c = push_handler (tag, CATCHER); | 1186 | struct handler *c = push_handler (tag, CATCHER); |
| 1181 | 1187 | ||
| 1188 | if (EQ (tag, Qexit)) | ||
| 1189 | minibuffer_quit_level = -1; | ||
| 1190 | |||
| 1182 | /* Call FUNC. */ | 1191 | /* Call FUNC. */ |
| 1183 | if (! sys_setjmp (c->jmp)) | 1192 | if (! sys_setjmp (c->jmp)) |
| 1184 | { | 1193 | { |
| @@ -1192,6 +1201,23 @@ internal_catch (Lisp_Object tag, | |||
| 1192 | Lisp_Object val = handlerlist->val; | 1201 | Lisp_Object val = handlerlist->val; |
| 1193 | clobbered_eassert (handlerlist == c); | 1202 | clobbered_eassert (handlerlist == c); |
| 1194 | handlerlist = handlerlist->next; | 1203 | handlerlist = handlerlist->next; |
| 1204 | if (EQ (tag, Qexit) && EQ (val, Qt)) | ||
| 1205 | /* If we've thrown t to tag `exit' from within a minibuffer, we | ||
| 1206 | exit all minibuffers more deeply nested than the current | ||
| 1207 | one. */ | ||
| 1208 | { | ||
| 1209 | EMACS_INT mini_depth = this_minibuffer_depth (Qnil); | ||
| 1210 | if (mini_depth && mini_depth != minibuffer_quit_level) | ||
| 1211 | { | ||
| 1212 | if (minibuffer_quit_level == -1) | ||
| 1213 | minibuffer_quit_level = mini_depth; | ||
| 1214 | if (minibuffer_quit_level | ||
| 1215 | && (minibuf_level > minibuffer_quit_level)) | ||
| 1216 | Fthrow (Qexit, Qt); | ||
| 1217 | } | ||
| 1218 | else | ||
| 1219 | minibuffer_quit_level = -1; | ||
| 1220 | } | ||
| 1195 | return val; | 1221 | return val; |
| 1196 | } | 1222 | } |
| 1197 | } | 1223 | } |