From 2536766cacdd5a38c56fd852e75f830328c84a8f Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Mon, 2 May 2016 22:54:47 -0400 Subject: [PATCH 1/2] Run :bind to print the current binding. The arg is now optional. If omitted, :bind prints the current binding as a message. If --mode is given, the binding for that mode is printed. --- qutebrowser/config/parsers/keyconf.py | 21 +++++++++++++++++---- tests/integration/features/keyinput.feature | 14 ++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/qutebrowser/config/parsers/keyconf.py b/qutebrowser/config/parsers/keyconf.py index 487659984..74252cc92 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 class KeyConfigError(Exception): @@ -150,19 +150,32 @@ 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') + 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/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 From b8a593cac557f567a26614acebb4bbeab550f5a6 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Sat, 23 Apr 2016 00:24:53 -0400 Subject: [PATCH 2/2] Show command completions for :bind. All commands will be offered as completions for the argument of :bind. Due to the way completers parse the command line, the following bind --mode caret j will throw off completions as 'caret' is treated as a positional arg in terms of the argument count for completions. In the above example, completion will be triggered for 'j' and no completions will be given for the actual command. bind --mode=caret j will complete correctly, though completions are not filtered by the given mode. I attempted an approach to filter the commands based on the mode but it ended up being messy and flaky. --- qutebrowser/completion/models/instances.py | 11 ++++++++++- qutebrowser/config/parsers/keyconf.py | 6 ++++-- qutebrowser/utils/usertypes.py | 3 ++- 3 files changed, 16 insertions(+), 4 deletions(-) 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 74252cc92..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, message +from qutebrowser.utils import log, utils, qtutils, message, usertypes class KeyConfigError(Exception): @@ -151,7 +151,9 @@ class KeyConfigParser(QObject): f.write(data) @cmdutils.register(instance='key-config', maxsplit=1, no_cmd_split=True, - win_id='win_id') + 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. 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.