diff --git a/qutebrowser/config/configcommands.py b/qutebrowser/config/configcommands.py index 43b9641fd..311ee4102 100644 --- a/qutebrowser/config/configcommands.py +++ b/qutebrowser/config/configcommands.py @@ -26,7 +26,7 @@ from PyQt5.QtCore import QUrl from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.completion.models import configmodel -from qutebrowser.utils import objreg, utils, message, standarddir, urlmatch +from qutebrowser.utils import objreg, message, standarddir, urlmatch from qutebrowser.config import configtypes, configexc, configfiles, configdata from qutebrowser.misc import editor from qutebrowser.keyinput import keyutils diff --git a/qutebrowser/keyinput/basekeyparser.py b/qutebrowser/keyinput/basekeyparser.py index 9510209df..63fc11eee 100644 --- a/qutebrowser/keyinput/basekeyparser.py +++ b/qutebrowser/keyinput/basekeyparser.py @@ -20,8 +20,6 @@ """Base class for vim-like key sequence parser.""" import enum -import re -import unicodedata from PyQt5.QtCore import pyqtSignal, QObject from PyQt5.QtGui import QKeySequence @@ -148,7 +146,8 @@ class BaseKeyParser(QObject): sequence = self._sequence.append_event(e) match, binding = self._match_key(sequence) if match == QKeySequence.NoMatch: - mapped = config.val.bindings.key_mappings.get(sequence, None) + mappings = config.val.bindings.key_mappings + mapped = mappings.get(sequence, None) if mapped is not None: match, binding = self._match_key(mapped) @@ -241,13 +240,13 @@ class BaseKeyParser(QObject): assert cmd self.bindings[key] = cmd - def _parse_key_command(self, modename, key, cmd): - """Parse the keys and their command and store them in the object.""" - # FIXME - # elif self._warn_on_keychains: - # log.keyboard.warning("Ignoring keychain '{}' in mode '{}' because " - # "keychains are not supported there." - # .format(key, modename)) + # FIXME + # def _parse_key_command(self, modename, key, cmd): + # """Parse the keys and their command and store them in the object.""" + # elif self._warn_on_keychains: + # log.keyboard.warning("Ignoring keychain '{}' in mode '{}' " + # "because keychains are not supported there." + # .format(key, modename)) def execute(self, cmdstr, keytype, count=None): """Handle a completed keychain. diff --git a/qutebrowser/keyinput/keyutils.py b/qutebrowser/keyinput/keyutils.py index 58b29123d..52c41d339 100644 --- a/qutebrowser/keyinput/keyutils.py +++ b/qutebrowser/keyinput/keyutils.py @@ -27,7 +27,7 @@ import attr from PyQt5.QtCore import Qt, QEvent from PyQt5.QtGui import QKeySequence, QKeyEvent -from qutebrowser.utils import utils, debug +from qutebrowser.utils import utils def key_to_string(key): @@ -209,8 +209,8 @@ class KeyInfo: an empty string if only modifiers are pressed. """ if utils.is_mac: - # Qt swaps Ctrl/Meta on macOS, so we switch it back here so the user - # can use it in the config as expected. See: + # Qt swaps Ctrl/Meta on macOS, so we switch it back here so the + # user can use it in the config as expected. See: # https://github.com/qutebrowser/qutebrowser/issues/110 # http://doc.qt.io/qt-5.4/osx-issues.html#special-keys modmask2str = collections.OrderedDict([ @@ -228,9 +228,9 @@ class KeyInfo: ]) modifier_keys = (Qt.Key_Control, Qt.Key_Alt, Qt.Key_Shift, Qt.Key_Meta, - Qt.Key_AltGr, Qt.Key_Super_L, Qt.Key_Super_R, - Qt.Key_Hyper_L, Qt.Key_Hyper_R, Qt.Key_Direction_L, - Qt.Key_Direction_R) + Qt.Key_AltGr, Qt.Key_Super_L, Qt.Key_Super_R, + Qt.Key_Hyper_L, Qt.Key_Hyper_R, Qt.Key_Direction_L, + Qt.Key_Direction_R) if self.key in modifier_keys: # Only modifier pressed return '' @@ -285,6 +285,18 @@ class KeyInfo: class KeySequence: + """A sequence of key presses. + + This internally uses chained QKeySequence objects and exposes a nicer + interface over it. + + Attributes: + _sequences: A list of QKeySequence + + Class attributes: + _MAX_LEN: The maximum amount of keys in a QKeySequence. + """ + _MAX_LEN = 4 def __init__(self, *keys): @@ -293,7 +305,7 @@ class KeySequence: sequence = QKeySequence(*sub) self._sequences.append(sequence) if keys: - assert len(self) > 0 + assert self self._validate() def __str__(self): @@ -316,15 +328,19 @@ class KeySequence: return utils.get_repr(self, keys=str(self)) def __lt__(self, other): + # pylint: disable=protected-access return self._sequences < other._sequences def __gt__(self, other): + # pylint: disable=protected-access return self._sequences > other._sequences def __eq__(self, other): + # pylint: disable=protected-access return self._sequences == other._sequences def __ne__(self, other): + # pylint: disable=protected-access return self._sequences != other._sequences def __hash__(self): @@ -334,6 +350,9 @@ class KeySequence: def __len__(self): return sum(len(seq) for seq in self._sequences) + def __bool__(self): + return bool(self._sequences) + def __getitem__(self, item): if isinstance(item, slice): keys = list(self._iter_keys()) @@ -351,6 +370,7 @@ class KeySequence: raise KeyParseError(keystr, "Got unknown key!") def matches(self, other): + """Check whether the given KeySequence matches with this one.""" # FIXME test this # pylint: disable=protected-access assert self._sequences @@ -369,16 +389,16 @@ class KeySequence: We don't care about a shift modifier with symbols (Shift-: should match a : binding even though we typed it with a shift on an US-keyboard) - However, we *do* care about Shift being involved if we got an upper-case - letter, as Shift-A should match a Shift-A binding, but not an "a" - binding. + However, we *do* care about Shift being involved if we got an + upper-case letter, as Shift-A should match a Shift-A binding, but not + an "a" binding. - In addition, Shift also *is* relevant when other modifiers are involved. + In addition, Shift also *is* relevant when other modifiers are + involved. Shift-Ctrl-X should not be equivalent to Ctrl-X. FIXME: create test cases! """ - # pylint: disable=protected-access modifiers = ev.modifiers() if (modifiers == Qt.ShiftModifier and @@ -394,6 +414,7 @@ class KeySequence: @classmethod def parse(cls, keystr): """Parse a keystring like or xyz and return a KeySequence.""" + # pylint: disable=protected-access # FIXME: test stuff like new = cls() strings = list(_parse_keystring(keystr)) @@ -402,7 +423,8 @@ class KeySequence: new._sequences.append(sequence) if keystr: - assert len(new) > 0, keystr + assert new, keystr + # pylint: disable=protected-access new._validate(keystr) return new diff --git a/qutebrowser/misc/keyhintwidget.py b/qutebrowser/misc/keyhintwidget.py index 35d453557..11446aa40 100644 --- a/qutebrowser/misc/keyhintwidget.py +++ b/qutebrowser/misc/keyhintwidget.py @@ -30,7 +30,6 @@ import re from PyQt5.QtWidgets import QLabel, QSizePolicy from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt -from PyQt5.QtGui import QKeySequence from qutebrowser.config import config from qutebrowser.utils import utils, usertypes diff --git a/qutebrowser/utils/utils.py b/qutebrowser/utils/utils.py index 9d95069c5..f7c1c90b0 100644 --- a/qutebrowser/utils/utils.py +++ b/qutebrowser/utils/utils.py @@ -26,18 +26,15 @@ import re import sys import enum import json -import collections import datetime import traceback import functools import contextlib import socket import shlex -import unicodedata -import attr -from PyQt5.QtCore import Qt, QUrl -from PyQt5.QtGui import QKeySequence, QColor, QClipboard, QDesktopServices +from PyQt5.QtCore import QUrl +from PyQt5.QtGui import QColor, QClipboard, QDesktopServices from PyQt5.QtWidgets import QApplication import pkg_resources import yaml @@ -49,7 +46,7 @@ except ImportError: # pragma: no cover YAML_C_EXT = False import qutebrowser -from qutebrowser.utils import qtutils, log, debug +from qutebrowser.utils import qtutils, log fake_clipboard = None diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py index a2a2697b1..f47ee7a0a 100644 --- a/tests/unit/config/test_config.py +++ b/tests/unit/config/test_config.py @@ -18,7 +18,6 @@ """Tests for qutebrowser.config.config.""" -import copy import types import unittest.mock diff --git a/tests/unit/keyinput/test_basekeyparser.py b/tests/unit/keyinput/test_basekeyparser.py index 91acfa423..ffd57d5f4 100644 --- a/tests/unit/keyinput/test_basekeyparser.py +++ b/tests/unit/keyinput/test_basekeyparser.py @@ -203,7 +203,8 @@ class TestSpecialKeys: assert not keyparser.execute.called def test_no_binding(self, monkeypatch, fake_keyevent_factory, keyparser): - monkeypatch.setattr(keyutils, 'keyevent_to_string', lambda binding: None) + monkeypatch.setattr(keyutils, 'keyevent_to_string', + lambda binding: None) keyparser.handle(fake_keyevent_factory(Qt.Key_A, Qt.NoModifier)) assert not keyparser.execute.called diff --git a/tests/unit/utils/test_utils.py b/tests/unit/utils/test_utils.py index 577ede306..e8391a74f 100644 --- a/tests/unit/utils/test_utils.py +++ b/tests/unit/utils/test_utils.py @@ -30,7 +30,7 @@ import re import shlex import attr -from PyQt5.QtCore import Qt, QUrl +from PyQt5.QtCore import QUrl from PyQt5.QtGui import QColor, QClipboard import pytest