aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiha Rihtaršič2021-07-20 14:36:45 +0200
committerLars Ingebrigtsen2021-07-20 14:36:45 +0200
commit7edbcb3648e9d08a4ccc291f672f831b4f07eb5c (patch)
tree30f6ce7415be55f973b0071d2d957023b9b8c4c7 /src
parent557c59591cb03729c7ab56719e5ed87a1f06d435 (diff)
downloademacs-7edbcb3648e9d08a4ccc291f672f831b4f07eb5c.tar.gz
emacs-7edbcb3648e9d08a4ccc291f672f831b4f07eb5c.zip
Quit minibuffers without aborting kmacros
* doc/lispref/commands.texi (Quitting): Document `minibuffer-quit' (Recursive Editing): Document throwing of function values to `exit'. * doc/lispref/errors.texi (Standard Errors): Document `minibuffer-quit' * lisp/minibuffer.el (minibuffer-quit-recursive-edit): New function. * lisp/simple.el (minibuffer-error-function): Do not abort keyboard macro execution if is minibuffer-quit is signaled (bug#48603). * src/data.c (syms_of_data): New error symbol `minibuffer-quit' * src/keyboard.c (recursive_edit_1): Implement throwing of function values to `exit`. In that case, the function will be called without arguments before returning from the command loop. (cmd_error): (Fcommand_error_default_function): Do not abort keyboard macro execution if minibuffer-quit is signaled. (command_loop_2): New argument HANDLERS. * src/macros.c (Fexecute_kbd_macro): Use command_loop_2 instead of command_loop_1. * src/minibuf.c (Fabort_minibuffers): Use it.
Diffstat (limited to 'src')
-rw-r--r--src/data.c2
-rw-r--r--src/keyboard.c45
-rw-r--r--src/lisp.h2
-rw-r--r--src/macros.c2
-rw-r--r--src/minibuf.c2
5 files changed, 38 insertions, 15 deletions
diff --git a/src/data.c b/src/data.c
index 9adfafacaa5..ffca7e75355 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3901,6 +3901,7 @@ syms_of_data (void)
3901 DEFSYM (Qerror, "error"); 3901 DEFSYM (Qerror, "error");
3902 DEFSYM (Quser_error, "user-error"); 3902 DEFSYM (Quser_error, "user-error");
3903 DEFSYM (Qquit, "quit"); 3903 DEFSYM (Qquit, "quit");
3904 DEFSYM (Qminibuffer_quit, "minibuffer-quit");
3904 DEFSYM (Qwrong_length_argument, "wrong-length-argument"); 3905 DEFSYM (Qwrong_length_argument, "wrong-length-argument");
3905 DEFSYM (Qwrong_type_argument, "wrong-type-argument"); 3906 DEFSYM (Qwrong_type_argument, "wrong-type-argument");
3906 DEFSYM (Qargs_out_of_range, "args-out-of-range"); 3907 DEFSYM (Qargs_out_of_range, "args-out-of-range");
@@ -3973,6 +3974,7 @@ syms_of_data (void)
3973 Fput (sym, Qerror_message, build_pure_c_string (msg)) 3974 Fput (sym, Qerror_message, build_pure_c_string (msg))
3974 3975
3975 PUT_ERROR (Qquit, Qnil, "Quit"); 3976 PUT_ERROR (Qquit, Qnil, "Quit");
3977 PUT_ERROR (Qminibuffer_quit, pure_cons (Qquit, Qnil), "Quit");
3976 3978
3977 PUT_ERROR (Quser_error, error_tail, ""); 3979 PUT_ERROR (Quser_error, error_tail, "");
3978 PUT_ERROR (Qwrong_length_argument, error_tail, "Wrong length argument"); 3980 PUT_ERROR (Qwrong_length_argument, error_tail, "Wrong length argument");
diff --git a/src/keyboard.c b/src/keyboard.c
index 77d6bbba623..db934686594 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -725,6 +725,9 @@ recursive_edit_1 (void)
725 if (STRINGP (val)) 725 if (STRINGP (val))
726 xsignal1 (Qerror, val); 726 xsignal1 (Qerror, val);
727 727
728 if (FUNCTIONP (val))
729 call0 (val);
730
728 return unbind_to (count, Qnil); 731 return unbind_to (count, Qnil);
729} 732}
730 733
@@ -921,6 +924,7 @@ static Lisp_Object
921cmd_error (Lisp_Object data) 924cmd_error (Lisp_Object data)
922{ 925{
923 Lisp_Object old_level, old_length; 926 Lisp_Object old_level, old_length;
927 Lisp_Object conditions;
924 char macroerror[sizeof "After..kbd macro iterations: " 928 char macroerror[sizeof "After..kbd macro iterations: "
925 + INT_STRLEN_BOUND (EMACS_INT)]; 929 + INT_STRLEN_BOUND (EMACS_INT)];
926 930
@@ -940,10 +944,15 @@ cmd_error (Lisp_Object data)
940 else 944 else
941 *macroerror = 0; 945 *macroerror = 0;
942 946
947 conditions = Fget (XCAR (data), Qerror_conditions);
948 if (NILP (Fmemq (Qminibuffer_quit, conditions)))
949 {
950 Vexecuting_kbd_macro = Qnil;
951 executing_kbd_macro = Qnil;
952 }
953
943 Vstandard_output = Qt; 954 Vstandard_output = Qt;
944 Vstandard_input = Qt; 955 Vstandard_input = Qt;
945 Vexecuting_kbd_macro = Qnil;
946 executing_kbd_macro = Qnil;
947 kset_prefix_arg (current_kboard, Qnil); 956 kset_prefix_arg (current_kboard, Qnil);
948 kset_last_prefix_arg (current_kboard, Qnil); 957 kset_last_prefix_arg (current_kboard, Qnil);
949 cancel_echoing (); 958 cancel_echoing ();
@@ -998,6 +1007,7 @@ Default value of `command-error-function'. */)
998 (Lisp_Object data, Lisp_Object context, Lisp_Object signal) 1007 (Lisp_Object data, Lisp_Object context, Lisp_Object signal)
999{ 1008{
1000 struct frame *sf = SELECTED_FRAME (); 1009 struct frame *sf = SELECTED_FRAME ();
1010 Lisp_Object conditions;
1001 1011
1002 CHECK_STRING (context); 1012 CHECK_STRING (context);
1003 1013
@@ -1024,17 +1034,27 @@ Default value of `command-error-function'. */)
1024 } 1034 }
1025 else 1035 else
1026 { 1036 {
1037 conditions = Fget (XCAR (data), Qerror_conditions);
1038
1027 clear_message (1, 0); 1039 clear_message (1, 0);
1028 Fdiscard_input ();
1029 message_log_maybe_newline (); 1040 message_log_maybe_newline ();
1030 bitch_at_user (); 1041
1042 if (!NILP (Fmemq (Qminibuffer_quit, conditions)))
1043 {
1044 Fding (Qt);
1045 }
1046 else
1047 {
1048 Fdiscard_input ();
1049 bitch_at_user ();
1050 }
1031 1051
1032 print_error_message (data, Qt, SSDATA (context), signal); 1052 print_error_message (data, Qt, SSDATA (context), signal);
1033 } 1053 }
1034 return Qnil; 1054 return Qnil;
1035} 1055}
1036 1056
1037static Lisp_Object command_loop_2 (Lisp_Object); 1057static Lisp_Object command_loop_1 (void);
1038static Lisp_Object top_level_1 (Lisp_Object); 1058static Lisp_Object top_level_1 (Lisp_Object);
1039 1059
1040/* Entry to editor-command-loop. 1060/* Entry to editor-command-loop.
@@ -1062,7 +1082,7 @@ command_loop (void)
1062 if (command_loop_level > 0 || minibuf_level > 0) 1082 if (command_loop_level > 0 || minibuf_level > 0)
1063 { 1083 {
1064 Lisp_Object val; 1084 Lisp_Object val;
1065 val = internal_catch (Qexit, command_loop_2, Qnil); 1085 val = internal_catch (Qexit, command_loop_2, Qerror);
1066 executing_kbd_macro = Qnil; 1086 executing_kbd_macro = Qnil;
1067 return val; 1087 return val;
1068 } 1088 }
@@ -1070,7 +1090,7 @@ command_loop (void)
1070 while (1) 1090 while (1)
1071 { 1091 {
1072 internal_catch (Qtop_level, top_level_1, Qnil); 1092 internal_catch (Qtop_level, top_level_1, Qnil);
1073 internal_catch (Qtop_level, command_loop_2, Qnil); 1093 internal_catch (Qtop_level, command_loop_2, Qerror);
1074 executing_kbd_macro = Qnil; 1094 executing_kbd_macro = Qnil;
1075 1095
1076 /* End of file in -batch run causes exit here. */ 1096 /* End of file in -batch run causes exit here. */
@@ -1083,15 +1103,16 @@ command_loop (void)
1083 editing loop, and reenter the editing loop. 1103 editing loop, and reenter the editing loop.
1084 When there is an error, cmd_error runs and returns a non-nil 1104 When there is an error, cmd_error runs and returns a non-nil
1085 value to us. A value of nil means that command_loop_1 itself 1105 value to us. A value of nil means that command_loop_1 itself
1086 returned due to end of file (or end of kbd macro). */ 1106 returned due to end of file (or end of kbd macro). HANDLERS is a
1107 list of condition names, passed to internal_condition_case. */
1087 1108
1088static Lisp_Object 1109Lisp_Object
1089command_loop_2 (Lisp_Object ignore) 1110command_loop_2 (Lisp_Object handlers)
1090{ 1111{
1091 register Lisp_Object val; 1112 register Lisp_Object val;
1092 1113
1093 do 1114 do
1094 val = internal_condition_case (command_loop_1, Qerror, cmd_error); 1115 val = internal_condition_case (command_loop_1, handlers, cmd_error);
1095 while (!NILP (val)); 1116 while (!NILP (val));
1096 1117
1097 return Qnil; 1118 return Qnil;
@@ -1234,7 +1255,7 @@ static int read_key_sequence (Lisp_Object *, Lisp_Object,
1234 bool, bool, bool, bool); 1255 bool, bool, bool, bool);
1235static void adjust_point_for_property (ptrdiff_t, bool); 1256static void adjust_point_for_property (ptrdiff_t, bool);
1236 1257
1237Lisp_Object 1258static Lisp_Object
1238command_loop_1 (void) 1259command_loop_1 (void)
1239{ 1260{
1240 modiff_count prev_modiff = 0; 1261 modiff_count prev_modiff = 0;
diff --git a/src/lisp.h b/src/lisp.h
index 1795b9d811b..b3f1dc16b13 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4417,7 +4417,7 @@ extern bool detect_input_pending_ignore_squeezables (void);
4417extern bool detect_input_pending_run_timers (bool); 4417extern bool detect_input_pending_run_timers (bool);
4418extern void safe_run_hooks (Lisp_Object); 4418extern void safe_run_hooks (Lisp_Object);
4419extern void cmd_error_internal (Lisp_Object, const char *); 4419extern void cmd_error_internal (Lisp_Object, const char *);
4420extern Lisp_Object command_loop_1 (void); 4420extern Lisp_Object command_loop_2 (Lisp_Object);
4421extern Lisp_Object read_menu_command (void); 4421extern Lisp_Object read_menu_command (void);
4422extern Lisp_Object recursive_edit_1 (void); 4422extern Lisp_Object recursive_edit_1 (void);
4423extern void record_auto_save (void); 4423extern void record_auto_save (void);
diff --git a/src/macros.c b/src/macros.c
index 60d0766a754..0752a5bb6f6 100644
--- a/src/macros.c
+++ b/src/macros.c
@@ -324,7 +324,7 @@ buffer before the macro is executed. */)
324 break; 324 break;
325 } 325 }
326 326
327 command_loop_1 (); 327 command_loop_2 (list1 (Qminibuffer_quit));
328 328
329 executing_kbd_macro_iterations = ++success_count; 329 executing_kbd_macro_iterations = ++success_count;
330 330
diff --git a/src/minibuf.c b/src/minibuf.c
index 1b842b77211..0f4349e70b8 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -496,7 +496,7 @@ confirm the aborting of the current minibuffer and all contained ones. */)
496 } 496 }
497 } 497 }
498 else 498 else
499 Fthrow (Qexit, Qt); 499 CALLN (Ffuncall, intern ("minibuffer-quit-recursive-edit"));
500 return Qnil; 500 return Qnil;
501} 501}
502 502