462 lines
15 KiB
Plaintext
462 lines
15 KiB
Plaintext
Configuring qutebrowser
|
||
=======================
|
||
|
||
IMPORTANT: qutebrowser's configuration system was completely rewritten in
|
||
September 2017. This information is not applicable to older releases, and older
|
||
information elsewhere might be outdated.
|
||
|
||
qutebrowser's config files
|
||
--------------------------
|
||
|
||
qutebrowser releases before v1.0.0 had a `qutebrowser.conf` and `keys.conf`
|
||
file. Those are not used anymore since v1.0.0.
|
||
|
||
When using `:set` and `:bind`, changes are saved to an `autoconfig.yml` file
|
||
automatically. If you don't want to have a config file which is curated by
|
||
hand, you can simply use those - see
|
||
<<autoconfig,"Configuring qutebrowser via the user interface">> for details.
|
||
|
||
For more advanced configuration, you can write a `config.py` file - see
|
||
<<configpy,"Configuring qutebrowser via config.py">>. When a `config.py`
|
||
exists, the `autoconfig.yml` file **is not read anymore** by default. You need
|
||
to <<configpy-autoconfig,load it from `config.py`>> if you want settings changed via
|
||
`:set`/`:bind` to persist between restarts.
|
||
|
||
[[patterns]]
|
||
URL pattern support
|
||
-------------------
|
||
|
||
Many settings are customizable depending on the page being visited by using URL
|
||
patterns. The link:settings{outfilesuffix}[settings documentation] marks such
|
||
settings with "This setting supports URL patterns.
|
||
|
||
The syntax is based on Chromium's
|
||
https://developer.chrome.com/docs/extensions/mv3/match_patterns/[URL pattern syntax].
|
||
As an extension, the scheme and path can be left off as a short-hand syntax, so
|
||
`example.com` is equivalent to `*://example.com/*`.
|
||
|
||
[[autoconfig]]
|
||
Configuring qutebrowser via the user interface
|
||
----------------------------------------------
|
||
|
||
The easy (but less flexible) way to configure qutebrowser is using its user
|
||
interface or command line. Changes you make this way are immediately active
|
||
(with the exception of a few settings, where this is pointed out in the
|
||
documentation) and are persisted in an `autoconfig.yml` file.
|
||
|
||
The `autoconfig.yml` file is located in the "config" folder listed on the
|
||
link:qute://version[] page. On macOS, the "auto config" folder is used, which is
|
||
different from where hand-written config files are kept.
|
||
|
||
However, **do not** edit `autoconfig.yml` by hand. Instead, see the next
|
||
section.
|
||
|
||
If you want to customize many settings, you can open the link:qute://settings[]
|
||
page by running `:set` without any arguments, where all settings are listed and
|
||
customizable.
|
||
|
||
Using the link:commands{outfilesuffix}#set[`:set`] command and command completion, you
|
||
can quickly set settings interactively, for example `:set tabs.position left`.
|
||
|
||
<<patterns,URL patterns>> can be used via
|
||
`:set --pattern *://example.com/* content.images false`, or with shorthand
|
||
syntax for both argument and pattern, `:set -u example.com content.images
|
||
false`.
|
||
|
||
To get more help about a setting, use e.g. `:help tabs.position`.
|
||
|
||
To bind and unbind keys, you can use the link:commands{outfilesuffix}#bind[`:bind`] and
|
||
link:commands{outfilesuffix}#unbind[`:unbind`] commands:
|
||
|
||
- Binding the key chain `,v` to the `:spawn mpv {url}` command:
|
||
`:bind ,v spawn mpv {url}`
|
||
- Unbinding the same key chain: `:unbind ,v`
|
||
|
||
Key chains starting with a comma are ideal for custom bindings, as the comma key
|
||
will never be used in a default keybinding.
|
||
|
||
See the help pages linked above (or `:help :bind`, `:help :unbind`) for more
|
||
information.
|
||
|
||
Other useful commands for config manipulation are
|
||
link:commands{outfilesuffix}#config-unset[`:config-unset`] to reset a value to its default,
|
||
link:commands{outfilesuffix}#config-clear[`:config-clear`] to reset the entire configuration,
|
||
and link:commands{outfilesuffix}#config-cycle[`:config-cycle`] to cycle a setting between
|
||
different values.
|
||
|
||
[[configpy]]
|
||
Configuring qutebrowser via config.py
|
||
-------------------------------------
|
||
|
||
For more powerful configuration possibilities, you can create a `config.py`
|
||
file. Since it's a Python file, you have much more flexibility for
|
||
configuration. Note that qutebrowser will never touch this file - this means
|
||
you'll be responsible for updating it when upgrading to a newer qutebrowser
|
||
version.
|
||
|
||
You can run `:config-edit` inside qutebrowser to open the file in your editor,
|
||
`:config-source` to reload the file (`:config-edit` does this automatically), or
|
||
`:config-write-py --defaults` to write a template file to work with.
|
||
|
||
The file should be located in the "config" location listed on
|
||
link:qute://version[], which is typically `~/.config/qutebrowser/config.py` on
|
||
Linux, `~/.qutebrowser/config.py` on macOS, and
|
||
`%APPDATA%/qutebrowser/config/config.py` on Windows.
|
||
|
||
Two global objects are pre-defined when running `config.py`: `c` and `config`.
|
||
|
||
Changing settings
|
||
~~~~~~~~~~~~~~~~~
|
||
|
||
While you can set settings using the `config.set()` method (which is explained
|
||
in the next section), it's easier to use the `c` shorthand object to easily set
|
||
settings like this:
|
||
|
||
.config.py:
|
||
[source,python]
|
||
----
|
||
c.tabs.position = "left"
|
||
c.completion.shrink = True
|
||
----
|
||
|
||
Note that qutebrowser does some Python magic so it's able to warn you about
|
||
mistyped config settings. As an example, if you do `c.tabs.possition = "left"`,
|
||
you'll get an error when starting.
|
||
|
||
See the link:settings{outfilesuffix}[settings help page] for all available settings. The
|
||
accepted values depend on the type of the option. Commonly used are:
|
||
|
||
- Strings: `c.tabs.position = "left"`
|
||
- Booleans: `c.completion.shrink = True`
|
||
- Integers: `c.messages.timeout = 5000`
|
||
- Dictionaries:
|
||
* `c.content.headers.custom = {'X-Hello': 'World', 'X-Awesome': 'yes'}` to override
|
||
any other values in the dictionary.
|
||
* `c.aliases['foo'] = 'message-info foo'` to add a single value.
|
||
- Lists:
|
||
* `c.url.start_pages = ["https://www.qutebrowser.org/"]` to override any
|
||
previous elements.
|
||
* `c.url.start_pages.append("https://www.python.org/")` to add a new value.
|
||
|
||
Any other config types (e.g. a color) are specified as a string. The only
|
||
exception is the `Regex` type, which can take either a string (with an `r`
|
||
prefix to preserve backslashes) or a Python regex object:
|
||
|
||
- `c.hints.next_regexes.append(r'\bvor\b')`
|
||
- `c.hints.prev_regexes.append(re.compile(r'\bzurück\b'))`
|
||
|
||
If you want to read a setting, you can use the `c` object to do so as well:
|
||
`c.colors.tabs.even.bg = c.colors.tabs.odd.bg`.
|
||
|
||
Using strings for setting names
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
If you want to set settings based on their name as a string, use the
|
||
`config.set` method:
|
||
|
||
.config.py:
|
||
[source,python]
|
||
----
|
||
# Equivalent to:
|
||
# c.content.javascript.enabled = False
|
||
config.set('content.javascript.enabled', False)
|
||
----
|
||
|
||
To read a setting, use the `config.get` method:
|
||
|
||
[source,python]
|
||
----
|
||
# Equivalent to:
|
||
# color = c.colors.completion.fg
|
||
color = config.get('colors.completion.fg')
|
||
----
|
||
|
||
Per-domain settings
|
||
~~~~~~~~~~~~~~~~~~~
|
||
|
||
Using `config.set` instead of the `c.` shorthand, many settings are also
|
||
customizable for a given <<patterns,URL patterns>>.
|
||
|
||
[source,python]
|
||
----
|
||
config.set('content.images', False, '*://example.com/')
|
||
----
|
||
|
||
Alternatively, you can use `with config.pattern(...) as p:` to get a shortcut
|
||
similar to `c.` which is scoped to the given domain:
|
||
|
||
[source,python]
|
||
----
|
||
with config.pattern('*://example.com/') as p:
|
||
p.content.images = False
|
||
----
|
||
|
||
Binding keys
|
||
~~~~~~~~~~~~
|
||
|
||
While it's possible to change the `bindings.commands` setting to customize the keyboard shortcuts, it's
|
||
preferred to use the `config.bind` command. Doing so ensures the commands are
|
||
valid and normalizes different expressions which map to the same key.
|
||
|
||
For details on how to specify keys and the available modes, see the
|
||
link:settings{outfilesuffix}#bindings.commands[documentation] for the `bindings.commands`
|
||
setting.
|
||
|
||
To bind a key:
|
||
|
||
.config.py:
|
||
[source,python]
|
||
----
|
||
config.bind('<Ctrl-v>', 'spawn mpv {url}')
|
||
----
|
||
|
||
To bind a key in a mode other than `'normal'`, add a `mode` argument:
|
||
|
||
[source,python]
|
||
----
|
||
config.bind('<Ctrl-y>', 'prompt-yes', mode='prompt')
|
||
----
|
||
|
||
To unbind a key (either a key which has been bound before, or a default binding):
|
||
|
||
[source,python]
|
||
----
|
||
config.unbind('<Ctrl-v>', mode='normal')
|
||
----
|
||
|
||
To bind keys without modifiers, specify a key chain to bind as a string. Key
|
||
chains starting with a comma are ideal for custom bindings, as the comma key
|
||
will never be used in a default keybinding.
|
||
|
||
[source,python]
|
||
----
|
||
config.bind(',v', 'spawn mpv {url}')
|
||
----
|
||
|
||
To suppress loading of any default keybindings, you can set
|
||
`c.bindings.default = {}`.
|
||
|
||
[[configpy-autoconfig]]
|
||
Loading `autoconfig.yml`
|
||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
All customization done via the UI (`:set`, `:bind` and `:unbind`) is
|
||
stored in the `autoconfig.yml` file. When a `config.py` file exists, `autoconfig.yml`
|
||
is not loaded automatically. To load `autoconfig.yml` automatically, add the
|
||
following snippet to `config.py`:
|
||
|
||
[source,python]
|
||
----
|
||
config.load_autoconfig()
|
||
----
|
||
|
||
You can configure which file overrides the other by the location of the above code snippet.
|
||
Place the snippet at the top to allow `config.py` to override `autoconfig.yml`.
|
||
Place the snippet at the bottom for the opposite effect.
|
||
|
||
Importing other modules
|
||
~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
You can import any module from the
|
||
https://docs.python.org/3/library/index.html[Python standard library] (e.g.
|
||
`import os.path`), as well as any module installed in the environment
|
||
qutebrowser is run with.
|
||
|
||
If you have an `utils.py` file in your qutebrowser config folder, you can import
|
||
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.
|
||
|
||
To read config data from a different file with `c` and `config` available, you
|
||
can use `config.source('otherfile.py')` in your `config.py`.
|
||
|
||
Getting the config directory
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
If you need to get the qutebrowser config directory, you can do so by reading
|
||
`config.configdir`. Similarly, 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
|
||
~~~~~~~~~~~~~~~
|
||
|
||
If there are errors in your `config.py`, qutebrowser will try to apply as much
|
||
of it as possible, and show an error dialog before starting.
|
||
|
||
qutebrowser tries to display errors which are easy to understand even for people
|
||
who are not used to writing Python. If you see a config error which you find
|
||
confusing or you think qutebrowser could handle better, please
|
||
https://github.com/qutebrowser/qutebrowser/issues[open an issue]!
|
||
|
||
Recipes
|
||
~~~~~~~
|
||
|
||
Reading a YAML file
|
||
^^^^^^^^^^^^^^^^^^^
|
||
|
||
To read a YAML config like this:
|
||
|
||
.config.yml:
|
||
----
|
||
tabs.position: left
|
||
tabs.show: switching
|
||
----
|
||
|
||
You can use:
|
||
|
||
.config.py:
|
||
[source,python]
|
||
----
|
||
import yaml
|
||
|
||
with (config.configdir / 'config.yml').open() as f:
|
||
yaml_data = yaml.safe_load(f)
|
||
|
||
for k, v in yaml_data.items():
|
||
config.set(k, v)
|
||
----
|
||
|
||
Reading a nested YAML file
|
||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
To read a YAML file with nested values like this:
|
||
|
||
.colors.yml:
|
||
----
|
||
colors:
|
||
statusbar:
|
||
normal:
|
||
bg: lime
|
||
fg: black
|
||
url:
|
||
fg: red
|
||
----
|
||
|
||
You can use:
|
||
|
||
.config.py:
|
||
[source,python]
|
||
----
|
||
import yaml
|
||
|
||
with (config.configdir / 'colors.yml').open() as f:
|
||
yaml_data = yaml.safe_load(f)
|
||
|
||
def dict_attrs(obj, path=''):
|
||
if isinstance(obj, dict):
|
||
for k, v in obj.items():
|
||
yield from dict_attrs(v, '{}.{}'.format(path, k) if path else k)
|
||
else:
|
||
yield path, obj
|
||
|
||
for k, v in dict_attrs(yaml_data):
|
||
config.set(k, v)
|
||
----
|
||
|
||
Note that this won't work for values which are dictionaries.
|
||
|
||
Binding chained commands
|
||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
If you have a lot of chained commands you want to bind, you can write a helper
|
||
to do so:
|
||
|
||
[source,python]
|
||
----
|
||
def bind_chained(key, *commands):
|
||
config.bind(key, ' ;; '.join(commands))
|
||
|
||
bind_chained('<Escape>', 'clear-keychain', 'search')
|
||
----
|
||
|
||
Reading colors from Xresources
|
||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
You can use something like this to read colors from an `~/.Xresources` file:
|
||
|
||
[source,python]
|
||
----
|
||
import subprocess
|
||
|
||
def read_xresources(prefix):
|
||
props = {}
|
||
x = subprocess.run(['xrdb', '-query'], stdout=subprocess.PIPE)
|
||
lines = x.stdout.decode().split('\n')
|
||
for line in filter(lambda l : l.startswith(prefix), lines):
|
||
prop, _, value = line.partition(':\t')
|
||
props[prop] = value
|
||
return props
|
||
|
||
xresources = read_xresources('*')
|
||
c.colors.statusbar.normal.bg = xresources['*.background']
|
||
----
|
||
|
||
Pre-built colorschemes
|
||
^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
- A collection of https://github.com/chriskempson/base16[base16] color-schemes can be found in https://github.com/theova/base16-qutebrowser[base16-qutebrowser] and used with https://github.com/AuditeMarlow/base16-manager[base16-manager].
|
||
- Another collection: https://github.com/leosolid/qutebrowser-themes[qutebrowser-themes]
|
||
- https://gitlab.com/jjzmajic/qutewal[Pywal integration]
|
||
- https://github.com/arcticicestudio/nord[Nord]: https://github.com/Linuus/nord-qutebrowser[Linuus], https://github.com/KnownAsDon/QuteBrowser-Nord-Theme[KnownAsDon]
|
||
- https://github.com/dracula/qutebrowser-dracula-theme[Dracula]
|
||
- https://gitlab.com/lovetocode999/selenized-qutebrowser[Selenized]
|
||
- https://github.com/morhetz/gruvbox[gruvbox]: https://github.com/The-Compiler/dotfiles/blob/master/qutebrowser/gruvbox.py[The-Compiler], https://gitlab.com/shaneyost/dots-popos-september-2020/-/blob/master/qutebrowser/config.py[Shane Yost]
|
||
- https://www.opencode.net/wakellor957/qb-breath/-/blob/main/qb-breath.py[Manjaro Breath-like]
|
||
|
||
Avoiding flake8 errors
|
||
^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
If you use an editor with flake8 and pylint integration, it may have some
|
||
complaints about invalid names, undefined variables, or missing docstrings.
|
||
You can silence those with:
|
||
|
||
[source,python]
|
||
----
|
||
# pylint: disable=C0111
|
||
c = c # noqa: F821 pylint: disable=E0602,C0103
|
||
config = config # noqa: F821 pylint: disable=E0602,C0103
|
||
----
|
||
|
||
For type annotation support (note that those imports aren't guaranteed to be
|
||
stable across qutebrowser versions):
|
||
|
||
[source,python]
|
||
----
|
||
# pylint: disable=C0111
|
||
from qutebrowser.config.configfiles import ConfigAPI # noqa: F401
|
||
from qutebrowser.config.config import ConfigContainer # noqa: F401
|
||
config: ConfigAPI = config # noqa: F821 pylint: disable=E0602,C0103
|
||
c: ConfigContainer = c # noqa: F821 pylint: disable=E0602,C0103
|
||
----
|
||
|
||
emacs-like config
|
||
^^^^^^^^^^^^^^^^^
|
||
|
||
Various emacs/conkeror-like keybinding configs exist:
|
||
|
||
- https://gitlab.com/jgkamat/qutemacs/blob/master/qutemacs.py[jgkamat]
|
||
- https://gitlab.com/Kaligule/qutebrowser-emacs-config/blob/master/config.py[Kaligule]
|
||
- https://me0w.net/pit/1540882719[nm0i]
|
||
- https://www.reddit.com/r/qutebrowser/comments/eh10i7/config_share_qute_with_emacs_keybindings/[jasonsun0310]
|
||
|
||
It's also mostly possible to get rid of modal keybindings by setting
|
||
`input.insert_mode.auto_enter` to `false`, and `input.forward_unbound_keys` to
|
||
`all`.
|
||
|
||
Other resources
|
||
^^^^^^^^^^^^^^^
|
||
|
||
- https://www.ii.com/qutebrowser-tips-fragments/[Infinite Ink: qutebrowser Tips and Fragments]
|
||
- https://www.ii.com/qutebrowser-configpy/[Infinite Ink: qutebrowser’s Template config.py]
|