diff --git a/qutebrowser/completion/models/instances.py b/qutebrowser/completion/models/instances.py index 002a8a815..1a3a95d3f 100644 --- a/qutebrowser/completion/models/instances.py +++ b/qutebrowser/completion/models/instances.py @@ -29,7 +29,8 @@ import functools from PyQt5.QtCore import pyqtSlot -from qutebrowser.completion.models import miscmodels, urlmodel, configmodel +from qutebrowser.completion.models import (miscmodels, urlmodel, configmodel, + base) from qutebrowser.utils import objreg, usertypes, log, debug from qutebrowser.config import configdata @@ -119,6 +120,13 @@ def init_session_completion(): _instances[usertypes.Completion.sessions] = model +def _init_empty_completion(): + """Initialize empty completion model.""" + log.completion.debug("Initializing empty completion.") + if usertypes.Completion.empty not in _instances: + _instances[usertypes.Completion.empty] = base.BaseCompletionModel() + + INITIALIZERS = { usertypes.Completion.command: _init_command_completion, usertypes.Completion.helptopic: _init_helptopic_completion, @@ -130,6 +138,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.empty: _init_empty_completion, } diff --git a/qutebrowser/config/parsers/keyconf.py b/qutebrowser/config/parsers/keyconf.py index 487659984..5d9e3fc0d 100644 --- a/qutebrowser/config/parsers/keyconf.py +++ b/qutebrowser/config/parsers/keyconf.py @@ -27,7 +27,7 @@ from PyQt5.QtCore import pyqtSignal, QObject from qutebrowser.config import configdata, textwrapper from qutebrowser.commands import cmdutils, cmdexc -from qutebrowser.utils import log, utils, qtutils +from qutebrowser.utils import log, utils, qtutils, message, usertypes class KeyConfigError(Exception): @@ -150,19 +150,34 @@ class KeyConfigParser(QObject): data = str(self) f.write(data) - @cmdutils.register(instance='key-config', maxsplit=1, no_cmd_split=True) - def bind(self, key, command, *, mode=None, force=False): + @cmdutils.register(instance='key-config', maxsplit=1, no_cmd_split=True, + win_id='win_id', + completion=[usertypes.Completion.empty, + usertypes.Completion.command]) + def bind(self, key, win_id, command=None, *, mode=None, force=False): """Bind a key to a command. Args: key: The keychain or special key (inside `<...>`) to bind. - command: The command to execute, with optional args. + command: The command to execute, with optional args, or None to + print the current binding. mode: A comma-separated list of modes to bind the key in (default: `normal`). force: Rebind the key if it is already bound. """ if mode is None: mode = 'normal' + + if command is None: + cmd = self.get_bindings_for(mode).get(key, None) + if cmd is None: + message.info(win_id, "{} is unbound in {} mode".format( + key, mode)) + else: + message.info(win_id, "{} is bound to '{}' in {} mode".format( + key, cmd, mode)) + return + mode = self._normalize_sectname(mode) for m in mode.split(','): if m not in configdata.KEY_DATA: diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index 0af42b291..accbe9448 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -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', + 'empty']) # Exit statuses for errors. Needs to be an int for sys.exit. diff --git a/tests/integration/features/keyinput.feature b/tests/integration/features/keyinput.feature index 1d930da24..656391de5 100644 --- a/tests/integration/features/keyinput.feature +++ b/tests/integration/features/keyinput.feature @@ -31,6 +31,20 @@ Feature: Keyboard input And I press the keys "test5" Then the message "test5-2" should be shown + Scenario: Printing an unbound key + When I run :bind test6 + Then the message "test6 is not bound in normal mode" should be shown + + Scenario: Printing a bound key + When I run :bind test6 message-info foo + And I run :bind test6 + Then the message "test6 is bound to 'message-info foo' in normal mode" should be shown + + Scenario: Printing a bound key in a given mode + When I run :bind --mode=caret test6 message-info bar + And I run :bind --mode=caret test6 + Then the message "test6 is bound to 'message-info bar' in caret mode" should be shown + # :unbind Scenario: Binding and unbinding a keychain