From 383968d948ba58dda9fb112ef001d5c29725e3e9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 19 Jun 2017 11:39:45 +0200 Subject: [PATCH] Add a Key config type Make sure any key we get from the config is normalized). --- qutebrowser/config/configdata.yml | 6 +++--- qutebrowser/config/configtypes.py | 15 ++++++++++++++- qutebrowser/keyinput/basekeyparser.py | 3 +-- tests/unit/config/test_configtypes.py | 14 ++++++++++++++ 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index 38b563dc5..e15a672fd 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -1811,8 +1811,8 @@ bindings.key_mappings: : 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. diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 11880bf80..b4918cd47 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -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 diff --git a/qutebrowser/keyinput/basekeyparser.py b/qutebrowser/keyinput/basekeyparser.py index 6722a4041..cf8aaa5f8 100644 --- a/qutebrowser/keyinput/basekeyparser.py +++ b/qutebrowser/keyinput/basekeyparser.py @@ -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: diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index 4e9678842..dfec66dac 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -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'), + ('', '') + ]) + 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),