diff options
| author | Miha Rihtaršič | 2021-09-20 07:59:29 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2021-09-20 07:59:29 +0200 |
| commit | 31ba9bbf6c2d0a265c77de1c068400b750ecf34b (patch) | |
| tree | 2ff04f3e3e9ff3b801f463f33c0671586b69475c /src | |
| parent | 995a623594de27d398f0d97fcab9277e37fe29d1 (diff) | |
| download | emacs-31ba9bbf6c2d0a265c77de1c068400b750ecf34b.tar.gz emacs-31ba9bbf6c2d0a265c77de1c068400b750ecf34b.zip | |
Refactor minibuffer aborting
* lisp/minibuffer.el (minibuffer-quit-recursive-edit): New optional
argument to specify how many levels of recursion to quit.
* src/eval.c (internal_catch): Remove special handling of 'exit
tag (bug#49700).
* src/minibuf.c (Fabort_minibuffers): Use
minibuffer-quit-recursive-edit to quit multiple levels of minibuffer
recursion.
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval.c | 22 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/minibuf.c | 9 |
3 files changed, 7 insertions, 25 deletions
diff --git a/src/eval.c b/src/eval.c index 48104bd0f45..76fe671b6dd 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1174,14 +1174,6 @@ usage: (catch TAG BODY...) */) | |||
| 1174 | FUNC should return a Lisp_Object. | 1174 | FUNC should return a Lisp_Object. |
| 1175 | This is how catches are done from within C code. */ | 1175 | This is how catches are done from within C code. */ |
| 1176 | 1176 | ||
| 1177 | /* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by | ||
| 1178 | throwing t to tag `exit'. | ||
| 1179 | 0 means there is no (throw 'exit t) in progress, or it wasn't from | ||
| 1180 | a minibuffer which isn't the most nested; | ||
| 1181 | N > 0 means the `throw' was done from the minibuffer at level N which | ||
| 1182 | wasn't the most nested. */ | ||
| 1183 | EMACS_INT minibuffer_quit_level = 0; | ||
| 1184 | |||
| 1185 | Lisp_Object | 1177 | Lisp_Object |
| 1186 | internal_catch (Lisp_Object tag, | 1178 | internal_catch (Lisp_Object tag, |
| 1187 | Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) | 1179 | Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) |
| @@ -1189,9 +1181,6 @@ internal_catch (Lisp_Object tag, | |||
| 1189 | /* This structure is made part of the chain `catchlist'. */ | 1181 | /* This structure is made part of the chain `catchlist'. */ |
| 1190 | struct handler *c = push_handler (tag, CATCHER); | 1182 | struct handler *c = push_handler (tag, CATCHER); |
| 1191 | 1183 | ||
| 1192 | if (EQ (tag, Qexit)) | ||
| 1193 | minibuffer_quit_level = 0; | ||
| 1194 | |||
| 1195 | /* Call FUNC. */ | 1184 | /* Call FUNC. */ |
| 1196 | if (! sys_setjmp (c->jmp)) | 1185 | if (! sys_setjmp (c->jmp)) |
| 1197 | { | 1186 | { |
| @@ -1205,17 +1194,6 @@ internal_catch (Lisp_Object tag, | |||
| 1205 | Lisp_Object val = handlerlist->val; | 1194 | Lisp_Object val = handlerlist->val; |
| 1206 | clobbered_eassert (handlerlist == c); | 1195 | clobbered_eassert (handlerlist == c); |
| 1207 | handlerlist = handlerlist->next; | 1196 | handlerlist = handlerlist->next; |
| 1208 | if (EQ (tag, Qexit) && EQ (val, Qt) && minibuffer_quit_level > 0) | ||
| 1209 | /* If we've thrown t to tag `exit' from within a minibuffer, we | ||
| 1210 | exit all minibuffers more deeply nested than the current | ||
| 1211 | one. */ | ||
| 1212 | { | ||
| 1213 | if (minibuf_level > minibuffer_quit_level | ||
| 1214 | && !NILP (Fminibuffer_innermost_command_loop_p (Qnil))) | ||
| 1215 | Fthrow (Qexit, Qt); | ||
| 1216 | else | ||
| 1217 | minibuffer_quit_level = 0; | ||
| 1218 | } | ||
| 1219 | return val; | 1197 | return val; |
| 1220 | } | 1198 | } |
| 1221 | } | 1199 | } |
diff --git a/src/lisp.h b/src/lisp.h index 9716b34baee..720e621d19c 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4120,7 +4120,6 @@ intern_c_string (const char *str) | |||
| 4120 | } | 4120 | } |
| 4121 | 4121 | ||
| 4122 | /* Defined in eval.c. */ | 4122 | /* Defined in eval.c. */ |
| 4123 | extern EMACS_INT minibuffer_quit_level; | ||
| 4124 | extern Lisp_Object Vautoload_queue; | 4123 | extern Lisp_Object Vautoload_queue; |
| 4125 | extern Lisp_Object Vrun_hooks; | 4124 | extern Lisp_Object Vrun_hooks; |
| 4126 | extern Lisp_Object Vsignaling_function; | 4125 | extern Lisp_Object Vsignaling_function; |
diff --git a/src/minibuf.c b/src/minibuf.c index 0e7baf30dca..a4219d2a63f 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -491,8 +491,13 @@ confirm the aborting of the current minibuffer and all contained ones. */) | |||
| 491 | array[1] = make_fixnum (minibuf_level - minibuf_depth + 1); | 491 | array[1] = make_fixnum (minibuf_level - minibuf_depth + 1); |
| 492 | if (!NILP (Fyes_or_no_p (Fformat (2, array)))) | 492 | if (!NILP (Fyes_or_no_p (Fformat (2, array)))) |
| 493 | { | 493 | { |
| 494 | minibuffer_quit_level = minibuf_depth; | 494 | /* Due to the above check, the current minibuffer is in the |
| 495 | Fthrow (Qexit, Qt); | 495 | most nested command loop, which means that we don't have |
| 496 | to abort any extra non-minibuffer recursive edits. Thus, | ||
| 497 | the number of recursive edits we have to abort equals the | ||
| 498 | number of minibuffers we have to abort. */ | ||
| 499 | CALLN (Ffuncall, intern ("minibuffer-quit-recursive-edit"), | ||
| 500 | array[1]); | ||
| 496 | } | 501 | } |
| 497 | } | 502 | } |
| 498 | else | 503 | else |