* buffer.h (FETCH_MULTIBYTE_CHAR): Define as inline.
[bpt/emacs.git] / src / keyboard.c
index eb9152f..c0b2ba2 100644 (file)
@@ -30,8 +30,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "keyboard.h"
 #include "window.h"
 #include "commands.h"
-#include "buffer.h"
 #include "character.h"
+#include "buffer.h"
 #include "disptab.h"
 #include "dispextern.h"
 #include "syntax.h"
@@ -217,9 +217,6 @@ uintmax_t num_input_events;
 
 static EMACS_INT last_auto_save;
 
-/* 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 started.  */
 static ptrdiff_t last_point_position;
 
@@ -241,6 +238,7 @@ Lisp_Object internal_last_event_frame;
 Time last_event_timestamp;
 
 static Lisp_Object Qx_set_selection, Qhandle_switch_frame;
+static Lisp_Object Qhandle_select_window;
 Lisp_Object QPRIMARY;
 
 static Lisp_Object Qself_insert_command;
@@ -1197,6 +1195,12 @@ This also exits all active minibuffers.  */)
   Fthrow (Qtop_level, Qnil);
 }
 
+static void user_error (const char*) NO_RETURN;
+static void user_error (const char *msg)
+{
+  xsignal1 (Quser_error, build_string (msg));
+}
+
 static Lisp_Object Fexit_recursive_edit (void) NO_RETURN;
 DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, "",
        doc: /* Exit from the innermost recursive edit or minibuffer.  */)
@@ -1205,7 +1209,7 @@ DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0,
   if (command_loop_level > 0 || minibuf_level > 0)
     Fthrow (Qexit, Qnil);
 
-  error ("No recursive edit is in progress");
+  user_error ("No recursive edit is in progress");
 }
 
 static Lisp_Object Fabort_recursive_edit (void) NO_RETURN;
@@ -1216,7 +1220,7 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0,
   if (command_loop_level > 0 || minibuf_level > 0)
     Fthrow (Qexit, Qt);
 
-  error ("No recursive edit is in progress");
+  user_error ("No recursive edit is in progress");
 }
 \f
 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
@@ -1369,9 +1373,9 @@ command_loop_1 (void)
 
   /* Do this after running Vpost_command_hook, for consistency.  */
   KVAR (current_kboard, Vlast_command) = Vthis_command;
-  KVAR (current_kboard, Vreal_last_command) = real_this_command;
+  KVAR (current_kboard, Vreal_last_command) = Vreal_this_command;
   if (!CONSP (last_command_event))
