/* Keyboard and mouse input; editor command loop.
- Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1985,86,87,88,89,93,94 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "syssignal.h"
#include "systty.h"
+
+/* This is to get the definitions of the XK_ symbols. */
+#ifdef HAVE_X_WINDOWS
+#include "xterm.h"
+#endif
+
+/* Include systime.h after xterm.h to avoid double inclusion of time.h. */
#include "systime.h"
extern int errno;
Lisp_Object last_input_char;
/* If not Qnil, a list of objects to be read as subsequent command input. */
-Lisp_Object unread_command_events;
+Lisp_Object Vunread_command_events;
/* If not -1, an event to be read as subsequent command input. */
int unread_command_char;
instead of the actual command. */
Lisp_Object this_command;
+/* The value of point when the last command was executed. */
+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
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;
-#endif
/* The timestamp of the last input event we received from the X server.
X Windows wants this for selection ownership. */
Lisp_Object Vpre_command_hook, Vpost_command_hook;
Lisp_Object Qcommand_hook_internal, Vcommand_hook_internal;
+/* List of deferred actions to be performed at a later time.
+ The precise format isn't relevant here; we just check whether it is nil. */
+Lisp_Object Vdeferred_action_list;
+
+/* Function to call to handle deferred actions, when there are any. */
+Lisp_Object Vdeferred_action_function;
+
/* File in which we write all commands we read. */
FILE *dribble;
Lisp_Object Fthis_command_keys ();
Lisp_Object Qextended_command_history;
+Lisp_Object Qpolling_period;
+
/* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt
happens. */
EMACS_TIME *input_available_clear_time;
/* Where to append more text to echobuf if we want to. */
static char *echoptr;
+/* If we have echoed a prompt string specified by the user,
+ this is its length. Otherwise this is -1. */
+static int echo_after_prompt;
+
/* Nonzero means don't try to suspend even if the operating system seems
to support it. */
static int cannot_suspend;
char *str;
{
int len = strlen (str);
+
if (len > sizeof echobuf - 4)
len = sizeof echobuf - 4;
bcopy (str, echobuf, len);
echoptr = echobuf + len;
*echoptr = '\0';
+ echo_after_prompt = len;
+
echo ();
}
{
if (!immediate_echo && echoptr == echobuf)
return;
+ /* Do nothing if we just printed a prompt. */
+ if (echo_after_prompt == echoptr - echobuf)
+ return;
/* Do nothing if not echoing at all. */
if (echoptr == 0)
return;
immediate_echo = 1;
for (i = 0; i < this_command_key_count; i++)
- echo_char (XVECTOR (this_command_keys)->contents[i]);
+ {
+ Lisp_Object c;
+ c = XVECTOR (this_command_keys)->contents[i];
+ if (! (EVENT_HAS_PARAMETERS (c)
+ && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
+ echo_char (c);
+ }
echo_dash ();
}
{
immediate_echo = 0;
echoptr = echobuf;
+ echo_after_prompt = -1;
}
/* Return the length of the current echo string. */
if (this_command_key_count >= size)
{
- Lisp_Object new_keys = Fmake_vector (make_number (size * 2), Qnil);
+ Lisp_Object new_keys;
+ new_keys = Fmake_vector (make_number (size * 2), Qnil);
bcopy (XVECTOR (this_command_keys)->contents,
XVECTOR (new_keys)->contents,
size * sizeof (Lisp_Object));
}
/* When an auto-save happens, record the "time", and don't do again soon. */
+
record_auto_save ()
{
last_auto_save = num_nonmacro_input_chars;
}
+
+/* Make an auto save happen as soon as possible at command level. */
+
+force_auto_save_soon ()
+{
+ last_auto_save = - auto_save_interval - 1;
+
+ record_asynch_buffer_change ();
+}
\f
DEFUN ("recursive-edit", Frecursive_edit, Srecursive_edit, 0, 0, "",
"Invoke the editor command loop recursively.\n\
Lisp_Object Fcommand_execute ();
static int read_key_sequence ();
+static void safe_run_hooks ();
Lisp_Object
command_loop_1 ()
nonundocount = 0;
no_redisplay = 0;
this_command_key_count = 0;
- last_command = this_command;
/* Make sure this hook runs after commands that get errors and
throw to top level. */
- if (!NILP (Vpost_command_hook))
- {
- /* If we get an error during the post-command-hook,
- cause post-command-hook to be nil. */
- Vcommand_hook_internal = Vpost_command_hook;
- Vpost_command_hook = Qnil;
+ /* Note that the value cell will never directly contain nil
+ if the symbol is a local variable. */
+ if (!NILP (XSYMBOL (Qpost_command_hook)->value) && !NILP (Vrun_hooks))
+ safe_run_hooks (Qpost_command_hook);
- call1 (Vrun_hooks, Qcommand_hook_internal);
-
- Vpost_command_hook = Vcommand_hook_internal;
- }
+ if (!NILP (Vdeferred_action_list))
+ call0 (Vdeferred_action_function);
+
+ /* Do this after running Vpost_command_hook, for consistency. */
+ last_command = this_command;
while (1)
{
if (!NILP (Vquit_flag))
{
Vquit_flag = Qnil;
- unread_command_events = Fcons (make_number (quit_char), Qnil);
+ Vunread_command_events = Fcons (make_number (quit_char), Qnil);
}
}
prev_buffer = current_buffer;
prev_modiff = MODIFF;
+ last_point_position = PT;
+ XSET (last_point_position_buffer, Lisp_Buffer, prev_buffer);
/* Execute the command. */
this_command = cmd;
- if (!NILP (Vpre_command_hook))
- {
- /* If we get an error during the pre-command-hook,
- cause pre-command-hook to be nil. */
- Vcommand_hook_internal = Vpre_command_hook;
- Vpre_command_hook = Qnil;
-
- call1 (Vrun_hooks, Qcommand_hook_internal);
-
- Vpre_command_hook = Vcommand_hook_internal;
- }
+ /* Note that the value cell will never directly contain nil
+ if the symbol is a local variable. */
+ if (!NILP (XSYMBOL (Qpre_command_hook)->value) && !NILP (Vrun_hooks))
+ safe_run_hooks (Qpre_command_hook);
if (NILP (this_command))
{
{
/* Recognize some common commands in common situations and
do them directly. */
- if (EQ (this_command, Qforward_char) && point < ZV)
+ if (EQ (this_command, Qforward_char) && PT < ZV)
{
struct Lisp_Vector *dp
= window_display_table (XWINDOW (selected_window));
- lose = FETCH_CHAR (point);
- SET_PT (point + 1);
+ lose = FETCH_CHAR (PT);
+ SET_PT (PT + 1);
if ((dp
? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
- && XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1)
+ ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
+ : (NILP (DISP_CHAR_VECTOR (dp, lose))
+ && (lose >= 0x20 && lose < 0x7f)))
: (lose >= 0x20 && lose < 0x7f))
&& (XFASTINT (XWINDOW (selected_window)->last_modified)
>= MODIFF)
&& (XFASTINT (XWINDOW (selected_window)->last_point)
- == point - 1)
+ == PT - 1)
&& !windows_or_buffers_changed
&& EQ (current_buffer->selective_display, Qnil)
&& !detect_input_pending ()
no_redisplay = direct_output_forward_char (1);
goto directly_done;
}
- else if (EQ (this_command, Qbackward_char) && point > BEGV)
+ else if (EQ (this_command, Qbackward_char) && PT > BEGV)
{
struct Lisp_Vector *dp
= window_display_table (XWINDOW (selected_window));
- SET_PT (point - 1);
- lose = FETCH_CHAR (point);
+ SET_PT (PT - 1);
+ lose = FETCH_CHAR (PT);
if ((dp
- ? (XTYPE (DISP_CHAR_VECTOR (dp, lose)) != Lisp_Vector
- && XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1)
+ ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
+ ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
+ : (NILP (DISP_CHAR_VECTOR (dp, lose))
+ && (lose >= 0x20 && lose < 0x7f)))
: (lose >= 0x20 && lose < 0x7f))
&& (XFASTINT (XWINDOW (selected_window)->last_modified)
>= MODIFF)
&& (XFASTINT (XWINDOW (selected_window)->last_point)
- == point + 1)
+ == PT + 1)
&& !windows_or_buffers_changed
&& EQ (current_buffer->selective_display, Qnil)
&& !detect_input_pending ()
&& XTYPE (last_command_char) == Lisp_Int)
{
unsigned char c = XINT (last_command_char);
+ int value;
- if (NILP (Vexecuting_macro) &&
- !EQ (minibuf_window, selected_window))
+ if (NILP (Vexecuting_macro)
+ && !EQ (minibuf_window, selected_window))
{
if (!nonundocount || nonundocount >= 20)
{
}
nonundocount++;
}
- lose = (XFASTINT (XWINDOW (selected_window)->last_modified)
- < MODIFF)
- || (XFASTINT (XWINDOW (selected_window)->last_point)
- != point)
- || MODIFF <= current_buffer->save_modified
- || windows_or_buffers_changed
- || !EQ (current_buffer->selective_display, Qnil)
- || detect_input_pending ()
- || !NILP (Vexecuting_macro);
- if (internal_self_insert (c, 0))
- {
- lose = 1;
- nonundocount = 0;
- }
- if (!lose &&
- (point == ZV || FETCH_CHAR (point) == '\n'))
+ lose = ((XFASTINT (XWINDOW (selected_window)->last_modified)
+ < MODIFF)
+ || (XFASTINT (XWINDOW (selected_window)->last_point)
+ != PT)
+ || MODIFF <= current_buffer->save_modified
+ || windows_or_buffers_changed
+ || !EQ (current_buffer->selective_display, Qnil)
+ || detect_input_pending ()
+ || !NILP (Vexecuting_macro));
+ value = internal_self_insert (c, 0);
+ if (value)
+ lose = 1;
+ if (value == 2)
+ nonundocount = 0;
+
+ if (!lose
+ && (PT == ZV || FETCH_CHAR (PT) == '\n'))
{
struct Lisp_Vector *dp
= window_display_table (XWINDOW (selected_window));
if (dp)
{
- Lisp_Object obj = DISP_CHAR_VECTOR (dp, lose);
-
- if (XTYPE (obj) == Lisp_Vector
- && XVECTOR (obj)->size == 1
- && (XTYPE (obj = XVECTOR (obj)->contents[0])
- == Lisp_Int))
- no_redisplay =
- direct_output_for_insert (XINT (obj));
+ Lisp_Object obj;
+
+ obj = DISP_CHAR_VECTOR (dp, lose);
+ if (NILP (obj))
+ {
+ /* Do it only for char codes
+ that by default display as themselves. */
+ if (lose >= 0x20 && lose <= 0x7e)
+ no_redisplay = direct_output_for_insert (lose);
+ }
+ else if (XTYPE (obj) == Lisp_Vector
+ && XVECTOR (obj)->size == 1
+ && (XTYPE (obj = XVECTOR (obj)->contents[0])
+ == Lisp_Int)
+ /* Insist face not specified in glyph. */
+ && (XINT (obj) & ((-1) << 8)) == 0)
+ no_redisplay
+ = direct_output_for_insert (XINT (obj));
}
else
{
}
directly_done: ;
- if (!NILP (Vpost_command_hook))
- {
- /* If we get an error during the post-command-hook,
- cause post-command-hook to be nil. */
- Vcommand_hook_internal = Vpost_command_hook;
- Vpost_command_hook = Qnil;
-
- call1 (Vrun_hooks, Qcommand_hook_internal);
+ /* Note that the value cell will never directly contain nil
+ if the symbol is a local variable. */
+ if (!NILP (XSYMBOL (Qpost_command_hook)->value) && !NILP (Vrun_hooks))
+ safe_run_hooks (Qpost_command_hook);
- Vpost_command_hook = Vcommand_hook_internal;
- }
+ if (!NILP (Vdeferred_action_list))
+ call0 (Vdeferred_action_function);
/* If there is a prefix argument,
1) We don't want last_command to be ``universal-argument''
this_command_key_count = 0;
}
- if (!NILP (current_buffer->mark_active))
+ if (!NILP (current_buffer->mark_active) && !NILP (Vrun_hooks))
{
if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode))
{
}
}
}
+
+/* If we get an error while running the hook, cause the hook variable
+ to be nil. Also inhibit quits, so that C-g won't cause the hook
+ to mysteriously evaporate. */
+static void
+safe_run_hooks (hook)
+ Lisp_Object hook;
+{
+ Lisp_Object value;
+ int count = specpdl_ptr - specpdl;
+ specbind (Qinhibit_quit, Qt);
+
+ /* We read and set the variable with functions,
+ in case it's buffer-local. */
+ value = Vcommand_hook_internal = Fsymbol_value (hook);
+ Fset (hook, Qnil);
+ call1 (Vrun_hooks, Qcommand_hook_internal);
+ Fset (hook, value);
+
+ unbind_to (count, Qnil);
+}
\f
/* Number of seconds between polling for input. */
int polling_period;
/* Nonzero means polling for input is temporarily suppressed. */
int poll_suppress_count;
-#ifdef POLL_FOR_INPUT
+/* Nonzero if polling_for_input is actually being used. */
int polling_for_input;
+#ifdef POLL_FOR_INPUT
+
/* Handle an alarm once each second and read pending input
so as to handle a C-g if it comces in. */
#endif
}
+/* Nonzero if we are using polling to handle input asynchronously. */
+
+int
+input_polling_used ()
+{
+#ifdef POLL_FOR_INPUT
+ return read_socket_hook && !interrupt_input;
+#else
+ return 0;
+#endif
+}
+
/* Turn off polling. */
stop_polling ()
poll_suppress_count = count;
#endif
}
+
+/* Bind polling_period to a value at least N.
+ But don't decrease it. */
+
+bind_polling_period (n)
+ int n;
+{
+#ifdef POLL_FOR_INPUT
+ int new = polling_period;
+
+ if (n > new)
+ new = n;
+
+ stop_polling ();
+ specbind (Qpolling_period, make_number (new));
+ /* Start a new alarm with the new period. */
+ start_polling ();
+#endif
+}
\f
/* Applying the control modifier to CHARACTER. */
int
int count;
jmp_buf save_jump;
- if (CONSP (unread_command_events))
+ if (CONSP (Vunread_command_events))
{
- c = XCONS (unread_command_events)->car;
- unread_command_events = XCONS (unread_command_events)->cdr;
+ c = XCONS (Vunread_command_events)->car;
+ Vunread_command_events = XCONS (Vunread_command_events)->cdr;
if (this_command_key_count == 0)
goto reread_first;
goto reread_first;
}
- if (commandflag >= 0 && !input_pending && !detect_input_pending ())
+ /* Don't bother updating menu bars while doing mouse tracking.
+ We get events very rapidly then, and the menu bar won't be changing.
+ We do update the menu bar once on entry to Ftrack_mouse. */
+ if (commandflag > 0 && !input_pending && !detect_input_pending ())
prepare_menu_bars ();
/* Save outer setjmp data, in case called recursively. */
menu prompting. If EVENT_HAS_PARAMETERS then we are reading
after a mouse event so don't try a minibuf menu. */
c = Qnil;
- if (nmaps > 0 && INTERACTIVE &&
- !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event))
+ if (nmaps > 0 && INTERACTIVE
+ && !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event)
+ /* Don't bring up a menu if we already have another event. */
+ && NILP (Vunread_command_events)
+ && unread_command_char < 0
+ && !detect_input_pending ())
{
c = read_char_minibuf_menu_prompt (commandflag, nmaps, maps);
- if ( ! NILP(c) ) return c ;
+ if (! NILP (c))
+ goto non_reread;
}
/* If in middle of key sequence and minibuffer not active,
}
/* Try reading using an X menu.
- This is never confused with reading using the minibuf because the recursive
- call of read_char in read_char_minibuf_menu_prompt does not pass on
- any keys maps */
- if (nmaps > 0 && INTERACTIVE &&
- !NILP (prev_event) && EVENT_HAS_PARAMETERS (prev_event))
+ This is never confused with reading using the minibuf
+ because the recursive call of read_char in read_char_minibuf_menu_prompt
+ does not pass on any keymaps. */
+ if (nmaps > 0 && INTERACTIVE
+ && !NILP (prev_event) && EVENT_HAS_PARAMETERS (prev_event)
+ /* Don't bring up a menu if we already have another event. */
+ && NILP (Vunread_command_events)
+ && unread_command_char < 0)
c = read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu);
/* Slow down auto saves logarithmically in size of current buffer,
if (!NILP (c))
break;
if (commandflag >= 0 && !input_pending && !detect_input_pending ())
- redisplay ();
+ {
+ prepare_menu_bars ();
+ redisplay ();
+ }
}
/* Terminate Emacs in batch mode if at eof. */
start_polling ();
+ /* Buffer switch events are only for internal wakeups
+ so don't show them to the user. */
+ if (XTYPE (c) == Lisp_Buffer)
+ return c;
+
+ /* Wipe the echo area. */
echo_area_glyphs = 0;
/* Handle things that only apply to characters. */
if (dribble)
{
if (XTYPE (c) == Lisp_Int)
- putc (XINT (c), dribble);
+ {
+ if (XUINT (c) < 0x100)
+ putc (XINT (c), dribble);
+ else
+ fprintf (dribble, " 0x%x", XUINT (c));
+ }
else
{
- Lisp_Object dribblee = c;
+ Lisp_Object dribblee;
/* If it's a structured event, take the event header. */
- dribblee = EVENT_HEAD (dribblee);
+ dribblee = EVENT_HEAD (c);
if (XTYPE (dribblee) == Lisp_Symbol)
{
from_macro:
reread_first:
- /* Record this character as part of the current key.
- Don't record mouse motion; it should never matter. */
+ /* Don't echo mouse motion events. */
if (! (EVENT_HAS_PARAMETERS (c)
&& EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
- {
- echo_char (c);
- add_command_key (c);
- }
+ echo_char (c);
+
+ /* Record this character as part of the current key. */
+ add_command_key (c);
/* Re-reading in the middle of a command */
reread:
XSET (val, Lisp_Int, do_mouse_tracking);
record_unwind_protect (tracking_off, val);
+ if (!input_pending && !detect_input_pending ())
+ prepare_menu_bars ();
+
do_mouse_tracking = 1;
val = Fprogn (args);
get returned to Emacs as an event, the next event read
will set Vlast_event_frame again, so this is safe to do. */
{
- Lisp_Object focus
- = FRAME_FOCUS_FRAME (XFRAME (event->frame_or_window));
+ Lisp_Object focus;
+ focus = FRAME_FOCUS_FRAME (XFRAME (event->frame_or_window));
if (NILP (focus))
internal_last_event_frame = event->frame_or_window;
else
kbd_fetch_ptr = event + 1;
}
#endif
+ else if (event->kind == menu_bar_event)
+ {
+ /* The event value is in the frame_or_window slot. */
+ obj = event->frame_or_window;
+ kbd_fetch_ptr = event + 1;
+ }
+ else if (event->kind == buffer_switch_event)
+ {
+ /* The value doesn't matter here; only the type is tested. */
+ XSET (obj, Lisp_Buffer, current_buffer);
+ kbd_fetch_ptr = event + 1;
+ }
/* Just discard these, by returning nil.
(They shouldn't be found in the buffer,
but on some machines it appears they do show up.) */
else
{
#ifdef MULTI_FRAME
- Lisp_Object frame = event->frame_or_window;
+ Lisp_Object frame;
Lisp_Object focus;
+ frame = event->frame_or_window;
if (XTYPE (frame) == Lisp_Window)
frame = WINDOW_FRAME (XWINDOW (frame));
frames. */
if (f)
{
- Lisp_Object frame = FRAME_FOCUS_FRAME (f);
+ Lisp_Object frame;
+ frame = FRAME_FOCUS_FRAME (f);
if (NILP (frame))
XSET (frame, Lisp_Frame, f);
}
#endif
+#if defined(MULTI_FRAME) || defined(HAVE_MOUSE)
/* If we didn't decide to make a switch-frame event, go ahead and
return a mouse-motion event. */
if (NILP (obj))
obj = make_lispy_movement (f, bar_window, part, x, y, time);
- }
+#endif
+ }
else
/* We were promised by the above while loop that there was
something for us to read! */
"help",
"break", /* 0xff6b */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, "backtab", 0,
0, /* 0xff76 */
0, 0, 0, 0, 0, 0, 0, 0, "kp-numlock", /* 0xff7f */
"kp-space", /* 0xff80 */ /* IsKeypadKey */
"kp-f2",
"kp-f3",
"kp-f4",
- 0, /* 0xff95 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ "kp-home", /* 0xff95 */
+ "kp-left",
+ "kp-up",
+ "kp-right",
+ "kp-down",
+ "kp-prior", /* kp-page-up */
+ "kp-next", /* kp-page-down */
+ "kp-end",
+ "kp-begin",
+ "kp-insert",
+ "kp-delete",
+ 0, /* 0xffa0 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
"kp-multiply", /* 0xffaa */
"kp-add",
"kp-separator",
/ sizeof (lispy_function_keys[0])));
break;
+#if defined(MULTI_FRAME) || defined(HAVE_MOUSE)
/* A mouse click. Figure out where it is, decide whether it's
a press, click or drag, and build the appropriate structure. */
case mouse_click:
Lisp_Object posn;
int row, column;
+ /* Ignore mouse events that were made on frame that
+ have been deleted. */
+ if (! FRAME_LIVE_P (f))
+ return Qnil;
+
pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
&column, &row, 0, 0);
#endif
{
Lisp_Object items, item;
+ int hpos;
+ int i;
+
+ /* Activate the menu bar on the down event. If the
+ up event comes in before the menu code can deal with it,
+ just ignore it. */
+ if (! (event->modifiers & down_modifier))
+ return Qnil;
#ifdef USE_X_TOOLKIT
/* The click happened in the menubar.
XFASTINT (event->y) = 1;
#else /* not USE_X_TOOLKIT */
- int hpos;
- int i;
-
+ item = Qnil;
items = FRAME_MENU_BAR_ITEMS (f);
for (i = 0; i < XVECTOR (items)->size; i += 3)
{
window = window_from_coordinates (f, column, row, &part);
if (XTYPE (window) != Lisp_Window)
- posn = Qnil;
+ {
+ window = event->frame_or_window;
+ posn = Qnil;
+ }
else
{
int pixcolumn, pixrow;
{
/* The third element of every position should be the (x,y)
pair. */
- Lisp_Object down = Fnth (make_number (2), start_pos);
+ Lisp_Object down;
+ down = Fnth (make_number (2), start_pos);
if (EQ (event->x, XCONS (down)->car)
&& EQ (event->y, XCONS (down)->cdr))
{
{
/* Get the symbol we should use for the mouse click. */
- Lisp_Object head
- = modify_event_symbol (button,
- event->modifiers,
- Qmouse_click, Qnil,
- lispy_mouse_names, &mouse_syms,
- (sizeof (lispy_mouse_names)
- / sizeof (lispy_mouse_names[0])));
-
+ Lisp_Object head;
+
+ head = modify_event_symbol (button,
+ event->modifiers,
+ Qmouse_click, Qnil,
+ lispy_mouse_names, &mouse_syms,
+ (sizeof (lispy_mouse_names)
+ / sizeof (lispy_mouse_names[0])));
if (event->modifiers & drag_modifier)
return Fcons (head,
Fcons (start_pos,
Qnil));
}
}
+#endif /* MULTI_FRAME or HAVE_MOUSE */
/* The 'kind' field of the event is something we don't recognize. */
default:
}
}
+#if defined(MULTI_FRAME) || defined(HAVE_MOUSE)
+
static Lisp_Object
make_lispy_movement (frame, bar_window, part, x, y, time)
FRAME_PTR frame;
Lisp_Object x, y;
unsigned long time;
{
+#ifdef MULTI_FRAME
/* Is it a scroll bar movement? */
if (frame && ! NILP (bar_window))
{
- Lisp_Object part_sym = *scroll_bar_parts[(int) part];
+ Lisp_Object part_sym;
+ part_sym = *scroll_bar_parts[(int) part];
return Fcons (Qscroll_bar_movement,
(Fcons (Fcons (bar_window,
Fcons (Qvertical_scroll_bar,
/* Or is it an ordinary mouse movement? */
else
+#endif /* MULTI_FRAME */
{
int area;
Lisp_Object window;
Lisp_Object posn;
int column, row;
- pixel_to_glyph_coords (frame, XINT (x), XINT (y), &column, &row, 0, 0);
-
+#ifdef MULTI_FRAME
if (frame)
- window = window_from_coordinates (frame, column, row, &area);
+#else
+ if (1)
+#endif
+ {
+ /* It's in a frame; which window on that frame? */
+ pixel_to_glyph_coords (frame, XINT (x), XINT (y), &column, &row, 0, 1);
+ window = window_from_coordinates (frame, column, row, &area);
+ }
else
window = Qnil;
XSET (posn, Lisp_Int,
buffer_posn_from_coords (XWINDOW (window), column, row));
}
+#ifdef MULTI_FRAME
else if (frame != 0)
{
XSET (window, Lisp_Frame, frame);
posn = Qnil;
}
+#endif
else
{
window = Qnil;
}
}
+#endif /* neither MULTI_FRAME nor HAVE_MOUSE */
+
/* Construct a switch frame event. */
static Lisp_Object
make_lispy_switch_frame (frame)
}
{
- Lisp_Object new_name = make_uninit_string (mod_len + base_len);
+ Lisp_Object new_name;
+ new_name = make_uninit_string (mod_len + base_len);
bcopy (new_mods, XSTRING (new_name)->data, mod_len);
bcopy (base, XSTRING (new_name)->data + mod_len, base_len);
parse_modifiers (symbol)
Lisp_Object symbol;
{
- Lisp_Object elements = Fget (symbol, Qevent_symbol_element_mask);
+ Lisp_Object elements;
+ elements = Fget (symbol, Qevent_symbol_element_mask);
if (CONSP (elements))
return elements;
else
{
int end;
int modifiers = parse_modifiers_uncached (symbol, &end);
- Lisp_Object unmodified
- = Fintern (make_string (XSYMBOL (symbol)->name->data + end,
- XSYMBOL (symbol)->name->size - end),
- Qnil);
+ Lisp_Object unmodified;
Lisp_Object mask;
+ unmodified = Fintern (make_string (XSYMBOL (symbol)->name->data + end,
+ XSYMBOL (symbol)->name->size - end),
+ Qnil);
+
if (modifiers & ~((1<<VALBITS) - 1))
abort ();
XFASTINT (mask) = modifiers;
/* The click modifier never figures into cache indices. */
cache = Fget (base, Qmodifier_cache);
XFASTINT (index) = (modifiers & ~click_modifier);
- entry = Fassq (index, cache);
+ entry = assq_no_quit (index, cache);
if (CONSP (entry))
new_symbol = XCONS (entry)->cdr;
Qevent_kind set right as well. */
if (NILP (Fget (new_symbol, Qevent_kind)))
{
- Lisp_Object kind = Fget (base, Qevent_kind);
+ Lisp_Object kind;
+ kind = Fget (base, Qevent_kind);
if (! NILP (kind))
Fput (new_symbol, Qevent_kind, kind);
}
{
/* It's hopefully okay to write the code this way, since everything
will soon be in caches, and no consing will be done at all. */
- Lisp_Object parsed = parse_modifiers (symbol);
+ Lisp_Object parsed;
+ parsed = parse_modifiers (symbol);
return apply_modifiers (XCONS (XCONS (parsed)->cdr)->car,
XCONS (parsed)->car);
}
/* Is this a request for a valid symbol? */
if (symbol_num < 0 || symbol_num >= table_size)
- abort ();
+ return Qnil;
if (CONSP (*symbol_table))
value = Fcdr (assq_no_quit (symbol_int, *symbol_table));
{
/* No; let's create it. */
if (!NILP (name_alist))
- value = Fassq (symbol_int, name_alist);
+ value = Fcdr_safe (Fassq (symbol_int, name_alist));
else if (name_table[symbol_num])
value = intern (name_table[symbol_num]);
- else
+
+ if (NILP (value))
{
char buf[20];
sprintf (buf, "key-%d", symbol_num);
read_avail_input (expected);
#endif
}
+
+/* Put a buffer_switch_event in the buffer
+ so that read_key_sequence will notice the new current buffer. */
+
+record_asynch_buffer_change ()
+{
+ struct input_event event;
+ Lisp_Object tem;
+
+ event.kind = buffer_switch_event;
+ event.frame_or_window = Qnil;
+
+ /* We don't need a buffer-switch event unless Emacs is waiting for input.
+ The purpose of the event is to make read_key_sequence look up the
+ keymaps again. If we aren't in read_key_sequence, we don't need one,
+ and the event could cause trouble by messing up (input-pending-p). */
+ tem = Fwaiting_for_user_input_p ();
+ if (NILP (tem))
+ return;
+
+ /* Make sure no interrupt happens while storing the event. */
+#ifdef SIGIO
+ if (interrupt_input)
+ {
+ SIGMASKTYPE mask;
+ mask = sigblockx (SIGIO);
+ kbd_buffer_store_event (&event);
+ sigsetmask (mask);
+ }
+ else
+#endif
+ {
+ stop_polling ();
+ kbd_buffer_store_event (&event);
+ start_polling ();
+ }
+}
\f
#ifndef VMS
the kbd_buffer can really hold. That may prevent loss
of characters on some systems when input is stuffed at us. */
unsigned char cbuf[KBD_BUFFER_SIZE - 1];
+ int n_to_read;
+ /* Determine how many characters we should *try* to read. */
#ifdef MSDOS
- nread = dos_keysns ();
- if (nread == 0) return 0;
-#else */ not MSDOS */
+ n_to_read = dos_keysns ();
+ if (n_to_read == 0)
+ return 0;
+#else /* not MSDOS */
#ifdef FIONREAD
/* Find out how much input is available. */
- if (ioctl (0, FIONREAD, &nread) < 0)
+ if (ioctl (0, FIONREAD, &n_to_read) < 0)
/* Formerly simply reported no input, but that sometimes led to
a failure of Emacs to terminate.
SIGHUP seems appropriate if we can't reach the terminal. */
rather than to the whole process group?
Perhaps on systems with FIONREAD Emacs is alone in its group. */
kill (getpid (), SIGHUP);
- if (nread == 0)
+ if (n_to_read == 0)
return 0;
- if (nread > sizeof cbuf)
- nread = sizeof cbuf;
+ if (n_to_read > sizeof cbuf)
+ n_to_read = sizeof cbuf;
#else /* no FIONREAD */
#if defined(USG) || defined(DGUX)
/* Read some input if available, but don't wait. */
- nread = sizeof cbuf;
+ n_to_read = sizeof cbuf;
fcntl (fileno (stdin), F_SETFL, O_NDELAY);
#else
you lose;
#endif
#endif /* not MSDOS */
- /* Now read; for one reason or another, this will not block. */
- while (1)
+ /* Now read; for one reason or another, this will not block.
+ NREAD is set to the number of chars read. */
+ do
{
#ifdef MSDOS
cbuf[0] = dos_keyread();
nread = 1;
#else
- nread = read (fileno (stdin), cbuf, nread);
+ nread = read (fileno (stdin), cbuf, n_to_read);
#endif
-#ifdef AIX
+#if defined (AIX) && (! defined (aix386) && defined (_BSD))
/* The kernel sometimes fails to deliver SIGHUP for ptys.
This looks incorrect, but it isn't, because _BSD causes
O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
if (nread == 0)
kill (0, SIGHUP);
#endif
- /* This code is wrong, but at least it gets the right results.
- Fix it for 19.23. */
- /* Retry the read if it is interrupted. */
- if (nread >= 0
+ }
+ while (
+ /* We used to retry the read if it was interrupted.
+ But this does the wrong thing when O_NDELAY causes
+ an EAGAIN error. Does anybody know of a situation
+ where a retry is actually needed? */
+#if 0
+ nread < 0 && (errno == EAGAIN
#ifdef EFAULT
- || ! (errno == EAGAIN || errno == EFAULT
-#else
- || ! (errno == EAGAIN
+ || errno == EFAULT
#endif
#ifdef EBADSLT
- || errno == EBADSLT
+ || errno == EBADSLT
#endif
- ))
- break;
- }
+ )
+#else
+ 0
+#endif
+ );
#ifndef FIONREAD
#if defined (USG) || defined (DGUX)
/* Return a vector of menu items for a menu bar, appropriate
to the current buffer. Each item has three elements in the vector:
- KEY STRING nil.
+ KEY STRING MAPLIST.
OLD is an old vector we can optionally reuse, or nil. */
}
\f
/* Scan one map KEYMAP, accumulating any menu items it defines
- that have not yet been seen in RESULT. Return the updated RESULT.
- *OLD is the frame's old menu bar list; we swipe elts from that
- to avoid consing. */
+ in menu_bar_items_vector. */
static void
menu_bar_one_keymap (keymap)
menu_bar_item (key, item_string, Fcdr (binding));
}
else if (EQ (binding, Qundefined))
- menu_bar_item (key, item_string, binding);
+ menu_bar_item (key, Qnil, binding);
}
else if (XTYPE (item) == Lisp_Vector)
{
menu_bar_item (key, item_string, Fcdr (binding));
}
else if (EQ (binding, Qundefined))
- menu_bar_item (key, item_string, binding);
+ menu_bar_item (key, Qnil, binding);
}
}
}
return Qnil;
}
+/* Add one item to menu_bar_items_vector, for KEY, ITEM_STRING and DEF.
+ If there's already an item for KEY, add this DEF to it. */
+
static void
menu_bar_item (key, item_string, def)
Lisp_Object key, item_string, def;
if (EQ (def, Qundefined))
{
- /* If a map has an explicit nil as definition,
+ /* If a map has an explicit `undefined' as definition,
discard any previously made menu bar item. */
for (i = 0; i < menu_bar_items_index; i += 3)
menu_bar_items_index -= 3;
return;
}
+
+ /* If there's no definition for this key yet,
+ just ignore `undefined'. */
+ return;
}
/* See if this entry is enabled. */
if (NILP (enabled))
return;
- /* If there's already such an item, don't make another. */
+ /* Find any existing item for this KEY. */
for (i = 0; i < menu_bar_items_index; i += 3)
if (EQ (key, XVECTOR (menu_bar_items_vector)->contents[i]))
break;
- /* If we did not find this item, add it at the end. */
+ /* If we did not find this KEY, add it at the end. */
if (i == menu_bar_items_index)
{
/* If vector is too small, get a bigger one. */
/* Add this item. */
XVECTOR (menu_bar_items_vector)->contents[i++] = key;
XVECTOR (menu_bar_items_vector)->contents[i++] = item_string;
- XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
+ XVECTOR (menu_bar_items_vector)->contents[i++] = Fcons (def, Qnil);
menu_bar_items_index = i;
}
+ /* We did find an item for this KEY. Add DEF to its list of maps. */
+ else
+ {
+ Lisp_Object old;
+ old = XVECTOR (menu_bar_items_vector)->contents[i + 2];
+ XVECTOR (menu_bar_items_vector)->contents[i + 2] = Fcons (def, old);
+ }
}
\f
/* Read a character using menus based on maps in the array MAPS.
/* If we got more than one event, put all but the first
onto this list to be read later.
Return just the first event now. */
- unread_command_events
- = nconc2 (XCONS (value)->cdr, unread_command_events);
+ Vunread_command_events
+ = nconc2 (XCONS (value)->cdr, Vunread_command_events);
value = XCONS (value)->car;
}
- if (NILP (value))
+ else if (NILP (value))
value = Qt;
if (used_mouse_menu)
*used_mouse_menu = 1;
}
static Lisp_Object
-read_char_minibuf_menu_prompt(commandflag, nmaps, maps)
+read_char_minibuf_menu_prompt (commandflag, nmaps, maps)
int commandflag ;
int nmaps;
Lisp_Object *maps;
int width = FRAME_WIDTH (selected_frame) - 4;
char *menu = (char *) alloca (width + 4);
int idx = -1;
- int nobindings ;
+ int nobindings = 1;
Lisp_Object rest, vector;
if (! menu_prompting)
CURRENT with non-prefix bindings for meta-prefix-char become nil in
NEXT.
- When KEY is not defined in any of the keymaps, if it is an upper
- case letter and there are bindings for the corresponding lower-case
- letter, return the bindings for the lower-case letter.
- We store 1 in *CASE_CONVERTED in this case.
- Otherwise, we don't change *CASE_CONVERTED.
-
If KEY has no bindings in any of the CURRENT maps, NEXT is left
unmodified.
NEXT may == CURRENT. */
static int
-follow_key (key, nmaps, current, defs, next, case_converted)
+follow_key (key, nmaps, current, defs, next)
Lisp_Object key;
Lisp_Object *current, *defs, *next;
int nmaps;
- int *case_converted;
{
int i, first_binding;
defs[i] = Qnil;
}
- /* When KEY is not defined in any of the keymaps, if it is an upper
- case letter and there are bindings for the corresponding
- lower-case letter, return the bindings for the lower-case letter. */
- if (first_binding == nmaps
- && XTYPE (key) == Lisp_Int
- && ((((XINT (key) & 0x3ffff)
- < XSTRING (current_buffer->downcase_table)->size)
- && UPPERCASEP (XINT (key) & 0x3ffff))
- || (XINT (key) & shift_modifier)))
- {
- if (XINT (key) & shift_modifier)
- XSETINT (key, XINT (key) & ~shift_modifier);
- else
- XSETINT (key, (DOWNCASE (XINT (key) & 0x3ffff)
- | (XINT (key) & ~0x3ffff)));
-
- first_binding = nmaps;
- for (i = nmaps - 1; i >= 0; i--)
- {
- if (! NILP (current[i]))
- {
- defs[i] = get_keyelt (access_keymap (current[i], key, 1, 0));
- if (! NILP (defs[i]))
- first_binding = i;
- }
- else
- defs[i] = Qnil;
- }
- if (first_binding != nmaps)
- *case_converted = 1;
- }
-
/* Given the set of bindings we've found, produce the next set of maps. */
if (first_binding < nmaps)
for (i = 0; i < nmaps; i++)
struct buffer *starting_buffer;
- /* Nonzero if we found the binding for one of the chars
- in this key sequence by downcasing it. */
- int case_converted = 0;
-
/* Nonzero if we seem to have got the beginning of a binding
in function_key_map. */
int function_key_possible = 0;
{
if (!NILP (prompt))
echo_prompt (XSTRING (prompt)->data);
- else if (cursor_in_echo_area)
+ else if (cursor_in_echo_area && echo_keystrokes)
/* 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. */
echo_dash ();
replay_sequence:
starting_buffer = current_buffer;
- case_converted = 0;
function_key_possible = 0;
/* Build our list of keymaps.
Thus, if ESC O a has a function-key-map translation
and ESC o has a binding, don't return after ESC O,
so that we can translate ESC O plus the next character. */
- || (function_key_possible && case_converted))
+ )
{
Lisp_Object key;
int used_mouse_menu = 0;
{
key = keybuf[t];
add_command_key (key);
- echo_char (key);
+ if (echo_keystrokes)
+ echo_char (key);
}
/* If not, we should actually read a character. */
or when user programs play with this-command-keys. */
if (EVENT_HAS_PARAMETERS (key))
{
- Lisp_Object kind = EVENT_HEAD_KIND (EVENT_HEAD (key));
+ Lisp_Object kind;
+ kind = EVENT_HEAD_KIND (EVENT_HEAD (key));
if (EQ (kind, Qmouse_click))
{
- Lisp_Object window = POSN_WINDOW (EVENT_START (key));
- Lisp_Object posn = POSN_BUFFER_POSN (EVENT_START (key));
+ Lisp_Object window, posn;
+ window = POSN_WINDOW (EVENT_START (key));
+ posn = POSN_BUFFER_POSN (EVENT_START (key));
if (XTYPE (posn) == Lisp_Cons)
{
/* We're looking at the second event of a
goto replay_key;
}
}
- else
+ else if (CONSP (XCONS (key)->cdr)
+ && CONSP (EVENT_START (key))
+ && CONSP (XCONS (EVENT_START (key))->cdr))
{
- Lisp_Object posn = POSN_BUFFER_POSN (EVENT_START (key));
+ Lisp_Object posn;
+ posn = POSN_BUFFER_POSN (EVENT_START (key));
/* Handle menu-bar events:
insert the dummy prefix event `menu-bar'. */
if (EQ (posn, Qmenu_bar))
if (t + 1 >= bufsize)
error ("key sequence too long");
/* Run the Lucid hook. */
- call1 (Vrun_hooks, Qactivate_menubar_hook);
+ if (!NILP (Vrun_hooks))
+ call1 (Vrun_hooks, Qactivate_menubar_hook);
/* If it has changed current-menubar from previous value,
really recompute the menubar from the value. */
if (! NILP (Vlucid_menu_bar_dirty_flag))
nmaps - first_binding,
submaps + first_binding,
defs + first_binding,
- submaps + first_binding,
- &case_converted)
+ submaps + first_binding)
+ first_binding);
/* If KEY wasn't bound, we'll try some fallbacks. */
if (first_binding >= nmaps)
{
- Lisp_Object head = EVENT_HEAD (key);
+ Lisp_Object head;
+ head = EVENT_HEAD (key);
if (EQ (head, Vhelp_char))
{
read_key_sequence_cmd = Vprefix_help_command;
if (XTYPE (head) == Lisp_Symbol)
{
- Lisp_Object breakdown = parse_modifiers (head);
- int modifiers = XINT (XCONS (XCONS (breakdown)->cdr)->car);
+ Lisp_Object breakdown;
+ int modifiers;
+ breakdown = parse_modifiers (head);
+ modifiers = XINT (XCONS (XCONS (breakdown)->cdr)->car);
/* Attempt to reduce an unbound mouse event to a simpler
event that is bound:
Drags reduce to clicks.
nmaps - local_first_binding,
submaps + local_first_binding,
defs + local_first_binding,
- submaps + local_first_binding,
- &case_converted)
+ submaps + local_first_binding)
+ local_first_binding);
/* If that click is bound, go for it. */
off the end of it. We only want to scan real keyboard input
for function key sequences, so if mock_input says that we're
re-reading old events, don't examine it. */
- if ((first_binding >= nmaps || case_converted)
+ if (first_binding >= nmaps
&& t >= mock_input)
{
Lisp_Object fkey_next;
fkey_next
= get_keyelt (access_keymap (fkey_next, key, 1, 0));
+#if 0 /* I didn't turn this on, because it might cause trouble
+ for the mapping of return into C-m and tab into C-i. */
+ /* Optionally don't map function keys into other things.
+ This enables the user to redefine kp- keys easily. */
+ if (SYMBOLP (key) && !NILP (Vinhibit_function_key_mapping))
+ fkey_next = Qnil;
+#endif
+
/* If the function key map gives a function, not an
array, then call the function with no args and use
its value instead. */
}
}
}
+
+ /* If KEY is not defined in any of the keymaps,
+ and cannot be part of a function key or translation,
+ and is an upper case letter
+ use the corresponding lower-case letter instead. */
+ if (first_binding == nmaps && ! function_key_possible
+ && XTYPE (key) == Lisp_Int
+ && ((((XINT (key) & 0x3ffff)
+ < XSTRING (current_buffer->downcase_table)->size)
+ && UPPERCASEP (XINT (key) & 0x3ffff))
+ || (XINT (key) & shift_modifier)))
+ {
+ if (XINT (key) & shift_modifier)
+ XSETINT (key, XINT (key) & ~shift_modifier);
+ else
+ XSETINT (key, (DOWNCASE (XINT (key) & 0x3ffff)
+ | (XINT (key) & ~0x3ffff)));
+
+ keybuf[t - 1] = key;
+ mock_input = t;
+ goto replay_sequence;
+ }
}
read_key_sequence_cmd = (first_binding < nmaps
Better ideas? */
for (; t < mock_input; t++)
{
- echo_char (keybuf[t]);
+ if (echo_keystrokes)
+ echo_char (keybuf[t]);
add_command_key (keybuf[t]);
}
if (XTYPE (cmd) == Lisp_Symbol)
{
tem = Fget (cmd, Qdisabled);
- if (!NILP (tem))
+ if (!NILP (tem) && !NILP (Vrun_hooks))
return call1 (Vrun_hooks, Qdisabled_command_hook);
}
Actually, the value is nil only if we can be sure that no input is available.")
()
{
- if (!NILP (unread_command_events) || unread_command_char != -1)
+ if (!NILP (Vunread_command_events) || unread_command_char != -1)
return (Qt);
return detect_input_pending () ? Qt : Qnil;
defining_kbd_macro = 0;
update_mode_lines++;
- unread_command_events = Qnil;
+ Vunread_command_events = Qnil;
unread_command_char = -1;
discard_tty_input ();
int old_errno = errno;
#ifdef USG
- /* USG systems forget handlers when they are used;
- must reestablish each time */
- signal (SIGINT, interrupt_signal);
- signal (SIGQUIT, interrupt_signal);
+ if (!read_socket_hook && NILP (Vwindow_system))
+ {
+ /* USG systems forget handlers when they are used;
+ must reestablish each time */
+ signal (SIGINT, interrupt_signal);
+ signal (SIGQUIT, interrupt_signal);
+ }
#endif /* USG */
cancel_echoing ();
clear_waiting_for_input ();
input_pending = 0;
- unread_command_events = Qnil;
+ Vunread_command_events = Qnil;
unread_command_char = -1;
#ifdef POLL_FOR_INPUT
command_loop_level = -1;
immediate_quit = 0;
quit_char = Ctl ('g');
- unread_command_events = Qnil;
+ Vunread_command_events = Qnil;
unread_command_char = -1;
total_keys = 0;
recent_keys_index = 0;
if (initialized)
Ffillarray (kbd_buffer_frame_or_window, Qnil);
- if (!noninteractive)
+ if (!noninteractive && !read_socket_hook && NILP (Vwindow_system))
{
signal (SIGINT, interrupt_signal);
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
SIGQUIT and we can't tell which one it will give us. */
signal (SIGQUIT, interrupt_signal);
#endif /* HAVE_TERMIO */
+ }
/* Note SIGIO has been undef'd if FIONREAD is missing. */
#ifdef SIGIO
- signal (SIGIO, input_available_signal);
+ if (!noninteractive)
+ signal (SIGIO, input_available_signal);
#endif /* SIGIO */
- }
/* Use interrupt input by default, if it works and noninterrupt input
has deficiencies. */
Qactivate_menubar_hook = intern ("activate-menubar-hook");
staticpro (&Qactivate_menubar_hook);
+ Qpolling_period = intern ("polling-period");
+ staticpro (&Qpolling_period);
+
{
struct event_head *p;
= Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil);
staticpro (&kbd_buffer_frame_or_window);
+ accent_key_syms = Qnil;
+ staticpro (&accent_key_syms);
+
func_key_syms = Qnil;
staticpro (&func_key_syms);
+ system_key_syms = Qnil;
+ staticpro (&system_key_syms);
+
mouse_syms = Qnil;
staticpro (&mouse_syms);
DEFVAR_LISP ("last-command-char", &last_command_char,
"Last input event that was part of a command.");
- DEFVAR_LISP ("last-command-event", &last_command_char,
+ DEFVAR_LISP_NOPRO ("last-command-event", &last_command_char,
"Last input event that was part of a command.");
DEFVAR_LISP ("last-nonmenu-event", &last_nonmenu_event,
DEFVAR_LISP ("last-input-char", &last_input_char,
"Last input event.");
- DEFVAR_LISP ("last-input-event", &last_input_char,
+ DEFVAR_LISP_NOPRO ("last-input-event", &last_input_char,
"Last input event.");
- DEFVAR_LISP ("unread-command-events", &unread_command_events,
+ DEFVAR_LISP ("unread-command-events", &Vunread_command_events,
"List of objects to be read as next command input events.");
DEFVAR_INT ("unread-command-char", &unread_command_char,
"*Number of complete keys read from the keyboard so far.");
num_input_keys = 0;
-#ifdef MULTI_FRAME
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;
-#endif
DEFVAR_LISP ("help-char", &Vhelp_char,
"Character to recognize as meaning Help.\n\
Vcommand_hook_internal = Qnil;
DEFVAR_LISP ("pre-command-hook", &Vpre_command_hook,
- "Normal hook run before each command is executed.");
+ "Normal hook run before each command is executed.\n\
+While the hook is run, its value is temporarily set to nil\n\
+to avoid an unbreakable infinite loop if a hook function gets an error.\n\
+As a result, a hook function cannot straightforwardly alter the value of\n\
+`pre-command-hook'. See the Emacs Lisp manual for a way of\n\
+implementing hook functions that alter the set of hook functions.");
Vpre_command_hook = Qnil;
DEFVAR_LISP ("post-command-hook", &Vpost_command_hook,
- "Normal hook run after each command is executed.");
+ "Normal hook run after each command is executed.\n\
+While the hook is run, its value is temporarily set to nil\n\
+to avoid an unbreakable infinite loop if a hook function gets an error.\n\
+As a result, a hook function cannot straightforwardly alter the value of\n\
+`post-command-hook'. See the Emacs Lisp manual for a way of\n\
+implementing hook functions that alter the set of hook functions.");
Vpost_command_hook = Qnil;
DEFVAR_LISP ("lucid-menu-bar-dirty-flag", &Vlucid_menu_bar_dirty_flag,
Each element should have the form (N . SYMBOL) where N is the\n\
numeric keysym code (sans the \"system-specific\" bit 1<<28)\n\
and SYMBOL is its name.");
- Vmenu_bar_final_items = Qnil;
+ Vsystem_key_alist = Qnil;
+
+ DEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list,
+ "List of deferred actions to be performed at a later time.\n\
+The precise format isn't relevant here; we just check whether it is nil.");
+ Vdeferred_action_list = Qnil;
+
+ DEFVAR_LISP ("deferred-action-function", &Vdeferred_action_function,
+ "Function to call to handle deferred actions, after each command.\n\
+This function is called with no arguments after each command\n\
+whenever `deferred-action-list' is non-nil.");
+ Vdeferred_action_function = Qnil;
}
keys_of_keyboard ()