diff options
| author | Richard M. Stallman | 1995-08-03 00:02:07 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1995-08-03 00:02:07 +0000 |
| commit | 569871d219474c845722eb170dec381c8b3874db (patch) | |
| tree | 62ef76e4c280dcb27d14569f353dc7d32b94ad7f /src | |
| parent | 9b37d8a91055ea2948251361f9c025d4f19cd990 (diff) | |
| download | emacs-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.c | 88 |
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 | ||
| 5003 | static int | 5003 | static int |
| 5004 | follow_key (key, nmaps, current, defs, next) | 5004 | follow_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 | } |