diff --git a/doc/help/configuring.asciidoc b/doc/help/configuring.asciidoc index 3425fc924..23368a5ff 100644 --- a/doc/help/configuring.asciidoc +++ b/doc/help/configuring.asciidoc @@ -225,6 +225,23 @@ that via `import utils` as well. While it's in some cases possible to import code from the qutebrowser installation, doing so is unsupported and discouraged. +Getting the config directory +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you need to get the qutebrowser config directory, you can do so by reading +`config.configdir`. Similarily, you can get the qutebrowser data directory via +`config.datadir`. + +This gives you a https://docs.python.org/3/library/pathlib.html[`pathlib.Path` +object], on which you can use `/` to add more directory parts, or `str(...)` to +get a string: + +.config.py: +[source,python] +---- +print(str(config.configdir / 'config.py') +---- + Handling errors ~~~~~~~~~~~~~~~ diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py index 55c6d7e3a..622280ee7 100644 --- a/qutebrowser/config/configfiles.py +++ b/qutebrowser/config/configfiles.py @@ -19,6 +19,7 @@ """Configuration files residing on disk.""" +import pathlib import types import os.path import sys @@ -177,6 +178,8 @@ class ConfigAPI: _keyconfig: The KeyConfig object. load_autoconfig: Whether autoconfig.yml should be loaded. errors: Errors which occurred while setting options. + configdir: The qutebrowser config directory, as pathlib.Path. + datadir: The qutebrowser data directory, as pathlib.Path. """ def __init__(self, conf, keyconfig): @@ -184,6 +187,8 @@ class ConfigAPI: self._keyconfig = keyconfig self.load_autoconfig = True self.errors = [] + self.configdir = pathlib.Path(standarddir.config()) + self.datadir = pathlib.Path(standarddir.data()) @contextlib.contextmanager def _handle_error(self, action, name): diff --git a/tests/unit/config/test_configfiles.py b/tests/unit/config/test_configfiles.py index 5661c3ff9..ed5d2b882 100644 --- a/tests/unit/config/test_configfiles.py +++ b/tests/unit/config/test_configfiles.py @@ -236,7 +236,7 @@ class TestConfigPyModules: pytestmark = pytest.mark.usefixtures('config_stub', 'key_config_stub') @pytest.fixture - def confpy(self, tmpdir): + def confpy(self, tmpdir, config_tmpdir, data_tmpdir): return ConfPy(tmpdir) @pytest.fixture @@ -303,7 +303,7 @@ class TestConfigPy: pytestmark = pytest.mark.usefixtures('config_stub', 'key_config_stub') @pytest.fixture - def confpy(self, tmpdir): + def confpy(self, tmpdir, config_tmpdir, data_tmpdir): return ConfPy(tmpdir) def test_assertions(self, confpy): @@ -312,6 +312,14 @@ class TestConfigPy: with pytest.raises(AssertionError): confpy.read() # no errors=True so it gets raised + @pytest.mark.parametrize('what', ['configdir', 'datadir']) + def test_getting_dirs(self, confpy, what): + confpy.write('import pathlib', + 'directory = config.{}'.format(what), + 'assert isinstance(directory, pathlib.Path)', + 'assert directory.exists()') + confpy.read() + @pytest.mark.parametrize('line', [ 'c.colors.hints.bg = "red"', 'config.set("colors.hints.bg", "red")', @@ -373,17 +381,18 @@ class TestConfigPy: assert config.instance._values['aliases']['foo'] == 'message-info foo' assert config.instance._values['aliases']['bar'] == 'message-info bar' - def test_reading_default_location(self, config_tmpdir): + def test_reading_default_location(self, config_tmpdir, data_tmpdir): (config_tmpdir / 'config.py').write_text( 'c.colors.hints.bg = "red"', 'utf-8') configfiles.read_config_py() assert config.instance._values['colors.hints.bg'] == 'red' - def test_reading_missing_default_location(self, config_tmpdir): + def test_reading_missing_default_location(self, config_tmpdir, + data_tmpdir): assert not (config_tmpdir / 'config.py').exists() configfiles.read_config_py() # Should not crash - def test_oserror(self, tmpdir): + def test_oserror(self, tmpdir, data_tmpdir, config_tmpdir): with pytest.raises(configexc.ConfigFileErrors) as excinfo: configfiles.read_config_py(str(tmpdir / 'foo'))