Add a custom KeySequence class
This commit is contained in:
parent
a565b77bf0
commit
600919a23a
@ -28,6 +28,7 @@ from PyQt5.QtGui import QKeySequence
|
|||||||
|
|
||||||
from qutebrowser.config import config
|
from qutebrowser.config import config
|
||||||
from qutebrowser.utils import usertypes, log, utils
|
from qutebrowser.utils import usertypes, log, utils
|
||||||
|
from qutebrowser.keyinput import sequence
|
||||||
|
|
||||||
|
|
||||||
class BaseKeyParser(QObject):
|
class BaseKeyParser(QObject):
|
||||||
@ -83,7 +84,7 @@ class BaseKeyParser(QObject):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self._win_id = win_id
|
self._win_id = win_id
|
||||||
self._modename = None
|
self._modename = None
|
||||||
self._sequence = QKeySequence()
|
self._sequence = sequence.KeySequence()
|
||||||
self._count = ''
|
self._count = ''
|
||||||
if supports_count is None:
|
if supports_count is None:
|
||||||
supports_count = supports_chains
|
supports_count = supports_chains
|
||||||
@ -142,7 +143,7 @@ class BaseKeyParser(QObject):
|
|||||||
self._count += txt
|
self._count += txt
|
||||||
return None
|
return None
|
||||||
|
|
||||||
sequence = QKeySequence(*self._sequence, e.modifiers() | e.key())
|
sequence = self._sequence.append_event(e)
|
||||||
match, binding = self._match_key(sequence)
|
match, binding = self._match_key(sequence)
|
||||||
if match == QKeySequence.NoMatch:
|
if match == QKeySequence.NoMatch:
|
||||||
mappings = config.val.bindings.key_mappings
|
mappings = config.val.bindings.key_mappings
|
||||||
@ -151,22 +152,22 @@ class BaseKeyParser(QObject):
|
|||||||
# FIXME
|
# FIXME
|
||||||
raise Exception
|
raise Exception
|
||||||
txt = mapped
|
txt = mapped
|
||||||
sequence = QKeySequence(*self._sequence, e.modifiers() | e.key())
|
sequence = self._sequence.append_event(e)
|
||||||
match, binding = self._match_key(sequence)
|
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:
|
if match == QKeySequence.ExactMatch:
|
||||||
self._debug_log("Definitive match for '{}'.".format(
|
self._debug_log("Definitive match for '{}'.".format(
|
||||||
self._sequence.toString()))
|
self._sequence))
|
||||||
count = int(self._count) if self._count else None
|
count = int(self._count) if self._count else None
|
||||||
self.clear_keystring()
|
self.clear_keystring()
|
||||||
self.execute(binding, self.Type.chain, count)
|
self.execute(binding, self.Type.chain, count)
|
||||||
elif match == QKeySequence.PartialMatch:
|
elif match == QKeySequence.PartialMatch:
|
||||||
self._debug_log("No match for '{}' (added {})".format(
|
self._debug_log("No match for '{}' (added {})".format(
|
||||||
self._sequence.toString(), txt))
|
self._sequence, txt))
|
||||||
elif match == QKeySequence.NoMatch:
|
elif match == QKeySequence.NoMatch:
|
||||||
self._debug_log("Giving up with '{}', no matches".format(
|
self._debug_log("Giving up with '{}', no matches".format(
|
||||||
self._sequence.toString()))
|
self._sequence))
|
||||||
self.clear_keystring()
|
self.clear_keystring()
|
||||||
else:
|
else:
|
||||||
raise utils.Unreachable("Invalid match value {!r}".format(match))
|
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
|
# don't emit twice if the keystring was cleared in self.clear_keystring
|
||||||
if self._sequence:
|
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
|
return match != QKeySequence.NoMatch
|
||||||
|
|
||||||
@ -262,7 +263,7 @@ class BaseKeyParser(QObject):
|
|||||||
"""Clear the currently entered key sequence."""
|
"""Clear the currently entered key sequence."""
|
||||||
if self._sequence:
|
if self._sequence:
|
||||||
self._debug_log("discarding keystring '{}'.".format(
|
self._debug_log("discarding keystring '{}'.".format(
|
||||||
self._sequence.toString()))
|
self._sequence))
|
||||||
self._sequence = QKeySequence()
|
self._sequence = sequence.KeySequence()
|
||||||
self._count = ''
|
self._count = ''
|
||||||
self.keystring_updated.emit('')
|
self.keystring_updated.emit('')
|
||||||
|
58
qutebrowser/keyinput/sequence.py
Normal file
58
qutebrowser/keyinput/sequence.py
Normal 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())
|
@ -35,6 +35,7 @@ from PyQt5.QtGui import QKeySequence
|
|||||||
from qutebrowser.config import config
|
from qutebrowser.config import config
|
||||||
from qutebrowser.utils import utils, usertypes
|
from qutebrowser.utils import utils, usertypes
|
||||||
from qutebrowser.commands import cmdutils
|
from qutebrowser.commands import cmdutils
|
||||||
|
from qutebrowser.keyinput import sequence
|
||||||
|
|
||||||
|
|
||||||
class KeyHintView(QLabel):
|
class KeyHintView(QLabel):
|
||||||
@ -106,7 +107,7 @@ class KeyHintView(QLabel):
|
|||||||
|
|
||||||
bindings_dict = config.key_instance.get_bindings_for(modename)
|
bindings_dict = config.key_instance.get_bindings_for(modename)
|
||||||
bindings = [(k, v) for (k, v) in sorted(bindings_dict.items())
|
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
|
not blacklisted(k) and
|
||||||
(takes_count(v) or not countstr)]
|
(takes_count(v) or not countstr)]
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ except ImportError: # pragma: no cover
|
|||||||
|
|
||||||
import qutebrowser
|
import qutebrowser
|
||||||
from qutebrowser.utils import qtutils, log, debug
|
from qutebrowser.utils import qtutils, log, debug
|
||||||
|
from qutebrowser.keyinput import sequence
|
||||||
|
|
||||||
|
|
||||||
fake_clipboard = None
|
fake_clipboard = None
|
||||||
@ -491,7 +492,7 @@ def _parse_single_key(keystr):
|
|||||||
raise KeyParseError(keystr, "Expecting either a single key or a "
|
raise KeyParseError(keystr, "Expecting either a single key or a "
|
||||||
"<Ctrl-x> like keybinding.")
|
"<Ctrl-x> like keybinding.")
|
||||||
|
|
||||||
seq = QKeySequence(normalize_keystr(keystr), QKeySequence.PortableText)
|
seq = sequence.KeySequence(normalize_keystr(keystr), QKeySequence.PortableText)
|
||||||
if len(seq) != 1:
|
if len(seq) != 1:
|
||||||
raise KeyParseError(keystr, "Got {} keys instead of 1.".format(
|
raise KeyParseError(keystr, "Got {} keys instead of 1.".format(
|
||||||
len(seq)))
|
len(seq)))
|
||||||
@ -545,7 +546,7 @@ def _parse_keystring(keystr):
|
|||||||
def parse_keystring(keystr):
|
def parse_keystring(keystr):
|
||||||
"""Parse a keystring like <Ctrl-x> or xyz and return a KeyInfo list."""
|
"""Parse a keystring like <Ctrl-x> or xyz and return a KeyInfo list."""
|
||||||
s = ', '.join(_parse_keystring(keystr))
|
s = ', '.join(_parse_keystring(keystr))
|
||||||
return QKeySequence(s)
|
return sequence.KeySequence(s)
|
||||||
|
|
||||||
|
|
||||||
def normalize_keystr(keystr):
|
def normalize_keystr(keystr):
|
||||||
|
Loading…
Reference in New Issue
Block a user