-    KVAR (current_kboard, Vlast_repeatable_command) = real_this_command;
+    KVAR (current_kboard, Vlast_repeatable_command) = Vreal_this_command;
 
   while (1)
     {
@@ -1438,7 +1442,7 @@ command_loop_1 (void)
       before_command_echo_length = echo_length ();
 
       Vthis_command = Qnil;
-      real_this_command = Qnil;
+      Vreal_this_command = Qnil;
       Vthis_original_command = Qnil;
       Vthis_command_keys_shift_translated = Qnil;
 
@@ -1477,10 +1481,10 @@ command_loop_1 (void)
         from that position.  But also throw away beg_unchanged and
         end_unchanged information in that case, so that redisplay will
         update the whole window properly.  */
-      if (!NILP (XWINDOW (selected_window)->force_start))
+      if (XWINDOW (selected_window)->force_start)
        {
          struct buffer *b;
-         XWINDOW (selected_window)->force_start = Qnil;
+         XWINDOW (selected_window)->force_start = 0;
          b = XBUFFER (XWINDOW (selected_window)->buffer);
          BUF_BEG_UNCHANGED (b) = BUF_END_UNCHANGED (b) = 0;
        }
@@ -1522,7 +1526,7 @@ command_loop_1 (void)
       /* Execute the command.  */
 
       Vthis_command = cmd;
-      real_this_command = cmd;
+      Vreal_this_command = cmd;
       safe_run_hooks (Qpre_command_hook);
 
       already_adjusted = 0;
@@ -1606,12 +1610,14 @@ command_loop_1 (void)
         If the command didn't actually create a prefix arg,
         but is merely a frame event that is transparent to prefix args,
         then the above doesn't apply.  */
-      if (NILP (KVAR (current_kboard, Vprefix_arg)) || CONSP (last_command_event))
+      if (NILP (KVAR (current_kboard, Vprefix_arg))
+         || CONSP (last_command_event))
        {
          KVAR (current_kboard, Vlast_command) = Vthis_command;
-         KVAR (current_kboard, Vreal_last_command) = real_this_command;
+         KVAR (current_kboard, Vreal_last_command) = Vreal_this_command;
          if (!CONSP (last_command_event))
-           KVAR (current_kboard, Vlast_repeatable_command) = real_this_command;
+           KVAR (current_kboard, Vlast_repeatable_command)
+             = Vreal_this_command;
          cancel_echoing ();
          this_command_key_count = 0;
          this_command_key_count_reset = 0;
@@ -1645,7 +1651,8 @@ command_loop_1 (void)
                      ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
                      : (!NILP (Vselect_active_regions)
                         && !NILP (Vtransient_mark_mode)))
-                 && !EQ (Vthis_command, Qhandle_switch_frame))
+                 && NILP (Fmemq (Vthis_command,
+                                 Vselection_inhibit_update_commands)))
                {
                  ptrdiff_t beg =
                    XINT (Fmarker_position (BVAR (current_buffer, mark)));
@@ -1877,7 +1884,7 @@ safe_run_hooks_error (Lisp_Object error_data)
     = CONSP (Vinhibit_quit) ? XCAR (Vinhibit_quit) : Vinhibit_quit;
   Lisp_Object fun = CONSP (Vinhibit_quit) ? XCDR (Vinhibit_quit) : Qnil;
   Lisp_Object args[4];
-  args[0] = build_string ("Error in %s (%s): %s");
+  args[0] = build_string ("Error in %s (%s): %S");
   args[1] = hook;
   args[2] = fun;
   args[3] = error_data;
@@ -2981,11 +2988,16 @@ read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
      own stuff with the echo area.  */
   if (!CONSP (c)
       || (!(EQ (Qhelp_echo, XCAR (c)))
-         && !(EQ (Qswitch_frame, XCAR (c)))))
+         && !(EQ (Qswitch_frame, XCAR (c)))
+         /* Don't wipe echo area for select window events: These might
+            get delayed via `mouse-autoselect-window' (Bug#11304).  */
+         && !(EQ (Qselect_window, XCAR (c)))))
     {
       if (!NILP (echo_area_buffer[0]))
-       safe_run_hooks (Qecho_area_clear_hook);
-      clear_message (1, 0);
+       {
+         safe_run_hooks (Qecho_area_clear_hook);
+         clear_message (1, 0);
+       }
     }
 
  reread_for_input_method:
@@ -3773,7 +3785,6 @@ kbd_buffer_get_event (KBOARD **kbp,
                       int *used_mouse_menu,
                       struct timeval *end_time)
 {
-  register int c;
   Lisp_Object obj;
 
 #ifdef subprocesses
@@ -3790,16 +3801,18 @@ kbd_buffer_get_event (KBOARD **kbp,
     }
 #endif /* subprocesses */
 
+#ifndef HAVE_DBUS  /* We want to read D-Bus events in batch mode.  */
   if (noninteractive
       /* In case we are running as a daemon, only do this before
         detaching from the terminal.  */
       || (IS_DAEMON && daemon_pipe[1] >= 0))
     {
-      c = getchar ();
+      int c = getchar ();
       XSETINT (obj, c);
       *kbp = current_kboard;
       return obj;
     }
+#endif /* ! HAVE_DBUS  */
 
   /* Wait until there is input available.  */
   for (;;)
@@ -7171,6 +7184,7 @@ tty_read_avail_input (struct terminal *terminal,
   return nread;
 }
 \f
+#if defined SYNC_INPUT || defined SIGIO
 static void
 handle_async_input (void)
 {
@@ -7197,7 +7211,9 @@ handle_async_input (void)
   --handling_signal;
 #endif
 }
+#endif /* SYNC_INPUT || SIGIO */
 
+#ifdef SYNC_INPUT
 void
 process_pending_signals (void)
 {
@@ -7205,6 +7221,7 @@ process_pending_signals (void)
     handle_async_input ();
   do_pending_atimers ();
 }
+#endif
 
 #ifdef SIGIO   /* for entire page */
 /* Note SIGIO has been undef'd if FIONREAD is missing.  */
@@ -10216,7 +10233,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
 
   memset (keybuf, 0, sizeof keybuf);
   GCPRO1 (keybuf[0]);
-  gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0]));
+  gcpro1.nvars = (sizeof keybuf / sizeof (keybuf[0]));
 
   if (NILP (continue_echo))
     {
@@ -10230,7 +10247,7 @@ DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
     cancel_hourglass ();
 #endif
 
-  i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
+  i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])),
                         prompt, ! NILP (dont_downcase_last),
                         ! NILP (can_return_switch_frame), 0);
 
