diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 3425880fec5..8ad9df2522a 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -2617,10 +2617,14 @@ returns the key sequence as a vector, never as a string. @cindex upper case key sequence @cindex downcasing in @code{lookup-key} @cindex shift-translation +@vindex translate-upper-case-key-bindings If an input character is upper-case (or has the shift modifier) and has no key binding, but its lower-case equivalent has one, then -@code{read-key-sequence} converts the character to lower case. Note -that @code{lookup-key} does not perform case conversion in this way. +@code{read-key-sequence} converts the character to lower case. (This +behaviour can be disabled by setting the +@code{translate-upper-case-key-bindings} user option to @code{nil}.) +Note that @code{lookup-key} does not perform case conversion in this +way. @vindex this-command-keys-shift-translated When reading input results in such a @dfn{shift-translation}, Emacs diff --git a/etc/NEWS b/etc/NEWS index 7deff1fa63f..b039310afa8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -51,6 +51,11 @@ These forms now indent like this: This change also affects 'cl-macrolet', 'cl-flet*' and 'cl-symbol-macrolet'. ++++ +** New user option 'translate-upper-case-key-bindings'. +This can be set to nil to inhibit translating upper case keys to lower +case keys. + * Changes in Specialized Modes and Packages in Emacs 29.1 diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 1a3e5682bba..a46107a6784 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -386,7 +386,7 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of (const :tag "When sent SIGUSR1" sigusr1) (const :tag "When sent SIGUSR2" sigusr2)) "24.1") - + (translate-upper-case-key-bindings keyboard boolean "29.1") ;; This is not good news because it will use the wrong ;; version-specific directories when you upgrade. We need ;; customization of the front of the list, maintaining the diff --git a/src/keyboard.c b/src/keyboard.c index bc6f97586dd..4f3232dc46c 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -10168,7 +10168,8 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt, use the corresponding lower-case letter instead. */ if (NILP (current_binding) && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t - && FIXNUMP (key)) + && FIXNUMP (key) + && translate_upper_case_key_bindings) { Lisp_Object new_key; EMACS_INT k = XFIXNUM (key); @@ -10220,12 +10221,14 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt, int modifiers = CONSP (breakdown) ? (XFIXNUM (XCAR (XCDR (breakdown)))) : 0; - if (modifiers & shift_modifier - /* Treat uppercase keys as shifted. */ - || (FIXNUMP (key) - && (KEY_TO_CHAR (key) - < XCHAR_TABLE (BVAR (current_buffer, downcase_table))->header.size) - && uppercasep (KEY_TO_CHAR (key)))) + if (translate_upper_case_key_bindings + && (modifiers & shift_modifier + /* Treat uppercase keys as shifted. */ + || (FIXNUMP (key) + && (KEY_TO_CHAR (key) + < XCHAR_TABLE (BVAR (current_buffer, + downcase_table))->header.size) + && uppercasep (KEY_TO_CHAR (key))))) { Lisp_Object new_key = (modifiers & shift_modifier @@ -12495,6 +12498,16 @@ If nil, Emacs crashes immediately in response to fatal signals. */); Vwhile_no_input_ignore_events, doc: /* Ignored events from while-no-input. */); + DEFVAR_BOOL ("translate-upper-case-key-bindings", + translate_upper_case_key_bindings, + doc: /* If non-nil, interpret upper case keys as lower case (when applicable). +Emacs allows binding both upper and lower case key sequences to +commands. However, if there is a lower case key sequence bound to a +command, and the user enters an upper case key sequence that is not +bound to a command, Emacs will use the lower case binding. Setting +this variable to nil inhibits this behaviour. */); + translate_upper_case_key_bindings = true; + pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper); }