Handle special keystrings case-insensitively.

Load all special keystrings (e.g. <ctrl-a>) into memory as lowercase,
and automatically lowercase any special keystring given to bind/unbind.
This prevents <ctrl-a> and <Ctrl-A> from being treated differently.

Resolves #816.
Also resolves #1544 (dupe).
This commit is contained in:
Ryan Roden-Corrent 2016-06-03 23:04:44 -04:00
parent 24db93f3eb
commit 1dc20f4d02
2 changed files with 33 additions and 0 deletions

View File

@ -165,6 +165,10 @@ class KeyConfigParser(QObject):
(default: `normal`). (default: `normal`).
force: Rebind the key if it is already bound. force: Rebind the key if it is already bound.
""" """
if utils.is_special_key(key):
# <Ctrl-t>, <ctrl-T>, and <ctrl-t> should be considered equivalent
key = key.lower()
if mode is None: if mode is None:
mode = 'normal' mode = 'normal'
@ -206,6 +210,10 @@ class KeyConfigParser(QObject):
mode: A comma-separated list of modes to unbind the key in mode: A comma-separated list of modes to unbind the key in
(default: `normal`). (default: `normal`).
""" """
if utils.is_special_key(key):
# <Ctrl-t>, <ctrl-T>, and <ctrl-t> should be considered equivalent
key = key.lower()
if mode is None: if mode is None:
mode = 'normal' mode = 'normal'
mode = self._normalize_sectname(mode) mode = self._normalize_sectname(mode)
@ -377,6 +385,9 @@ class KeyConfigParser(QObject):
def _add_binding(self, sectname, keychain, command, *, force=False): def _add_binding(self, sectname, keychain, command, *, force=False):
"""Add a new binding from keychain to command in section sectname.""" """Add a new binding from keychain to command in section sectname."""
if utils.is_special_key(keychain):
# <Ctrl-t>, <ctrl-T>, and <ctrl-t> should be considered equivalent
keychain = keychain.lower()
log.keyboard.vdebug("Adding binding {} -> {} in mode {}.".format( log.keyboard.vdebug("Adding binding {} -> {} in mode {}.".format(
keychain, command, sectname)) keychain, command, sectname))
if sectname not in self.keybindings: if sectname not in self.keybindings:

View File

@ -45,6 +45,22 @@ Feature: Keyboard input
And I run :bind --mode=caret test08 And I run :bind --mode=caret test08
Then the message "test08 is bound to 'message-info bar' in caret mode" should be shown Then the message "test08 is bound to 'message-info bar' in caret mode" should be shown
Scenario: Binding special keys with differing case (issue 1544)
When I run :bind <ctrl-test21> message-info test01
And I run :bind <Ctrl-Test21> message-info test01
Then the error "Duplicate keychain <ctrl-test21> - use --force to override!" should be shown
Scenario: Print a special binding with differing case (issue 1544)
When I run :bind <Ctrl-Test22> message-info foo
And I run :bind <ctrl-test22>
Then the message "<ctrl-test22> is bound to 'message-info foo' in normal mode" should be shown
Scenario: Overriding a special binding with differing case (issue 816)
When I run :bind <ctrl-test23> message-info foo
And I run :bind --force <Ctrl-Test23> message-info bar
And I run :bind <ctrl-test23>
Then the message "<ctrl-test23> is bound to 'message-info bar' in normal mode" should be shown
# :unbind # :unbind
Scenario: Binding and unbinding a keychain Scenario: Binding and unbinding a keychain
@ -67,6 +83,12 @@ Feature: Keyboard input
Then "No binding found for o." should be logged Then "No binding found for o." should be logged
# maybe check it's unbound in the config? # maybe check it's unbound in the config?
Scenario: Binding and unbinding a special keychain with differing case (issue 1544)
When I run :bind <ctrl-test24> message-error test09
And I run :unbind <Ctrl-Test24>
When I run :bind <ctrl-test24>
Then the message "<ctrl-test24> is unbound in normal mode" should be shown
# :clear-keychain # :clear-keychain
Scenario: Clearing the keychain Scenario: Clearing the keychain