X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/d29ee6b1a110cf5d170a10317a96acbbd4a1c68b..025ae9533de941cd045374c1639d20e9b830284a:/src/keyboard.c diff --git a/src/keyboard.c b/src/keyboard.c index 2230b339f5..526586f17f 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1,7 +1,7 @@ /* Keyboard and mouse input; editor command loop. Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -95,18 +95,7 @@ volatile int interrupt_input_blocked; during the current critical section. */ int interrupt_input_pending; - -#ifdef HAVE_WINDOW_SYSTEM -/* Make all keyboard buffers much bigger when using X windows. */ -#ifdef MAC_OS8 -/* But not too big (local data > 32K error) if on Mac OS Classic. */ -#define KBD_BUFFER_SIZE 512 -#else #define KBD_BUFFER_SIZE 4096 -#endif -#else /* No X-windows, character input */ -#define KBD_BUFFER_SIZE 4096 -#endif /* No X-windows */ #ifdef MULTI_KBOARD KBOARD *initial_kboard; @@ -143,6 +132,9 @@ int this_command_key_count_reset; Lisp_Object raw_keybuf; int raw_keybuf_count; +/* Non-nil if the present key sequence was obtained by shift translation. */ +Lisp_Object Vthis_command_keys_shift_translated; + #define GROW_RAW_KEYBUF \ if (raw_keybuf_count == XVECTOR (raw_keybuf)->size) \ raw_keybuf = larger_vector (raw_keybuf, raw_keybuf_count * 2, Qnil) \ @@ -669,8 +661,6 @@ static int store_user_signal_events P_ ((void)); /* Nonzero means don't try to suspend even if the operating system seems to support it. */ static int cannot_suspend; - -extern Lisp_Object Qidentity, Qonly; /* Install the string STR as the beginning of the string of echoing, so that it serves as a prompt for the next character. @@ -929,7 +919,7 @@ add_command_key (key) 2 * ASIZE (this_command_keys), Qnil); - AREF (this_command_keys, this_command_key_count) = key; + ASET (this_command_keys, this_command_key_count, key); ++this_command_key_count; } @@ -946,7 +936,7 @@ recursive_edit_1 () specbind (Qstandard_input, Qt); } -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM /* The command loop has started an hourglass timer, so we have to cancel it here, otherwise it will fire because the recursive edit can take some time. Do not check for display_hourglass_p here, @@ -1231,7 +1221,7 @@ cmd_error (data) Lisp_Object old_level, old_length; char macroerror[50]; -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) cancel_hourglass (); #endif @@ -1407,7 +1397,7 @@ DEFUN ("top-level", Ftop_level, Stop_level, 0, 0, "", doc: /* Exit all recursive editing levels. */) () { -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) cancel_hourglass (); #endif @@ -1530,7 +1520,7 @@ static void adjust_point_for_property P_ ((int, int)); /* Cancel hourglass from protect_unwind. ARG is not used. */ -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM static Lisp_Object cancel_hourglass_unwind (arg) Lisp_Object arg; @@ -1614,17 +1604,15 @@ command_loop_1 () if (minibuf_level && !NILP (echo_area_buffer[0]) - && EQ (minibuf_window, echo_area_window)) + && EQ (minibuf_window, echo_area_window) + && NUMBERP (Vminibuffer_message_timeout)) { /* Bind inhibit-quit to t so that C-g gets read in rather than quitting back to the minibuffer. */ int count = SPECPDL_INDEX (); specbind (Qinhibit_quit, Qt); - if (NUMBERP (Vminibuffer_message_timeout)) - sit_for (Vminibuffer_message_timeout, 0, 2); - else - sit_for (Qt, 0, 2); + sit_for (Vminibuffer_message_timeout, 0, 2); /* Clear the echo area. */ message2 (0, 0, 0); @@ -1661,6 +1649,7 @@ command_loop_1 () Vthis_command = Qnil; real_this_command = Qnil; Vthis_original_command = Qnil; + Vthis_command_keys_shift_translated = Qnil; /* Read next key sequence; i gets its length. */ i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0], @@ -1774,7 +1763,9 @@ command_loop_1 () /* Recognize some common commands in common situations and do them directly. */ - if (EQ (Vthis_command, Qforward_char) && PT < ZV) + if (EQ (Vthis_command, Qforward_char) && PT < ZV + && NILP (Vthis_command_keys_shift_translated) + && !CONSP (Vtransient_mark_mode)) { struct Lisp_Char_Table *dp = window_display_table (XWINDOW (selected_window)); @@ -1814,7 +1805,9 @@ command_loop_1 () direct_output_forward_char (1); goto directly_done; } - else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV) + else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV + && NILP (Vthis_command_keys_shift_translated) + && !CONSP (Vtransient_mark_mode)) { struct Lisp_Char_Table *dp = window_display_table (XWINDOW (selected_window)); @@ -1904,7 +1897,7 @@ command_loop_1 () /* Here for a command that isn't executed directly */ { -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM int scount = SPECPDL_INDEX (); if (display_hourglass_p @@ -1920,7 +1913,7 @@ command_loop_1 () Fundo_boundary (); Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil); -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM /* Do not check display_hourglass_p here, because Fcommand_execute could change it, but we should cancel hourglass cursor anyway. @@ -1974,14 +1967,6 @@ command_loop_1 () if (!NILP (current_buffer->mark_active) && !NILP (Vrun_hooks)) { - /* Setting transient-mark-mode to `only' is a way of - turning it on for just one command. */ - - if (EQ (Vtransient_mark_mode, Qidentity)) - Vtransient_mark_mode = Qnil; - if (EQ (Vtransient_mark_mode, Qonly)) - Vtransient_mark_mode = Qidentity; - if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode)) { /* We could also call `deactivate'mark'. */ @@ -2365,6 +2350,9 @@ make_ctrl_char (c) /* Save the upper bits here. */ int upper = c & ~0177; + if (! ASCII_BYTE_P (c)) + return c |= ctrl_modifier; + c &= 0177; /* Everything in the columns containing the upper-case letters @@ -2715,6 +2703,8 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time) /* if redisplay was requested */ if (commandflag >= 0) { + int echo_current = EQ (echo_message_buffer, echo_area_buffer[0]); + /* If there is pending input, process any events which are not user-visible, such as X selection_request events. */ if (input_pending @@ -2738,6 +2728,12 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time) swallow_events (0); /* If that cleared input_pending, try again to redisplay. */ } + + /* Prevent the redisplay we just did + from messing up echoing of the input after the prompt. */ + if (commandflag == 0 && echo_current) + echo_message_buffer = echo_area_buffer[0]; + } /* Message turns off echoing unless more keystrokes turn it on again. @@ -4507,6 +4503,13 @@ timer_resume_idle () /* This is only for debugging. */ struct input_event last_timer_event; +/* List of elisp functions to call, delayed because they were generated in + a context where Elisp could not be safely run (e.g. redisplay, signal, + ...). Each lement has the form (FUN . ARGS). */ +Lisp_Object pending_funcalls; + +extern Lisp_Object Qapply; + /* Check whether a timer has fired. To prevent larger problems we simply disregard elements that are not proper timers. Do not make a circular timer list for the time being. @@ -4543,6 +4546,14 @@ timer_check (do_it_now) chosen_timer = Qnil; GCPRO3 (timers, idle_timers, chosen_timer); + /* First run the code that was delayed. */ + while (CONSP (pending_funcalls)) + { + Lisp_Object funcall = XCAR (pending_funcalls); + pending_funcalls = XCDR (pending_funcalls); + safe_call2 (Qapply, XCAR (funcall), XCDR (funcall)); + } + if (CONSP (timers) || CONSP (idle_timers)) { EMACS_GET_TIME (now); @@ -7134,10 +7145,11 @@ read_avail_input (expected) kill (getpid (), SIGHUP); /* XXX Is calling delete_terminal safe here? It calls Fdelete_frame. */ - if (t->delete_terminal_hook) - (*t->delete_terminal_hook) (t); - else - delete_terminal (t); + { + Lisp_Object tmp; + XSETTERMINAL (tmp, t); + Fdelete_terminal (tmp, Qnoelisp); + } } if (hold_quit.kind != NO_EVENT) @@ -7234,7 +7246,7 @@ tty_read_avail_input (struct terminal *terminal, if (n_to_read > sizeof cbuf) n_to_read = sizeof cbuf; #else /* no FIONREAD */ -#if defined (USG) || defined (DGUX) || defined(CYGWIN) +#if defined (USG) || defined(CYGWIN) /* Read some input if available, but don't wait. */ n_to_read = sizeof cbuf; fcntl (fileno (tty->input), F_SETFL, O_NDELAY); @@ -7255,7 +7267,7 @@ tty_read_avail_input (struct terminal *terminal, Jeffrey Honig says this is generally safe. */ if (nread == -1 && errno == EIO) return -2; /* Close this terminal. */ -#if defined (AIX) && (! defined (aix386) && defined (_BSD)) +#if defined (AIX) && defined (_BSD) /* The kernel sometimes fails to deliver SIGHUP for ptys. This looks incorrect, but it isn't, because _BSD causes O_NDELAY to be defined in fcntl.h as O_NONBLOCK, @@ -7284,9 +7296,9 @@ tty_read_avail_input (struct terminal *terminal, ); #ifndef FIONREAD -#if defined (USG) || defined (DGUX) || defined (CYGWIN) +#if defined (USG) || defined (CYGWIN) fcntl (fileno (tty->input), F_SETFL, 0); -#endif /* USG or DGUX or CYGWIN */ +#endif /* USG or CYGWIN */ #endif /* no FIONREAD */ if (nread <= 0) @@ -7826,11 +7838,11 @@ parse_menu_item (item, notreal, inmenubar) /* Initialize optional entries. */ for (i = ITEM_PROPERTY_DEF; i < ITEM_PROPERTY_ENABLE; i++) - AREF (item_properties, i) = Qnil; - AREF (item_properties, ITEM_PROPERTY_ENABLE) = Qt; + ASET (item_properties, i, Qnil); + ASET (item_properties, ITEM_PROPERTY_ENABLE, Qt); /* Save the item here to protect it from GC. */ - AREF (item_properties, ITEM_PROPERTY_ITEM) = item; + ASET (item_properties, ITEM_PROPERTY_ITEM, item); item_string = XCAR (item); @@ -7839,12 +7851,12 @@ parse_menu_item (item, notreal, inmenubar) if (STRINGP (item_string)) { /* Old format menu item. */ - AREF (item_properties, ITEM_PROPERTY_NAME) = item_string; + ASET (item_properties, ITEM_PROPERTY_NAME, item_string); /* Maybe help string. */ if (CONSP (item) && STRINGP (XCAR (item))) { - AREF (item_properties, ITEM_PROPERTY_HELP) = XCAR (item); + ASET (item_properties, ITEM_PROPERTY_HELP, XCAR (item)); start = item; item = XCDR (item); } @@ -7859,27 +7871,27 @@ parse_menu_item (item, notreal, inmenubar) } /* This is the real definition--the function to run. */ - AREF (item_properties, ITEM_PROPERTY_DEF) = item; + ASET (item_properties, ITEM_PROPERTY_DEF, item); /* Get enable property, if any. */ if (SYMBOLP (item)) { tem = Fget (item, Qmenu_enable); if (!NILP (Venable_disabled_menus_and_buttons)) - AREF (item_properties, ITEM_PROPERTY_ENABLE) = Qt; + ASET (item_properties, ITEM_PROPERTY_ENABLE, Qt); else if (!NILP (tem)) - AREF (item_properties, ITEM_PROPERTY_ENABLE) = tem; + ASET (item_properties, ITEM_PROPERTY_ENABLE, tem); } } else if (EQ (item_string, Qmenu_item) && CONSP (item)) { /* New format menu item. */ - AREF (item_properties, ITEM_PROPERTY_NAME) = XCAR (item); + ASET (item_properties, ITEM_PROPERTY_NAME, XCAR (item)); start = XCDR (item); if (CONSP (start)) { /* We have a real binding. */ - AREF (item_properties, ITEM_PROPERTY_DEF) = XCAR (start); + ASET (item_properties, ITEM_PROPERTY_DEF, XCAR (start)); item = XCDR (start); /* Is there a cache list with key equivalences. */ @@ -7898,9 +7910,9 @@ parse_menu_item (item, notreal, inmenubar) if (EQ (tem, QCenable)) { if (!NILP (Venable_disabled_menus_and_buttons)) - AREF (item_properties, ITEM_PROPERTY_ENABLE) = Qt; + ASET (item_properties, ITEM_PROPERTY_ENABLE, Qt); else - AREF (item_properties, ITEM_PROPERTY_ENABLE) = XCAR (item); + ASET (item_properties, ITEM_PROPERTY_ENABLE, XCAR (item)); } else if (EQ (tem, QCvisible) && !notreal) { @@ -7911,7 +7923,7 @@ parse_menu_item (item, notreal, inmenubar) return 0; } else if (EQ (tem, QChelp)) - AREF (item_properties, ITEM_PROPERTY_HELP) = XCAR (item); + ASET (item_properties, ITEM_PROPERTY_HELP, XCAR (item)); else if (EQ (tem, QCfilter)) filter = item; else if (EQ (tem, QCkey_sequence)) @@ -7926,7 +7938,7 @@ parse_menu_item (item, notreal, inmenubar) { tem = XCAR (item); if (CONSP (tem) || (STRINGP (tem) && NILP (cachelist))) - AREF (item_properties, ITEM_PROPERTY_KEYEQ) = tem; + ASET (item_properties, ITEM_PROPERTY_KEYEQ, tem); } else if (EQ (tem, QCbutton) && CONSP (XCAR (item))) { @@ -7935,10 +7947,9 @@ parse_menu_item (item, notreal, inmenubar) type = XCAR (tem); if (EQ (type, QCtoggle) || EQ (type, QCradio)) { - AREF (item_properties, ITEM_PROPERTY_SELECTED) - = XCDR (tem); - AREF (item_properties, ITEM_PROPERTY_TYPE) - = type; + ASET (item_properties, ITEM_PROPERTY_SELECTED, + XCDR (tem)); + ASET (item_properties, ITEM_PROPERTY_TYPE, type); } } item = XCDR (item); @@ -7958,7 +7969,7 @@ parse_menu_item (item, notreal, inmenubar) item_string = menu_item_eval_property (item_string); if (!STRINGP (item_string)) return 0; - AREF (item_properties, ITEM_PROPERTY_NAME) = item_string; + ASET (item_properties, ITEM_PROPERTY_NAME, item_string); } /* If got a filter apply it on definition. */ @@ -7968,7 +7979,7 @@ parse_menu_item (item, notreal, inmenubar) def = menu_item_eval_property (list2 (XCAR (filter), list2 (Qquote, def))); - AREF (item_properties, ITEM_PROPERTY_DEF) = def; + ASET (item_properties, ITEM_PROPERTY_DEF, def); } /* Enable or disable selection of item. */ @@ -7981,7 +7992,7 @@ parse_menu_item (item, notreal, inmenubar) tem = menu_item_eval_property (tem); if (inmenubar && NILP (tem)) return 0; /* Ignore disabled items in menu bar. */ - AREF (item_properties, ITEM_PROPERTY_ENABLE) = tem; + ASET (item_properties, ITEM_PROPERTY_ENABLE, tem); } /* If we got no definition, this item is just unselectable text which @@ -7995,8 +8006,8 @@ parse_menu_item (item, notreal, inmenubar) /* For a subkeymap, just record its details and exit. */ if (CONSP (tem)) { - AREF (item_properties, ITEM_PROPERTY_MAP) = tem; - AREF (item_properties, ITEM_PROPERTY_DEF) = tem; + ASET (item_properties, ITEM_PROPERTY_MAP, tem); + ASET (item_properties, ITEM_PROPERTY_DEF, tem); return 1; } @@ -8110,7 +8121,8 @@ parse_menu_item (item, notreal, inmenubar) tem = XCDR (cachelist); if (newcache && !NILP (tem)) { - tem = concat3 (build_string (" ("), tem, build_string (")")); + tem = concat2 (build_string (" "), tem); + // tem = concat3 (build_string (" ("), tem, build_string (")")); XSETCDR (cachelist, tem); } @@ -8119,7 +8131,7 @@ parse_menu_item (item, notreal, inmenubar) return 1; /* If we have an equivalent key binding, use that. */ - AREF (item_properties, ITEM_PROPERTY_KEYEQ) = tem; + ASET (item_properties, ITEM_PROPERTY_KEYEQ, tem); /* Include this when menu help is implemented. tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]; @@ -8135,8 +8147,8 @@ parse_menu_item (item, notreal, inmenubar) /* Handle radio buttons or toggle boxes. */ tem = AREF (item_properties, ITEM_PROPERTY_SELECTED); if (!NILP (tem)) - AREF (item_properties, ITEM_PROPERTY_SELECTED) - = menu_item_eval_property (tem); + ASET (item_properties, ITEM_PROPERTY_SELECTED, + menu_item_eval_property (tem)); return 1; } @@ -9195,6 +9207,11 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, /* Likewise, for key_translation_map and input-decode-map. */ volatile keyremap keytran, indec; + /* Non-zero if we are trying to map a key by changing an upper-case + letter to lower case, or a shifted function key to an unshifted + one. */ + volatile int shift_translated = 0; + /* If we receive a `switch-frame' or `select-window' event in the middle of a key sequence, we put it off for later. While we're reading, we keep the event here. */ @@ -9590,7 +9607,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, } GROW_RAW_KEYBUF; - ASET (raw_keybuf, raw_keybuf_count++, key); + ASET (raw_keybuf, raw_keybuf_count, key); + raw_keybuf_count++; } /* Clicks in non-text areas get prefixed by the symbol @@ -9617,7 +9635,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, { Lisp_Object window, posn; - window = POSN_WINDOW (EVENT_START (key)); + window = POSN_WINDOW (EVENT_START (key)); posn = POSN_POSN (EVENT_START (key)); if (CONSP (posn) @@ -10105,13 +10123,14 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, XSETINT (new_key, XINT (key) & ~shift_modifier); else XSETINT (new_key, (DOWNCASE (XINT (key) & ~CHAR_MODIFIER_MASK) - | (XINT (key) & ~CHAR_MODIFIER_MASK))); + | (XINT (key) & CHAR_MODIFIER_MASK))); /* We have to do this unconditionally, regardless of whether the lower-case char is defined in the keymaps, because they might get translated through function-key-map. */ keybuf[t - 1] = new_key; mock_input = max (t, mock_input); + shift_translated = 1; goto replay_sequence; } @@ -10129,8 +10148,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, if (modifiers & shift_modifier /* Treat uppercase keys as shifted. */ || (INTEGERP (key) - & (KEY_TO_CHAR (key) - < XCHAR_TABLE (current_buffer->downcase_table)->size) + && (KEY_TO_CHAR (key) + < XCHAR_TABLE (current_buffer->downcase_table)->size) && UPPERCASEP (KEY_TO_CHAR (key)))) { Lisp_Object new_key @@ -10153,6 +10172,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, input-decode-map doesn't need to go through it again. */ fkey.start = fkey.end = 0; keytran.start = keytran.end = 0; + shift_translated = 1; goto replay_sequence; } @@ -10171,7 +10191,13 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, if ((dont_downcase_last || first_binding >= nmaps) && t > 0 && t - 1 == original_uppercase_position) - keybuf[t - 1] = original_uppercase; + { + keybuf[t - 1] = original_uppercase; + shift_translated = 0; + } + + if (shift_translated) + Vthis_command_keys_shift_translated = Qt; /* Occasionally we fabricate events, perhaps by expanding something according to function-key-map, or by adding a prefix symbol to a @@ -10190,8 +10216,6 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, add_command_key (keybuf[t]); } - - UNGCPRO; return t; } @@ -10273,7 +10297,7 @@ will read just one key sequence. */) this_single_command_key_start = 0; } -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) cancel_hourglass (); #endif @@ -10285,7 +10309,7 @@ will read just one key sequence. */) #if 0 /* The following is fine for code reading a key sequence and then proceeding with a lenghty computation, but it's not good for code reading keys in a loop, like an input method. */ -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) start_hourglass (); #endif @@ -10333,7 +10357,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, this_single_command_key_start = 0; } -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) cancel_hourglass (); #endif @@ -10342,7 +10366,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, prompt, ! NILP (dont_downcase_last), ! NILP (can_return_switch_frame), 0); -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) start_hourglass (); #endif @@ -10465,7 +10489,7 @@ give to the command you invoke, if it asks for an argument. */) Lisp_Object saved_keys, saved_last_point_position_buffer; Lisp_Object bindings, value; struct gcpro gcpro1, gcpro2, gcpro3; -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM /* The call to Fcompleting_read wil start and cancel the hourglass, but if the hourglass was already scheduled, this means that no hourglass will be shown for the actual M-x command itself. @@ -10505,7 +10529,7 @@ give to the command you invoke, if it asks for an argument. */) Qt, Qnil, Qextended_command_history, Qnil, Qnil); -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM if (hstarted) start_hourglass (); #endif @@ -11726,6 +11750,8 @@ struct event_head head_table[] = { void syms_of_keyboard () { + pending_funcalls = Qnil; + Vpre_help_message = Qnil; staticpro (&Vpre_help_message); @@ -12083,6 +12109,14 @@ The command can set this variable; whatever is put here will be in `last-command' during the following command. */); Vthis_command = Qnil; + DEFVAR_LISP ("this-command-keys-shift-translated", + &Vthis_command_keys_shift_translated, + doc: /* Non-nil if the key sequence activating this command was shift-translated. +Shift-translation occurs when there is no binding for the key sequence +as entered, but a binding was found by changing an upper-case letter +to lower-case, or a shifted function key to an unshifted one. */); + Vthis_command_keys_shift_translated = Qnil; + DEFVAR_LISP ("this-original-command", &Vthis_original_command, doc: /* The command bound to the current key sequence before remapping. It equals `this-command' if the original command was not remapped through