]> git.eshelyaron.com Git - emacs.git/commitdiff
Refactor minibuffer aborting
authorMiha Rihtaršič <miha@kamnitnik.top>
Mon, 20 Sep 2021 05:59:29 +0000 (07:59 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Mon, 20 Sep 2021 05:59:29 +0000 (07:59 +0200)
* 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.

lisp/minibuffer.el
src/eval.c
src/lisp.h
src/minibuf.c

index 9668e7c732c642848efc527e625008a5850630d9..b5c0054a3c2511c3a6317d242b96e31d1bb24197 100644 (file)
@@ -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."
index 48104bd0f45927a977dbb1222a3a02319311c39a..76fe671b6dd04ec4568656205601a0241761081a 100644 (file)
@@ -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;
     }
 }
index 9716b34baeeca46c41a5a0cf7d8a1d975532a7ed..720e621d19cbcbf6dac4a61be9950a2d06831eaa 100644 (file)
@@ -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;
index 0e7baf30dca756927c4c29ca88b7f2af0c1d6037..a4219d2a63f9da107d1f875b3f07554c2cade7a6 100644 (file)
@@ -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