[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/src/keyboard.c
From: |
Stefan Monnier |
Subject: |
[Emacs-diffs] Changes to emacs/src/keyboard.c |
Date: |
Sat, 10 May 2003 18:15:35 -0400 |
Index: emacs/src/keyboard.c
diff -c emacs/src/keyboard.c:1.740 emacs/src/keyboard.c:1.741
*** emacs/src/keyboard.c:1.740 Sat May 10 12:36:02 2003
--- emacs/src/keyboard.c Sat May 10 18:15:35 2003
***************
*** 8179,8198 ****
int nmaps;
{
int i, first_binding;
- int did_meta = 0;
first_binding = nmaps;
for (i = nmaps - 1; i >= 0; i--)
{
if (! NILP (current[i]))
{
! Lisp_Object map;
! if (did_meta)
! map = defs[i];
! else
! map = current[i];
!
! defs[i] = access_keymap (map, key, 1, 0, 1);
if (! NILP (defs[i]))
first_binding = i;
}
--- 8179,8191 ----
int nmaps;
{
int i, first_binding;
first_binding = nmaps;
for (i = nmaps - 1; i >= 0; i--)
{
if (! NILP (current[i]))
{
! defs[i] = access_keymap (current[i], key, 1, 0, 1);
if (! NILP (defs[i]))
first_binding = i;
}
***************
*** 8216,8221 ****
--- 8209,8327 ----
int start, end;
} keyremap;
+ /* Lookup KEY in MAP.
+ MAP is a keymap mapping keys to key vectors or functions.
+ If the mapping is a function and DO_FUNCTION is non-zero, then
+ the function is called with PROMPT as parameter and its return
+ value is used as the return value of this function (after checking
+ that it is indeed a vector). */
+
+ static Lisp_Object
+ access_keymap_keyremap (map, key, prompt, do_funcall)
+ Lisp_Object map, key, prompt;
+ int do_funcall;
+ {
+ Lisp_Object next;
+
+ next = access_keymap (map, key, 1, 0, 1);
+
+ /* Handle symbol with autoload definition. */
+ if (SYMBOLP (next) && !NILP (Ffboundp (next))
+ && CONSP (XSYMBOL (next)->function)
+ && EQ (XCAR (XSYMBOL (next)->function), Qautoload))
+ do_autoload (XSYMBOL (next)->function, next);
+
+ /* Handle a symbol whose function definition is a keymap
+ or an array. */
+ if (SYMBOLP (next) && !NILP (Ffboundp (next))
+ && (!NILP (Farrayp (XSYMBOL (next)->function))
+ || KEYMAPP (XSYMBOL (next)->function)))
+ next = XSYMBOL (next)->function;
+
+ /* If the keymap gives a function, not an
+ array, then call the function with one arg and use
+ its value instead. */
+ if (SYMBOLP (next) && !NILP (Ffboundp (next)) && do_funcall)
+ {
+ Lisp_Object tem;
+ tem = next;
+
+ next = call1 (next, prompt);
+ /* 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 (next) || STRINGP (next)))
+ error ("Function %s returns invalid key sequence", tem);
+ }
+ return next;
+ }
+
+ /* Do one step of the key remapping used for function-key-map and
+ key-translation-map:
+ KEYBUF is the buffer holding the input events.
+ BUFSIZE is its maximum size.
+ FKEY is a pointer to the keyremap structure to use.
+ INPUT is the index of the last element in KEYBUF.
+ DOIT if non-zero says that the remapping can actually take place.
+ DIFF is used to return the number of keys added/removed by the remapping.
+ PARENT is the root of the keymap.
+ PROMPT is the prompt to use if the remapping happens through a function.
+ The return value is non-zero if the remapping actually took place. */
+
+ static int
+ keyremap_step (keybuf, bufsize, fkey, input, doit, diff, parent, prompt)
+ Lisp_Object *keybuf, prompt, parent;
+ keyremap *fkey;
+ int input, doit, *diff, bufsize;
+ {
+ Lisp_Object next, key;
+
+ key = keybuf[fkey->end++];
+ next = access_keymap_keyremap (fkey->map, key, prompt, doit);
+
+ /* If keybuf[fkey->start..fkey->end] is bound in the
+ map and we're in a position to do the key remapping, replace it with
+ the binding and restart with fkey->start at the end. */
+ if ((VECTORP (next) || STRINGP (next)) && doit)
+ {
+ int len = XFASTINT (Flength (next));
+ int i;
+
+ *diff = len - (fkey->end - fkey->start);
+
+ if (input + *diff >= bufsize)
+ error ("Key sequence too long");
+
+ /* Shift the keys that follow fkey->end. */
+ if (*diff < 0)
+ for (i = fkey->end; i < input; i++)
+ keybuf[i + *diff] = keybuf[i];
+ else if (*diff > 0)
+ for (i = input - 1; i >= fkey->end; i--)
+ keybuf[i + *diff] = keybuf[i];
+ /* Overwrite the old keys with the new ones. */
+ for (i = 0; i < len; i++)
+ keybuf[fkey->start + i]
+ = Faref (next, make_number (i));
+
+ fkey->start = fkey->end += *diff;
+ fkey->map = parent;
+
+ return 1;
+ }
+
+ fkey->map = get_keymap (next, 0, 1);
+
+ /* If we no longer have a bound suffix, try a new position for
+ fkey->start. */
+ if (!CONSP (fkey->map))
+ {
+ fkey->end = ++fkey->start;
+ fkey->map = parent;
+ }
+ return 0;
+ }
/* Read a sequence of keys that ends with a non prefix character,
storing it in KEYBUF, a buffer of size BUFSIZE.
***************
*** 8335,8342 ****
/* Likewise, for key_translation_map. */
volatile keyremap keytran;
! /* If we receive a ``switch-frame'' event in the middle of a key sequence,
! we put it off for later. While we're reading, we keep the event here.
*/
volatile Lisp_Object delayed_switch_frame;
/* See the comment below... */
--- 8441,8449 ----
/* Likewise, for key_translation_map. */
volatile keyremap keytran;
! /* If we receive a `switch-frame' or `select-window' event in the middle of
! a key sequence, we put it off for later.
! While we're reading, we keep the event here. */
volatile Lisp_Object delayed_switch_frame;
/* See the comment below... */
***************
*** 8507,8512 ****
--- 8614,8622 ----
just one key. */
volatile int echo_local_start, keys_local_start, local_first_binding;
+ eassert (fkey.end == t || (fkey.end > t && fkey.end <= mock_input));
+ eassert (fkey.start <= fkey.end);
+ eassert (keytran.start <= keytran.end);
/* key-translation-map is applied *after* function-key-map. */
eassert (keytran.end <= fkey.start);
***************
*** 8675,8680 ****
--- 8785,8791 ----
Vquit_flag = Qnil;
if (EVENT_HAS_PARAMETERS (key)
+ /* Either a `switch-frame' or a `select-window' event. */
&& EQ (EVENT_HEAD_KIND (EVENT_HEAD (key)), Qswitch_frame))
{
/* If we're at the beginning of a key sequence, and the caller
***************
*** 9079,9285 ****
else
/* If the sequence is unbound, see if we can hang a function key
off the end of it. */
! {
! Lisp_Object next;
!
! /* Continue scan from fkey.end until we find a bound suffix.
! If we fail, increment fkey.start and start over from there. */
! while (fkey.end < t)
! {
! Lisp_Object key;
!
! key = keybuf[fkey.end++];
! next = access_keymap (fkey.map, key, 1, 0, 1);
!
! /* Handle symbol with autoload definition. */
! if (SYMBOLP (next) && ! NILP (Ffboundp (next))
! && CONSP (XSYMBOL (next)->function)
! && EQ (XCAR (XSYMBOL (next)->function), Qautoload))
! do_autoload (XSYMBOL (next)->function, next);
!
! /* Handle a symbol whose function definition is a keymap
! or an array. */
! if (SYMBOLP (next) && ! NILP (Ffboundp (next))
! && (!NILP (Farrayp (XSYMBOL (next)->function))
! || KEYMAPP (XSYMBOL (next)->function)))
! next = XSYMBOL (next)->function;
!
! #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))
! 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 (SYMBOLP (next) && ! NILP (Ffboundp (next))
! /* If there's a binding (i.e. first_binding >= nmaps)
! we don't want to apply this function-key-mapping. */
! && fkey.end == t && first_binding >= nmaps)
! {
! struct gcpro gcpro1, gcpro2, gcpro3;
! Lisp_Object tem;
! tem = next;
!
! GCPRO3 (fkey.map, keytran.map, delayed_switch_frame);
! next = call1 (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 (next) || STRINGP (next)))
! error ("Function in key-translation-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
! the binding and restart with fkey.start at the end. */
! if ((VECTORP (next) || STRINGP (next))
! /* If there's a binding (i.e. first_binding >= nmaps)
! we don't want to apply this function-key-mapping. */
! && fkey.end == t && first_binding >= nmaps)
! {
! int len = XFASTINT (Flength (next));
!
! t = fkey.start + len;
! if (t >= bufsize)
! error ("Key sequence too long");
!
! if (VECTORP (next))
! bcopy (XVECTOR (next)->contents,
! keybuf + fkey.start,
! (t - fkey.start) * sizeof (keybuf[0]));
! else if (STRINGP (next))
! {
! int i;
!
! for (i = 0; i < len; i++)
! XSETFASTINT (keybuf[fkey.start + i], SREF (next, i));
! }
!
! mock_input = t;
! fkey.start = fkey.end = t;
! fkey.map = Vfunction_key_map;
!
! /* Do pass the results through key-translation-map.
! But don't retranslate what key-translation-map
! has already translated. */
! keytran.end = keytran.start;
! keytran.map = Vkey_translation_map;
!
! goto replay_sequence;
! }
!
! fkey.map = get_keymap (next, 0, 1);
!
! /* If we no longer have a bound suffix, try a new positions for
! fkey.start. */
! if (!CONSP (fkey.map))
! {
! fkey.end = ++fkey.start;
! fkey.map = Vfunction_key_map;
! }
! }
! }
!
! /* Look for this sequence in key-translation-map. */
! {
! Lisp_Object next;
!
! /* Scan from keytran.end until we find a bound suffix. */
! while (keytran.end < fkey.start)
{
! Lisp_Object key;
!
! key = keybuf[keytran.end++];
! next = access_keymap (keytran.map, key, 1, 0, 1);
! /* Handle symbol with autoload definition. */
! if (SYMBOLP (next) && ! NILP (Ffboundp (next))
! && CONSP (XSYMBOL (next)->function)
! && EQ (XCAR (XSYMBOL (next)->function), Qautoload))
! do_autoload (XSYMBOL (next)->function, next);
!
! /* Handle a symbol whose function definition is a keymap
! or an array. */
! if (SYMBOLP (next) && ! NILP (Ffboundp (next))
! && (!NILP (Farrayp (XSYMBOL (next)->function))
! || KEYMAPP (XSYMBOL (next)->function)))
! next = XSYMBOL (next)->function;
!
! /* If the key translation map gives a function, not an
! array, then call the function with one arg and use
! its value instead. */
! if (SYMBOLP (next) && ! NILP (Ffboundp (next)))
{
! struct gcpro gcpro1, gcpro2, gcpro3;
! Lisp_Object tem;
! tem = next;
!
! GCPRO3 (fkey.map, keytran.map, delayed_switch_frame);
! next = call1 (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 (next) || STRINGP (next)))
! error ("Function in key-translation-map returns invalid key
sequence");
! }
!
! /* If keybuf[keytran.start..keytran.end] is bound in the
! 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 (next) || STRINGP (next)))
! {
! int len = XFASTINT (Flength (next));
! int i, diff = len - (keytran.end - keytran.start);
!
! mock_input = max (t, mock_input);
! if (mock_input + diff >= bufsize)
! error ("Key sequence too long");
!
! /* Shift the keys that are after keytran.end. */
! if (diff < 0)
! for (i = keytran.end; i < mock_input; i++)
! keybuf[i + diff] = keybuf[i];
! else if (diff > 0)
! for (i = mock_input - 1; i >= keytran.end; i--)
! keybuf[i + diff] = keybuf[i];
! /* Replace the keys between keytran.start and keytran.end
! with those from next. */
! for (i = 0; i < len; i++)
! keybuf[keytran.start + i]
! = Faref (next, make_number (i));
!
! mock_input += diff;
! keytran.start = keytran.end += diff;
! keytran.map = Vkey_translation_map;
!
! /* Adjust the function-key-map counters. */
! fkey.start += diff;
! fkey.end += diff;
!
goto replay_sequence;
}
! keytran.map = get_keymap (next, 0, 1);
! /* If we no longer have a bound suffix, try a new positions for
! keytran.start. */
! if (!CONSP (keytran.map))
! {
! keytran.end = ++keytran.start;
! keytran.map = Vkey_translation_map;
! }
! }
! }
/* If KEY is not defined in any of the keymaps,
and cannot be part of a function key or translation,
--- 9190,9238 ----
else
/* If the sequence is unbound, see if we can hang a function key
off the end of it. */
! /* Continue scan from fkey.end until we find a bound suffix. */
! while (fkey.end < t)
{
! struct gcpro gcpro1, gcpro2, gcpro3;
! int done, diff;
! GCPRO3 (fkey.map, keytran.map, delayed_switch_frame);
! done = keyremap_step (keybuf, bufsize, &fkey,
! max (t, mock_input),
! /* If there's a binding (i.e.
! first_binding >= nmaps) we don't want
! to apply this function-key-mapping. */
! fkey.end + 1 == t && first_binding >= nmaps,
! &diff, Vfunction_key_map, prompt);
! UNGCPRO;
! if (done)
{
! mock_input = diff + max (t, mock_input);
goto replay_sequence;
}
+ }
! /* Look for this sequence in key-translation-map.
! Scan from keytran.end until we find a bound suffix. */
! while (keytran.end < fkey.start)
! {
! struct gcpro gcpro1, gcpro2, gcpro3;
! int done, diff;
! GCPRO3 (fkey.map, keytran.map, delayed_switch_frame);
! done = keyremap_step (keybuf, bufsize, &keytran, max (t, mock_input),
! 1, &diff, Vkey_translation_map, prompt);
! UNGCPRO;
! if (done)
! {
! mock_input = diff + max (t, mock_input);
! /* Adjust the function-key-map counters. */
! fkey.end += diff;
! fkey.start += diff;
!
! goto replay_sequence;
! }
! }
/* If KEY is not defined in any of the keymaps,
and cannot be part of a function key or translation,
- [Emacs-diffs] Changes to emacs/src/keyboard.c, Stefan Monnier, 2003/05/03
- [Emacs-diffs] Changes to emacs/src/keyboard.c, Stefan Monnier, 2003/05/03
- [Emacs-diffs] Changes to emacs/src/keyboard.c, Stefan Monnier, 2003/05/05
- [Emacs-diffs] Changes to emacs/src/keyboard.c, Stefan Monnier, 2003/05/10
- [Emacs-diffs] Changes to emacs/src/keyboard.c,
Stefan Monnier <=
- [Emacs-diffs] Changes to emacs/src/keyboard.c, Stefan Monnier, 2003/05/11
- [Emacs-diffs] Changes to emacs/src/keyboard.c, Stefan Monnier, 2003/05/14
- [Emacs-diffs] Changes to emacs/src/keyboard.c, Stefan Monnier, 2003/05/14
- [Emacs-diffs] Changes to emacs/src/keyboard.c, Stefan Monnier, 2003/05/15
- [Emacs-diffs] Changes to emacs/src/keyboard.c, Stefan Monnier, 2003/05/24
- [Emacs-diffs] Changes to emacs/src/keyboard.c, Kim F. Storm, 2003/05/24
- [Emacs-diffs] Changes to emacs/src/keyboard.c, Juanma Barranquero, 2003/05/26