From: Miha Rihtaršič Date: Mon, 20 Sep 2021 05:59:29 +0000 (+0200) Subject: Refactor minibuffer aborting X-Git-Tag: emacs-28.0.90~822 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=31ba9bbf6c2d0a265c77de1c068400b750ecf34b;p=emacs.git 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. --- diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 9668e7c732c..b5c0054a3c2 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -2349,14 +2349,18 @@ that displays the \"*Completions*\" buffer." (add-hook 'minibuffer-exit-hook 'minibuffer-restore-windows) -(defun minibuffer-quit-recursive-edit () - "Quit the command that requested this recursive edit without error. -Like `abort-recursive-edit' without aborting keyboard macro -execution." - ;; See Info node `(elisp)Recursive Editing' for an explanation of - ;; throwing a function to `exit'. - (throw 'exit (lambda () - (signal 'minibuffer-quit nil)))) +(defun minibuffer-quit-recursive-edit (&optional levels) + "Quit the command that requested this recursive edit or minibuffer input. +Do so without terminating keyboard macro recording or execution. +LEVELS specifies the number of nested recursive edits to quit. +If nil, it defaults to 1." + (unless levels + (setq levels 1)) + (if (> levels 1) + ;; See Info node `(elisp)Recursive Editing' for an explanation + ;; of throwing a function to `exit'. + (throw 'exit (lambda () (minibuffer-quit-recursive-edit (1- levels)))) + (throw 'exit (lambda () (signal 'minibuffer-quit nil))))) (defun self-insert-and-exit () "Terminate minibuffer input." 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...) */) FUNC should return a Lisp_Object. This is how catches are done from within C code. */ -/* MINIBUFFER_QUIT_LEVEL is to handle quitting from nested minibuffers by - throwing t to tag `exit'. - 0 means there is no (throw 'exit t) in progress, or it wasn't from - a minibuffer which isn't the most nested; - N > 0 means the `throw' was done from the minibuffer at level N which - wasn't the most nested. */ -EMACS_INT minibuffer_quit_level = 0; - Lisp_Object internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) @@ -1189,9 +1181,6 @@ internal_catch (Lisp_Object tag, /* This structure is made part of the chain `catchlist'. */ struct handler *c = push_handler (tag, CATCHER); - if (EQ (tag, Qexit)) - minibuffer_quit_level = 0; - /* Call FUNC. */ if (! sys_setjmp (c->jmp)) { @@ -1205,17 +1194,6 @@ internal_catch (Lisp_Object tag, Lisp_Object val = handlerlist->val; clobbered_eassert (handlerlist == c); handlerlist = handlerlist->next; - if (EQ (tag, Qexit) && EQ (val, Qt) && minibuffer_quit_level > 0) - /* If we've thrown t to tag `exit' from within a minibuffer, we - exit all minibuffers more deeply nested than the current - one. */ - { - if (minibuf_level > minibuffer_quit_level - && !NILP (Fminibuffer_innermost_command_loop_p (Qnil))) - Fthrow (Qexit, Qt); - else - minibuffer_quit_level = 0; - } return val; } } 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) } /* Defined in eval.c. */ -extern EMACS_INT minibuffer_quit_level; extern Lisp_Object Vautoload_queue; extern Lisp_Object Vrun_hooks; 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. */) array[1] = make_fixnum (minibuf_level - minibuf_depth + 1); if (!NILP (Fyes_or_no_p (Fformat (2, array)))) { - minibuffer_quit_level = minibuf_depth; - Fthrow (Qexit, Qt); + /* Due to the above check, the current minibuffer is in the + most nested command loop, which means that we don't have + to abort any extra non-minibuffer recursive edits. Thus, + the number of recursive edits we have to abort equals the + number of minibuffers we have to abort. */ + CALLN (Ffuncall, intern ("minibuffer-quit-recursive-edit"), + array[1]); } } else