Mercurial > emacs
changeset 10861:655e3daa560c
(cmd_error): Use clear_prefix_arg.
(internal_last_event_frame, Vlast_event_frame): Normal vars again.
All uses changed.
(Quniversal_argument, Qdigit_argument, Qnegative_argument): Declare.
(clear_prefix_arg, finalize_prefix_arg, describe_prefix_arg): New fns.
(command_loop_1): Handle digits and minus specially, when they're
part of a prefix arg.
Handle universal-argument and digit-argument and negative-argument
bindings here, rather than doing I/O in the Lisp code.
(read_char): When reading switch-frame events from the side queue,
set internal_last_event_frame.
(readable_events): Return non-zero if a side queue has data.
(kbd_buffer_get_event): Don't abort if event has no associated frame.
(read_key_sequence): Improve behavior when there's no current display.
(init_perdisplay): Initialize the new members.
author | Karl Heuer <kwzh@gnu.org> |
---|---|
date | Wed, 01 Mar 1995 04:27:37 +0000 |
parents | 9f9a34e401d5 |
children | b905092475a7 |
files | src/keyboard.c |
diffstat | 1 files changed, 181 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
--- a/src/keyboard.c Wed Mar 01 03:45:45 1995 +0000 +++ b/src/keyboard.c Wed Mar 01 04:27:37 1995 +0000 @@ -259,6 +259,20 @@ /* The buffer that was current when the last command was started. */ Lisp_Object last_point_position_buffer; +#ifdef MULTI_FRAME +/* The frame in which the last input event occurred, or Qmacro if the + last event came from a macro. We use this to determine when to + generate switch-frame events. This may be cleared by functions + like Fselect_frame, to make sure that a switch-frame event is + generated by the next character. */ +Lisp_Object internal_last_event_frame; +#endif + +/* A user-visible version of the above, intended to allow users to + figure out where the last event came from, if the event doesn't + carry that information itself (i.e. if it was a character). */ +Lisp_Object Vlast_event_frame; + /* The timestamp of the last input event we received from the X server. X Windows wants this for selection ownership. */ unsigned long last_event_timestamp; @@ -267,6 +281,7 @@ Lisp_Object Qforward_char; Lisp_Object Qbackward_char; Lisp_Object Qundefined; +Lisp_Object Quniversal_argument, Qdigit_argument, Qnegative_argument; /* read_key_sequence stores here the command definition of the key sequence that it reads. */ @@ -753,9 +768,7 @@ Vstandard_output = Qt; Vstandard_input = Qt; Vexecuting_macro = Qnil; - if (!current_perdisplay) - abort (); - current_perdisplay->Vprefix_arg = Qnil; + clear_prefix_arg (); cancel_echoing (); cmd_error_internal (data, 0); @@ -943,6 +956,43 @@ error ("No recursive edit is in progress"); } +void +clear_prefix_arg () +{ + if (!current_perdisplay) + abort (); + current_perdisplay->prefix_factor = Qnil; + current_perdisplay->prefix_value = Qnil; + current_perdisplay->prefix_sign = 1; + current_perdisplay->prefix_partial = 0; + Vprefix_arg = Qnil; +} + +static void +finalize_prefix_arg () +{ + if (!NILP (current_perdisplay->prefix_factor)) + Vprefix_arg = Fcons (current_perdisplay->prefix_factor, Qnil); + else if (NILP (current_perdisplay->prefix_value)) + Vprefix_arg = (current_perdisplay->prefix_sign > 0 ? Qnil : Qminus); + else if (current_perdisplay->prefix_sign > 0) + Vprefix_arg = current_perdisplay->prefix_value; + else + XSETINT (Vprefix_arg, -XINT (current_perdisplay->prefix_value)); + current_perdisplay->prefix_partial = 0; +} + +static void +describe_prefix_arg () +{ + if (INTEGERP (Vprefix_arg)) + message ("Arg: %d", Vprefix_arg); + else if (CONSP (Vprefix_arg)) + message ("Arg: [%d]", XCONS (Vprefix_arg)->car); + else if (EQ (Vprefix_arg, Qminus)) + message ("Arg: -"); +} + /* This is the actual command reading loop, sans error-handling encapsulation. */ @@ -1096,6 +1146,16 @@ last_point_position = PT; XSETBUFFER (last_point_position_buffer, prev_buffer); + /* If we're building a prefix argument, override minus and digits. */ + if (current_perdisplay->prefix_partial && i == 1 && NATNUMP (keybuf[0])) + { + if (XFASTINT (keybuf[0]) == '-' + && NILP (current_perdisplay->prefix_value)) + cmd = Qnegative_argument; + else if (XFASTINT (keybuf[0]) >= '0' && XFASTINT (keybuf[0]) <= '9') + cmd = Qdigit_argument; + } + /* Execute the command. */ this_command = cmd; @@ -1110,12 +1170,56 @@ bitch_at_user (); defining_kbd_macro = 0; update_mode_lines = 1; - current_perdisplay->Vprefix_arg = Qnil; - + clear_prefix_arg (); } else { - if (NILP (current_perdisplay->Vprefix_arg) && ! no_direct) + if (EQ (cmd, Quniversal_argument)) + { + if (!current_perdisplay->prefix_partial) + { + /* First C-u */ + XSETFASTINT (current_perdisplay->prefix_factor, 4); + current_perdisplay->prefix_value = Qnil; + current_perdisplay->prefix_sign = 1; + current_perdisplay->prefix_partial = 1; + } + else if (!NILP (current_perdisplay->prefix_factor)) + { + /* Subsequent C-u */ + XSETINT (current_perdisplay->prefix_factor, + XINT (current_perdisplay->prefix_factor) * 4); + } + else + { + /* Terminating C-u */ + finalize_prefix_arg (); + describe_prefix_arg (); + } + goto directly_done; + } + else if (EQ (cmd, Qnegative_argument)) + { + current_perdisplay->prefix_factor = Qnil; + current_perdisplay->prefix_sign *= -1; + current_perdisplay->prefix_partial = 1; + goto directly_done; + } + else if (EQ (cmd, Qdigit_argument) && INTEGERP (keybuf[0])) + { + current_perdisplay->prefix_factor = Qnil; + if (NILP (current_perdisplay->prefix_value)) + XSETFASTINT (current_perdisplay->prefix_value, 0); + XSETINT (current_perdisplay->prefix_value, + (XINT (current_perdisplay->prefix_value) * 10 + + (XINT (keybuf[0]) & 0177) - '0')); + current_perdisplay->prefix_partial = 1; + goto directly_done; + } + if (current_perdisplay->prefix_partial) + finalize_prefix_arg (); + + if (NILP (Vprefix_arg) && ! no_direct) { /* Recognize some common commands in common situations and do them directly. */ @@ -1238,7 +1342,7 @@ /* Here for a command that isn't executed directly */ nonundocount = 0; - if (NILP (current_perdisplay->Vprefix_arg)) + if (NILP (Vprefix_arg)) Fundo_boundary (); Fcommand_execute (this_command, Qnil); @@ -1262,7 +1366,7 @@ 3) we want to leave this_command_key_count non-zero, so that read_char will realize that it is re-reading a character, and not echo it a second time. */ - if (NILP (current_perdisplay->Vprefix_arg)) + if (NILP (Vprefix_arg)) { last_command = this_command; cancel_echoing (); @@ -1283,7 +1387,7 @@ finalize: /* Install chars successfully executed in kbd macro. */ - if (defining_kbd_macro && NILP (current_perdisplay->Vprefix_arg)) + if (defining_kbd_macro && NILP (Vprefix_arg)) finalize_kbd_macro_chars (); #ifdef MULTI_PERDISPLAY @@ -1546,10 +1650,7 @@ internal_last_event_frame after each command is read, but events read from a macro should never cause a new frame to be selected. */ - if (!current_perdisplay) - abort (); - current_perdisplay->internal_last_event_frame = Qmacro; - current_perdisplay->Vlast_event_frame = Qmacro; + Vlast_event_frame = internal_last_event_frame = Qmacro; #endif /* Exit the macro if we are at the end. @@ -1600,10 +1701,8 @@ { XSETINT (c, quit_char); #ifdef MULTI_FRAME - XSETFRAME (current_perdisplay->internal_last_event_frame, - selected_frame); - current_perdisplay->Vlast_event_frame - = current_perdisplay->internal_last_event_frame; + XSETFRAME (internal_last_event_frame, selected_frame); + Vlast_event_frame = internal_last_event_frame; #endif /* If we report the quit char as an event, don't do so more than once. */ @@ -1766,6 +1865,13 @@ { c = XCONS (perd->kbd_queue)->car; perd->kbd_queue = XCONS (perd->kbd_queue)->cdr; + input_pending = readable_events (); +#ifdef MULTI_FRAME + if (EVENT_HAS_PARAMETERS (c) + && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qswitch_frame)) + internal_last_event_frame = XCONS (XCONS (c)->cdr)->car; + Vlast_event_frame = internal_last_event_frame; +#endif } else { @@ -2081,6 +2187,18 @@ if (FRAMEP (do_mouse_tracking) && mouse_moved) return 1; #endif + if (display_locked) + { + if (CONSP (current_perdisplay->kbd_queue)) + return 1; + } + else + { + PERDISPLAY *perd; + for (perd = all_perdisplays; perd; perd = perd->next_perdisplay) + if (CONSP (perd->kbd_queue)) + return 1; + } return 0; } @@ -2118,14 +2236,12 @@ will set Vlast_event_frame again, so this is safe to do. */ { Lisp_Object focus; - PERDISPLAY *perd; focus = FRAME_FOCUS_FRAME (XFRAME (event->frame_or_window)); if (NILP (focus)) focus = event->frame_or_window; - perd = get_perdisplay (XFRAME (focus)); - perd->internal_last_event_frame = focus; - perd->Vlast_event_frame = focus; + internal_last_event_frame = focus; + Vlast_event_frame = focus; } #endif @@ -2261,9 +2377,12 @@ frame = XCONS (frame)->car; else if (WINDOWP (frame)) frame = WINDOW_FRAME (XWINDOW (frame)); + /* There are still some events that don't set this field. + For now, just ignore the problem. */ if (!FRAMEP (frame)) - abort (); - *perdp = get_perdisplay (XFRAME (frame)); + *perdp = all_perdisplays; + else + *perdp = get_perdisplay (XFRAME (frame)); } obj = Qnil; @@ -2357,10 +2476,10 @@ if (! NILP (focus)) frame = focus; - if (! EQ (frame, (*perdp)->internal_last_event_frame) + if (! EQ (frame, internal_last_event_frame) && XFRAME (frame) != selected_frame) obj = make_lispy_switch_frame (frame); - (*perdp)->internal_last_event_frame = frame; + internal_last_event_frame = frame; #endif /* MULTI_FRAME */ /* If we didn't decide to make a switch-frame event, go ahead @@ -2412,10 +2531,10 @@ if (NILP (frame)) XSETFRAME (frame, f); - if (! EQ (frame, (*perdp)->internal_last_event_frame) + if (! EQ (frame, internal_last_event_frame) && XFRAME (frame) != selected_frame) obj = make_lispy_switch_frame (frame); - (*perdp)->internal_last_event_frame = frame; + internal_last_event_frame = frame; } #endif @@ -2433,7 +2552,7 @@ input_pending = readable_events (); #ifdef MULTI_FRAME - (*perdp)->Vlast_event_frame = (*perdp)->internal_last_event_frame; + Vlast_event_frame = internal_last_event_frame; #endif return (obj); @@ -4801,7 +4920,7 @@ /* Record the initial state of the echo area and this_command_keys; we will need to restore them if we replay a key sequence. */ if (INTERACTIVE) - echo_start = echo_length (); + echo_start = (current_perdisplay ? echo_length () : 0); keys_start = this_command_key_count; #if defined (GOBBLE_FIRST_EVENT) @@ -4875,7 +4994,7 @@ /* These are no-ops the first time through, but if we restart, they revert the echo area and this_command_keys to their original state. */ this_command_key_count = keys_start; - if (INTERACTIVE && t < mock_input) + if (INTERACTIVE && t < mock_input && current_perdisplay) echo_truncate (echo_start); /* If the best binding for the current key sequence is a keymap, or @@ -5687,9 +5806,9 @@ struct backtrace backtrace; extern int debug_on_next_call; - prefixarg = current_perdisplay->Vprefix_arg; - current_perdisplay->Vprefix_arg = Qnil; - current_perdisplay->Vcurrent_prefix_arg = prefixarg; + prefixarg = Vprefix_arg; + clear_prefix_arg (); + Vcurrent_prefix_arg = prefixarg; debug_on_next_call = 0; if (SYMBOLP (cmd)) @@ -5805,7 +5924,7 @@ UNGCPRO; function = Fintern (function, Qnil); - current_perdisplay->Vprefix_arg = prefixarg; + Vprefix_arg = prefixarg; this_command = function; return Fcommand_execute (function, Qt); @@ -6183,15 +6302,9 @@ abort (); #endif #ifdef MULTI_FRAME - { - Lisp_Object frame; - - if (!current_perdisplay) - abort (); - frame = current_perdisplay->internal_last_event_frame; - if (FRAMEP (frame) && XFRAME (frame) != selected_frame) - Fhandle_switch_frame (make_lispy_switch_frame (frame)); - } + if (FRAMEP (internal_last_event_frame) + && XFRAME (internal_last_event_frame) != selected_frame) + Fhandle_switch_frame (make_lispy_switch_frame (internal_last_event_frame)); #endif _longjmp (getcjmp, 1); @@ -6289,15 +6402,11 @@ init_perdisplay (perd) PERDISPLAY *perd; { - perd->Vprefix_arg = Qnil; - perd->Vcurrent_prefix_arg = Qnil; -#ifdef MULTI_FRAME - /* This means that command_loop_1 won't try to select anything the first - time through. */ - perd->internal_last_event_frame = Qnil; -#endif + perd->prefix_factor = Qnil; + perd->prefix_value = Qnil; + perd->prefix_sign = 1; + perd->prefix_partial = 0; perd->kbd_queue = Qnil; - perd->Vlast_event_frame = Qnil; perd->immediate_echo = 0; perd->echoptr = perd->echobuf; perd->echo_after_prompt = -1; @@ -6335,6 +6444,13 @@ #endif input_pending = 0; +#ifdef MULTI_FRAME + /* This means that command_loop_1 won't try to select anything the first + time through. */ + internal_last_event_frame = Qnil; + Vlast_event_frame = internal_last_event_frame; +#endif + #ifndef MULTI_PERDISPLAY if (initialized) wipe_perdisplay (&the_only_perdisplay); @@ -6424,6 +6540,15 @@ Qundefined = intern ("undefined"); staticpro (&Qundefined); + Quniversal_argument = intern ("universal-argument"); + staticpro (&Quniversal_argument); + + Qdigit_argument = intern ("digit-argument"); + staticpro (&Qdigit_argument); + + Qnegative_argument = intern ("negative-argument"); + staticpro (&Qnegative_argument); + Qpre_command_hook = intern ("pre-command-hook"); staticpro (&Qpre_command_hook); @@ -6641,6 +6766,11 @@ "Number of complete keys read from the keyboard so far."); num_input_keys = 0; + DEFVAR_LISP ("last-event-frame", &Vlast_event_frame, + "The frame in which the most recently read event occurred.\n\ +If the last event came from a keyboard macro, this is set to `macro'."); + Vlast_event_frame = Qnil; + DEFVAR_LISP ("help-char", &Vhelp_char, "Character to recognize as meaning Help.\n\ When it is read, do `(eval help-form)', and display result if it's a string.\n\ @@ -6781,28 +6911,6 @@ This function is called with no arguments after each command\n\ whenever `deferred-action-list' is non-nil."); Vdeferred_action_function = Qnil; - - DEFVAR_DISPLAY ("prefix-arg", Vprefix_arg, - "The value of the prefix argument for the next editing command.\n\ -It may be a number, or the symbol `-' for just a minus sign as arg,\n\ -or a list whose car is a number for just one or more C-U's\n\ -or nil if no argument has been specified.\n\ -\n\ -You cannot examine this variable to find the argument for this command\n\ -since it has been set to nil by the time you can look.\n\ -Instead, you should use the variable `current-prefix-arg', although\n\ -normally commands can get this prefix argument with (interactive \"P\")."); - - DEFVAR_DISPLAY ("current-prefix-arg", Vcurrent_prefix_arg, - "The value of the prefix argument for this editing command.\n\ -It may be a number, or the symbol `-' for just a minus sign as arg,\n\ -or a list whose car is a number for just one or more C-U's\n\ -or nil if no argument has been specified.\n\ -This is what `(interactive \"P\")' returns."); - - DEFVAR_DISPLAY ("last-event-frame", Vlast_event_frame, - "The frame in which the most recently read event occurred.\n\ -If the last event came from a keyboard macro, this is set to `macro'."); } keys_of_keyboard ()