/* Allow config.h to undefine symbols found here. */
#include <signal.h>
-#include "config.h"
+#include <config.h>
#include <stdio.h>
#undef NULL
#include "termchar.h"
Lisp_Object recursive_edit_unwind (), command_loop ();
Lisp_Object Fthis_command_keys ();
+Lisp_Object Qextended_command_history;
/* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt
happens. */
#endif /* 0 */
/* Read next key sequence; i gets its length. */
- i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])), 0);
+ i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])), Qnil);
++num_input_keys;
/* If in middle of key sequence and minibuffer not active,
start echoing if enough time elapses. */
if (minibuf_level == 0 && !immediate_echo && this_command_key_count > 0
+ && ! noninteractive
&& echo_keystrokes > 0
&& (echo_area_glyphs == 0 || *echo_area_glyphs == 0))
{
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
+ = FRAME_FOCUS_FRAME (XFRAME (event->frame_or_window));
if (NILP (focus))
internal_last_event_frame = event->frame_or_window;
if (kbd_fetch_ptr - 1 != kbd_store_ptr)
{
kbd_store_ptr->kind = event->kind;
- kbd_store_ptr->code = event->code;
- kbd_store_ptr->part = event->part;
- kbd_store_ptr->frame_or_window = event->frame_or_window;
- kbd_store_ptr->modifiers = event->modifiers;
- kbd_store_ptr->x = event->x;
- kbd_store_ptr->y = event->y;
- kbd_store_ptr->timestamp = event->timestamp;
+ if (event->kind == selection_request_event)
+ {
+ /* We must not use the ordinary copying code for this case,
+ since `part' is an enum and copying it might not copy enough
+ in this case. */
+ bcopy (event, kbd_store_ptr, sizeof (*event));
+ }
+ else
+ {
+ kbd_store_ptr->code = event->code;
+ kbd_store_ptr->part = event->part;
+ kbd_store_ptr->frame_or_window = event->frame_or_window;
+ kbd_store_ptr->modifiers = event->modifiers;
+ kbd_store_ptr->x = event->x;
+ kbd_store_ptr->y = event->y;
+ kbd_store_ptr->timestamp = event->timestamp;
+ }
(XVECTOR (kbd_buffer_frame_or_window)->contents[kbd_store_ptr
- kbd_buffer]
= event->frame_or_window);
nread = (*read_socket_hook) (0, buf, KBD_BUFFER_SIZE, expected, expected);
else
{
- unsigned char cbuf[KBD_BUFFER_SIZE];
+ /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
+ 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];
#ifdef FIONREAD
/* Find out how much input is available. */
if (nread > sizeof cbuf)
nread = sizeof cbuf;
#else /* no FIONREAD */
-#ifdef USG
+#if defined(USG) || defined(DGUX)
/* Read some input if available, but don't wait. */
nread = sizeof cbuf;
fcntl (fileno (stdin), F_SETFL, O_NDELAY);
/* Now read; for one reason or another, this will not block. */
while (1)
{
- nread = read (fileno (stdin), cbuf, nread);
+ int value = read (fileno (stdin), cbuf, nread);
#ifdef AIX
/* 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,
and that causes a value other than 0 when there is no input. */
- if (nread == 0)
+ if (value == 0)
kill (SIGHUP, 0);
#endif
/* Retry the read if it is interrupted. */
- if (nread >= 0
+ if (value >= 0
|| ! (errno == EAGAIN || errno == EFAULT
#ifdef EBADSLT
|| errno == EBADSLT
#endif
))
- break;
+ {
+ nread = value;
+ break;
+ }
}
#ifndef FIONREAD
if (XINT (key) & shift_modifier)
XSETINT (key, XINT (key) & ~shift_modifier);
else
- XSETINT (key, DOWNCASE (XINT (key)));
+ XSETINT (key, (DOWNCASE (XINT (key) & 0x3ffff)
+ | (XINT (key) & ~0x3ffff)));
first_binding = nmaps;
for (i = nmaps - 1; i >= 0; i--)
read_key_sequence (keybuf, bufsize, prompt)
Lisp_Object *keybuf;
int bufsize;
- char *prompt;
+ Lisp_Object prompt;
{
int count = specpdl_ptr - specpdl;
we put it off for later. While we're reading, we keep the event here. */
Lisp_Object delayed_switch_frame;
+ /* See the comment below... */
+#if defined (GOBBLE_FIRST_EVENT)
Lisp_Object first_event;
+#endif
+
+ struct buffer *starting_buffer;
int junk;
if (INTERACTIVE)
{
- if (prompt)
- echo_prompt (prompt);
+ if (!NILP (prompt))
+ echo_prompt (XSTRING (prompt)->data);
else if (cursor_in_echo_area)
/* 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_start = echo_length ();
keys_start = this_command_key_count;
-#if 0 /* This doesn't quite work, because some of the things
- that read_char does cannot safely be bypassed.
- It seems too risky to try to make this work right. */
+#if defined (GOBBLE_FIRST_EVENT)
+ /* This doesn't quite work, because some of the things that read_char
+ does cannot safely be bypassed. It seems too risky to try to make
+ this work right. */
+
/* Read the first char of the sequence specially, before setting
up any keymaps, in case a filter runs and switches buffers on us. */
- first_event = read_char (!prompt, 0, submaps, last_nonmenu_event,
+ first_event = read_char (NILP (prompt), 0, submaps, last_nonmenu_event,
&junk);
-#endif
+#endif /* GOBBLE_FIRST_EVENT */
/* We jump here when the key sequence has been thoroughly changed, and
we need to rescan it starting from the beginning. When we jump here,
keybuf[0..mock_input] holds the sequence we should reread. */
replay_sequence:
+ starting_buffer = current_buffer;
+
/* Build our list of keymaps.
If we recognize a function key and replace its escape sequence in
keybuf with its symbol, or if the sequence starts with a mouse
if (! NILP (submaps[first_binding]))
break;
- /* We jump here when a function key substitution has forced us to
- reprocess the current key sequence. keybuf[0..mock_input] is the
- sequence we want to reread. */
+ /* Start from the beginning in keybuf. */
t = 0;
/* These are no-ops the first time through, but if we restart, they
{
struct buffer *buf = current_buffer;
- key = read_char (!prompt, nmaps, submaps, last_nonmenu_event,
+ key = read_char (NILP (prompt), nmaps, submaps, last_nonmenu_event,
&used_mouse_menu);
/* read_char returns t when it shows a menu and the user rejects it.
goto done;
}
+ /* If we have a quit that was typed in another frame, and
+ quit_throw_to_read_char switched buffers,
+ replay to get the right keymap. */
+ if (EQ (key, quit_char) && current_buffer != starting_buffer)
+ {
+ keybuf[t++] = key;
+ mock_input = t;
+ Vquit_flag = Qnil;
+ goto replay_sequence;
+ }
+
Vquit_flag = Qnil;
}
}
}
- new_head =
- apply_modifiers (modifiers, XCONS (breakdown)->car);
- new_click =
- Fcons (new_head, Fcons (EVENT_START (key), Qnil));
+ new_head
+ = apply_modifiers (modifiers, XCONS (breakdown)->car);
+ new_click
+ = Fcons (new_head, Fcons (EVENT_START (key), Qnil));
/* Look for a binding for this new key. follow_key
promises that it didn't munge submaps the
last time we called it, since key was unbound. */
- first_binding =
- (follow_key (new_click,
- nmaps - local_first_binding,
- submaps + local_first_binding,
- defs + local_first_binding,
- submaps + local_first_binding)
- + local_first_binding);
+ first_binding
+ = (follow_key (new_click,
+ nmaps - local_first_binding,
+ submaps + local_first_binding,
+ defs + local_first_binding,
+ submaps + local_first_binding)
+ + local_first_binding);
/* If that click is bound, go for it. */
if (first_binding < nmaps)
fkey_next
= get_keyelt (access_keymap (fkey_next, key, 1, 0));
+ /* If the function key map gives a function, not an
+ array, then call the function with no args and use
+ its value instead. */
+ if (SYMBOLP (fkey_next) && ! NILP (Ffboundp (fkey_next))
+ && fkey_end == t)
+ {
+ struct gcpro gcpro1, gcpro2, gcpro3;
+ Lisp_Object tem;
+ tem = fkey_next;
+
+ GCPRO3 (fkey_map, keytran_map, delayed_switch_frame);
+ fkey_next = call1 (fkey_next, prompt);
+ UNGCPRO;
+ /* If the function returned something invalid,
+ barf--don't ignore it.
+ (To ignore it safely, we would need to gcpro a bunch of
+ other variables.) */
+ if (! (VECTORP (fkey_next) || STRINGP (fkey_next)))
+ error ("Function in function-key-map returns invalid key sequence");
+ }
+
/* If keybuf[fkey_start..fkey_end] is bound in the
function key map and it's a suffix of the current
sequence (i.e. fkey_end == t), replace it with
int i;
for (i = 0; i < len; i++)
- XFASTINT (keybuf[fkey_start + i]) =
- XSTRING (fkey_next)->data[i];
+ XFASTINT (keybuf[fkey_start + i])
+ = XSTRING (fkey_next)->data[i];
}
mock_input = t;
keytran_next
= get_keyelt (access_keymap (keytran_next, key, 1, 0));
+ /* If the key translation map gives a function, not an
+ array, then call the function with no args and use
+ its value instead. */
+ if (SYMBOLP (keytran_next) && ! NILP (Ffboundp (keytran_next))
+ && keytran_end == t)
+ {
+ struct gcpro gcpro1, gcpro2, gcpro3;
+ Lisp_Object tem;
+ tem = keytran_next;
+
+ GCPRO3 (keytran_map, keytran_map, delayed_switch_frame);
+ keytran_next = call1 (keytran_next, prompt);
+ UNGCPRO;
+ /* If the function returned something invalid,
+ barf--don't ignore it.
+ (To ignore it safely, we would need to gcpro a bunch of
+ other variables.) */
+ if (! (VECTORP (keytran_next) || STRINGP (keytran_next)))
+ error ("Function in function-key-map returns invalid key sequence");
+ }
+
/* If keybuf[keytran_start..keytran_end] is bound in the
- function key map and it's a suffix of the current
+ key translation map and it's a suffix of the current
sequence (i.e. keytran_end == t), replace it with
the binding and restart with keytran_start at the end. */
if ((VECTORP (keytran_next) || STRINGP (keytran_next))
If the key sequence starts with a mouse click, then the sequence is read\n\
using the keymaps of the buffer of the window clicked in, not the buffer\n\
of the selected window as normal.\n\
-\n\
+""\n\
`read-key-sequence' drops unbound button-down events, since you normally\n\
only care about the click or drag events which follow them. If a drag\n\
or multi-click event is unbound, but the corresponding click event would\n\
if (NILP (continue_echo))
this_command_key_count = 0;
- i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
- NILP (prompt) ? 0 : XSTRING (prompt)->data);
+ i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])), prompt);
if (i == -1)
{
/* Prompt with buf, and then read a string, completing from and
restricting to the set of all defined commands. Don't provide
- any initial input. The last Qnil says not to perform a
- peculiar hack on the initial input. */
+ any initial input. Save the command read on the extended-command
+ history list. */
function = Fcompleting_read (build_string (buf),
Vobarray, Qcommandp,
- Qt, Qnil, Qnil);
+ Qt, Qnil, Qextended_command_history);
/* Set this_command_keys to the concatenation of saved_keys and
function, followed by a RET. */
if (poll_suppress_count == 0)
abort ();
#endif
+ if (XFRAME (internal_last_event_frame) != selected_frame)
+ Fhandle_switch_frame (make_lispy_switch_frame (internal_last_event_frame));
_longjmp (getcjmp, 1);
}
this_command_keys = Fmake_vector (make_number (40), Qnil);
staticpro (&this_command_keys);
+ Qextended_command_history = intern ("extended-command-history");
+ Fset (Qextended_command_history, Qnil);
+ staticpro (&Qextended_command_history);
+
kbd_buffer_frame_or_window
= Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil);
staticpro (&kbd_buffer_frame_or_window);
\n\
Note that the character ?\C-@, equivalent to the integer zero, does\n\
not count as a control character; rather, it counts as a character\n\
-with no modifiers; thus, setting extra_keyboard_modifiers to zero\n\
+with no modifiers; thus, setting `extra-keyboard-modifiers' to zero\n\
cancels any modification.");
extra_keyboard_modifiers = 0;