@@ -10337,146 +10354,6 @@ a special event, so ignore the prefix argument and don't clear it.  */)
 
 
 \f
-DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_command,
-       1, 1, "P",
-       doc: /* Read function name, then read its arguments and call it.
-
-To pass a numeric argument to the command you are invoking with, specify
-the numeric argument to this command.
-
-Noninteractively, the argument PREFIXARG is the prefix argument to
-give to the command you invoke, if it asks for an argument.  */)
-  (Lisp_Object prefixarg)
-{
-  Lisp_Object function;
-  ptrdiff_t saved_last_point_position;
-  Lisp_Object saved_keys, saved_last_point_position_buffer;
-  Lisp_Object bindings, value;
-  struct gcpro gcpro1, gcpro2, gcpro3;
-#ifdef HAVE_WINDOW_SYSTEM
-  /* The call to Fcompleting_read will 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.
-     So we restart it if it is already scheduled.  Note that checking
-     hourglass_shown_p is not enough,  normally the hourglass is not shown,
-     just scheduled to be shown.  */
-  int hstarted = hourglass_started ();
-#endif
-
-  saved_keys = Fvector (this_command_key_count,
-                       XVECTOR (this_command_keys)->contents);
-  saved_last_point_position_buffer = last_point_position_buffer;
-  saved_last_point_position = last_point_position;
-  GCPRO3 (saved_keys, prefixarg, saved_last_point_position_buffer);
-
-  function = call0 (intern ("read-extended-command"));
-
-#ifdef HAVE_WINDOW_SYSTEM
-  if (hstarted) start_hourglass ();
-#endif
-
-  if (STRINGP (function) && SCHARS (function) == 0)
-    error ("No command name given");
-
-  /* Set this_command_keys to the concatenation of saved_keys and
-     function, followed by a RET.  */
-  {
-    Lisp_Object *keys;
-    int i;
-
-    this_command_key_count = 0;
-    this_command_key_count_reset = 0;
-    this_single_command_key_start = 0;
-
-    keys = XVECTOR (saved_keys)->contents;
-    for (i = 0; i < ASIZE (saved_keys); i++)
-      add_command_key (keys[i]);
-
-    for (i = 0; i < SCHARS (function); i++)
-      add_command_key (Faref (function, make_number (i)));
-
-    add_command_key (make_number ('\015'));
-  }
-
-  last_point_position = saved_last_point_position;
-  last_point_position_buffer = saved_last_point_position_buffer;
-
-  UNGCPRO;
-
-  function = Fintern (function, Qnil);
-  KVAR (current_kboard, Vprefix_arg) = prefixarg;
-  Vthis_command = function;
-  real_this_command = function;
-
-  /* If enabled, show which key runs this command.  */
-  if (!NILP (Vsuggest_key_bindings)
-      && NILP (Vexecuting_kbd_macro)
-      && SYMBOLP (function))
-    bindings = Fwhere_is_internal (function, Voverriding_local_map,
-                                  Qt, Qnil, Qnil);
-  else
-    bindings = Qnil;
-
-  value = Qnil;
-  GCPRO3 (bindings, value, function);
-  value = Fcommand_execute (function, Qt, Qnil, Qnil);
-
-  /* If the command has a key binding, print it now.  */
-  if (!NILP (bindings)
-      && ! (VECTORP (bindings) && EQ (Faref (bindings, make_number (0)),
-                                     Qmouse_movement)))
-    {
-      /* But first wait, and skip the message if there is input.  */
-      Lisp_Object waited;
-
-      /* If this command displayed something in the echo area;
-        wait a few seconds, then display our suggestion message.  */
-      if (NILP (echo_area_buffer[0]))
-       waited = sit_for (make_number (0), 0, 2);
-      else if (NUMBERP (Vsuggest_key_bindings))
-       waited = sit_for (Vsuggest_key_bindings, 0, 2);
-      else
-       waited = sit_for (make_number (2), 0, 2);
-
-      if (!NILP (waited) && ! CONSP (Vunread_command_events))
-       {
-         Lisp_Object binding;
-         char *newmessage;
-         int message_p = push_message ();
-         ptrdiff_t count = SPECPDL_INDEX ();
-         ptrdiff_t newmessage_len, newmessage_alloc;
-         USE_SAFE_ALLOCA;
-
-         record_unwind_protect (pop_message_unwind, Qnil);
-         binding = Fkey_description (bindings, Qnil);
-         newmessage_alloc =
-           (sizeof "You can run the command `' with "
-            + SBYTES (SYMBOL_NAME (function)) + SBYTES (binding));
-         SAFE_ALLOCA (newmessage, char *, newmessage_alloc);
-         newmessage_len =
-           esprintf (newmessage, "You can run the command `%s' with %s",
-                     SDATA (SYMBOL_NAME (function)),
-                     SDATA (binding));
-         message2 (newmessage,
-                   newmessage_len,
-                   STRING_MULTIBYTE (binding));
-         if (NUMBERP (Vsuggest_key_bindings))
-           waited = sit_for (Vsuggest_key_bindings, 0, 2);
-         else
-           waited = sit_for (make_number (2), 0, 2);
-
-         if (!NILP (waited) && message_p)
-           restore_message ();
-
-         SAFE_FREE ();
-         unbind_to (count, Qnil);
-       }
-    }
-
-  RETURN_UNGCPRO (value);
-}
-
-\f
 /* Return nonzero if input events are pending.  */
 
 int
