Filter keyhints based on count prefix.

If a count prefix is given, only hint commands that can take a count.
This commit is contained in:
Ryan Roden-Corrent 2017-10-02 12:01:53 -04:00
parent 5d787c84ea
commit 4a9e22163b
4 changed files with 23 additions and 6 deletions

View File

@ -515,3 +515,7 @@ class Command:
raise cmdexc.PrerequisitesError(
"{}: This command is only allowed in {} mode, not {}.".format(
self.name, mode_names, mode.name))
def takes_count(self):
"""Return true iff this command can take a count argument."""
return any(arg.count for arg in self._qute_args)

View File

@ -33,6 +33,7 @@ from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt
from qutebrowser.config import config
from qutebrowser.utils import utils, usertypes
from qutebrowser.commands import cmdutils
class KeyHintView(QLabel):
@ -86,7 +87,7 @@ class KeyHintView(QLabel):
Args:
prefix: The current partial keystring.
"""
_, prefix = re.match(r'^(\d*)(.*)', prefix).groups()
countstr, prefix = re.match(r'^(\d*)(.*)', prefix).groups()
if not prefix:
self._show_timer.stop()
self.hide()
@ -96,11 +97,17 @@ class KeyHintView(QLabel):
return any(fnmatch.fnmatchcase(keychain, glob)
for glob in config.val.keyhint.blacklist)
def takes_count(cmdstr):
cmdname = cmdstr.split(' ')[0]
cmd = cmdutils.cmd_dict.get(cmdname)
return cmd and cmd.takes_count()
bindings_dict = config.key_instance.get_bindings_for(modename)
bindings = [(k, v) for (k, v) in sorted(bindings_dict.items())
if k.startswith(prefix) and
not utils.is_special_key(k) and
not blacklisted(k)]
not blacklisted(k) and
(takes_count(v) or not countstr)]
if not bindings:
self._show_timer.stop()

View File

@ -336,6 +336,7 @@ class FakeCommand:
deprecated = attr.ib(False)
completion = attr.ib(None)
maxsplit = attr.ib(None)
takes_count = attr.ib(lambda: False)
class FakeTimer(QObject):

View File

@ -92,15 +92,20 @@ def test_suggestions(keyhint, config_stub):
('a', 'yellow', 'c', 'message-info cmd-ac'))
def test_suggestions_with_count(keyhint, config_stub):
"""Test that keyhints are shown based on a prefix."""
bindings = {'normal': {'aa': 'message-info cmd-aa'}}
def test_suggestions_with_count(keyhint, config_stub, monkeypatch, stubs):
"""Test that a count prefix filters out commands that take no count."""
monkeypatch.setattr('qutebrowser.commands.cmdutils.cmd_dict', {
'foo': stubs.FakeCommand(name='foo', takes_count=lambda: False),
'bar': stubs.FakeCommand(name='bar', takes_count=lambda: True),
})
bindings = {'normal': {'aa': 'foo', 'ab': 'bar'}}
config_stub.val.bindings.default = bindings
config_stub.val.bindings.commands = bindings
keyhint.update_keyhint('normal', '2a')
assert keyhint.text() == expected_text(
('a', 'yellow', 'a', 'message-info cmd-aa'),
('a', 'yellow', 'b', 'bar'),
)