Add a custom KeySequence class

This commit is contained in:
Florian Bruhin 2017-12-29 00:53:37 +01:00
parent a565b77bf0
commit 600919a23a
4 changed files with 74 additions and 13 deletions

View File

@ -28,6 +28,7 @@ from PyQt5.QtGui import QKeySequence
from qutebrowser.config import config
from qutebrowser.utils import usertypes, log, utils
from qutebrowser.keyinput import sequence
class BaseKeyParser(QObject):
@ -83,7 +84,7 @@ class BaseKeyParser(QObject):
super().__init__(parent)
self._win_id = win_id
self._modename = None
self._sequence = QKeySequence()
self._sequence = sequence.KeySequence()
self._count = ''
if supports_count is None:
supports_count = supports_chains
@ -142,7 +143,7 @@ class BaseKeyParser(QObject):
self._count += txt
return None
sequence = QKeySequence(*self._sequence, e.modifiers() | e.key())
sequence = self._sequence.append_event(e)
match, binding = self._match_key(sequence)
if match == QKeySequence.NoMatch:
mappings = config.val.bindings.key_mappings
@ -151,22 +152,22 @@ class BaseKeyParser(QObject):
# FIXME
raise Exception
txt = mapped
sequence = QKeySequence(*self._sequence, e.modifiers() | e.key())
sequence = self._sequence.append_event(e)
match, binding = self._match_key(sequence)
self._sequence = QKeySequence(*self._sequence, e.modifiers() | e.key())
self._sequence = self._sequence.append_event(e)
if match == QKeySequence.ExactMatch:
self._debug_log("Definitive match for '{}'.".format(
self._sequence.toString()))
self._sequence))
count = int(self._count) if self._count else None
self.clear_keystring()
self.execute(binding, self.Type.chain, count)
elif match == QKeySequence.PartialMatch:
self._debug_log("No match for '{}' (added {})".format(
self._sequence.toString(), txt))
self._sequence, txt))
elif match == QKeySequence.NoMatch:
self._debug_log("Giving up with '{}', no matches".format(
self._sequence.toString()))
self._sequence))
self.clear_keystring()
else:
raise utils.Unreachable("Invalid match value {!r}".format(match))
@ -210,7 +211,7 @@ class BaseKeyParser(QObject):
# don't emit twice if the keystring was cleared in self.clear_keystring
if self._sequence:
self.keystring_updated.emit(self._count + self._sequence.toString())
self.keystring_updated.emit(self._count + str(self._sequence))
return match != QKeySequence.NoMatch
@ -262,7 +263,7 @@ class BaseKeyParser(QObject):
"""Clear the currently entered key sequence."""
if self._sequence:
self._debug_log("discarding keystring '{}'.".format(
self._sequence.toString()))
self._sequence = QKeySequence()
self._sequence))
self._sequence = sequence.KeySequence()
self._count = ''
self.keystring_updated.emit('')

View File

@ -0,0 +1,58 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Our own QKeySequence-like class and related utilities."""
from PyQt5.QtGui import QKeySequence
from qutebrowser.utils import utils
class KeySequence:
def __init__(self, *args):
self._sequence = QKeySequence(*args)
def __str__(self):
return self._sequence.toString()
def __repr__(self):
return utils.get_repr(self, keys=str(self))
def __lt__(self, other):
return self._sequence < other._sequence
def __gt__(self, other):
return self._sequence > other._sequence
def __eq__(self, other):
return self._sequence == other._sequence
def __ne__(self, other):
return self._sequence != other._sequence
def __hash__(self):
return hash(self._sequence)
def matches(self, other):
# pylint: disable=protected-access
return self._sequence.matches(other._sequence)
def append_event(self, ev):
return self.__class__(*self._sequence, ev.modifiers() | ev.key())

View File

@ -35,6 +35,7 @@ from PyQt5.QtGui import QKeySequence
from qutebrowser.config import config
from qutebrowser.utils import utils, usertypes
from qutebrowser.commands import cmdutils
from qutebrowser.keyinput import sequence
class KeyHintView(QLabel):
@ -106,7 +107,7 @@ class KeyHintView(QLabel):
bindings_dict = config.key_instance.get_bindings_for(modename)
bindings = [(k, v) for (k, v) in sorted(bindings_dict.items())
if k.matches(QKeySequence(prefix)) and # FIXME
if k.matches(sequence.KeySequence(prefix)) and # FIXME
not blacklisted(k) and
(takes_count(v) or not countstr)]

View File

@ -50,6 +50,7 @@ except ImportError: # pragma: no cover
import qutebrowser
from qutebrowser.utils import qtutils, log, debug
from qutebrowser.keyinput import sequence
fake_clipboard = None
@ -491,7 +492,7 @@ def _parse_single_key(keystr):
raise KeyParseError(keystr, "Expecting either a single key or a "
"<Ctrl-x> like keybinding.")
seq = QKeySequence(normalize_keystr(keystr), QKeySequence.PortableText)
seq = sequence.KeySequence(normalize_keystr(keystr), QKeySequence.PortableText)
if len(seq) != 1:
raise KeyParseError(keystr, "Got {} keys instead of 1.".format(
len(seq)))
@ -545,7 +546,7 @@ def _parse_keystring(keystr):
def parse_keystring(keystr):
"""Parse a keystring like <Ctrl-x> or xyz and return a KeyInfo list."""
s = ', '.join(_parse_keystring(keystr))
return QKeySequence(s)
return sequence.KeySequence(s)
def normalize_keystr(keystr):