summaryrefslogtreecommitdiff
path: root/qutebrowser/keyinput
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2020-06-17 13:52:25 +0200
committerFlorian Bruhin <me@the-compiler.org>2020-06-17 15:42:42 +0200
commitb25c7d5b36a239f8520670390692c96a2812d300 (patch)
tree31715078b54701a9d4330f7b526d6ee4ee8dfa9f /qutebrowser/keyinput
parente9a23498b25ed213afda6e787743327a4573ee60 (diff)
downloadqutebrowser-b25c7d5b36a239f8520670390692c96a2812d300.tar.gz
qutebrowser-b25c7d5b36a239f8520670390692c96a2812d300.zip
modeparsers: Refactor how hints are handled
Instead of binding hints to fake :follow-hint commands, we now use a separate CommandKeyParser and ask that for its match result. If the key matches with the command parser, it is bound in hint mode, so we clear the hint keystring and defer to the command handling instead. If it doesn't, we continue hint handling as usual - however, the HintKeyParser is now not a CommandKeyParser anymore, so we don't have to deal with command parsing (and have a custom execute implementation instead). Closes #4504 Fixes #4392 Fixes #4368 Helps with #5084, though it doesn't completely fix that yet. Supersedes #3742 (fix for #3735) Supersedes #4691 (fix for #4264)
Diffstat (limited to 'qutebrowser/keyinput')
-rw-r--r--qutebrowser/keyinput/keyutils.py15
-rw-r--r--qutebrowser/keyinput/modeparsers.py27
2 files changed, 19 insertions, 23 deletions
diff --git a/qutebrowser/keyinput/keyutils.py b/qutebrowser/keyinput/keyutils.py
index 142bedd2f..b95f4a55d 100644
--- a/qutebrowser/keyinput/keyutils.py
+++ b/qutebrowser/keyinput/keyutils.py
@@ -180,21 +180,6 @@ def _is_printable(key: Qt.Key) -> bool:
return key <= 0xff and key not in [Qt.Key_Space, _NIL_KEY]
-def is_special_hint_mode(key: Qt.Key, modifiers: _ModifierType) -> bool:
- """Check whether this key should clear the keychain in hint mode.
-
- When we press "s<Escape>", we don't want <Escape> to be handled as part of
- a key chain in hint mode.
- """
- _assert_plain_key(key)
- _assert_plain_modifier(modifiers)
- if is_modifier_key(key):
- return False
- return not (_is_printable(key) and
- modifiers in [Qt.ShiftModifier, Qt.NoModifier,
- Qt.KeypadModifier])
-
-
def is_special(key: Qt.Key, modifiers: _ModifierType) -> bool:
"""Check whether this key requires special key syntax."""
_assert_plain_key(key)
diff --git a/qutebrowser/keyinput/modeparsers.py b/qutebrowser/keyinput/modeparsers.py
index e848250c0..a55639898 100644
--- a/qutebrowser/keyinput/modeparsers.py
+++ b/qutebrowser/keyinput/modeparsers.py
@@ -136,7 +136,7 @@ class NormalKeyParser(CommandKeyParser):
self._inhibited = False
-class HintKeyParser(CommandKeyParser):
+class HintKeyParser(basekeyparser.BaseKeyParser):
"""KeyChainParser for hints.
@@ -151,8 +151,12 @@ class HintKeyParser(CommandKeyParser):
hintmanager: hints.HintManager,
parent: QObject = None) -> None:
super().__init__(mode=usertypes.KeyMode.hint, win_id=win_id,
- commandrunner=commandrunner, parent=parent,
- supports_count=False)
+ parent=parent, supports_count=False)
+ self._command_parser = CommandKeyParser(mode=usertypes.KeyMode.hint,
+ win_id=win_id,
+ commandrunner=commandrunner,
+ parent=self,
+ supports_count=False)
self._hintmanager = hintmanager
self._filtertext = ''
self._last_press = LastPress.none
@@ -198,11 +202,14 @@ class HintKeyParser(CommandKeyParser):
if dry_run:
return super().handle(e, dry_run=True)
- if keyutils.is_special_hint_mode(Qt.Key(e.key()), e.modifiers()):
- log.keyboard.debug("Got special key, clearing keychain")
+ assert not dry_run
+
+ if (self._command_parser.handle(e, dry_run=True) !=
+ QKeySequence.NoMatch):
+ log.keyboard.debug("Handling key via command parser")
self.clear_keystring()
+ return self._command_parser.handle(e)
- assert not dry_run
match = super().handle(e)
if match == QKeySequence.PartialMatch:
@@ -227,11 +234,15 @@ class HintKeyParser(CommandKeyParser):
`self._filtertext`.
"""
self._read_config()
- self.bindings.update({keyutils.KeySequence.parse(s):
- 'follow-hint -s ' + s for s in strings})
+ self.bindings.update({keyutils.KeySequence.parse(s): s
+ for s in strings})
if not preserve_filter:
self._filtertext = ''
+ def execute(self, cmdstr: str, count: int = None) -> None:
+ assert count is None
+ self._hintmanager.handle_partial_key(cmdstr)
+
class RegisterKeyParser(CommandKeyParser):