Mercurial > emacs
changeset 22945:58a8427745ec
(Vthis_command): Renamed from this_command.
(real_this_command): New variable, but not a Lisp variable;
updated like Vthis_command, but never altered by Lisp programs.
(command_loop_1): Use real_this_command to set Vreal_last_command.
(read_char): When input method returns no chars, call cancel_echoing.
Restore the previous echo area message and this_command_keys, too.
(Vinput_method_previous_message): New variable.
(syms_of_keyboard): Set up lisp variable.
(Qinput_method_exit_on_first_char, Qinput_method_use_echo_area): New variables.
(syms_of_keyboard): Initialize them.
(Fread_key_sequence): New arg COMMAND_LOOP.
Bind those variables.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sat, 08 Aug 1998 03:13:39 +0000 |
parents | c2bb9ab28588 |
children | cfde96067373 |
files | src/keyboard.c |
diffstat | 1 files changed, 129 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
--- a/src/keyboard.c Sat Aug 08 03:02:37 1998 +0000 +++ b/src/keyboard.c Sat Aug 08 03:13:39 1998 +0000 @@ -317,7 +317,10 @@ /* The command being executed by the command loop. Commands may set this, and the value set will be copied into current_kboard->Vlast_command instead of the actual command. */ -Lisp_Object this_command; +Lisp_Object Vthis_command; + +/* This is like Vthis_command, except that commands never set it. */ +Lisp_Object real_this_command; /* The value of point when the last command was executed. */ int last_point_position; @@ -368,6 +371,10 @@ Lisp_Object Vinput_method_function; Lisp_Object Qinput_method_function; +/* When we call Vinput_method_function, + this holds the echo area message that was just erased. */ +Lisp_Object Vinput_method_previous_message; + /* Non-nil means deactivate the mark at end of this command. */ Lisp_Object Vdeactivate_mark; @@ -396,6 +403,9 @@ Lisp_Object Vdeferred_action_function; Lisp_Object Qdeferred_action_function; +Lisp_Object Qinput_method_exit_on_first_char; +Lisp_Object Qinput_method_use_echo_area; + /* File in which we write all commands we read. */ FILE *dribble; @@ -1185,8 +1195,8 @@ } /* Do this after running Vpost_command_hook, for consistency. */ - current_kboard->Vlast_command = this_command; - current_kboard->Vreal_last_command = this_command; + current_kboard->Vlast_command = Vthis_command; + current_kboard->Vreal_last_command = real_this_command; while (1) { @@ -1253,7 +1263,8 @@ before_command_key_count = this_command_key_count; before_command_echo_length = echo_length (); - this_command = Qnil; + Vthis_command = Qnil; + real_this_command = Qnil; /* Read next key sequence; i gets its length. */ i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0], @@ -1318,13 +1329,14 @@ /* Execute the command. */ - this_command = cmd; + Vthis_command = cmd; + real_this_command = cmd; /* Note that the value cell will never directly contain nil if the symbol is a local variable. */ if (!NILP (Vpre_command_hook) && !NILP (Vrun_hooks)) safe_run_hooks (Qpre_command_hook); - if (NILP (this_command)) + if (NILP (Vthis_command)) { /* nil means key is undefined. */ bitch_at_user (); @@ -1341,7 +1353,7 @@ /* Recognize some common commands in common situations and do them directly. */ - if (EQ (this_command, Qforward_char) && PT < ZV) + if (EQ (Vthis_command, Qforward_char) && PT < ZV) { struct Lisp_Char_Table *dp = window_display_table (XWINDOW (selected_window)); @@ -1370,7 +1382,7 @@ no_redisplay = direct_output_forward_char (1); goto directly_done; } - else if (EQ (this_command, Qbackward_char) && PT > BEGV) + else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV) { struct Lisp_Char_Table *dp = window_display_table (XWINDOW (selected_window)); @@ -1396,7 +1408,7 @@ no_redisplay = direct_output_forward_char (-1); goto directly_done; } - else if (EQ (this_command, Qself_insert_command) + else if (EQ (Vthis_command, Qself_insert_command) /* Try this optimization only on ascii keystrokes. */ && INTEGERP (last_command_char)) { @@ -1480,7 +1492,7 @@ nonundocount = 0; if (NILP (current_kboard->Vprefix_arg)) Fundo_boundary (); - Fcommand_execute (this_command, Qnil, Qnil, Qnil); + Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil); } directly_done: ; current_kboard->Vlast_prefix_arg = Vcurrent_prefix_arg; @@ -1518,8 +1530,8 @@ then the above doesn't apply. */ if (NILP (current_kboard->Vprefix_arg) || CONSP (last_command_char)) { - current_kboard->Vlast_command = this_command; - current_kboard->Vreal_last_command = this_command; + current_kboard->Vlast_command = Vthis_command; + current_kboard->Vreal_last_command = real_this_command; cancel_echoing (); this_command_key_count = 0; this_single_command_key_start = 0; @@ -1788,17 +1800,19 @@ jmp_buf save_jump; int key_already_recorded = 0; Lisp_Object tem, save; + Lisp_Object echo_area_message; Lisp_Object also_record; int reread; - struct gcpro gcpro1; + struct gcpro gcpro1, gcpro2; also_record = Qnil; before_command_key_count = this_command_key_count; before_command_echo_length = echo_length (); c = Qnil; - - GCPRO1 (c); + echo_area_message = Qnil; + + GCPRO2 (c, echo_area_message); retry: @@ -2274,11 +2288,6 @@ goto retry; } - /* Wipe the echo area. */ - if (echo_area_glyphs) - safe_run_hooks (Qecho_area_clear_hook); - echo_area_glyphs = 0; - /* Handle things that only apply to characters. */ if (INTEGERP (c)) { @@ -2331,27 +2340,53 @@ if (! NILP (also_record)) record_char (also_record); + /* Wipe the echo area. + But first, if we are about to use an input method, + save the echo area contents for it to refer to. */ + if (INTEGERP (c) + && ! NILP (Vinput_method_function) + && (unsigned) XINT (c) >= ' ' + && (unsigned) XINT (c) < 127) + Vinput_method_previous_message = echo_area_message = Fcurrent_message (); + + /* Now wipe the echo area. */ + if (echo_area_glyphs) + safe_run_hooks (Qecho_area_clear_hook); + echo_area_glyphs = 0; + reread_for_input_method: from_macro: /* Pass this to the input method, if appropriate. */ - if (INTEGERP (c)) - { - /* If this is a printing character, run the input method. */ - if (! NILP (Vinput_method_function) - && (unsigned) XINT (c) >= ' ' - && (unsigned) XINT (c) < 127) + if (INTEGERP (c) + && ! NILP (Vinput_method_function) + && (unsigned) XINT (c) >= ' ' + && (unsigned) XINT (c) < 127) + { + Lisp_Object keys; + int key_count = this_command_key_count - 1; + int saved = current_kboard->immediate_echo; + struct gcpro gcpro1; + + keys = Fcopy_sequence (this_command_keys); + GCPRO1 (keys); + tem = call1 (Vinput_method_function, c); + UNGCPRO; + current_kboard->immediate_echo = saved; + /* The input method can return no events. */ + if (! CONSP (tem)) { - int saved = current_kboard->immediate_echo; - tem = call1 (Vinput_method_function, c); - current_kboard->immediate_echo = saved; - /* The input method can return no events. */ - if (! CONSP (tem)) - goto retry; - /* It returned one event or more. */ - c = XCONS (tem)->car; - Vunread_post_input_method_events - = nconc2 (XCONS (tem)->cdr, Vunread_post_input_method_events); + /* Bring back the previous message, if any. */ + if (! NILP (Vinput_method_previous_message)) + message_with_string ("%s", echo_area_message, 0); + this_command_keys = keys; + this_command_key_count = key_count; + cancel_echoing (); + goto retry; } + /* It returned one event or more. */ + c = XCONS (tem)->car; + Vunread_post_input_method_events + = nconc2 (XCONS (tem)->cdr, Vunread_post_input_method_events); } reread_first: @@ -7611,24 +7646,36 @@ \n\ `read-key-sequence' checks `function-key-map' for function key\n\ sequences, where they wouldn't conflict with ordinary bindings. See\n\ -`function-key-map' for more details.") +`function-key-map' for more details.\n\ +\n\ +The optional fifth argument COMMAND-LOOP, if non-nil, means\n\ +that this key sequence is being read by something that will\n\ +read commands one after another. It should be nil if the caller\n\ +will read just one key sequence.") (prompt, continue_echo, dont_downcase_last, can_return_switch_frame) #endif -DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 4, 0, +DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0, 0) - (prompt, continue_echo, dont_downcase_last, can_return_switch_frame) + (prompt, continue_echo, dont_downcase_last, can_return_switch_frame, + command_loop) Lisp_Object prompt, continue_echo, dont_downcase_last; - Lisp_Object can_return_switch_frame; + Lisp_Object can_return_switch_frame, command_loop; { Lisp_Object keybuf[30]; register int i; struct gcpro gcpro1, gcpro2; + int count = specpdl_ptr - specpdl; if (!NILP (prompt)) CHECK_STRING (prompt, 0); QUIT; + specbind (Qinput_method_exit_on_first_char, + (NILP (command_loop) ? Qt : Qnil)); + specbind (Qinput_method_use_echo_area, + (NILP (command_loop) ? Qt : Qnil)); + bzero (keybuf, sizeof keybuf); GCPRO1 (keybuf[0]); gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0])); @@ -7649,24 +7696,31 @@ QUIT; } UNGCPRO; - return make_event_array (i, keybuf); + return unbind_to (count, make_event_array (i, keybuf)); } DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector, - Sread_key_sequence_vector, 1, 4, 0, + Sread_key_sequence_vector, 1, 5, 0, "Like `read-key-sequence' but always return a vector.") - (prompt, continue_echo, dont_downcase_last, can_return_switch_frame) + (prompt, continue_echo, dont_downcase_last, can_return_switch_frame, + command_loop) Lisp_Object prompt, continue_echo, dont_downcase_last; - Lisp_Object can_return_switch_frame; + Lisp_Object can_return_switch_frame, command_loop; { Lisp_Object keybuf[30]; register int i; struct gcpro gcpro1, gcpro2; + int count = specpdl_ptr - specpdl; if (!NILP (prompt)) CHECK_STRING (prompt, 0); QUIT; + specbind (Qinput_method_exit_on_first_char, + (NILP (command_loop) ? Qt : Qnil)); + specbind (Qinput_method_use_echo_area, + (NILP (command_loop) ? Qt : Qnil)); + bzero (keybuf, sizeof keybuf); GCPRO1 (keybuf[0]); gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0])); @@ -7687,7 +7741,7 @@ QUIT; } UNGCPRO; - return Fvector (i, keybuf); + return unbind_to (count, Fvector (i, keybuf)); } DEFUN ("command-execute", Fcommand_execute, Scommand_execute, 1, 4, 0, @@ -7870,7 +7924,8 @@ function = Fintern (function, Qnil); current_kboard->Vprefix_arg = prefixarg; - this_command = function; + Vthis_command = function; + real_this_command = function; /* If enabled, show which key runs this command. */ if (!NILP (Vsuggest_key_bindings) @@ -8736,6 +8791,9 @@ staticpro (&item_properties); item_properties = Qnil; + staticpro (&real_this_command); + real_this_command = Qnil; + Qtimer_event_handler = intern ("timer-event-handler"); staticpro (&Qtimer_event_handler); @@ -8844,6 +8902,14 @@ Qinput_method_function = intern ("input-method-function"); staticpro (&Qinput_method_function); + Qinput_method_exit_on_first_char = intern ("input-method-exit-on-first-char"); + staticpro (&Qinput_method_exit_on_first_char); + Qinput_method_use_echo_area = intern ("input-method-use-echo-area"); + staticpro (&Qinput_method_use_echo_area); + + Fset (Qinput_method_exit_on_first_char, Qnil); + Fset (Qinput_method_use_echo_area, Qnil); + { struct event_head *p; @@ -9000,11 +9066,11 @@ DEFVAR_KBOARD ("real-last-command", Vreal_last_command, "Same as `last-command', but never altered by Lisp code."); - DEFVAR_LISP ("this-command", &this_command, + DEFVAR_LISP ("this-command", &Vthis_command, "The command now being executed.\n\ The command can set this variable; whatever is put here\n\ will be in `last-command' during the following command."); - this_command = Qnil; + Vthis_command = Qnil; DEFVAR_INT ("auto-save-interval", &auto_save_interval, "*Number of keyboard input characters between auto-saves.\n\ @@ -9247,8 +9313,22 @@ The function should return a list of zero or more events\n\ to be used as input. If it wants to put back some events\n\ to be reconsidered, separately, by the input method,\n\ -it can add them to the beginning of `unread-command-events'."); +it can add them to the beginning of `unread-command-events'.\n\ +\n\ +The input method function can find in `input-method-previous-method'\n\ +the previous echo area message.\n\ +\n\ +The input method function should refer to the variables\n\ +`input-method-use-echo-area' and `input-method-exit-on-first-char'\n\ +for guidance on what to do."); Vinput_method_function = Qnil; + + DEFVAR_LISP ("input-method-previous-message", + &Vinput_method_previous_message, + "When `input-mehod-function' is called, hold the previous echo area message.\n\ +This variable exists because `read-event' clears the echo area\n\ +before running the input method. It is nil if there was no message."); + Vinput_method_previous_message = Qnil; } void