summaryrefslogtreecommitdiff
path: root/src/keyboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/keyboard.c')
-rw-r--r--src/keyboard.c132
1 files changed, 79 insertions, 53 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 4555b71abe7..91faf4582fa 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -580,7 +580,10 @@ echo_dash (void)
idx = make_fixnum (SCHARS (KVAR (current_kboard, echo_string)) - 1);
last_char = Faref (KVAR (current_kboard, echo_string), idx);
- if (XFIXNUM (last_char) == '-' && XFIXNUM (prev_char) != ' ')
+ if ((XFIXNUM (last_char) == '-' && XFIXNUM (prev_char) != ' ')
+ /* Or a keystroke help message. */
+ || (echo_keystrokes_help
+ && XFIXNUM (last_char) == ')' && XFIXNUM (prev_char) == 'p'))
return;
}
@@ -589,6 +592,12 @@ echo_dash (void)
AUTO_STRING (dash, "-");
kset_echo_string (current_kboard,
concat2 (KVAR (current_kboard, echo_string), dash));
+
+ if (echo_keystrokes_help)
+ kset_echo_string (current_kboard,
+ calln (Qhelp__append_keystrokes_help,
+ KVAR (current_kboard, echo_string)));
+
echo_now ();
}
@@ -1026,7 +1035,7 @@ cmd_error_internal (Lisp_Object data, const char *context)
{
/* The immediate context is not interesting for Quits,
since they are asynchronous. */
- if (signal_quit_p (XCAR (data)))
+ if (signal_quit_p (data))
Vsignaling_function = Qnil;
Vquit_flag = Qnil;
@@ -1067,8 +1076,9 @@ Default value of `command-error-function'. */)
write to stderr and quit. In daemon mode, there are
many other potential errors that do not prevent frames
from being created, so continuing as normal is better in
- that case. */
- || (!IS_DAEMON && FRAME_INITIAL_P (sf))
+ that case, as long as the daemon has actually finished
+ initialization. */
+ || (!(IS_DAEMON && !DAEMON_RUNNING) && FRAME_INITIAL_P (sf))
|| noninteractive))
{
print_error_message (data, Qexternal_debugging_output,
@@ -1163,7 +1173,18 @@ command_loop_2 (Lisp_Object handlers)
static Lisp_Object
top_level_2 (void)
{
- return Feval (Vtop_level, Qnil);
+ /* If we're in batch mode, print a backtrace unconditionally when
+ encountering an error, to help with debugging. */
+ bool setup_handler = noninteractive;
+ if (setup_handler)
+ /* FIXME: Should we (re)use `list_of_error` from `xdisp.c`? */
+ push_handler_bind (list1 (Qerror), Qdebug_early__handler, 0);
+
+ Lisp_Object res = Feval (Vtop_level, Qt);
+
+ if (setup_handler)
+ pop_handler ();
+ return res;
}
static Lisp_Object
@@ -1355,7 +1376,6 @@ command_loop_1 (void)
display_malloc_warning ();
Vdeactivate_mark = Qnil;
- backtrace_yet = false;
/* Don't ignore mouse movements for more than a single command
loop. (This flag is set in xdisp.c whenever the tool bar is
@@ -2600,7 +2620,8 @@ read_char (int commandflag, Lisp_Object map,
goto reread_for_input_method;
}
- if (!NILP (Vexecuting_kbd_macro))
+ /* If we're executing a macro, process it unless we are at its end. */
+ if (!NILP (Vexecuting_kbd_macro) && !at_end_of_macro_p ())
{
/* We set this to Qmacro; since that's not a frame, nobody will
try to switch frames on us, and the selected window will
@@ -2614,16 +2635,6 @@ read_char (int commandflag, Lisp_Object map,
selected. */
Vlast_event_frame = internal_last_event_frame = Qmacro;
- /* Exit the macro if we are at the end.
- Also, some things replace the macro with t
- to force an early exit. */
- if (EQ (Vexecuting_kbd_macro, Qt)
- || executing_kbd_macro_index >= XFIXNAT (Flength (Vexecuting_kbd_macro)))
- {
- XSETINT (c, -1);
- goto exit;
- }
-
c = Faref (Vexecuting_kbd_macro, make_int (executing_kbd_macro_index));
if (STRINGP (Vexecuting_kbd_macro)
&& (XFIXNAT (c) & 0x80) && (XFIXNAT (c) <= 0xff))
@@ -4176,6 +4187,16 @@ kbd_buffer_get_event (KBOARD **kbp,
break;
}
+#ifdef HAVE_ANDROID
+ case NOTIFICATION_EVENT:
+ {
+ kbd_fetch_ptr = next_kbd_event (event);
+ input_pending = readable_events (0);
+ CALLN (Fapply, XCAR (event->ie.arg), XCDR (event->ie.arg));
+ break;
+ }
+#endif /* HAVE_ANDROID */
+
#ifdef HAVE_EXT_MENU_BAR
case MENU_BAR_ACTIVATE_EVENT:
{
@@ -8609,7 +8630,7 @@ menu_item_eval_property_1 (Lisp_Object arg)
{
/* If we got a quit from within the menu computation,
quit all the way out of it. This takes care of C-] in the debugger. */
- if (CONSP (arg) && signal_quit_p (XCAR (arg)))
+ if (signal_quit_p (arg))
quit ();
return Qnil;
@@ -9072,7 +9093,7 @@ process_tab_bar_item (Lisp_Object key, Lisp_Object def, Lisp_Object data, void *
}
/* Access slot with index IDX of vector tab_bar_item_properties. */
-#define PROP(IDX) AREF (tab_bar_item_properties, (IDX))
+#define PROP(IDX) AREF (tab_bar_item_properties, IDX)
static void
set_prop_tab_bar (ptrdiff_t idx, Lisp_Object val)
{
@@ -9456,7 +9477,7 @@ process_tool_bar_item (Lisp_Object key, Lisp_Object def, Lisp_Object data, void
}
/* Access slot with index IDX of vector tool_bar_item_properties. */
-#define PROP(IDX) AREF (tool_bar_item_properties, (IDX))
+#define PROP(IDX) AREF (tool_bar_item_properties, IDX)
static void
set_prop (ptrdiff_t idx, Lisp_Object val)
{
@@ -10431,9 +10452,6 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
Lisp_Object original_uppercase UNINIT;
int original_uppercase_position = -1;
- /* Gets around Microsoft compiler limitations. */
- bool dummyflag = false;
-
#ifdef HAVE_TEXT_CONVERSION
bool disabled_conversion;
@@ -10675,8 +10693,16 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
}
used_mouse_menu = used_mouse_menu_history[t];
}
-
- /* If not, we should actually read a character. */
+ /* If we're at the end of a macro, exit it by returning 0,
+ unless there are unread events pending. */
+ else if (!NILP (Vexecuting_kbd_macro)
+ && at_end_of_macro_p ()
+ && !requeued_events_pending_p ())
+ {
+ t = 0;
+ goto done;
+ }
+ /* Otherwise, we should actually read a character. */
else
{
{
@@ -10768,18 +10794,6 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
return -1;
}
- /* read_char returns -1 at the end of a macro.
- Emacs 18 handles this by returning immediately with a
- zero, so that's what we'll do. */
- if (FIXNUMP (key) && XFIXNUM (key) == -1)
- {
- t = 0;
- /* The Microsoft C compiler can't handle the goto that
- would go here. */
- dummyflag = true;
- break;
- }
-
/* If the current buffer has been changed from under us, the
keymap may have changed, so replay the sequence. */
if (BUFFERP (key))
@@ -11281,10 +11295,7 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
&& help_char_p (EVENT_HEAD (key)) && t > 1)
{
read_key_sequence_cmd = Vprefix_help_command;
- /* The Microsoft C compiler can't handle the goto that
- would go here. */
- dummyflag = true;
- break;
+ goto done;
}
/* If KEY is not defined in any of the keymaps,
@@ -11333,8 +11344,9 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
}
}
}
- if (!dummyflag)
- read_key_sequence_cmd = current_binding;
+ read_key_sequence_cmd = current_binding;
+
+ done:
read_key_sequence_remapped
/* Remap command through active keymaps.
Do the remapping here, before the unbind_to so it uses the keymaps
@@ -11546,18 +11558,26 @@ clear_input_pending (void)
input_pending = false;
}
-/* Return true if there are pending requeued events.
- This isn't used yet. The hope is to make wait_reading_process_output
- call it, and return if it runs Lisp code that unreads something.
- The problem is, kbd_buffer_get_event needs to be fixed to know what
- to do in that case. It isn't trivial. */
+/* Return true if there are pending requeued command events. */
bool
-requeued_events_pending_p (void)
+requeued_command_events_pending_p (void)
{
return (CONSP (Vunread_command_events));
}
+/* Return true if there are any pending requeued events (command events
+ or events to be processed by other levels of the input processing
+ stages). */
+
+bool
+requeued_events_pending_p (void)
+{
+ return (requeued_command_events_pending_p ()
+ || !NILP (Vunread_post_input_method_events)
+ || !NILP (Vunread_input_method_events));
+}
+
DEFUN ("input-pending-p", Finput_pending_p, Sinput_pending_p, 0, 1, 0,
doc: /* Return t if command input is currently available with no wait.
Actually, the value is nil only if we can be sure that no input is available;
@@ -11566,9 +11586,7 @@ if there is a doubt, the value is t.
If CHECK-TIMERS is non-nil, timers that are ready to run will do so. */)
(Lisp_Object check_timers)
{
- if (CONSP (Vunread_command_events)
- || !NILP (Vunread_post_input_method_events)
- || !NILP (Vunread_input_method_events))
+ if (requeued_events_pending_p ())
return (Qt);
/* Process non-user-visible events (Bug#10195). */
@@ -12938,6 +12956,8 @@ syms_of_keyboard (void)
DEFSYM (Qhelp_key_binding, "help-key-binding");
+ DEFSYM (Qhelp__append_keystrokes_help, "help--append-keystrokes-help");
+
DEFSYM (Qecho_keystrokes, "echo-keystrokes");
Fset (Qinput_method_exit_on_first_char, Qnil);
@@ -13213,11 +13233,17 @@ Emacs also does a garbage collection if that seems to be warranted. */);
XSETFASTINT (Vauto_save_timeout, 30);
DEFVAR_LISP ("echo-keystrokes", Vecho_keystrokes,
- doc: /* Nonzero means echo unfinished commands after this many seconds of pause.
+ doc: /* Nonzero means echo unfinished commands after this many seconds of pause.
The value may be integer or floating point.
If the value is zero, don't echo at all. */);
Vecho_keystrokes = make_fixnum (1);
+ DEFVAR_BOOL ("echo-keystrokes-help", echo_keystrokes_help,
+ doc: /* Whether to append help text to echoed commands.
+When non-nil, a reference to `C-h' is printed after echoed
+keystrokes. */);
+ echo_keystrokes_help = true;
+
DEFVAR_LISP ("polling-period", Vpolling_period,
doc: /* Interval between polling for input during Lisp execution.
The reason for polling is to make C-g work to stop a running program.