@@ -10921,6 +10798,11 @@ interrupt_signal (int signalnum)       /* If we don't have an argument, some */
   errno = old_errno;
 }
 
+/* If Emacs is stuck because `inhibit-quit' is true, then keep track
+   of the number of times C-g has been requested.  If C-g is pressed
+   enough times, then quit anyway.  See bug#6585.  */
+static int force_quit_count;
+
 /* This routine is called at interrupt level in response to C-g.
 
    It is called from the SIGINT handler or kbd_buffer_store_event.
@@ -11039,8 +10921,16 @@ handle_interrupt (void)
          UNGCPRO;
        }
       else
-       /* Else request quit when it's safe */
-       Vquit_flag = Qt;
+        { /* Else request quit when it's safe.  */
+          if (NILP (Vquit_flag))
+           force_quit_count = 0;
+         if (++force_quit_count == 3)
+            {
+              immediate_quit = 1;
+              Vinhibit_quit = Qnil;
+            }
+          Vquit_flag = Qt;
+        }
     }
 
 /* TODO: The longjmp in this call throws the NS event loop integration off,
@@ -11581,9 +11471,6 @@ syms_of_keyboard (void)
   staticpro (&tool_bar_items_vector);
   tool_bar_items_vector = Qnil;
 
-  staticpro (&real_this_command);
-  real_this_command = Qnil;
-
   DEFSYM (Qtimer_event_handler, "timer-event-handler");
   DEFSYM (Qdisabled_command_function, "disabled-command-function");
   DEFSYM (Qself_insert_command, "self-insert-command");
@@ -11654,6 +11541,7 @@ syms_of_keyboard (void)
   DEFSYM (Qx_set_selection, "x-set-selection");
   DEFSYM (QPRIMARY, "PRIMARY");
   DEFSYM (Qhandle_switch_frame, "handle-switch-frame");
+  DEFSYM (Qhandle_select_window, "handle-select-window");
 
   DEFSYM (Qinput_method_function, "input-method-function");
   DEFSYM (Qinput_method_exit_on_first_char, "input-method-exit-on-first-char");
@@ -11773,7 +11661,6 @@ syms_of_keyboard (void)
   defsubr (&Sset_quit_char);
   defsubr (&Sset_input_mode);
   defsubr (&Scurrent_input_mode);
-  defsubr (&Sexecute_extended_command);
   defsubr (&Sposn_at_point);
   defsubr (&Sposn_at_x_y);
 
@@ -11837,12 +11724,14 @@ was a kill command.
 See Info node `(elisp)Multiple Terminals'.  */);
 
   DEFVAR_KBOARD ("real-last-command", Vreal_last_command,
-                doc: /* Same as `last-command', but never altered by Lisp code.  */);
+                doc: /* Same as `last-command', but never altered by Lisp code.
+Taken from the previous value of `real-this-command'.  */);
 
   DEFVAR_KBOARD ("last-repeatable-command", Vlast_repeatable_command,
                 doc: /* Last command that may be repeated.
 The last command executed that was not bound to an input event.
-This is the command `repeat' will try to repeat.  */);
+This is the command `repeat' will try to repeat.
+Taken from a previous value of `real-this-command'.  */);
 
   DEFVAR_LISP ("this-command", Vthis_command,
               doc: /* The command now being executed.
@@ -11850,6 +11739,10 @@ The command can set this variable; whatever is put here
 will be in `last-command' during the following command.  */);
   Vthis_command = Qnil;
 
