diff options
| author | Miha Rihtaršič | 2021-07-20 14:36:45 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2021-07-20 14:36:45 +0200 |
| commit | 7edbcb3648e9d08a4ccc291f672f831b4f07eb5c (patch) | |
| tree | 30f6ce7415be55f973b0071d2d957023b9b8c4c7 /src | |
| parent | 557c59591cb03729c7ab56719e5ed87a1f06d435 (diff) | |
| download | emacs-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.c | 2 | ||||
| -rw-r--r-- | src/keyboard.c | 45 | ||||
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/macros.c | 2 | ||||
| -rw-r--r-- | src/minibuf.c | 2 |
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 | |||
| 921 | cmd_error (Lisp_Object data) | 924 | cmd_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 | ||
| 1037 | static Lisp_Object command_loop_2 (Lisp_Object); | 1057 | static Lisp_Object command_loop_1 (void); |
| 1038 | static Lisp_Object top_level_1 (Lisp_Object); | 1058 | static 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 | ||
| 1088 | static Lisp_Object | 1109 | Lisp_Object |
| 1089 | command_loop_2 (Lisp_Object ignore) | 1110 | command_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); |
| 1235 | static void adjust_point_for_property (ptrdiff_t, bool); | 1256 | static void adjust_point_for_property (ptrdiff_t, bool); |
| 1236 | 1257 | ||
| 1237 | Lisp_Object | 1258 | static Lisp_Object |
| 1238 | command_loop_1 (void) | 1259 | command_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); | |||
| 4417 | extern bool detect_input_pending_run_timers (bool); | 4417 | extern bool detect_input_pending_run_timers (bool); |
| 4418 | extern void safe_run_hooks (Lisp_Object); | 4418 | extern void safe_run_hooks (Lisp_Object); |
| 4419 | extern void cmd_error_internal (Lisp_Object, const char *); | 4419 | extern void cmd_error_internal (Lisp_Object, const char *); |
| 4420 | extern Lisp_Object command_loop_1 (void); | 4420 | extern Lisp_Object command_loop_2 (Lisp_Object); |
| 4421 | extern Lisp_Object read_menu_command (void); | 4421 | extern Lisp_Object read_menu_command (void); |
| 4422 | extern Lisp_Object recursive_edit_1 (void); | 4422 | extern Lisp_Object recursive_edit_1 (void); |
| 4423 | extern void record_auto_save (void); | 4423 | extern 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 | ||