summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2021-03-20 11:10:30 +0100
committerFlorian Bruhin <me@the-compiler.org>2021-03-20 11:17:38 +0100
commit10c3eb0bef09139fba770b6a24374d629d6d9b04 (patch)
tree97a7e2632e8a45410d41a4dbbf23c1fa814bdb0a
parentc6028d763ee2266e3fd7d88d821726d09d264d27 (diff)
downloadqutebrowser-10c3eb0bef09139fba770b6a24374d629d6d9b04.tar.gz
qutebrowser-10c3eb0bef09139fba770b6a24374d629d6d9b04.zip
Fix bindings.key_mappings with multiple keys
Otherwise, when e.g. doing "<Meta+Up>": "gg" in bindings.key_mappings, there's a crash like: Traceback (most recent call last): File "/usr/lib/python3.9/site-packages/qutebrowser/keyinput/eventfilter.py", line 105, in eventFilter return handler(typing.cast(QKeyEvent, event)) File "/usr/lib/python3.9/site-packages/qutebrowser/keyinput/eventfilter.py", line 75, in _handle_key_event return man.handle_event(event) File "/usr/lib/python3.9/site-packages/qutebrowser/keyinput/modeman.py", line 462, in handle_event return handler(cast(QKeyEvent, event)) File "/usr/lib/python3.9/site-packages/qutebrowser/keyinput/modeman.py", line 283, in _handle_keypress match = parser.handle(event, dry_run=dry_run) File "/usr/lib/python3.9/site-packages/qutebrowser/keyinput/modeparsers.py", line 105, in handle match = super().handle(e, dry_run=dry_run) File "/usr/lib/python3.9/site-packages/qutebrowser/keyinput/basekeyparser.py", line 309, in handle result = self._match_key_mapping(result.sequence) File "/usr/lib/python3.9/site-packages/qutebrowser/keyinput/basekeyparser.py", line 246, in _match_key_mapping mapped = sequence.with_mappings( File "/usr/lib/python3.9/site-packages/qutebrowser/keyinput/keyutils.py", line 675, in with_mappings assert len(new_seq) == 1 AssertionError While this isn't the intended way to use this setting, we shouldn't crash - and let's just make it work instead of forbidding it. (cherry picked from commit 5b6d2c60b46e233d4788a9b34d15fdb7d8d1c114)
-rw-r--r--qutebrowser/keyinput/keyutils.py7
-rw-r--r--tests/unit/keyinput/test_keyutils.py19
2 files changed, 15 insertions, 11 deletions
diff --git a/qutebrowser/keyinput/keyutils.py b/qutebrowser/keyinput/keyutils.py
index 01a07d6a0..ddf818708 100644
--- a/qutebrowser/keyinput/keyutils.py
+++ b/qutebrowser/keyinput/keyutils.py
@@ -648,10 +648,9 @@ class KeySequence:
for key in self._iter_keys():
key_seq = KeySequence(key)
if key_seq in mappings:
- new_seq = mappings[key_seq]
- assert len(new_seq) == 1
- key = new_seq[0].to_int()
- keys.append(key)
+ keys += [info.to_int() for info in mappings[key_seq]]
+ else:
+ keys.append(key)
return self.__class__(*keys)
@classmethod
diff --git a/tests/unit/keyinput/test_keyutils.py b/tests/unit/keyinput/test_keyutils.py
index 8ab2ab147..195518127 100644
--- a/tests/unit/keyinput/test_keyutils.py
+++ b/tests/unit/keyinput/test_keyutils.py
@@ -482,13 +482,18 @@ class TestKeySequence:
Qt.Key_A | Qt.ControlModifier)
assert seq.strip_modifiers() == expected
- def test_with_mappings(self):
- seq = keyutils.KeySequence.parse('foobar')
- mappings = {
- keyutils.KeySequence.parse('b'): keyutils.KeySequence.parse('t')
- }
- seq2 = seq.with_mappings(mappings)
- assert seq2 == keyutils.KeySequence.parse('footar')
+ @pytest.mark.parametrize('inp, mappings, expected', [
+ ('foobar', {'b': 't'}, 'footar'),
+ ('foo<Ctrl+x>bar', {'<Ctrl+x>': '<Ctrl+y>'}, 'foo<Ctrl+y>bar'),
+ ('foobar', {'b': 'sa'}, 'foosaar'),
+ ])
+ def test_with_mappings(self, inp, mappings, expected):
+ seq = keyutils.KeySequence.parse(inp)
+ seq2 = seq.with_mappings({
+ keyutils.KeySequence.parse(k): keyutils.KeySequence.parse(v)
+ for k, v in mappings.items()
+ })
+ assert seq2 == keyutils.KeySequence.parse(expected)
@pytest.mark.parametrize('keystr, expected', [
('<Ctrl-Alt-y>',