Show hidden commands in completion for :bind.

There is a fair amount of duplicate code around command completion that
could probably be refactored.

Resolves #1707.
This commit is contained in:
Ryan Roden-Corrent 2016-08-01 12:30:12 -04:00
parent dd9470af94
commit 0ea61d5f15
5 changed files with 75 additions and 3 deletions

View File

@ -114,6 +114,13 @@ def init_session_completion():
_instances[usertypes.Completion.sessions] = model
def _init_bind_completion():
"""Initialize the command completion model."""
log.completion.debug("Initializing bind completion.")
model = miscmodels.BindCompletionModel()
_instances[usertypes.Completion.bind] = model
INITIALIZERS = {
usertypes.Completion.command: _init_command_completion,
usertypes.Completion.helptopic: _init_helptopic_completion,
@ -125,6 +132,7 @@ INITIALIZERS = {
usertypes.Completion.quickmark_by_name: init_quickmark_completions,
usertypes.Completion.bookmark_by_url: init_bookmark_completions,
usertypes.Completion.sessions: init_session_completion,
usertypes.Completion.bind: _init_bind_completion,
}
@ -182,5 +190,7 @@ def init():
keyconf = objreg.get('key-config')
keyconf.changed.connect(
functools.partial(update, [usertypes.Completion.command]))
keyconf.changed.connect(
functools.partial(update, [usertypes.Completion.bind]))
objreg.get('config').changed.connect(_update_aliases)

View File

@ -30,7 +30,7 @@ from qutebrowser.completion.models import base
class CommandCompletionModel(base.BaseCompletionModel):
"""A CompletionModel filled with all commands and descriptions."""
"""A CompletionModel filled with non-hidden commands and descriptions."""
# https://github.com/The-Compiler/qutebrowser/issues/545
# pylint: disable=abstract-method
@ -259,3 +259,33 @@ class TabCompletionModel(base.BaseCompletionModel):
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=int(win_id))
tabbed_browser.on_tab_close_requested(int(tab_index) - 1)
class BindCompletionModel(base.BaseCompletionModel):
"""A CompletionModel filled with all bindable commands and descriptions."""
# https://github.com/The-Compiler/qutebrowser/issues/545
# pylint: disable=abstract-method
COLUMN_WIDTHS = (20, 60, 20)
def __init__(self, parent=None):
super().__init__(parent)
assert cmdutils.cmd_dict
cmdlist = []
for obj in set(cmdutils.cmd_dict.values()):
if ((obj.debug and not objreg.get('args').debug) or
obj.deprecated):
pass
else:
cmdlist.append((obj.name, obj.desc))
for name, cmd in config.section('aliases').items():
cmdlist.append((name, "Alias for '{}'".format(cmd)))
cat = self.new_category("Commands")
# map each command to its bound keys and show these in the misc column
key_config = objreg.get('key-config')
cmd_to_keys = key_config.get_reverse_bindings_for('normal')
for (name, desc) in sorted(cmdlist):
self.new_item(cat, name, desc, ', '.join(cmd_to_keys[name]))

View File

@ -153,7 +153,7 @@ class KeyConfigParser(QObject):
@cmdutils.register(instance='key-config', maxsplit=1, no_cmd_split=True,
no_replace_variables=True)
@cmdutils.argument('win_id', win_id=True)
@cmdutils.argument('command', completion=usertypes.Completion.command)
@cmdutils.argument('command', completion=usertypes.Completion.bind)
def bind(self, key, win_id, command=None, *, mode='normal', force=False):
"""Bind a key to a command.

View File

@ -238,7 +238,8 @@ KeyMode = enum('KeyMode', ['normal', 'hint', 'command', 'yesno', 'prompt',
# Available command completions
Completion = enum('Completion', ['command', 'section', 'option', 'value',
'helptopic', 'quickmark_by_name',
'bookmark_by_url', 'url', 'tab', 'sessions'])
'bookmark_by_url', 'url', 'tab', 'sessions',
'bind'])
# Exit statuses for errors. Needs to be an int for sys.exit.

View File

@ -448,3 +448,34 @@ def test_setting_value_completion(qtmodeltester, monkeypatch, stubs,
('11', '', ''),
])
]
def test_bind_completion(qtmodeltester, monkeypatch, stubs, config_stub,
key_config_stub):
"""Test the results of command completion.
Validates that:
- only non-hidden and non-deprecated commands are included
- commands are sorted by name
- the command description is shown in the desc column
- the binding (if any) is shown in the misc column
- aliases are included
"""
_patch_cmdutils(monkeypatch, stubs,
'qutebrowser.completion.models.miscmodels.cmdutils')
config_stub.data['aliases'] = {'rock': 'roll'}
key_config_stub.set_bindings_for('normal', {'s': 'stop', 'rr': 'roll'})
model = miscmodels.BindCompletionModel()
qtmodeltester.data_display_may_return_none = True
qtmodeltester.check(model)
actual = _get_completions(model)
assert actual == [
("Commands", [
('drop', 'drop all user data', ''),
('hide', '', ''),
('rock', "Alias for 'roll'", ''),
('roll', 'never gonna give you up', 'rr'),
('stop', 'stop qutebrowser', 's')
])
]