]> git.eshelyaron.com Git - emacs.git/commitdiff
(cmd_error): Use clear_prefix_arg.
authorKarl Heuer <kwzh@gnu.org>
Wed, 1 Mar 1995 04:27:37 +0000 (04:27 +0000)
committerKarl Heuer <kwzh@gnu.org>
Wed, 1 Mar 1995 04:27:37 +0000 (04:27 +0000)
(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.

src/keyboard.c

index c85cffa87833baad2c051ecd0da2f039a93a4c10..fd524fe51052ec916198f0b648b7db54a25af33f 100644 (file)
@@ -259,6 +259,20 @@ int last_point_position;
 /* 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 Qself_insert_command;
 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 @@ cmd_error (data)
   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 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0,
   error ("No recursive edit is in progress");
 }
 \f
+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: -");
+}
+\f
 /* This is the actual command reading loop,
    sans error-handling encapsulation.  */
 
@@ -1096,6 +1146,16 @@ command_loop_1 ()
       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 @@ command_loop_1 ()
          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 @@ command_loop_1 ()
          /* 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 @@ command_loop_1 ()
         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 @@ command_loop_1 ()
     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 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
         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 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
     {
       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 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
        {
          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 @@ readable_events ()
   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 @@ kbd_buffer_store_event (event)
             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 @@ kbd_buffer_get_event (PERDISPLAY **perdp)
          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 @@ kbd_buffer_get_event (PERDISPLAY **perdp)
          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 @@ kbd_buffer_get_event (PERDISPLAY **perdp)
          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 @@ kbd_buffer_get_event (PERDISPLAY **perdp)
   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 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last)
   /* 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 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last)
   /* 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 @@ Otherwise, that is done only if an arg is read using the minibuffer.")
   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 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_
   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 @@ quit_throw_to_read_char ()
     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 @@ void
 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 @@ init_keyboard ()
 #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 @@ syms_of_keyboard ()
   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 @@ by position only.");
     "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 @@ The precise format isn't relevant here; we just check whether it is nil.");
 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 ()