/* Keyboard and mouse input; editor command loop.
-Copyright (C) 1985-1989, 1993-1997, 1999-2015 Free Software Foundation,
+Copyright (C) 1985-1989, 1993-1997, 1999-2016 Free Software Foundation,
Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
#include <config.h>
-#include "sysstdio.h"
#include <sys/stat.h>
#include "lisp.h"
+#include "coding.h"
#include "termchar.h"
#include "termopts.h"
#include "frame.h"
#include "commands.h"
#include "character.h"
#include "buffer.h"
-#include "disptab.h"
#include "dispextern.h"
#include "syntax.h"
#include "intervals.h"
#include "keymap.h"
#include "blockinput.h"
-#include "puresize.h"
#include "systime.h"
#include "atimer.h"
#include "process.h"
#include <unistd.h>
#include <fcntl.h>
+#include <ignore-value.h>
+
#ifdef HAVE_WINDOW_SYSTEM
#include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */
Lisp_Object this_command_keys;
ptrdiff_t this_command_key_count;
-/* True after calling Freset_this_command_lengths.
- Usually it is false. */
-static bool this_command_key_count_reset;
-
/* This vector is used as a buffer to record the events that were actually read
by read_key_sequence. */
static Lisp_Object raw_keybuf;
that precede this key sequence. */
static ptrdiff_t this_single_command_key_start;
-/* Record values of this_command_key_count and echo_length ()
- before this command was read. */
-static ptrdiff_t before_command_key_count;
-static ptrdiff_t before_command_echo_length;
-
#ifdef HAVE_STACK_OVERFLOW_HANDLING
/* For longjmp to recover from C stack overflow. */
/* Last size recorded for a current buffer which is not a minibuffer. */
static ptrdiff_t last_non_minibuf_size;
-/* Total number of times read_char has returned, modulo UINTMAX_MAX + 1. */
uintmax_t num_input_events;
+ptrdiff_t point_before_last_command_or_undo;
+struct buffer *buffer_before_last_command_or_undo;
/* Value of num_nonmacro_input_events as of last auto save. */
static EMACS_INT last_auto_save;
-/* The value of point when the last command was started. */
+/* The value of point when the last command was started. */
static ptrdiff_t last_point_position;
/* The frame in which the last input event occurred, or Qmacro if the
kb->echo_string_ = val;
}
static void
+kset_echo_prompt (struct kboard *kb, Lisp_Object val)
+{
+ kb->echo_prompt_ = val;
+}
+static void
kset_kbd_queue (struct kboard *kb, Lisp_Object val)
{
kb->kbd_queue_ = val;
}
\f
+static bool
+echo_keystrokes_p (void)
+{
+ return (FLOATP (Vecho_keystrokes) ? XFLOAT_DATA (Vecho_keystrokes) > 0.0
+ : INTEGERP (Vecho_keystrokes) ? XINT (Vecho_keystrokes) > 0
+ : false);
+}
+
/* Add C to the echo string, without echoing it immediately. C can be
a character, which is pretty-printed, or a symbol, whose name is
printed. */
ptrdiff_t size = sizeof initbuf;
char *buffer = initbuf;
char *ptr = buffer;
- Lisp_Object echo_string;
+ Lisp_Object echo_string = KVAR (current_kboard, echo_string);
USE_SAFE_ALLOCA;
- echo_string = KVAR (current_kboard, echo_string);
+ if (STRINGP (echo_string) && SCHARS (echo_string) > 0)
+ /* Add a space at the end as a separator between keys. */
+ ptr++[0] = ' ';
/* If someone has passed us a composite event, use its head symbol. */
c = EVENT_HEAD (c);
ptr += len;
}
- /* Replace a dash from echo_dash with a space, otherwise add a space
- at the end as a separator between keys. */
- AUTO_STRING (space, " ");
- if (STRINGP (echo_string) && SCHARS (echo_string) > 1)
- {
- Lisp_Object last_char, prev_char, idx;
-
- idx = make_number (SCHARS (echo_string) - 2);
- prev_char = Faref (echo_string, idx);
-
- idx = make_number (SCHARS (echo_string) - 1);
- last_char = Faref (echo_string, idx);
-
- /* We test PREV_CHAR to make sure this isn't the echoing of a
- minus-sign. */
- if (XINT (last_char) == '-' && XINT (prev_char) != ' ')
- Faset (echo_string, idx, make_number (' '));
- else
- echo_string = concat2 (echo_string, space);
- }
- else if (STRINGP (echo_string) && SCHARS (echo_string) > 0)
- echo_string = concat2 (echo_string, space);
-
kset_echo_string
(current_kboard,
concat2 (echo_string, make_string (buffer, ptr - buffer)));
SAFE_FREE ();
}
-/* Add C to the echo string, if echoing is going on. C can be a
- character or a symbol. */
-
-static void
-echo_char (Lisp_Object c)
-{
- if (current_kboard->immediate_echo)
- {
- echo_add_key (c);
- echo_now ();
- }
-}
-
/* Temporarily add a dash to the end of the echo string if it's not
empty, so that it serves as a mini-prompt for the very next
character. */
if (NILP (KVAR (current_kboard, echo_string)))
return;
- if (this_command_key_count == 0)
- return;
-
if (!current_kboard->immediate_echo
&& SCHARS (KVAR (current_kboard, echo_string)) == 0)
return;
/* Do nothing if we just printed a prompt. */
- if (current_kboard->echo_after_prompt
- == SCHARS (KVAR (current_kboard, echo_string)))
+ if (STRINGP (KVAR (current_kboard, echo_prompt))
+ && (SCHARS (KVAR (current_kboard, echo_prompt))
+ == SCHARS (KVAR (current_kboard, echo_string))))
return;
/* Do nothing if we have already put a dash at the end. */
echo_now ();
}
-/* Display the current echo string, and begin echoing if not already
- doing so. */
-
static void
-echo_now (void)
+echo_update (void)
{
- if (!current_kboard->immediate_echo)
+ if (current_kboard->immediate_echo)
{
ptrdiff_t i;
- current_kboard->immediate_echo = true;
+ Lisp_Object prompt = KVAR (current_kboard, echo_prompt);
+ Lisp_Object prefix = call0 (Qinternal_echo_keystrokes_prefix);
+ kset_echo_string (current_kboard,
+ NILP (prompt) ? prefix
+ : NILP (prefix) ? prompt
+ : concat2 (prompt, prefix));
for (i = 0; i < this_command_key_count; i++)
{
Lisp_Object c;
- /* Set before_command_echo_length to the value that would
- have been saved before the start of this subcommand in
- command_loop_1, if we had already been echoing then. */
- if (i == this_single_command_key_start)
- before_command_echo_length = echo_length ();
-
c = AREF (this_command_keys, i);
if (! (EVENT_HAS_PARAMETERS (c)
&& EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
- echo_char (c);
+ echo_add_key (c);
}
- /* Set before_command_echo_length to the value that would
- have been saved before the start of this subcommand in
- command_loop_1, if we had already been echoing then. */
- if (this_command_key_count == this_single_command_key_start)
- before_command_echo_length = echo_length ();
+ echo_now ();
+ }
+}
+
+/* Display the current echo string, and begin echoing if not already
+ doing so. */
+static void
+echo_now (void)
+{
+ if (!current_kboard->immediate_echo
+ /* This test breaks calls that use `echo_now' to display the echo_prompt.
+ && echo_keystrokes_p () */)
+ {
+ current_kboard->immediate_echo = true;
+ echo_update ();
/* Put a dash at the end to invite the user to type more. */
echo_dash ();
}
cancel_echoing (void)
{
current_kboard->immediate_echo = false;
- current_kboard->echo_after_prompt = -1;
+ kset_echo_prompt (current_kboard, Qnil);
kset_echo_string (current_kboard, Qnil);
ok_to_echo_at_next_pause = NULL;
echo_kboard = NULL;
static void
add_command_key (Lisp_Object key)
{
-#if 0 /* Not needed after we made Freset_this_command_lengths
- do the job immediately. */
- /* If reset-this-command-length was called recently, obey it now.
- See the doc string of that function for an explanation of why. */
- if (before_command_restore_flag)
- {
- this_command_key_count = before_command_key_count_1;
- if (this_command_key_count < this_single_command_key_start)
- this_single_command_key_start = this_command_key_count;
- echo_truncate (before_command_echo_length_1);
- before_command_restore_flag = 0;
- }
-#endif
-
if (this_command_key_count >= ASIZE (this_command_keys))
this_command_keys = larger_vector (this_command_keys, 1, -1);
\f
DEFUN ("recursive-edit", Frecursive_edit, Srecursive_edit, 0, 0, "",
doc: /* Invoke the editor command loop recursively.
-To get out of the recursive edit, a command can throw to ‘exit’ -- for
-instance ‘(throw \\='exit nil)’.
-If you throw a value other than t, ‘recursive-edit’ returns normally
+To get out of the recursive edit, a command can throw to `exit' -- for
+instance (throw \\='exit nil).
+If you throw a value other than t, `recursive-edit' returns normally
to the function that called it. Throwing a t value causes
-‘recursive-edit’ to quit, so that control returns to the command loop
+`recursive-edit' to quit, so that control returns to the command loop
one level up.
This function is called by the editor initialization to begin editing. */)
bool, bool, bool, bool);
static void adjust_point_for_property (ptrdiff_t, bool);
-/* The last boundary auto-added to buffer-undo-list. */
-Lisp_Object last_undo_boundary;
-
-/* FIXME: This is wrong rather than test window-system, we should call
- a new set-selection, which will then dispatch to x-set-selection, or
- tty-set-selection, or w32-set-selection, ... */
-
Lisp_Object
command_loop_1 (void)
{
- Lisp_Object cmd;
- Lisp_Object keybuf[30];
- int i;
EMACS_INT prev_modiff = 0;
struct buffer *prev_buffer = NULL;
bool already_adjusted = 0;
cancel_echoing ();
this_command_key_count = 0;
- this_command_key_count_reset = false;
this_single_command_key_start = 0;
if (NILP (Vmemory_full))
while (1)
{
+ Lisp_Object cmd;
+ Lisp_Object keybuf[30];
+ int i;
+
if (! FRAME_LIVE_P (XFRAME (selected_frame)))
Fkill_emacs (Qnil);
&& !NILP (Ffboundp (Qrecompute_lucid_menubar)))
call0 (Qrecompute_lucid_menubar);
- before_command_key_count = this_command_key_count;
- before_command_echo_length = echo_length ();
-
Vthis_command = Qnil;
Vreal_this_command = Qnil;
Vthis_original_command = Qnil;
{
cancel_echoing ();
this_command_key_count = 0;
- this_command_key_count_reset = false;
this_single_command_key_start = 0;
goto finalize;
}
}
#endif
- if (NILP (KVAR (current_kboard, Vprefix_arg))) /* FIXME: Why? --Stef */
- {
- Lisp_Object undo = BVAR (current_buffer, undo_list);
- Fundo_boundary ();
- last_undo_boundary
- = (EQ (undo, BVAR (current_buffer, undo_list))
- ? Qnil : BVAR (current_buffer, undo_list));
- }
+ /* Ensure that we have added appropriate undo-boundaries as a
+ result of changes from the last command. */
+ call0 (Qundo_auto__add_boundary);
+
+ /* Record point and buffer, so we can put point into the undo
+ information if necessary. */
+ point_before_last_command_or_undo = PT;
+ buffer_before_last_command_or_undo = current_buffer;
+
call1 (Qcommand_execute, Vthis_command);
#ifdef HAVE_WINDOW_SYSTEM
safe_run_hooks (Qdeferred_action_function);
- /* If there is a prefix argument,
- 1) We don't want Vlast_command to be ``universal-argument''
- (that would be dumb), so don't set Vlast_command,
- 2) we want to leave echoing on so that the prefix will be
- echoed as part of this key sequence, so don't call
- cancel_echoing, and
- 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 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))
+ kset_last_command (current_kboard, Vthis_command);
+ kset_real_last_command (current_kboard, Vreal_this_command);
+ if (!CONSP (last_command_event))
+ kset_last_repeatable_command (current_kboard, Vreal_this_command);
+
+ this_command_key_count = 0;
+ this_single_command_key_start = 0;
+
+ if (current_kboard->immediate_echo
+ && !NILP (call0 (Qinternal_echo_keystrokes_prefix)))
{
- kset_last_command (current_kboard, Vthis_command);
- kset_real_last_command (current_kboard, Vreal_this_command);
- if (!CONSP (last_command_event))
- kset_last_repeatable_command (current_kboard, Vreal_this_command);
- cancel_echoing ();
- this_command_key_count = 0;
- this_command_key_count_reset = false;
- this_single_command_key_start = 0;
+ current_kboard->immediate_echo = false;
+ /* Refresh the echo message. */
+ echo_now ();
}
+ else
+ cancel_echoing ();
if (!NILP (BVAR (current_buffer, mark_active))
&& !NILP (Vrun_hooks))
}
}
-static bool
-echo_keystrokes_p (void)
-{
- return (FLOATP (Vecho_keystrokes) ? XFLOAT_DATA (Vecho_keystrokes) > 0.0
- : INTEGERP (Vecho_keystrokes) ? XINT (Vecho_keystrokes) > 0 : false);
-}
-
/* Read a character from the keyboard; call the redisplay if needed. */
/* commandflag 0 means do not autosave, but do redisplay.
-1 means do not redisplay, but do autosave.
also_record = Qnil;
-#if 0 /* This was commented out as part of fixing echo for C-u left. */
- before_command_key_count = this_command_key_count;
- before_command_echo_length = echo_length ();
-#endif
c = Qnil;
previous_echo_area_message = Qnil;
goto reread_for_input_method;
}
- this_command_key_count_reset = false;
-
if (!NILP (Vexecuting_kbd_macro))
{
/* We set this to Qmacro; since that's not a frame, nobody will
(3) There's only one place in 20.x where ok_to_echo_at_next_pause
is set to a non-null value. This is done in read_char and it is
- set to echo_area_glyphs after a call to echo_char. That means
+ set to echo_area_glyphs. That means
ok_to_echo_at_next_pause is either null or
current_kboard->echobuf with the appropriate current_kboard at
that time.
if (minibuf_level == 0
&& !end_time
&& !current_kboard->immediate_echo
- && this_command_key_count > 0
+ && (this_command_key_count > 0
+ || !NILP (call0 (Qinternal_echo_keystrokes_prefix)))
&& ! noninteractive
&& echo_keystrokes_p ()
&& (/* No message. */
{
Lisp_Object keys;
ptrdiff_t key_count;
- bool key_count_reset;
ptrdiff_t command_key_start;
ptrdiff_t count = SPECPDL_INDEX ();
bool saved_immediate_echo = current_kboard->immediate_echo;
struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause;
Lisp_Object saved_echo_string = KVAR (current_kboard, echo_string);
- ptrdiff_t saved_echo_after_prompt = current_kboard->echo_after_prompt;
-
-#if 0
- if (before_command_restore_flag)
- {
- this_command_key_count = before_command_key_count_1;
- if (this_command_key_count < this_single_command_key_start)
- this_single_command_key_start = this_command_key_count;
- echo_truncate (before_command_echo_length_1);
- before_command_restore_flag = 0;
- }
-#endif
+ Lisp_Object saved_echo_prompt = KVAR (current_kboard, echo_prompt);
/* Save the this_command_keys status. */
key_count = this_command_key_count;
- key_count_reset = this_command_key_count_reset;
command_key_start = this_single_command_key_start;
if (key_count > 0)
/* Clear out this_command_keys. */
this_command_key_count = 0;
- this_command_key_count_reset = false;
this_single_command_key_start = 0;
/* Now wipe the echo area. */
/* Restore the saved echoing state
and this_command_keys state. */
this_command_key_count = key_count;
- this_command_key_count_reset = key_count_reset;
this_single_command_key_start = command_key_start;
if (key_count > 0)
this_command_keys = keys;
cancel_echoing ();
ok_to_echo_at_next_pause = saved_ok_to_echo;
- /* Do not restore the echo area string when the user is
- introducing a prefix argument. Otherwise we end with
- repetitions of the partially introduced prefix
- argument. (bug#19875) */
- if (NILP (intern ("prefix-arg")))
- {
- kset_echo_string (current_kboard, saved_echo_string);
- }
- current_kboard->echo_after_prompt = saved_echo_after_prompt;
+ kset_echo_string (current_kboard, saved_echo_string);
+ kset_echo_prompt (current_kboard, saved_echo_prompt);
if (saved_immediate_echo)
echo_now ();
goto retry;
}
- if ((! reread || this_command_key_count == 0
- || this_command_key_count_reset)
+ if ((! reread || this_command_key_count == 0)
&& !end_time)
{
/* Don't echo mouse motion events. */
- if (echo_keystrokes_p ()
- && ! (EVENT_HAS_PARAMETERS (c)
- && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
- {
- echo_char (c);
- if (! NILP (also_record))
- echo_char (also_record);
- /* Once we reread a character, echoing can happen
- the next time we pause to read a new one. */
- ok_to_echo_at_next_pause = current_kboard;
- }
+ if (! (EVENT_HAS_PARAMETERS (c)
+ && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
+ /* Once we reread a character, echoing can happen
+ the next time we pause to read a new one. */
+ ok_to_echo_at_next_pause = current_kboard;
/* Record this character as part of the current key. */
add_command_key (c);
if (! NILP (also_record))
add_command_key (also_record);
+
+ echo_update ();
}
last_input_event = c;
record_char (c);
-#if 0
- before_command_key_count = this_command_key_count;
- before_command_echo_length = echo_length ();
-#endif
-
- /* Don't echo mouse motion events. */
- if (echo_keystrokes_p ())
- {
- echo_char (c);
-
- /* Once we reread a character, echoing can happen
- the next time we pause to read a new one. */
- ok_to_echo_at_next_pause = 0;
- }
+ /* Once we reread a character, echoing can happen
+ the next time we pause to read a new one. */
+ ok_to_echo_at_next_pause = NULL;
/* Record this character as part of the current key. */
add_command_key (c);
+ echo_update ();
/* Re-reading in the middle of a command. */
last_input_event = c;
else
store_kbd_macro_char (c);
- if (!recorded)
- {
- total_keys += total_keys < NUM_RECENT_KEYS;
- ASET (recent_keys, recent_keys_index, c);
- if (++recent_keys_index >= NUM_RECENT_KEYS)
- recent_keys_index = 0;
- }
- else if (recorded < 0)
+ /* recent_keys should not include events from keyboard macros. */
+ if (NILP (Vexecuting_kbd_macro))
{
- /* We need to remove one or two events from recent_keys.
- To do this, we simply put nil at those events and move the
- recent_keys_index backwards over those events. Usually,
- users will never see those nil events, as they will be
- overwritten by the command keys entered to see recent_keys
- (e.g. C-h l). */
-
- while (recorded++ < 0 && total_keys > 0)
+ if (!recorded)
{
- if (total_keys < NUM_RECENT_KEYS)
- total_keys--;
- if (--recent_keys_index < 0)
- recent_keys_index = NUM_RECENT_KEYS - 1;
- ASET (recent_keys, recent_keys_index, Qnil);
+ total_keys += total_keys < NUM_RECENT_KEYS;
+ ASET (recent_keys, recent_keys_index, c);
+ if (++recent_keys_index >= NUM_RECENT_KEYS)
+ recent_keys_index = 0;
+ }
+ else if (recorded < 0)
+ {
+ /* We need to remove one or two events from recent_keys.
+ To do this, we simply put nil at those events and move the
+ recent_keys_index backwards over those events. Usually,
+ users will never see those nil events, as they will be
+ overwritten by the command keys entered to see recent_keys
+ (e.g. C-h l). */
+
+ while (recorded++ < 0 && total_keys > 0)
+ {
+ if (total_keys < NUM_RECENT_KEYS)
+ total_keys--;
+ if (--recent_keys_index < 0)
+ recent_keys_index = NUM_RECENT_KEYS - 1;
+ ASET (recent_keys, recent_keys_index, Qnil);
+ }
}
- }
- num_nonmacro_input_events++;
+ num_nonmacro_input_events++;
+ }
/* Write c to the dribble file. If c is a lispy event, write
the event's symbol to the dribble file, in <brackets>. Bleaugh.
#endif
))
{
- union buffered_input_event *event;
-
- event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
- ? kbd_fetch_ptr
- : kbd_buffer);
+ union buffered_input_event *event = kbd_fetch_ptr;
do
{
+ if (event == kbd_buffer + KBD_BUFFER_SIZE)
+ event = kbd_buffer;
if (!(
#ifdef USE_TOOLKIT_SCROLL_BARS
(flags & READABLE_EVENTS_FILTER_EVENTS) &&
&& event->kind == BUFFER_SWITCH_EVENT))
return 1;
event++;
- if (event == kbd_buffer + KBD_BUFFER_SIZE)
- event = kbd_buffer;
}
while (event != kbd_store_ptr);
}
obj = make_lispy_event (&event->ie);
kbd_fetch_ptr = event + 1;
}
+#endif
+#ifdef HAVE_XWIDGETS
+ else if (event->kind == XWIDGET_EVENT)
+ {
+ obj = make_lispy_event (&event->ie);
+ kbd_fetch_ptr = event + 1;
+ }
#endif
else if (event->kind == CONFIG_CHANGED_EVENT)
{
}
#endif /* HAVE_DBUS */
-#if defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY
+#ifdef HAVE_XWIDGETS
+ case XWIDGET_EVENT:
+ {
+ return Fcons (Qxwidget_event, event->arg);
+ }
+#endif
+
+
+#if defined HAVE_INOTIFY || defined HAVE_KQUEUE || defined HAVE_GFILENOTIFY
case FILE_NOTIFY_EVENT:
{
return Fcons (Qfile_notify, event->arg);
}
-#endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY */
+#endif /* HAVE_INOTIFY || HAVE_KQUEUE || HAVE_GFILENOTIFY */
case CONFIG_CHANGED_EVENT:
return list3 (Qconfig_changed_event,
/* Install the string PROMPT as the beginning of the string
of echoing, so that it serves as a prompt for the next
character. */
- kset_echo_string (current_kboard, prompt);
- current_kboard->echo_after_prompt = SCHARS (prompt);
+ kset_echo_prompt (current_kboard, prompt);
+ /* FIXME: This use of echo_now doesn't look quite right and is ugly
+ since it forces us to fiddle with current_kboard->immediate_echo
+ before and after. */
+ current_kboard->immediate_echo = false;
echo_now ();
+ if (!echo_keystrokes_p ())
+ current_kboard->immediate_echo = false;
}
- else if (cursor_in_echo_area
+ else if (cursor_in_echo_area /* FIXME: Not sure why we test this here,
+ maybe we should just drop this test. */
&& echo_keystrokes_p ())
/* This doesn't put in a dash if the echo buffer is empty, so
you don't always see a dash hanging out in the minibuffer. */
{
key = keybuf[t];
add_command_key (key);
- if (echo_keystrokes_p ()
- && current_kboard->immediate_echo)
+ if (current_kboard->immediate_echo)
{
- echo_add_key (key);
- echo_dash ();
+ /* Set immediate_echo to false so as to force echo_now to
+ redisplay (it will set immediate_echo right back to true). */
+ current_kboard->immediate_echo = false;
+ echo_now ();
}
}
Better ideas? */
for (; t < mock_input; t++)
- {
- if (echo_keystrokes_p ())
- echo_char (keybuf[t]);
- add_command_key (keybuf[t]);
- }
+ add_command_key (keybuf[t]);
+ echo_update ();
return t;
}
if (NILP (continue_echo))
{
this_command_key_count = 0;
- this_command_key_count_reset = false;
this_single_command_key_start = 0;
}
return Fvector (raw_keybuf_count, XVECTOR (raw_keybuf)->contents);
}
-DEFUN ("reset-this-command-lengths", Freset_this_command_lengths,
- Sreset_this_command_lengths, 0, 0, 0,
- doc: /* Make the unread events replace the last command and echo.
-Used in `universal-argument-other-key'.
-
-`universal-argument-other-key' rereads the event just typed.
-It then gets translated through `function-key-map'.
-The translated event has to replace the real events,
-both in the value of (this-command-keys) and in echoing.
-To achieve this, `universal-argument-other-key' calls
-`reset-this-command-lengths', which discards the record of reading
-these events the first time. */)
- (void)
-{
- this_command_key_count = before_command_key_count;
- if (this_command_key_count < this_single_command_key_start)
- this_single_command_key_start = this_command_key_count;
-
- echo_truncate (before_command_echo_length);
-
- /* Cause whatever we put into unread-command-events
- to echo as if it were being freshly read from the keyboard. */
- this_command_key_count_reset = true;
-
- return Qnil;
-}
-
DEFUN ("clear-this-command-keys", Fclear_this_command_keys,
Sclear_this_command_keys, 0, 1, 0,
doc: /* Clear out the vector that `this-command-keys' returns.
int i;
this_command_key_count = 0;
- this_command_key_count_reset = false;
if (NILP (keep_record))
{
deliver_process_signal (sig, handle_interrupt_signal);
}
+/* Output MSG directly to standard output, without buffering. Ignore
+ failures. This is safe in a signal handler. */
+static void
+write_stdout (char const *msg)
+{
+ ignore_value (write (STDOUT_FILENO, msg, strlen (msg)));
+}
+
+/* Read a byte from stdin, without buffering. Safe in signal handlers. */
+static int
+read_stdin (void)
+{
+ char c;
+ return read (STDIN_FILENO, &c, 1) == 1 ? c : EOF;
+}
/* 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
sigemptyset (&blocked);
sigaddset (&blocked, SIGINT);
pthread_sigmask (SIG_BLOCK, &blocked, 0);
+ fflush (stdout);
}
- fflush (stdout);
reset_all_sys_modes ();
#ifdef SIGTSTP
/* Perhaps should really fork an inferior shell?
But that would not provide any way to get back
to the original shell, ever. */
- printf ("No support for stopping a process on this operating system;\n");
- printf ("you can continue or abort.\n");
+ write_stdout ("No support for stopping a process"
+ " on this operating system;\n"
+ "you can continue or abort.\n");
#endif /* not SIGTSTP */
#ifdef MSDOS
/* We must remain inside the screen area when the internal terminal
the code used for auto-saving doesn't cope with the mark bit. */
if (!gc_in_progress)
{
- printf ("Auto-save? (y or n) ");
- fflush (stdout);
- if (((c = getchar ()) & ~040) == 'Y')
+ write_stdout ("Auto-save? (y or n) ");
+ c = read_stdin ();
+ if (c == 'y' || c == 'Y')
{
Fdo_auto_save (Qt, Qnil);
#ifdef MSDOS
- printf ("\r\nAuto-save done");
-#else /* not MSDOS */
- printf ("Auto-save done\n");
-#endif /* not MSDOS */
+ write_stdout ("\r\nAuto-save done");
+#else
+ write_stdout ("Auto-save done\n");
+#endif
}
- while (c != '\n') c = getchar ();
+ while (c != '\n')
+ c = read_stdin ();
}
else
{
/* During GC, it must be safe to reenable quitting again. */
Vinhibit_quit = Qnil;
+ write_stdout
+ (
#ifdef MSDOS
- printf ("\r\n");
-#endif /* not MSDOS */
- printf ("Garbage collection in progress; cannot auto-save now\r\n");
- printf ("but will instead do a real quit after garbage collection ends\r\n");
- fflush (stdout);
+ "\r\n"
+#endif
+ "Garbage collection in progress; cannot auto-save now\r\n"
+ "but will instead do a real quit"
+ " after garbage collection ends\r\n");
}
#ifdef MSDOS
- printf ("\r\nAbort? (y or n) ");
-#else /* not MSDOS */
- printf ("Abort (and dump core)? (y or n) ");
-#endif /* not MSDOS */
- fflush (stdout);
- if (((c = getchar ()) & ~040) == 'Y')
+ write_stdout ("\r\nAbort? (y or n) ");
+#else
+ write_stdout ("Abort (and dump core)? (y or n) ");
+#endif
+ c = read_stdin ();
+ if (c == 'y' || c == 'Y')
emacs_abort ();
- while (c != '\n') c = getchar ();
+ while (c != '\n')
+ c = read_stdin ();
#ifdef MSDOS
- printf ("\r\nContinuing...\r\n");
+ write_stdout ("\r\nContinuing...\r\n");
#else /* not MSDOS */
- printf ("Continuing...\n");
+ write_stdout ("Continuing...\n");
#endif /* not MSDOS */
- fflush (stdout);
init_all_sys_modes ();
}
else
kb->kbd_queue_has_data = false;
kb->immediate_echo = false;
kset_echo_string (kb, Qnil);
- kb->echo_after_prompt = -1;
+ kset_echo_prompt (kb, Qnil);
kb->kbd_macro_buffer = 0;
kb->kbd_macro_bufsize = 0;
kset_defining_kbd_macro (kb, Qnil);
DEFSYM (Qpre_command_hook, "pre-command-hook");
DEFSYM (Qpost_command_hook, "post-command-hook");
+ DEFSYM (Qundo_auto__add_boundary, "undo-auto--add-boundary");
+
DEFSYM (Qdeferred_action_function, "deferred-action-function");
DEFSYM (Qdelayed_warnings_hook, "delayed-warnings-hook");
DEFSYM (Qfunction_key, "function-key");
DEFSYM (Qdbus_event, "dbus-event");
#endif
+#ifdef HAVE_XWIDGETS
+ DEFSYM (Qxwidget_event, "xwidget-event");
+#endif
+
#ifdef USE_FILE_NOTIFY
DEFSYM (Qfile_notify, "file-notify");
#endif /* USE_FILE_NOTIFY */
staticpro (&raw_keybuf);
DEFSYM (Qcommand_execute, "command-execute");
+ DEFSYM (Qinternal_echo_keystrokes_prefix, "internal-echo-keystrokes-prefix");
accent_key_syms = Qnil;
staticpro (&accent_key_syms);
defsubr (&Sthis_command_keys_vector);
defsubr (&Sthis_single_command_keys);
defsubr (&Sthis_single_command_raw_keys);
- defsubr (&Sreset_this_command_lengths);
defsubr (&Sclear_this_command_keys);
defsubr (&Ssuspend_emacs);
defsubr (&Sabort_recursive_edit);
DEFVAR_BOOL ("cannot-suspend", cannot_suspend,
doc: /* Non-nil means to always spawn a subshell instead of suspending.
-\(Even if the operating system has support for stopping a process.\) */);
+\(Even if the operating system has support for stopping a process.) */);
cannot_suspend = false;
DEFVAR_BOOL ("menu-prompting", menu_prompting,
doc: /* Normal hook run before each command is executed.
If an unhandled error happens in running this hook,
the function in which the error occurred is unconditionally removed, since
-otherwise the error might happen repeatedly and make Emacs nonfunctional. */);
+otherwise the error might happen repeatedly and make Emacs nonfunctional.
+
+See also `post-command-hook'. */);
Vpre_command_hook = Qnil;
DEFVAR_LISP ("post-command-hook", Vpost_command_hook,
doc: /* Normal hook run after each command is executed.
If an unhandled error happens in running this hook,
the function in which the error occurred is unconditionally removed, since
-otherwise the error might happen repeatedly and make Emacs nonfunctional. */);
+otherwise the error might happen repeatedly and make Emacs nonfunctional.
+
+It is a bad idea to use this hook for expensive processing. If
+unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to
+avoid making Emacs unresponsive while the user types.
+
+See also `pre-command-hook'. */);
Vpost_command_hook = Qnil;
#if 0
DEFVAR_LISP ("disable-point-adjustment", Vdisable_point_adjustment,
doc: /* If non-nil, suppress point adjustment after executing a command.
-After a command is executed, if point is moved into a region that has
-special properties (e.g. composition, display), we adjust point to
-the boundary of the region. But, when a command sets this variable to
-non-nil, we suppress the point adjustment.
+After a command is executed, if point moved into a region that has
+special properties (e.g. composition, display), Emacs adjusts point to
+the boundary of the region. But when a command leaves this variable at
+a non-nil value (e.g., with a setq), this point adjustment is suppressed.
This variable is set to nil before reading a command, and is checked
just after executing the command. */);
DEFVAR_LISP ("global-disable-point-adjustment",
Vglobal_disable_point_adjustment,
- doc: /* If non-nil, always suppress point adjustment.
+ doc: /* If non-nil, always suppress point adjustments.
-The default value is nil, in which case, point adjustment are
-suppressed only after special commands that set
-`disable-point-adjustment' (which see) to non-nil. */);
+The default value is nil, in which case point adjustments are
+suppressed only after special commands that leave
+`disable-point-adjustment' (which see) at a non-nil value. */);
Vglobal_disable_point_adjustment = Qnil;
DEFVAR_LISP ("minibuffer-message-timeout", Vminibuffer_message_timeout,
mark_object (KVAR (kb, Vlocal_function_key_map));
mark_object (KVAR (kb, Vdefault_minibuffer_frame));
mark_object (KVAR (kb, echo_string));
+ mark_object (KVAR (kb, echo_prompt));
}
{
union buffered_input_event *event;