Merge BaseKeyParser._handle_key into .handle
This commit is contained in:
parent
3a79f1293f
commit
b85fe8f678
@ -88,69 +88,6 @@ class BaseKeyParser(QObject):
|
||||
if self.do_log:
|
||||
log.keyboard.debug(message)
|
||||
|
||||
def _handle_key(self, e):
|
||||
"""Handle a new keypress.
|
||||
|
||||
Separate the keypress into count/command, then check if it matches
|
||||
any possible command, and either run the command, ignore it, or
|
||||
display an error.
|
||||
|
||||
Args:
|
||||
e: the KeyPressEvent from Qt.
|
||||
|
||||
Return:
|
||||
A QKeySequence match or None.
|
||||
"""
|
||||
key = e.key()
|
||||
txt = keyutils.keyevent_to_string(e)
|
||||
self._debug_log("Got key: 0x{:x} / text: '{}'".format(key, txt))
|
||||
|
||||
if not txt:
|
||||
self._debug_log("Ignoring, no text char")
|
||||
return QKeySequence.NoMatch
|
||||
|
||||
# if len(txt) == 1:
|
||||
# category = unicodedata.category(txt)
|
||||
# is_control_char = (category == 'Cc')
|
||||
# else:
|
||||
# is_control_char = False
|
||||
|
||||
# if (not txt) or is_control_char:
|
||||
# self._debug_log("Ignoring, no text char")
|
||||
# return QKeySequence.NoMatch
|
||||
|
||||
if (txt.isdigit() and self._supports_count and not
|
||||
(not self._count and txt == '0')):
|
||||
assert len(txt) == 1, txt
|
||||
self._count += txt
|
||||
return None
|
||||
|
||||
sequence = self._sequence.append_event(e)
|
||||
match, binding = self._match_key(sequence)
|
||||
if match == QKeySequence.NoMatch:
|
||||
mappings = config.val.bindings.key_mappings
|
||||
mapped = mappings.get(sequence, None)
|
||||
if mapped is not None:
|
||||
match, binding = self._match_key(mapped)
|
||||
|
||||
self._sequence = self._sequence.append_event(e)
|
||||
if match == QKeySequence.ExactMatch:
|
||||
self._debug_log("Definitive match for '{}'.".format(
|
||||
self._sequence))
|
||||
count = int(self._count) if self._count else None
|
||||
self.clear_keystring()
|
||||
self.execute(binding, count)
|
||||
elif match == QKeySequence.PartialMatch:
|
||||
self._debug_log("No match for '{}' (added {})".format(
|
||||
self._sequence, txt))
|
||||
elif match == QKeySequence.NoMatch:
|
||||
self._debug_log("Giving up with '{}', no matches".format(
|
||||
self._sequence))
|
||||
self.clear_keystring()
|
||||
else:
|
||||
raise utils.Unreachable("Invalid match value {!r}".format(match))
|
||||
return match
|
||||
|
||||
def _match_key(self, sequence):
|
||||
"""Try to match a given keystring with any bound keychain.
|
||||
|
||||
@ -175,21 +112,70 @@ class BaseKeyParser(QObject):
|
||||
return (QKeySequence.NoMatch, None)
|
||||
|
||||
def handle(self, e):
|
||||
"""Handle a new keypress and call the respective handlers.
|
||||
"""Handle a new keypress.
|
||||
|
||||
Separate the keypress into count/command, then check if it matches
|
||||
any possible command, and either run the command, ignore it, or
|
||||
display an error.
|
||||
|
||||
Args:
|
||||
e: the KeyPressEvent from Qt
|
||||
e: the KeyPressEvent from Qt.
|
||||
|
||||
Return:
|
||||
True if the event was handled, False otherwise.
|
||||
A QKeySequence match.
|
||||
"""
|
||||
match = self._handle_key(e)
|
||||
key = e.key()
|
||||
txt = keyutils.keyevent_to_string(e)
|
||||
self._debug_log("Got key: 0x{:x} / text: '{}'".format(key, txt))
|
||||
|
||||
# don't emit twice if the keystring was cleared in self.clear_keystring
|
||||
if self._sequence:
|
||||
if not txt:
|
||||
self._debug_log("Ignoring, no text char")
|
||||
return QKeySequence.NoMatch
|
||||
|
||||
# if len(txt) == 1:
|
||||
# category = unicodedata.category(txt)
|
||||
# is_control_char = (category == 'Cc')
|
||||
# else:
|
||||
# is_control_char = False
|
||||
|
||||
# if (not txt) or is_control_char:
|
||||
# self._debug_log("Ignoring, no text char")
|
||||
# return QKeySequence.NoMatch
|
||||
|
||||
if (txt.isdigit() and self._supports_count and not
|
||||
(not self._count and txt == '0')):
|
||||
assert len(txt) == 1, txt
|
||||
self._count += txt
|
||||
return QKeySequence.ExactMatch
|
||||
|
||||
sequence = self._sequence.append_event(e)
|
||||
match, binding = self._match_key(sequence)
|
||||
if match == QKeySequence.NoMatch:
|
||||
mappings = config.val.bindings.key_mappings
|
||||
mapped = mappings.get(sequence, None)
|
||||
if mapped is not None:
|
||||
match, binding = self._match_key(mapped)
|
||||
|
||||
self._sequence = self._sequence.append_event(e)
|
||||
|
||||
if match == QKeySequence.ExactMatch:
|
||||
self._debug_log("Definitive match for '{}'.".format(
|
||||
self._sequence))
|
||||
count = int(self._count) if self._count else None
|
||||
self.clear_keystring()
|
||||
self.execute(binding, count)
|
||||
elif match == QKeySequence.PartialMatch:
|
||||
self._debug_log("No match for '{}' (added {})".format(
|
||||
self._sequence, txt))
|
||||
self.keystring_updated.emit(self._count + str(self._sequence))
|
||||
elif match == QKeySequence.NoMatch:
|
||||
self._debug_log("Giving up with '{}', no matches".format(
|
||||
self._sequence))
|
||||
self.clear_keystring()
|
||||
else:
|
||||
raise utils.Unreachable("Invalid match value {!r}".format(match))
|
||||
|
||||
return match != QKeySequence.NoMatch
|
||||
return match
|
||||
|
||||
@config.change_filter('bindings')
|
||||
def _on_config_changed(self):
|
||||
|
@ -157,7 +157,7 @@ class ModeManager(QObject):
|
||||
if curmode != usertypes.KeyMode.insert:
|
||||
log.modes.debug("got keypress in mode {} - delegating to "
|
||||
"{}".format(curmode, utils.qualname(parser)))
|
||||
handled = parser.handle(event)
|
||||
match = parser.handle(event)
|
||||
|
||||
is_non_alnum = (
|
||||
event.modifiers() not in [Qt.NoModifier, Qt.ShiftModifier] or
|
||||
@ -165,7 +165,7 @@ class ModeManager(QObject):
|
||||
|
||||
forward_unbound_keys = config.val.input.forward_unbound_keys
|
||||
|
||||
if handled:
|
||||
if match:
|
||||
filter_this = True
|
||||
elif (parser.passthrough or forward_unbound_keys == 'all' or
|
||||
(forward_unbound_keys == 'auto' and is_non_alnum)):
|
||||
@ -178,10 +178,10 @@ class ModeManager(QObject):
|
||||
|
||||
if curmode != usertypes.KeyMode.insert:
|
||||
focus_widget = QApplication.instance().focusWidget()
|
||||
log.modes.debug("handled: {}, forward_unbound_keys: {}, "
|
||||
log.modes.debug("match: {}, forward_unbound_keys: {}, "
|
||||
"passthrough: {}, is_non_alnum: {} --> "
|
||||
"filter: {} (focused: {!r})".format(
|
||||
handled, forward_unbound_keys,
|
||||
match, forward_unbound_keys,
|
||||
parser.passthrough, is_non_alnum, filter_this,
|
||||
focus_widget))
|
||||
return filter_this
|
||||
|
@ -153,8 +153,8 @@ class HintKeyParser(keyparser.CommandKeyParser):
|
||||
self._read_config('hint')
|
||||
self.keystring_updated.connect(self.on_keystring_updated)
|
||||
|
||||
def _handle_special_key(self, e):
|
||||
"""Override _handle_special_key to handle string filtering.
|
||||
def _handle_filter_key(self, e):
|
||||
"""Handle keys for string filtering.
|
||||
|
||||
Return True if the keypress has been handled, and False if not.
|
||||
|
||||
@ -162,10 +162,8 @@ class HintKeyParser(keyparser.CommandKeyParser):
|
||||
e: the KeyPressEvent from Qt.
|
||||
|
||||
Return:
|
||||
True if event has been handled, False otherwise.
|
||||
A QKeySequence match.
|
||||
"""
|
||||
# FIXME rewrite this
|
||||
# FIXME should backspacing be a more generic hint feature?
|
||||
log.keyboard.debug("Got special key 0x{:x} text {}".format(
|
||||
e.key(), e.text()))
|
||||
hintmanager = objreg.get('hintmanager', scope='tab',
|
||||
@ -178,7 +176,7 @@ class HintKeyParser(keyparser.CommandKeyParser):
|
||||
if self._last_press == LastPress.filtertext and self._filtertext:
|
||||
self._filtertext = self._filtertext[:-1]
|
||||
hintmanager.filter_hints(self._filtertext)
|
||||
return True
|
||||
return QKeySequence.ExactMatch
|
||||
elif self._last_press == LastPress.keystring and self._sequence:
|
||||
self._sequence = self._sequence[:-1]
|
||||
self.keystring_updated.emit(str(self._sequence))
|
||||
@ -187,18 +185,18 @@ class HintKeyParser(keyparser.CommandKeyParser):
|
||||
# in numeric mode after the number has been deleted).
|
||||
hintmanager.filter_hints(self._filtertext)
|
||||
self._last_press = LastPress.filtertext
|
||||
return True
|
||||
return QKeySequence.ExactMatch
|
||||
else:
|
||||
return False
|
||||
return QKeySequence.NoMatch
|
||||
elif hintmanager.current_mode() != 'number':
|
||||
return False
|
||||
return QKeySequence.NoMatch
|
||||
elif not e.text():
|
||||
return False
|
||||
return QKeySequence.NoMatch
|
||||
else:
|
||||
self._filtertext += e.text()
|
||||
hintmanager.filter_hints(self._filtertext)
|
||||
self._last_press = LastPress.filtertext
|
||||
return True
|
||||
return QKeySequence.ExactMatch
|
||||
|
||||
def handle(self, e):
|
||||
"""Handle a new keypress and call the respective handlers.
|
||||
@ -209,25 +207,18 @@ class HintKeyParser(keyparser.CommandKeyParser):
|
||||
Returns:
|
||||
True if the match has been handled, False otherwise.
|
||||
"""
|
||||
# FIXME rewrite this
|
||||
match = self._handle_key(e)
|
||||
match = super().handle(e)
|
||||
if match == QKeySequence.PartialMatch:
|
||||
# FIXME do we need to check self._sequence here?
|
||||
self.keystring_updated.emit(str(self._sequence))
|
||||
self._last_press = LastPress.keystring
|
||||
return True
|
||||
elif match == QKeySequence.ExactMatch:
|
||||
self._last_press = LastPress.none
|
||||
return True
|
||||
elif match is None: # FIXME
|
||||
return None
|
||||
elif match == QKeySequence.NoMatch:
|
||||
# We couldn't find a keychain so we check if it's a special key.
|
||||
return self._handle_special_key(e)
|
||||
return self._handle_filter_key(e)
|
||||
else:
|
||||
raise ValueError("Got invalid match type {}!".format(match))
|
||||
|
||||
return match != QKeySequence.NoMatch
|
||||
return match
|
||||
|
||||
def update_bindings(self, strings, preserve_filter=False):
|
||||
"""Update bindings when the hint strings changed.
|
||||
@ -285,15 +276,16 @@ class RegisterKeyParser(keyparser.CommandKeyParser):
|
||||
Return:
|
||||
True if event has been handled, False otherwise.
|
||||
"""
|
||||
# FIXME rewrite this
|
||||
if super().handle(e):
|
||||
return True
|
||||
match = super().handle(e)
|
||||
if match:
|
||||
return match
|
||||
|
||||
key = e.text()
|
||||
|
||||
if key == '' or keyutils.keyevent_to_string(e) is None:
|
||||
# this is not a proper register key, let it pass and keep going
|
||||
return False
|
||||
# FIXME can we simplify this when we refactor keyutils.py?
|
||||
return QKeySequence.NoMatch
|
||||
|
||||
tabbed_browser = objreg.get('tabbed-browser', scope='window',
|
||||
window=self._win_id)
|
||||
@ -315,5 +307,4 @@ class RegisterKeyParser(keyparser.CommandKeyParser):
|
||||
message.error(str(err), stack=traceback.format_exc())
|
||||
|
||||
self.request_leave.emit(self._mode, "valid register key", True)
|
||||
|
||||
return True
|
||||
return QKeySequence.ExactMatch
|
||||
|
Loading…
Reference in New Issue
Block a user