+  DEFVAR_LISP ("real-this-command", Vreal_this_command,
+              doc: /* This is like `this-command', except that commands should never modify it.  */);
+  Vreal_this_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.
@@ -12170,19 +12063,13 @@ whenever `deferred-action-list' is non-nil.  */);
   Vdeferred_action_function = Qnil;
 
   DEFVAR_LISP ("delayed-warnings-list", Vdelayed_warnings_list,
-               doc: /* List of warnings to be displayed as soon as possible.
+               doc: /* List of warnings to be displayed after this command.
 Each element must be a list (TYPE MESSAGE [LEVEL [BUFFER-NAME]]),
 as per the args of `display-warning' (which see).
 If this variable is non-nil, `delayed-warnings-hook' will be run
 immediately after running `post-command-hook'.  */);
   Vdelayed_warnings_list = Qnil;
 
-  DEFVAR_LISP ("suggest-key-bindings", Vsuggest_key_bindings,
-              doc: /* Non-nil means show the equivalent key-binding when M-x command has one.
-The value can be a length of time to show the message for.
-If the value is non-nil and not a number, we wait 2 seconds.  */);
-  Vsuggest_key_bindings = Qt;
-
   DEFVAR_LISP ("timer-list", Vtimer_list,
               doc: /* List of active absolute time timers in order of increasing time.  */);
   Vtimer_list = Qnil;
@@ -12290,6 +12177,16 @@ text in the region before modifying the buffer.  The next
 `deactivate-mark' call uses this to set the window selection.  */);
   Vsaved_region_selection = Qnil;
 
+  DEFVAR_LISP ("selection-inhibit-update-commands",
+              Vselection_inhibit_update_commands,
+              doc: /* List of commands which should not update the selection.
+Normally, if `select-active-regions' is non-nil and the mark remains
+active after a command (i.e. the mark was not deactivated), the Emacs
+command loop sets the selection to the text in the region.  However,
+if the command is in this list, the selection is not updated.  */);
+  Vselection_inhibit_update_commands
+    = list2 (Qhandle_switch_frame, Qhandle_select_window);
+
   DEFVAR_LISP ("debug-on-event",
                Vdebug_on_event,
                doc: /* Enter debugger on this event.  When Emacs
@@ -12368,7 +12265,7 @@ keys_of_keyboard (void)
 }
 
 /* Mark the pointers in the kboard objects.
-   Called by the Fgarbage_collector.  */
+   Called by Fgarbage_collect.  */
 void
 mark_kboards (void)
 {