qutebrowser: add support for per domain settings (#7078)

Add `programs.qutebrowser.perDomainSettings` which let's one to set
configuration options for specific URLs [1].

It option doesn't check if the options passed to it are valid, it
translates the config to python code to be written on the file as is.
Mimicking the behaviour of `programs.qutebrowser.settings`.

Added a new test case `test-qutebrowser-url-settings` for testing the
implementation.

[1]: bb7bbb6ead/doc/help/configuring.asciidoc (per-domain-settings)
This commit is contained in:
octvs
2025-05-20 19:43:52 +02:00
committed by GitHub
parent 3f591550a9
commit 29dda415f5
4 changed files with 111 additions and 25 deletions

View File

@@ -16,26 +16,18 @@ let
cfg = config.programs.qutebrowser;
formatLine =
o: n: v:
let
formatValue =
v:
if v == null then
"None"
else if builtins.isBool v then
(if v then "True" else "False")
else if builtins.isString v then
''"${v}"''
else if builtins.isList v then
"[${concatStringsSep ", " (map formatValue v)}]"
else
builtins.toString v;
in
if builtins.isAttrs v then
concatStringsSep "\n" (mapAttrsToList (formatLine "${o}${n}.") v)
pythonize =
v:
if v == null then
"None"
else if builtins.isBool v then
(if v then "True" else "False")
else if builtins.isString v then
''"${v}"''
else if builtins.isList v then
"[${concatStringsSep ", " (map pythonize v)}]"
else
"${o}${n} = ${formatValue v}";
builtins.toString v;
formatDictLine =
o: n: v:
@@ -55,6 +47,19 @@ let
formatQuickmarks = n: s: "${n} ${s}";
# flattenSettings attrset -> [ [ <opt_path> <opt_value>] ]
flattenSettings =
x:
lib.collect (x: !builtins.isAttrs x) (
lib.mapAttrsRecursive (path: value: [
(lib.concatStringsSep "." path)
value
]) x
);
configSet = l: "config.set(${lib.concatStringsSep ", " (map pythonize l)})";
setUrlConfig = url: conf: map (x: configSet (x ++ [ url ])) (flattenSettings conf);
in
{
options.programs.qutebrowser = {
@@ -285,6 +290,27 @@ in
Extra lines added to qutebrowser {file}`config.py` file.
'';
};
perDomainSettings = mkOption {
type = types.attrsOf types.anything;
default = { };
description = ''
Options to set, as in `settings` but per domain.
Refer to {option}`settings` for details.
'';
example = literalExpression ''
{
"zoom.us" = {
content = {
autoplay = true;
media.audio_capture = true;
media.video_capture = true;
};
};
"github.com".colors.webpage.darkmode.enabled = false;
};
'';
};
};
config =
@@ -293,13 +319,14 @@ in
[
(if cfg.loadAutoconfig then "config.load_autoconfig()" else "config.load_autoconfig(False)")
]
++ mapAttrsToList (formatLine "c.") cfg.settings
++ map configSet (flattenSettings cfg.settings)
++ mapAttrsToList (formatDictLine "c.aliases") cfg.aliases
++ mapAttrsToList (formatDictLine "c.url.searchengines") cfg.searchEngines
++ mapAttrsToList (formatDictLine "c.bindings.key_mappings") cfg.keyMappings
++ lib.optional (!cfg.enableDefaultBindings) "c.bindings.default = {}"
++ mapAttrsToList formatKeyBindings cfg.keyBindings
++ lib.optional (cfg.extraConfig != "") cfg.extraConfig
++ lib.lists.flatten (mapAttrsToList setUrlConfig cfg.perDomainSettings)
);
quickmarksFile = lib.optionals (cfg.quickmarks != { }) concatStringsSep "\n" (

View File

@@ -3,4 +3,5 @@
qutebrowser-keybindings = ./keybindings.nix;
qutebrowser-quickmarks = ./quickmarks.nix;
qutebrowser-settings = ./settings.nix;
qutebrowser-url-settings = ./url-settings.nix;
}

View File

@@ -37,11 +37,11 @@
home-files/${qutebrowserConfig} \
${builtins.toFile "qutebrowser-expected-config.py" ''
config.load_autoconfig(False)
c.colors.hints.bg = "#000000"
c.colors.hints.fg = "#ffffff"
c.colors.tabs.bar.bg = "#000000"
c.spellcheck.languages = ["en-US", "sv-SE"]
c.tabs.tabs_are_windows = True
config.set("colors.hints.bg", "#000000")
config.set("colors.hints.fg", "#ffffff")
config.set("colors.tabs.bar.bg", "#000000")
config.set("spellcheck.languages", ["en-US", "sv-SE"])
config.set("tabs.tabs_are_windows", True)
# Extra qutebrowser configuration.
''}
'';

View File

@@ -0,0 +1,58 @@
{ pkgs, ... }:
{
programs.qutebrowser = {
enable = true;
settings = {
colors = {
hints = {
bg = "#000000";
fg = "#ffffff";
};
tabs.bar.bg = "#000000";
webpage.darkmode.enabled = true;
};
};
perDomainSettings = {
"zoom.us" = {
content = {
autoplay = true;
media.audio_capture = true;
media.video_capture = true;
};
};
"web.whatsapp.com".colors.webpage.darkmode.enabled = false;
};
extraConfig = ''
# Extra qutebrowser configuration.
'';
};
nmt.script =
let
qutebrowserConfig =
if pkgs.stdenv.hostPlatform.isDarwin then
".qutebrowser/config.py"
else
".config/qutebrowser/config.py";
in
''
assertFileContent \
home-files/${qutebrowserConfig} \
${builtins.toFile "qutebrowser-expected-config.py" ''
config.load_autoconfig(False)
config.set("colors.hints.bg", "#000000")
config.set("colors.hints.fg", "#ffffff")
config.set("colors.tabs.bar.bg", "#000000")
config.set("colors.webpage.darkmode.enabled", True)
# Extra qutebrowser configuration.
config.set("colors.webpage.darkmode.enabled", False, "web.whatsapp.com")
config.set("content.autoplay", True, "zoom.us")
config.set("content.media.audio_capture", True, "zoom.us")
config.set("content.media.video_capture", True, "zoom.us")''}
'';
}