# HG changeset patch # User Richard M. Stallman # Date 807408127 0 # Node ID dd9049c5c51db80e50b53d4581cbbcc1c6a7aed6 # Parent a285eaa710ac0dda57b5a281692257b7d8e86d2b (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. diff -r a285eaa710ac -r dd9049c5c51d src/keyboard.c --- a/src/keyboard.c Wed Aug 02 23:56:20 1995 +0000 +++ b/src/keyboard.c Thu Aug 03 00:02:07 1995 +0000 @@ -4998,7 +4998,7 @@ If KEY has no bindings in any of the CURRENT maps, NEXT is left unmodified. - NEXT may == CURRENT. */ + NEXT may be the same array as CURRENT. */ static int follow_key (key, nmaps, current, defs, next) @@ -5007,26 +5007,30 @@ int nmaps; { int i, first_binding; + int did_meta = 0; /* If KEY is a meta ASCII character, treat it like meta-prefix-char - followed by the corresponding non-meta character. */ + followed by the corresponding non-meta character. + Put the results into DEFS, since we are going to alter that anyway. + Do not alter CURRENT or NEXT. */ if (INTEGERP (key) && (XINT (key) & CHAR_META)) { for (i = 0; i < nmaps; i++) if (! NILP (current[i])) { - next[i] = - get_keyelt (access_keymap (current[i], meta_prefix_char, 1, 0)); + Lisp_Object def; + def = get_keyelt (access_keymap (current[i], + meta_prefix_char, 1, 0)); /* Note that since we pass the resulting bindings through get_keymap_1, non-prefix bindings for meta-prefix-char disappear. */ - next[i] = get_keymap_1 (next[i], 0, 1); + defs[i] = get_keymap_1 (def, 0, 1); } else - next[i] = Qnil; - - current = next; + defs[i] = Qnil; + + did_meta = 1; XSETINT (key, XFASTINT (key) & ~CHAR_META); } @@ -5035,7 +5039,13 @@ { if (! NILP (current[i])) { - defs[i] = get_keyelt (access_keymap (current[i], key, 1, 0)); + Lisp_Object map; + if (did_meta) + map = defs[i]; + else + map = current[i]; + + defs[i] = get_keyelt (access_keymap (map, key, 1, 0)); if (! NILP (defs[i])) first_binding = i; } @@ -5956,18 +5966,35 @@ && UPPERCASEP (XINT (key) & 0x3ffff)) || (XINT (key) & shift_modifier))) { + Lisp_Object new_key; + int new_first_binding; + original_uppercase = key; original_uppercase_position = t - 1; - if (XINT (key) & shift_modifier) - XSETINT (key, XINT (key) & ~shift_modifier); + if (XINT (new_key) & shift_modifier) + XSETINT (new_key, XINT (key) & ~shift_modifier); else - XSETINT (key, (DOWNCASE (XINT (key) & 0x3ffff) - | (XINT (key) & ~0x3ffff))); - - keybuf[t - 1] = key; - mock_input = t; - goto replay_sequence; + XSETINT (new_key, (DOWNCASE (XINT (key) & 0x3ffff) + | (XINT (key) & ~0x3ffff))); + + /* See if new_key has a binding. + If it does not have one, this does not alter SUBMAPS. */ + new_first_binding + = (follow_key (new_key, + nmaps - local_first_binding, + submaps + local_first_binding, + defs + local_first_binding, + submaps + local_first_binding) + + local_first_binding); + + /* If that lower-case char is bound, use it instead. */ + if (new_first_binding < nmaps) + { + keybuf[t - 1] = new_key; + mock_input = t; + goto replay_sequence; + } } /* If KEY is not defined in any of the keymaps, and cannot be part of a function key or translation, @@ -5987,13 +6014,30 @@ modifiers = XINT (XCONS (XCONS (breakdown)->cdr)->car); if (modifiers & shift_modifier) { + Lisp_Object new_key; + int new_first_binding; + modifiers &= ~shift_modifier; - key = apply_modifiers (modifiers, - XCONS (breakdown)->car); - - keybuf[t - 1] = key; - mock_input = t; - goto replay_sequence; + new_key = apply_modifiers (modifiers, + XCONS (breakdown)->car); + + /* See if new_key has a binding. + If it does not have one, this does not alter SUBMAPS. */ + new_first_binding + = (follow_key (new_key, + nmaps - local_first_binding, + submaps + local_first_binding, + defs + local_first_binding, + submaps + local_first_binding) + + local_first_binding); + + /* If that unshifted key is bound, use it instead. */ + if (new_first_binding < nmaps) + { + keybuf[t - 1] = new_key; + mock_input = t; + goto replay_sequence; + } } } }