record_char (c)
Lisp_Object c;
{
- /* Don't record `help-echo' in recent_keys unless it shows some help
- message, and a different help than the previoiusly recorded
- event. */
- if (CONSP (c) && EQ (XCAR (c), Qhelp_echo))
+ int recorded = 0;
+
+ if (CONSP (c) && (EQ (XCAR (c), Qhelp_echo) || EQ (XCAR (c), Qmouse_movement)))
{
- Lisp_Object help;
+ /* To avoid filling recent_keys with help-echo and mouse-movement
+ events, we filter out repeated help-echo events, only store the
+ first and last in a series of mouse-movement events, and don't
+ store repeated help-echo events which are only separated by
+ mouse-movement events. */
- help = Fcar (Fcdr (XCDR (c)));
- if (STRINGP (help))
+ Lisp_Object ev1, ev2, ev3;
+ int ix1, ix2, ix3;
+
+ if ((ix1 = recent_keys_index - 1) < 0)
+ ix1 = NUM_RECENT_KEYS - 1;
+ ev1 = AREF (recent_keys, ix1);
+
+ if ((ix2 = ix1 - 1) < 0)
+ ix2 = NUM_RECENT_KEYS - 1;
+ ev2 = AREF (recent_keys, ix2);
+
+ if ((ix3 = ix2 - 1) < 0)
+ ix3 = NUM_RECENT_KEYS - 1;
+ ev3 = AREF (recent_keys, ix3);
+
+ if (EQ (XCAR (c), Qhelp_echo))
{
- int last_idx;
- Lisp_Object last_c, last_help;
-
- last_idx = recent_keys_index - 1;
- if (last_idx < 0)
- last_idx = NUM_RECENT_KEYS - 1;
- last_c = AREF (recent_keys, last_idx);
-
- if (!CONSP (last_c)
- || !EQ (XCAR (last_c), Qhelp_echo)
- || (last_help = Fcar (Fcdr (XCDR (last_c))),
- !EQ (last_help, help)))
+ /* Don't record `help-echo' in recent_keys unless it shows some help
+ message, and a different help than the previoiusly recorded
+ event. */
+ Lisp_Object help, last_help;
+
+ help = Fcar_safe (Fcdr_safe (XCDR (c)));
+ if (!STRINGP (help))
+ recorded = 1;
+ else if (CONSP (ev1) && EQ (XCAR (ev1), Qhelp_echo)
+ && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev1))), EQ (last_help, help)))
+ recorded = 1;
+ else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
+ && CONSP (ev2) && EQ (XCAR (ev2), Qhelp_echo)
+ && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev2))), EQ (last_help, help)))
+ recorded = -1;
+ else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
+ && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
+ && CONSP (ev3) && EQ (XCAR (ev3), Qhelp_echo)
+ && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev3))), EQ (last_help, help)))
+ recorded = -2;
+ }
+ else if (EQ (XCAR (c), Qmouse_movement))
+ {
+ /* Only record one pair of `mouse-movement' on a window in recent_keys.
+ So additional mouse movement events replace the last element. */
+ Lisp_Object last_window, window;
+
+ window = Fcar_safe (Fcar_safe (XCDR (c)));
+ if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
+ && (last_window = Fcar_safe (Fcar_safe (XCDR (ev1))), EQ (last_window, window))
+ && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
+ && (last_window = Fcar_safe (Fcar_safe (XCDR (ev2))), EQ (last_window, window)))
{
- total_keys++;
- ASET (recent_keys, recent_keys_index, c);
- if (++recent_keys_index >= NUM_RECENT_KEYS)
- recent_keys_index = 0;
+ ASET (recent_keys, ix1, c);
+ recorded = 1;
}
}
}
else
+ store_kbd_macro_char (c);
+
+ if (!recorded)
{
total_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++;
/* Write c to the dribble file. If c is a lispy event, write
the event's symbol to the dribble file, in <brackets>. Bleaugh.
fflush (dribble);
}
-
- if (!CONSP (c) || !EQ (Qhelp_echo, XCAR (c)))
- store_kbd_macro_char (c);
-
- num_nonmacro_input_events++;
}
Lisp_Object