From 8edaad51c3a09ecc19fb5c4e7c71806f3447829b Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 3 Oct 2017 16:28:11 +0200 Subject: [PATCH] Add a :config-source command See #2794 --- doc/help/commands.asciidoc | 14 +++++++++ qutebrowser/config/configcommands.py | 27 ++++++++++++++-- tests/unit/config/test_configcommands.py | 39 ++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index d7a6cc503..1d25727aa 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -33,6 +33,7 @@ It is possible to run or bind multiple commands by separating them with `;;`. |<>|Close the current window. |<>|Set all settings back to their default. |<>|Cycle an option between multiple values. +|<>|Read a config.py file. |<>|Unset an option. |<>|Download a given URL, or current page if no URL given. |<>|Cancel the last/[count]th download. @@ -228,6 +229,19 @@ Cycle an option between multiple values. * +*-t*+, +*--temp*+: Set value temporarily until qutebrowser is closed. * +*-p*+, +*--print*+: Print the value after setting. +[[config-source]] +=== config-source +Syntax: +:config-source [*--clear*] ['filename']+ + +Read a config.py file. + +==== positional arguments +* +'filename'+: The file to load. If not given, loads the default config.py. + + +==== optional arguments +* +*-c*+, +*--clear*+: Clear current settings first. + [[config-unset]] === config-unset Syntax: +:config-unset [*--temp*] 'option'+ diff --git a/qutebrowser/config/configcommands.py b/qutebrowser/config/configcommands.py index 1e9fe31cd..b63a959b7 100644 --- a/qutebrowser/config/configcommands.py +++ b/qutebrowser/config/configcommands.py @@ -19,14 +19,15 @@ """Commands related to the configuration.""" +import os.path import contextlib from PyQt5.QtCore import QUrl from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.completion.models import configmodel -from qutebrowser.utils import objreg, utils, message -from qutebrowser.config import configtypes, configexc +from qutebrowser.utils import objreg, utils, message, standarddir +from qutebrowser.config import configtypes, configexc, configfiles class ConfigCommands: @@ -203,3 +204,25 @@ class ConfigCommands: removed. """ self._config.clear(save_yaml=save) + + @cmdutils.register(instance='config-commands') + def config_source(self, filename=None, clear=False): + """Read a config.py file. + + Args: + filename: The file to load. If not given, loads the default + config.py. + clear: Clear current settings first. + """ + if filename is None: + filename = os.path.join(standarddir.config(), 'config.py') + else: + filename = os.path.expanduser(filename) + + if clear: + self.config_clear() + + try: + configfiles.read_config_py(filename) + except configexc.ConfigFileErrors as e: + raise cmdexc.CommandError(e) diff --git a/tests/unit/config/test_configcommands.py b/tests/unit/config/test_configcommands.py index 85e4d0543..33e68cf7e 100644 --- a/tests/unit/config/test_configcommands.py +++ b/tests/unit/config/test_configcommands.py @@ -263,6 +263,45 @@ class TestUnsetAndClear: assert config_stub._yaml[name] == 'never' +class TestSource: + + """Test :config-source.""" + + pytestmark = pytest.mark.usefixtures('config_tmpdir', 'data_tmpdir') + + @pytest.mark.parametrize('use_default_dir', [True, False]) + @pytest.mark.parametrize('clear', [True, False]) + def test_config_source(self, tmpdir, commands, config_stub, config_tmpdir, + use_default_dir, clear): + assert config_stub.val.content.javascript.enabled + config_stub.val.ignore_case = 'always' + + if use_default_dir: + pyfile = config_tmpdir / 'config.py' + arg = None + else: + pyfile = tmpdir / 'sourced.py' + arg = str(pyfile) + pyfile.write_text('c.content.javascript.enabled = False\n', + encoding='utf-8') + + commands.config_source(arg, clear=clear) + + assert not config_stub.val.content.javascript.enabled + assert config_stub.val.ignore_case == ('smart' if clear else 'always') + + def test_errors(self, commands, config_tmpdir): + pyfile = config_tmpdir / 'config.py' + pyfile.write_text('c.foo = 42', encoding='utf-8') + + with pytest.raises(cmdexc.CommandError) as excinfo: + commands.config_source() + + expected = ("Errors occurred while reading config.py:\n" + " While setting 'foo': No option 'foo'") + assert str(excinfo.value) == expected + + class TestBind: """Tests for :bind and :unbind."""