2020-04-07 09:10:07 +02:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
|
|
cfg = config.programs.qutebrowser;
|
|
|
|
|
|
|
|
formatLine = o: n: v:
|
|
|
|
let
|
|
|
|
formatValue = v:
|
2024-01-18 18:13:01 +01:00
|
|
|
if v == null then
|
2020-04-07 09:10:07 +02:00
|
|
|
"None"
|
|
|
|
else if builtins.isBool v then
|
|
|
|
(if v then "True" else "False")
|
|
|
|
else if builtins.isString v then
|
|
|
|
''"${v}"''
|
2020-04-09 17:40:37 +02:00
|
|
|
else if builtins.isList v then
|
|
|
|
"[${concatStringsSep ", " (map formatValue v)}]"
|
2020-04-07 09:10:07 +02:00
|
|
|
else
|
|
|
|
builtins.toString v;
|
|
|
|
in if builtins.isAttrs v then
|
|
|
|
concatStringsSep "\n" (mapAttrsToList (formatLine "${o}${n}.") v)
|
|
|
|
else
|
|
|
|
"${o}${n} = ${formatValue v}";
|
|
|
|
|
2020-05-02 00:48:03 +02:00
|
|
|
formatDictLine = o: n: v: ''${o}['${n}'] = "${v}"'';
|
|
|
|
|
|
|
|
formatKeyBindings = m: b:
|
|
|
|
let
|
|
|
|
formatKeyBinding = m: k: c:
|
2024-01-18 18:13:01 +01:00
|
|
|
if c == null then
|
|
|
|
''config.unbind("${k}", mode="${m}")''
|
|
|
|
else
|
|
|
|
''config.bind("${k}", "${escape [ ''"'' ] c}", mode="${m}")'';
|
2020-05-02 00:48:03 +02:00
|
|
|
in concatStringsSep "\n" (mapAttrsToList (formatKeyBinding m) b);
|
|
|
|
|
2021-06-15 18:22:21 +02:00
|
|
|
formatQuickmarks = n: s: "${n} ${s}";
|
|
|
|
|
2020-04-07 09:10:07 +02:00
|
|
|
in {
|
|
|
|
options.programs.qutebrowser = {
|
2023-07-02 01:45:18 +02:00
|
|
|
enable = mkEnableOption "qutebrowser";
|
2020-04-07 09:10:07 +02:00
|
|
|
|
2020-06-15 20:29:19 +02:00
|
|
|
package = mkOption {
|
|
|
|
type = types.package;
|
|
|
|
default = pkgs.qutebrowser;
|
2021-10-09 11:14:08 +02:00
|
|
|
defaultText = literalExpression "pkgs.qutebrowser";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "Qutebrowser package to install.";
|
2020-06-15 20:29:19 +02:00
|
|
|
};
|
|
|
|
|
2020-05-02 00:48:03 +02:00
|
|
|
aliases = mkOption {
|
|
|
|
type = types.attrsOf types.str;
|
|
|
|
default = { };
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2020-05-02 00:48:03 +02:00
|
|
|
Aliases for commands.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2021-03-05 04:33:23 +01:00
|
|
|
loadAutoconfig = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2021-03-05 04:33:23 +01:00
|
|
|
Load settings configured via the GUI.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2020-05-02 00:48:03 +02:00
|
|
|
searchEngines = mkOption {
|
|
|
|
type = types.attrsOf types.str;
|
|
|
|
default = { };
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2020-05-02 00:48:03 +02:00
|
|
|
Search engines that can be used via the address bar. Maps a search
|
2023-07-01 01:30:13 +02:00
|
|
|
engine name (such as `DEFAULT`, or
|
|
|
|
`ddg`) to a URL with a `{}`
|
2020-05-02 00:48:03 +02:00
|
|
|
placeholder. The placeholder will be replaced by the search term, use
|
2023-07-01 01:30:13 +02:00
|
|
|
`{{` and `}}` for literal
|
|
|
|
`{/}` signs. The search engine named
|
|
|
|
`DEFAULT` is used when
|
|
|
|
`url.auto_search` is turned on and something else than
|
2020-05-02 00:48:03 +02:00
|
|
|
a URL was entered to be opened. Other search engines can be used by
|
|
|
|
prepending the search engine name to the search term, for example
|
2023-07-01 01:30:13 +02:00
|
|
|
`:open google qutebrowser`.
|
2020-05-02 00:48:03 +02:00
|
|
|
'';
|
2021-10-09 11:14:08 +02:00
|
|
|
example = literalExpression ''
|
2020-05-02 00:48:03 +02:00
|
|
|
{
|
|
|
|
w = "https://en.wikipedia.org/wiki/Special:Search?search={}&go=Go&ns0=1";
|
|
|
|
aw = "https://wiki.archlinux.org/?search={}";
|
2024-04-17 23:58:16 +02:00
|
|
|
nw = "https://wiki.nixos.org/index.php?search={}";
|
2020-05-02 00:48:03 +02:00
|
|
|
g = "https://www.google.com/search?hl=en&q={}";
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2020-04-07 09:10:07 +02:00
|
|
|
settings = mkOption {
|
2020-11-30 03:54:55 +01:00
|
|
|
type = types.attrsOf types.anything;
|
2020-04-07 09:10:07 +02:00
|
|
|
default = { };
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 01:30:13 +02:00
|
|
|
Options to add to qutebrowser {file}`config.py` file.
|
|
|
|
See <https://qutebrowser.org/doc/help/settings.html>
|
2020-04-07 09:10:07 +02:00
|
|
|
for options.
|
|
|
|
'';
|
2021-10-09 11:14:08 +02:00
|
|
|
example = literalExpression ''
|
2020-04-07 09:10:07 +02:00
|
|
|
{
|
|
|
|
colors = {
|
|
|
|
hints = {
|
|
|
|
bg = "#000000";
|
|
|
|
fg = "#ffffff";
|
|
|
|
};
|
|
|
|
tabs.bar.bg = "#000000";
|
|
|
|
};
|
|
|
|
tabs.tabs_are_windows = true;
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2020-05-02 00:48:03 +02:00
|
|
|
keyMappings = mkOption {
|
|
|
|
type = types.attrsOf types.str;
|
|
|
|
default = { };
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2020-05-02 00:48:03 +02:00
|
|
|
This setting can be used to map keys to other keys. When the key used
|
|
|
|
as dictionary-key is pressed, the binding for the key used as
|
|
|
|
dictionary-value is invoked instead. This is useful for global
|
|
|
|
remappings of keys, for example to map Ctrl-[ to Escape. Note that when
|
2023-07-01 01:30:13 +02:00
|
|
|
a key is bound (via `bindings.default` or
|
|
|
|
`bindings.commands`), the mapping is ignored.
|
2020-05-02 00:48:03 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
enableDefaultBindings = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2020-05-02 00:48:03 +02:00
|
|
|
Disable to prevent loading default key bindings.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
keyBindings = mkOption {
|
2024-01-18 18:13:01 +01:00
|
|
|
type = with types; attrsOf (attrsOf (nullOr (separatedString " ;; ")));
|
2020-05-02 00:48:03 +02:00
|
|
|
default = { };
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2020-05-02 00:48:03 +02:00
|
|
|
Key bindings mapping keys to commands in different modes. This setting
|
|
|
|
is a dictionary containing mode names and dictionaries mapping keys to
|
2023-07-01 02:40:42 +02:00
|
|
|
commands: `{mode: {key: command}}` If you want to map
|
|
|
|
a key to another key, check the `keyMappings` setting
|
|
|
|
instead. For modifiers, you can use either `-` or
|
|
|
|
`+` as delimiters, and these names:
|
|
|
|
|
|
|
|
Control
|
|
|
|
: `Control`, `Ctrl`
|
|
|
|
|
|
|
|
Meta
|
|
|
|
: `Meta`, `Windows`, `Mod4`
|
|
|
|
|
|
|
|
Alt
|
|
|
|
: `Alt`, `Mod1`
|
|
|
|
|
|
|
|
Shift
|
|
|
|
: `Shift`
|
|
|
|
|
|
|
|
For simple keys (no `<>`-signs), a capital
|
2020-05-02 00:48:03 +02:00
|
|
|
letter means the key is pressed with Shift. For special keys (with
|
2023-07-01 02:40:42 +02:00
|
|
|
`<>`-signs), you need to explicitly add
|
|
|
|
`Shift-` to match a key pressed with shift. If you
|
|
|
|
want a binding to do nothing, bind it to the `nop`
|
2020-05-02 00:48:03 +02:00
|
|
|
command. If you want a default binding to be passed through to the
|
|
|
|
website, bind it to null. Note that some commands which are only useful
|
|
|
|
for bindings (but not used interactively) are hidden from the command
|
2023-07-01 02:40:42 +02:00
|
|
|
completion. See `:help` for a full list of available
|
2020-05-02 00:48:03 +02:00
|
|
|
commands. The following modes are available:
|
|
|
|
|
2023-07-01 02:40:42 +02:00
|
|
|
`normal`
|
|
|
|
: Default mode, where most commands are invoked.
|
|
|
|
|
|
|
|
`insert`
|
|
|
|
: Entered when an input field is focused on a website, or by
|
|
|
|
pressing `i` in normal mode. Passes through almost all keypresses
|
|
|
|
to the website, but has some bindings like
|
|
|
|
`<Ctrl-e>` to open an external editor.
|
|
|
|
Note that single keys can't be bound in this mode.
|
|
|
|
|
|
|
|
`hint`
|
|
|
|
: Entered when `f` is pressed to select links with the keyboard. Note
|
|
|
|
that single keys can't be bound in this mode.
|
|
|
|
|
|
|
|
`passthrough`
|
|
|
|
: Similar to insert mode, but passes through all keypresses except
|
|
|
|
`<Escape>` to leave the mode. It might be
|
|
|
|
useful to bind `<Escape>` to some other
|
|
|
|
key in this mode if you want to be able to send an Escape key to
|
|
|
|
the website as well. Note that single keys can't be bound in this
|
|
|
|
mode.
|
|
|
|
|
|
|
|
`command`
|
|
|
|
: Entered when pressing the `:` key in order to enter a command. Note
|
|
|
|
that single keys can't be bound in this mode.
|
|
|
|
|
|
|
|
`prompt`
|
|
|
|
: Entered when there's a prompt to display, like for download
|
|
|
|
locations or when invoked from JavaScript.
|
|
|
|
|
|
|
|
`yesno`
|
|
|
|
: Entered when there's a yes/no prompt displayed.
|
|
|
|
|
|
|
|
`caret`
|
|
|
|
: Entered when pressing the `v` mode, used to select text using the
|
|
|
|
keyboard.
|
|
|
|
|
|
|
|
`register`
|
|
|
|
: Entered when qutebrowser is waiting for a register name/key for
|
|
|
|
commands like `:set-mark`.
|
2020-05-02 00:48:03 +02:00
|
|
|
'';
|
2021-10-09 11:14:08 +02:00
|
|
|
example = literalExpression ''
|
2020-05-02 00:48:03 +02:00
|
|
|
{
|
|
|
|
normal = {
|
|
|
|
"<Ctrl-v>" = "spawn mpv {url}";
|
|
|
|
",p" = "spawn --userscript qute-pass";
|
|
|
|
",l" = '''config-cycle spellcheck.languages ["en-GB"] ["en-US"]''';
|
2023-03-15 19:22:12 +01:00
|
|
|
"<F1>" = mkMerge [
|
|
|
|
"config-cycle tabs.show never always"
|
|
|
|
"config-cycle statusbar.show in-mode always"
|
|
|
|
"config-cycle scrolling.bar never always"
|
|
|
|
];
|
2020-05-02 00:48:03 +02:00
|
|
|
};
|
|
|
|
prompt = {
|
|
|
|
"<Ctrl-y>" = "prompt-yes";
|
|
|
|
};
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2021-06-15 18:22:21 +02:00
|
|
|
quickmarks = mkOption {
|
|
|
|
type = types.attrsOf types.str;
|
|
|
|
default = { };
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 01:30:13 +02:00
|
|
|
Quickmarks to add to qutebrowser's {file}`quickmarks` file.
|
2021-06-15 18:22:21 +02:00
|
|
|
Note that when Home Manager manages your quickmarks, you cannot edit them at runtime.
|
|
|
|
'';
|
2021-10-09 11:14:08 +02:00
|
|
|
example = literalExpression ''
|
2021-06-15 18:22:21 +02:00
|
|
|
{
|
|
|
|
nixpkgs = "https://github.com/NixOS/nixpkgs";
|
|
|
|
home-manager = "https://github.com/nix-community/home-manager";
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2023-10-18 22:56:15 +02:00
|
|
|
greasemonkey = mkOption {
|
|
|
|
type = types.listOf types.package;
|
|
|
|
default = [ ];
|
|
|
|
example = literalExpression ''
|
|
|
|
[
|
|
|
|
(pkgs.fetchurl {
|
|
|
|
url = "https://raw.githubusercontent.com/afreakk/greasemonkeyscripts/1d1be041a65c251692ee082eda64d2637edf6444/youtube_sponsorblock.js";
|
|
|
|
sha256 = "sha256-e3QgDPa3AOpPyzwvVjPQyEsSUC9goisjBUDMxLwg8ZE=";
|
|
|
|
})
|
|
|
|
(pkgs.writeText "some-script.js" '''
|
|
|
|
// ==UserScript==
|
|
|
|
// @name Some Greasemonkey script
|
|
|
|
// ==/UserScript==
|
|
|
|
''')
|
|
|
|
]
|
|
|
|
'';
|
|
|
|
description = ''
|
|
|
|
Greasemonkey userscripts to add to qutebrowser's {file}`greasemonkey`
|
|
|
|
directory.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2020-04-07 09:10:07 +02:00
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 01:30:13 +02:00
|
|
|
Extra lines added to qutebrowser {file}`config.py` file.
|
2020-04-07 09:10:07 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2021-04-28 20:41:30 +02:00
|
|
|
config = let
|
|
|
|
qutebrowserConfig = concatStringsSep "\n" ([
|
|
|
|
(if cfg.loadAutoconfig then
|
|
|
|
"config.load_autoconfig()"
|
|
|
|
else
|
|
|
|
"config.load_autoconfig(False)")
|
|
|
|
] ++ mapAttrsToList (formatLine "c.") cfg.settings
|
2020-05-02 00:48:03 +02:00
|
|
|
++ mapAttrsToList (formatDictLine "c.aliases") cfg.aliases
|
|
|
|
++ mapAttrsToList (formatDictLine "c.url.searchengines") cfg.searchEngines
|
|
|
|
++ mapAttrsToList (formatDictLine "c.bindings.key_mappings")
|
|
|
|
cfg.keyMappings
|
2020-07-27 10:54:11 +02:00
|
|
|
++ optional (!cfg.enableDefaultBindings) "c.bindings.default = {}"
|
2020-05-02 00:48:03 +02:00
|
|
|
++ mapAttrsToList formatKeyBindings cfg.keyBindings
|
2020-04-07 09:10:07 +02:00
|
|
|
++ optional (cfg.extraConfig != "") cfg.extraConfig);
|
2021-06-15 18:22:21 +02:00
|
|
|
|
|
|
|
quickmarksFile = optionals (cfg.quickmarks != { }) concatStringsSep "\n"
|
|
|
|
((mapAttrsToList formatQuickmarks cfg.quickmarks));
|
2023-10-18 22:56:15 +02:00
|
|
|
|
|
|
|
greasemonkeyDir = optionals (cfg.greasemonkey != [ ]) pkgs.linkFarmFromDrvs
|
|
|
|
"greasemonkey-userscripts" cfg.greasemonkey;
|
2021-04-28 20:41:30 +02:00
|
|
|
in mkIf cfg.enable {
|
|
|
|
home.packages = [ cfg.package ];
|
|
|
|
|
|
|
|
home.file.".qutebrowser/config.py" =
|
|
|
|
mkIf pkgs.stdenv.hostPlatform.isDarwin { text = qutebrowserConfig; };
|
|
|
|
|
2021-06-15 18:22:21 +02:00
|
|
|
home.file.".qutebrowser/quickmarks" =
|
|
|
|
mkIf (cfg.quickmarks != { } && pkgs.stdenv.hostPlatform.isDarwin) {
|
|
|
|
text = quickmarksFile;
|
|
|
|
};
|
|
|
|
|
2021-04-28 20:41:30 +02:00
|
|
|
xdg.configFile."qutebrowser/config.py" =
|
2021-07-09 05:24:21 +02:00
|
|
|
mkIf pkgs.stdenv.hostPlatform.isLinux {
|
|
|
|
text = qutebrowserConfig;
|
|
|
|
onChange = ''
|
2021-08-01 00:54:47 +02:00
|
|
|
hash="$(echo -n "$USER" | md5sum | cut -d' ' -f1)"
|
2021-07-09 05:24:21 +02:00
|
|
|
socket="''${XDG_RUNTIME_DIR:-/run/user/$UID}/qutebrowser/ipc-$hash"
|
2021-08-01 00:54:47 +02:00
|
|
|
if [[ -S $socket ]]; then
|
2021-07-09 05:24:21 +02:00
|
|
|
command=${
|
|
|
|
escapeShellArg (builtins.toJSON {
|
|
|
|
args = [ ":config-source" ];
|
|
|
|
target_arg = null;
|
|
|
|
protocol_version = 1;
|
|
|
|
})
|
|
|
|
}
|
2021-08-01 00:54:47 +02:00
|
|
|
echo "$command" | ${pkgs.socat}/bin/socat -lf /dev/null - UNIX-CONNECT:"$socket"
|
2021-07-09 05:24:21 +02:00
|
|
|
fi
|
|
|
|
unset hash socket command
|
|
|
|
'';
|
|
|
|
};
|
2021-06-15 18:22:21 +02:00
|
|
|
|
|
|
|
xdg.configFile."qutebrowser/quickmarks" =
|
|
|
|
mkIf (cfg.quickmarks != { } && pkgs.stdenv.hostPlatform.isLinux) {
|
|
|
|
text = quickmarksFile;
|
|
|
|
};
|
2023-10-18 22:56:15 +02:00
|
|
|
|
|
|
|
home.file.".qutebrowser/greasemonkey" =
|
|
|
|
mkIf (cfg.greasemonkey != [ ] && pkgs.stdenv.hostPlatform.isDarwin) {
|
|
|
|
source = greasemonkeyDir;
|
|
|
|
};
|
|
|
|
|
|
|
|
xdg.configFile."qutebrowser/greasemonkey" =
|
|
|
|
mkIf (cfg.greasemonkey != [ ] && pkgs.stdenv.hostPlatform.isLinux) {
|
|
|
|
source = greasemonkeyDir;
|
|
|
|
};
|
2020-04-07 09:10:07 +02:00
|
|
|
};
|
|
|
|
}
|