aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1995-08-03 00:02:07 +0000
committerRichard M. Stallman1995-08-03 00:02:07 +0000
commit569871d219474c845722eb170dec381c8b3874db (patch)
tree62ef76e4c280dcb27d14569f353dc7d32b94ad7f /src
parent9b37d8a91055ea2948251361f9c025d4f19cd990 (diff)
downloademacs-569871d219474c845722eb170dec381c8b3874db.tar.gz
emacs-569871d219474c845722eb170dec381c8b3874db.zip
(read_key_sequence): Don't downshift an event
if that fails to make it bound. (follow_key): Don't alter contents of NEXT until the end.
Diffstat (limited to 'src')
-rw-r--r--src/keyboard.c88
1 files changed, 66 insertions, 22 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 2810ec0b02b..fa0f4bdce37 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4998,7 +4998,7 @@ read_char_minibuf_menu_prompt (commandflag, nmaps, maps)
4998 If KEY has no bindings in any of the CURRENT maps, NEXT is left 4998 If KEY has no bindings in any of the CURRENT maps, NEXT is left
4999 unmodified. 4999 unmodified.
5000 5000
5001 NEXT may == CURRENT. */ 5001 NEXT may be the same array as CURRENT. */
5002 5002
5003static int 5003static int
5004follow_key (key, nmaps, current, defs, next) 5004follow_key (key, nmaps, current, defs, next)
@@ -5007,26 +5007,30 @@ follow_key (key, nmaps, current, defs, next)
5007 int nmaps; 5007 int nmaps;
5008{ 5008{
5009 int i, first_binding; 5009 int i, first_binding;
5010 int did_meta = 0;
5010 5011
5011 /* If KEY is a meta ASCII character, treat it like meta-prefix-char 5012 /* If KEY is a meta ASCII character, treat it like meta-prefix-char
5012 followed by the corresponding non-meta character. */ 5013 followed by the corresponding non-meta character.
5014 Put the results into DEFS, since we are going to alter that anyway.
5015 Do not alter CURRENT or NEXT. */
5013 if (INTEGERP (key) && (XINT (key) & CHAR_META)) 5016 if (INTEGERP (key) && (XINT (key) & CHAR_META))
5014 { 5017 {
5015 for (i = 0; i < nmaps; i++) 5018 for (i = 0; i < nmaps; i++)
5016 if (! NILP (current[i])) 5019 if (! NILP (current[i]))
5017 { 5020 {
5018 next[i] = 5021 Lisp_Object def;
5019 get_keyelt (access_keymap (current[i], meta_prefix_char, 1, 0)); 5022 def = get_keyelt (access_keymap (current[i],
5023 meta_prefix_char, 1, 0));
5020 5024
5021 /* Note that since we pass the resulting bindings through 5025 /* Note that since we pass the resulting bindings through
5022 get_keymap_1, non-prefix bindings for meta-prefix-char 5026 get_keymap_1, non-prefix bindings for meta-prefix-char
5023 disappear. */ 5027 disappear. */
5024 next[i] = get_keymap_1 (next[i], 0, 1); 5028 defs[i] = get_keymap_1 (def, 0, 1);
5025 } 5029 }
5026 else 5030 else
5027 next[i] = Qnil; 5031 defs[i] = Qnil;
5028 5032
5029 current = next; 5033 did_meta = 1;
5030 XSETINT (key, XFASTINT (key) & ~CHAR_META); 5034 XSETINT (key, XFASTINT (key) & ~CHAR_META);
5031 } 5035 }
5032 5036
@@ -5035,7 +5039,13 @@ follow_key (key, nmaps, current, defs, next)
5035 { 5039 {
5036 if (! NILP (current[i])) 5040 if (! NILP (current[i]))
5037 { 5041 {
5038 defs[i] = get_keyelt (access_keymap (current[i], key, 1, 0)); 5042 Lisp_Object map;
5043 if (did_meta)
5044 map = defs[i];
5045 else
5046 map = current[i];
5047
5048 defs[i] = get_keyelt (access_keymap (map, key, 1, 0));
5039 if (! NILP (defs[i])) 5049 if (! NILP (defs[i]))
5040 first_binding = i; 5050 first_binding = i;
5041 } 5051 }
@@ -5956,18 +5966,35 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
5956 && UPPERCASEP (XINT (key) & 0x3ffff)) 5966 && UPPERCASEP (XINT (key) & 0x3ffff))
5957 || (XINT (key) & shift_modifier))) 5967 || (XINT (key) & shift_modifier)))
5958 { 5968 {
5969 Lisp_Object new_key;
5970 int new_first_binding;
5971
5959 original_uppercase = key; 5972 original_uppercase = key;
5960 original_uppercase_position = t - 1; 5973 original_uppercase_position = t - 1;
5961 5974
5962 if (XINT (key) & shift_modifier) 5975 if (XINT (new_key) & shift_modifier)
5963 XSETINT (key, XINT (key) & ~shift_modifier); 5976 XSETINT (new_key, XINT (key) & ~shift_modifier);
5964 else 5977 else
5965 XSETINT (key, (DOWNCASE (XINT (key) & 0x3ffff) 5978 XSETINT (new_key, (DOWNCASE (XINT (key) & 0x3ffff)
5966 | (XINT (key) & ~0x3ffff))); 5979 | (XINT (key) & ~0x3ffff)));
5967 5980
5968 keybuf[t - 1] = key; 5981 /* See if new_key has a binding.
5969 mock_input = t; 5982 If it does not have one, this does not alter SUBMAPS. */
5970 goto replay_sequence; 5983 new_first_binding
5984 = (follow_key (new_key,
5985 nmaps - local_first_binding,
5986 submaps + local_first_binding,
5987 defs + local_first_binding,
5988 submaps + local_first_binding)
5989 + local_first_binding);
5990
5991 /* If that lower-case char is bound, use it instead. */
5992 if (new_first_binding < nmaps)
5993 {
5994 keybuf[t - 1] = new_key;
5995 mock_input = t;
5996 goto replay_sequence;
5997 }
5971 } 5998 }
5972 /* If KEY is not defined in any of the keymaps, 5999 /* If KEY is not defined in any of the keymaps,
5973 and cannot be part of a function key or translation, 6000 and cannot be part of a function key or translation,
@@ -5987,13 +6014,30 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
5987 modifiers = XINT (XCONS (XCONS (breakdown)->cdr)->car); 6014 modifiers = XINT (XCONS (XCONS (breakdown)->cdr)->car);
5988 if (modifiers & shift_modifier) 6015 if (modifiers & shift_modifier)
5989 { 6016 {
5990 modifiers &= ~shift_modifier; 6017 Lisp_Object new_key;
5991 key = apply_modifiers (modifiers, 6018 int new_first_binding;
5992 XCONS (breakdown)->car);
5993 6019
5994 keybuf[t - 1] = key; 6020 modifiers &= ~shift_modifier;
5995 mock_input = t; 6021 new_key = apply_modifiers (modifiers,
5996 goto replay_sequence; 6022 XCONS (breakdown)->car);
6023
6024 /* See if new_key has a binding.
6025 If it does not have one, this does not alter SUBMAPS. */
6026 new_first_binding
6027 = (follow_key (new_key,
6028 nmaps - local_first_binding,
6029 submaps + local_first_binding,
6030 defs + local_first_binding,
6031 submaps + local_first_binding)
6032 + local_first_binding);
6033
6034 /* If that unshifted key is bound, use it instead. */
6035 if (new_first_binding < nmaps)
6036 {
6037 keybuf[t - 1] = new_key;
6038 mock_input = t;
6039 goto replay_sequence;
6040 }
5997 } 6041 }
5998 } 6042 }
5999 } 6043 }