From 245212efa15e7c9d1cf65a45c7465e2760ff40f4 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Tue, 9 Aug 2016 07:35:26 -0400 Subject: [PATCH 1/5] Allow binding to an alias. Fix #1813: Cannot :bind to alias --- qutebrowser/config/parsers/keyconf.py | 5 +++-- tests/end2end/features/keyinput.feature | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/qutebrowser/config/parsers/keyconf.py b/qutebrowser/config/parsers/keyconf.py index 7c7eb5554..7a14a76d1 100644 --- a/qutebrowser/config/parsers/keyconf.py +++ b/qutebrowser/config/parsers/keyconf.py @@ -25,7 +25,7 @@ import itertools from PyQt5.QtCore import pyqtSignal, QObject -from qutebrowser.config import configdata, textwrapper +from qutebrowser.config import configdata, textwrapper, config from qutebrowser.commands import cmdutils, cmdexc from qutebrowser.utils import log, utils, qtutils, message, usertypes @@ -352,7 +352,8 @@ class KeyConfigParser(QObject): line)) commands = [c.split(maxsplit=1)[0].strip() for c in commands] for cmd in commands: - if cmd not in cmdutils.cmd_dict: + aliases = config.section('aliases') + if cmd not in cmdutils.cmd_dict and cmd not in aliases: raise KeyConfigError("Invalid command '{}'!".format(cmd)) def _read_command(self, line): diff --git a/tests/end2end/features/keyinput.feature b/tests/end2end/features/keyinput.feature index 6287c645f..3ae32368b 100644 --- a/tests/end2end/features/keyinput.feature +++ b/tests/end2end/features/keyinput.feature @@ -61,6 +61,18 @@ Feature: Keyboard input And I run :bind Then the message " is bound to 'message-info bar' in normal mode" should be shown + Scenario: Binding to an alias + When I run :set aliases 'mib' 'message-info baz' + And I run :bind test25 mib + And I press the keys "test25" + Then the message "baz" should be shown + + Scenario: Printing a bound alias + When I run :set aliases 'mib' 'message-info baz' + And I run :bind mib + And I run :bind + Then the message " is bound to 'mib' in normal mode" should be shown + # :unbind Scenario: Binding and unbinding a keychain From 91ec5cc3562f293a79bdf8770a31b5153ba2e3ec Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Tue, 9 Aug 2016 08:23:31 -0400 Subject: [PATCH 2/5] Update command completion on setting an alias. Wire up the config change event to update command completion on changing aliases, so the new aliases will be included. Fixes #1814. Currently we do not have tests at a high enough level to test whether signals are wired up correctly to update completions. --- qutebrowser/completion/models/instances.py | 10 +++++++++- tests/unit/config/test_config.py | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/qutebrowser/completion/models/instances.py b/qutebrowser/completion/models/instances.py index 568607b79..d3b49c0ec 100644 --- a/qutebrowser/completion/models/instances.py +++ b/qutebrowser/completion/models/instances.py @@ -29,7 +29,7 @@ import functools from qutebrowser.completion.models import miscmodels, urlmodel, configmodel from qutebrowser.utils import objreg, usertypes, log, debug -from qutebrowser.config import configdata +from qutebrowser.config import configdata, config _instances = {} @@ -155,6 +155,12 @@ def update(completions): did_run.append(func) +@config.change_filter('aliases', function=True) +def _update_aliases(): + """Update completions that include command aliases.""" + update([usertypes.Completion.command]) + + def init(): """Initialize completions. Note this only connects signals.""" quickmark_manager = objreg.get('quickmark-manager') @@ -176,3 +182,5 @@ def init(): keyconf = objreg.get('key-config') keyconf.changed.connect( functools.partial(update, [usertypes.Completion.command])) + + objreg.get('config').changed.connect(_update_aliases) diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py index f2a6a79f1..e2f91c0d1 100644 --- a/tests/unit/config/test_config.py +++ b/tests/unit/config/test_config.py @@ -214,7 +214,7 @@ class TestKeyConfigParser: """Test config.parsers.keyconf.KeyConfigParser.""" - def test_cmd_binding(self, cmdline_test): + def test_cmd_binding(self, cmdline_test, config_stub): """Test various command bindings. See https://github.com/The-Compiler/qutebrowser/issues/615 @@ -222,6 +222,7 @@ class TestKeyConfigParser: Args: cmdline_test: A pytest fixture which provides testcases. """ + config_stub.data = {'aliases': []} kcp = keyconf.KeyConfigParser(None, None) kcp._cur_section = 'normal' if cmdline_test.valid: From 30d2403b7f835ac985965f1ee41086e4cc4aded6 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Tue, 9 Aug 2016 16:59:46 -0400 Subject: [PATCH 3/5] Avoid config/keyconf circular import. --- qutebrowser/config/config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index a5521e275..ebee19c53 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -36,7 +36,7 @@ import collections.abc from PyQt5.QtCore import pyqtSignal, QObject, QUrl, QSettings from qutebrowser.config import configdata, configexc, textwrapper -from qutebrowser.config.parsers import ini, keyconf +from qutebrowser.config.parsers import ini from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.utils import (message, objreg, utils, standarddir, log, qtutils, error, usertypes) @@ -178,6 +178,7 @@ def _init_key_config(parent): Args: parent: The parent to use for the KeyConfigParser. """ + from qutebrowser.config.parsers import keyconf args = objreg.get('args') try: key_config = keyconf.KeyConfigParser(standarddir.config(), 'keys.conf', From 7c5d0eea44e0bb39bc35879511960091cc789c95 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 10 Aug 2016 09:38:17 +0200 Subject: [PATCH 4/5] Update changelog --- CHANGELOG.asciidoc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index c22ede6eb..f0fb2f11b 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -69,6 +69,13 @@ Removed - The `ui -> hide-mouse-cursor` setting since it was completely broken and nobody seemed to care. +Fixed +~~~~~ + +- `:bind` can now be used to bind to an alias (binding by editing `keys.conf` + already worked before) +- The command completion now updates correctly when changing aliases + v0.8.3 (unreleased) ------------------- From bf29c2a7535aac900ffad781d5547a2d6a20d9f9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 10 Aug 2016 09:40:38 +0200 Subject: [PATCH 5/5] Import keyconf at file scope again in config.py Various code (like src2asciidoc.py) relies on all @cmdutils.register decorators being called when qutebrowser.app is imported. Moving the keyconf import to _init_key_config broke that assumption, as keyconf isn't imported anywhere anymore - which caused :bind and :unbind to vanish from the generated documentation. In the long run we should perhaps use venusian: http://docs.pylonsproject.org/projects/venusian/ But for now, this is the easiest solution. --- qutebrowser/config/config.py | 2 +- qutebrowser/config/parsers/keyconf.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 54e81d659..5ef7d0ee6 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -36,6 +36,7 @@ import collections.abc from PyQt5.QtCore import pyqtSignal, QObject, QUrl, QSettings from qutebrowser.config import configdata, configexc, textwrapper +from qutebrowser.config.parsers import keyconf from qutebrowser.config.parsers import ini from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.utils import (message, objreg, utils, standarddir, log, @@ -178,7 +179,6 @@ def _init_key_config(parent): Args: parent: The parent to use for the KeyConfigParser. """ - from qutebrowser.config.parsers import keyconf args = objreg.get('args') try: key_config = keyconf.KeyConfigParser(standarddir.config(), 'keys.conf', diff --git a/qutebrowser/config/parsers/keyconf.py b/qutebrowser/config/parsers/keyconf.py index 7a14a76d1..2eebd6bd9 100644 --- a/qutebrowser/config/parsers/keyconf.py +++ b/qutebrowser/config/parsers/keyconf.py @@ -25,7 +25,7 @@ import itertools from PyQt5.QtCore import pyqtSignal, QObject -from qutebrowser.config import configdata, textwrapper, config +from qutebrowser.config import configdata, textwrapper from qutebrowser.commands import cmdutils, cmdexc from qutebrowser.utils import log, utils, qtutils, message, usertypes @@ -335,6 +335,7 @@ class KeyConfigParser(QObject): def _validate_command(self, line): """Check if a given command is valid.""" + from qutebrowser.config import config if line == self.UNBOUND_COMMAND: return commands = line.split(';;')