Add a Key config type

Make sure any key we get from the config is normalized).
This commit is contained in:
Florian Bruhin 2017-06-19 11:39:45 +02:00
parent 0d062b28bf
commit 383968d948
4 changed files with 32 additions and 6 deletions

View File

@ -1811,8 +1811,8 @@ bindings.key_mappings:
<Ctrl-[>: <Escape>
type:
name: Dict
keytype: String
valtype: String
keytype: Key
valtype: Key
desc: >-
This setting can be used to map keys to other keys.
@ -2071,7 +2071,7 @@ bindings.commands:
'prompt', 'caret', 'register']
valtype:
name: Dict
keytype: String # key
keytype: Key
valtype: Command
desc: >-
Keybindings mapping keys to commands in different modes.

View File

@ -1016,7 +1016,7 @@ class Dict(BaseType):
super().__init__(none_ok)
# If the keytype is not a string, we'll get problems with showing it as
# json in to_str() as json converts keys to strings.
assert isinstance(keytype, String), keytype
assert isinstance(keytype, (String, Key)), keytype
self.keytype = keytype
self.valtype = valtype
self.fixed_keys = fixed_keys
@ -1458,3 +1458,16 @@ class TimestampTemplate(BaseType):
value, "Invalid format string: {}".format(error))
return value
class Key(BaseType):
"""A name of a key."""
def to_py(self, value):
self._basic_py_validation(value, str)
if not value:
return None
if utils.is_special_key(value):
value = '<{}>'.format(utils.normalize_keystr(value[1:-1]))
return value

View File

@ -347,8 +347,7 @@ class BaseKeyParser(QObject):
def _parse_key_command(self, modename, key, cmd):
"""Parse the keys and their command and store them in the object."""
if utils.is_special_key(key):
keystr = utils.normalize_keystr(key[1:-1])
self.special_bindings[keystr] = cmd
self.special_bindings[key[1:-1]] = cmd
elif self._supports_chains:
self.bindings[key] = cmd
elif self._warn_on_keychains:

View File

@ -1801,6 +1801,20 @@ class TestTimestampTemplate:
klass().to_py('%')
class TestKey:
@pytest.fixture
def klass(self):
return configtypes.Key
@pytest.mark.parametrize('val, expected', [
('gC', 'gC'),
('<Control-x>', '<ctrl+x>')
])
def test_to_py_valid(self, klass, val, expected):
assert klass().to_py(val) == expected
@pytest.mark.parametrize('first, second, equal', [
(re.compile('foo'), RegexEq('foo'), True),
(RegexEq('bar'), re.compile('bar'), True),