diff --git a/modules/programs/alacritty.nix b/modules/programs/alacritty.nix index ea908f2b..9c3e8e75 100644 --- a/modules/programs/alacritty.nix +++ b/modules/programs/alacritty.nix @@ -3,9 +3,8 @@ with lib; let - cfg = config.programs.alacritty; - + yamlFormat = pkgs.formats.yaml { }; in { options = { programs.alacritty = { @@ -19,7 +18,7 @@ in { }; settings = mkOption { - type = types.attrs; + type = yamlFormat.type; default = { }; example = literalExample '' { @@ -51,6 +50,11 @@ in { home.packages = [ cfg.package ]; xdg.configFile."alacritty/alacritty.yml" = mkIf (cfg.settings != { }) { + # TODO: Replace by the generate function but need to figure out how to + # handle the escaping first. + # + # source = yamlFormat.generate "alacritty.yml" cfg.settings; + text = replaceStrings [ "\\\\" ] [ "\\" ] (builtins.toJSON cfg.settings); }; diff --git a/modules/programs/astroid-accounts.nix b/modules/programs/astroid-accounts.nix index 17544ff7..fb803867 100644 --- a/modules/programs/astroid-accounts.nix +++ b/modules/programs/astroid-accounts.nix @@ -16,7 +16,7 @@ with lib; }; extraConfig = mkOption { - type = types.attrs; + type = types.attrsOf types.anything; default = { }; example = { select_query = ""; }; description = '' diff --git a/modules/programs/astroid.nix b/modules/programs/astroid.nix index af12b10e..8af18f16 100644 --- a/modules/programs/astroid.nix +++ b/modules/programs/astroid.nix @@ -7,6 +7,8 @@ let cfg = config.programs.astroid; + jsonFormat = pkgs.formats.json { }; + astroidAccounts = filterAttrs (n: v: v.astroid.enable) config.accounts.email.accounts; @@ -36,19 +38,18 @@ let } // astroid.extraConfig; # See https://github.com/astroidmail/astroid/wiki/Configuration-Reference - configFile = mailAccounts: - let - template = fromJSON (readFile ./astroid-config-template.json); - astroidConfig = foldl' recursiveUpdate template [ - { - astroid.notmuch_config = "${config.xdg.configHome}/notmuch/notmuchrc"; - accounts = mapAttrs (n: accountAttr) astroidAccounts; - crypto.gpg.path = "${pkgs.gnupg}/bin/gpg"; - } - cfg.extraConfig - cfg.externalEditor - ]; - in builtins.toJSON astroidConfig; + finalConfig = let + template = fromJSON (readFile ./astroid-config-template.json); + astroidConfig = foldl' recursiveUpdate template [ + { + astroid.notmuch_config = "${config.xdg.configHome}/notmuch/notmuchrc"; + accounts = mapAttrs (n: accountAttr) astroidAccounts; + crypto.gpg.path = "${pkgs.gnupg}/bin/gpg"; + } + cfg.extraConfig + cfg.externalEditor + ]; + in astroidConfig; in { options = { @@ -90,9 +91,13 @@ in { }; extraConfig = mkOption { - type = types.attrs; + type = jsonFormat.type; default = { }; - example = { poll.interval = 0; }; + example = literalExample '' + { + poll.interval = 0; + } + ''; description = '' JSON config that will override the default Astroid configuration. ''; @@ -107,13 +112,8 @@ in { config = mkIf cfg.enable { home.packages = [ pkgs.astroid ]; - xdg.configFile."astroid/config".source = pkgs.runCommand "out.json" { - json = configFile astroidAccounts; - preferLocalBuild = true; - allowSubstitutes = false; - } '' - echo -n "$json" | ${pkgs.jq}/bin/jq . > $out - ''; + xdg.configFile."astroid/config".source = + jsonFormat.generate "astroid-config" finalConfig; xdg.configFile."astroid/poll.sh" = { executable = true; diff --git a/modules/programs/beets.nix b/modules/programs/beets.nix index 1a45bbea..6eb183dd 100644 --- a/modules/programs/beets.nix +++ b/modules/programs/beets.nix @@ -6,6 +6,8 @@ let cfg = config.programs.beets; + yamlFormat = pkgs.formats.yaml { }; + in { meta.maintainers = [ maintainers.rycee ]; @@ -39,7 +41,7 @@ in { }; settings = mkOption { - type = types.attrs; + type = yamlFormat.type; default = { }; description = '' Configuration written to @@ -52,7 +54,7 @@ in { config = mkIf cfg.enable { home.packages = [ cfg.package ]; - xdg.configFile."beets/config.yaml".text = - builtins.toJSON config.programs.beets.settings; + xdg.configFile."beets/config.yaml".source = + yamlFormat.generate "beets-config" cfg.settings; }; } diff --git a/modules/programs/direnv.nix b/modules/programs/direnv.nix index 1d1374b8..92a6e668 100644 --- a/modules/programs/direnv.nix +++ b/modules/programs/direnv.nix @@ -5,16 +5,8 @@ with lib; let cfg = config.programs.direnv; - configFile = config: - pkgs.runCommand "config.toml" { - buildInputs = [ pkgs.remarshal ]; - preferLocalBuild = true; - allowSubstitutes = false; - } '' - remarshal -if json -of toml \ - < ${pkgs.writeText "config.json" (builtins.toJSON config)} \ - > $out - ''; + + tomlFormat = pkgs.formats.toml { }; in { meta.maintainers = [ maintainers.rycee ]; @@ -23,7 +15,7 @@ in { enable = mkEnableOption "direnv, the environment switcher"; config = mkOption { - type = types.attrs; + type = tomlFormat.type; default = { }; description = '' Configuration written to @@ -80,8 +72,9 @@ in { config = mkIf cfg.enable { home.packages = [ pkgs.direnv ]; - xdg.configFile."direnv/config.toml" = - mkIf (cfg.config != { }) { source = configFile cfg.config; }; + xdg.configFile."direnv/config.toml" = mkIf (cfg.config != { }) { + source = tomlFormat.generate "direnv-config" cfg.config; + }; xdg.configFile."direnv/direnvrc" = let text = concatStringsSep "\n" (optional (cfg.stdlib != "") cfg.stdlib diff --git a/modules/programs/git.nix b/modules/programs/git.nix index 312269de..78346c6a 100644 --- a/modules/programs/git.nix +++ b/modules/programs/git.nix @@ -101,7 +101,7 @@ let }; contents = mkOption { - type = types.attrs; + type = types.attrsOf types.anything; default = { }; description = '' Configuration to include. If empty then a path must be given. diff --git a/modules/programs/matplotlib.nix b/modules/programs/matplotlib.nix index da80c116..0d4e48c9 100644 --- a/modules/programs/matplotlib.nix +++ b/modules/programs/matplotlib.nix @@ -23,7 +23,7 @@ in { config = mkOption { default = { }; - type = types.attrs; + type = types.attrsOf types.anything; description = '' Add terms to the matplotlibrc file to control the default matplotlib behavior. diff --git a/modules/programs/mercurial.nix b/modules/programs/mercurial.nix index 8e9a3bef..2fc6e007 100644 --- a/modules/programs/mercurial.nix +++ b/modules/programs/mercurial.nix @@ -6,6 +6,8 @@ let cfg = config.programs.mercurial; + iniFormat = pkgs.formats.ini { }; + in { options = { @@ -30,19 +32,19 @@ in { }; aliases = mkOption { - type = types.attrs; + type = types.attrsOf types.anything; default = { }; description = "Mercurial aliases to define."; }; extraConfig = mkOption { - type = types.either types.attrs types.lines; + type = types.either (types.attrsOf types.anything) types.lines; default = { }; description = "Additional configuration to add."; }; iniContent = mkOption { - type = types.attrsOf types.attrs; + type = iniFormat.type; internal = true; }; @@ -71,7 +73,8 @@ in { username = cfg.userName + " <" + cfg.userEmail + ">"; }; - xdg.configFile."hg/hgrc".text = generators.toINI { } cfg.iniContent; + xdg.configFile."hg/hgrc".source = + iniFormat.generate "hgrc" cfg.iniContent; } (mkIf (cfg.ignores != [ ] || cfg.ignoresRegexp != [ ]) { diff --git a/modules/programs/neovim.nix b/modules/programs/neovim.nix index ea58e3f3..c0ee24cf 100644 --- a/modules/programs/neovim.nix +++ b/modules/programs/neovim.nix @@ -156,7 +156,7 @@ in { }; configure = mkOption { - type = types.attrs; + type = types.attrsOf types.anything; default = { }; example = literalExample '' configure = { diff --git a/modules/programs/qutebrowser.nix b/modules/programs/qutebrowser.nix index 798363fb..282861d9 100644 --- a/modules/programs/qutebrowser.nix +++ b/modules/programs/qutebrowser.nix @@ -78,7 +78,7 @@ in { }; settings = mkOption { - type = types.attrs; + type = types.attrsOf types.anything; default = { }; description = '' Options to add to qutebrowser config.py file. diff --git a/modules/programs/taskwarrior.nix b/modules/programs/taskwarrior.nix index cf95511f..6a887e0f 100644 --- a/modules/programs/taskwarrior.nix +++ b/modules/programs/taskwarrior.nix @@ -40,7 +40,7 @@ in { enable = mkEnableOption "Task Warrior"; config = mkOption { - type = types.attrs; + type = types.attrsOf types.anything; default = { }; example = literalExample '' { diff --git a/modules/programs/urxvt.nix b/modules/programs/urxvt.nix index e4c72bfe..5eb3d90d 100644 --- a/modules/programs/urxvt.nix +++ b/modules/programs/urxvt.nix @@ -124,7 +124,7 @@ in { extraConfig = mkOption { default = { }; - type = types.attrs; + type = types.attrsOf types.anything; description = "Additional configuration to add."; example = { "shading" = 15; }; }; diff --git a/modules/programs/vscode.nix b/modules/programs/vscode.nix index f5710ae9..5f440025 100644 --- a/modules/programs/vscode.nix +++ b/modules/programs/vscode.nix @@ -8,6 +8,8 @@ let vscodePname = cfg.package.pname; + jsonFormat = pkgs.formats.json { }; + configDir = { "vscode" = "Code"; "vscode-insiders" = "Code - Insiders"; @@ -46,7 +48,7 @@ in { }; userSettings = mkOption { - type = types.attrs; + type = jsonFormat.type; default = { }; example = literalExample '' { @@ -125,10 +127,10 @@ in { toSymlink = concatMap toPaths cfg.extensions; in foldr (a: b: a // b) { "${configFilePath}" = mkIf (cfg.userSettings != { }) { - text = builtins.toJSON cfg.userSettings; + source = jsonFormat.generate "vscode-user-settings" cfg.userSettings; }; "${keybindingsFilePath}" = mkIf (cfg.keybindings != [ ]) { - text = builtins.toJSON cfg.keybindings; + source = jsonFormat.generate "vscode-keybindings" cfg.keybindings; }; } toSymlink; }; diff --git a/modules/services/dwm-status.nix b/modules/services/dwm-status.nix index 7a19e5e5..a0c2a724 100644 --- a/modules/services/dwm-status.nix +++ b/modules/services/dwm-status.nix @@ -5,11 +5,13 @@ with lib; let cfg = config.services.dwm-status; + jsonFormat = pkgs.formats.json { }; + features = [ "audio" "backlight" "battery" "cpu_load" "network" "time" ]; - configText = builtins.toJSON ({ inherit (cfg) order; } // cfg.extraConfig); + finalConfig = { inherit (cfg) order; } // cfg.extraConfig; - configFile = pkgs.writeText "dwm-status.json" configText; + configFile = jsonFormat.generate "dwm-status.json" finalConfig; in { options = { @@ -30,7 +32,7 @@ in { }; extraConfig = mkOption { - type = types.attrs; + type = jsonFormat.type; default = { }; example = literalExample '' { diff --git a/modules/services/hound.nix b/modules/services/hound.nix index 00589f34..07b5d476 100644 --- a/modules/services/hound.nix +++ b/modules/services/hound.nix @@ -6,12 +6,14 @@ let cfg = config.services.hound; - configFile = pkgs.writeText "hound-config.json" (builtins.toJSON { + jsonFormat = pkgs.formats.json { }; + + configFile = jsonFormat.generate "hound-config.json" { max-concurrent-indexers = cfg.maxConcurrentIndexers; dbpath = cfg.databasePath; repos = cfg.repositories; health-check-url = "/healthz"; - }); + }; houndOptions = [ "--addr ${cfg.listenAddress}" "--conf ${configFile}" ]; @@ -41,7 +43,7 @@ in { }; repositories = mkOption { - type = types.attrsOf (types.uniq types.attrs); + type = types.attrsOf jsonFormat.type; default = { }; example = literalExample '' { diff --git a/modules/services/xsuspender.nix b/modules/services/xsuspender.nix index 2eb40f5d..7d855f05 100644 --- a/modules/services/xsuspender.nix +++ b/modules/services/xsuspender.nix @@ -6,6 +6,8 @@ let cfg = config.services.xsuspender; + iniFormat = pkgs.formats.ini { }; + xsuspenderOptions = types.submodule { options = { matchWmClassContains = mkOption { @@ -139,7 +141,7 @@ in { }; iniContent = mkOption { - type = types.attrsOf types.attrs; + type = iniFormat.type; internal = true; }; }; @@ -170,7 +172,8 @@ in { # To make the xsuspender tool available. home.packages = [ pkgs.xsuspender ]; - xdg.configFile."xsuspender.conf".text = generators.toINI { } cfg.iniContent; + xdg.configFile."xsuspender.conf".source = + iniFormat.generate "xsuspender.conf" cfg.iniContent; systemd.user.services.xsuspender = { Unit = { diff --git a/tests/modules/programs/alacritty/default.nix b/tests/modules/programs/alacritty/default.nix index f63e033d..3ccd9a91 100644 --- a/tests/modules/programs/alacritty/default.nix +++ b/tests/modules/programs/alacritty/default.nix @@ -1,4 +1,5 @@ { alacritty-example-settings = ./example-settings.nix; alacritty-empty-settings = ./empty-settings.nix; + alacritty-merging-settings = ./settings-merging.nix; } diff --git a/tests/modules/programs/alacritty/settings-merging-expected.yml b/tests/modules/programs/alacritty/settings-merging-expected.yml new file mode 100644 index 00000000..49d92a61 --- /dev/null +++ b/tests/modules/programs/alacritty/settings-merging-expected.yml @@ -0,0 +1 @@ +{"font":{"bold":{"family":"SFMono"},"normal":{"family":"SFMono"}},"key_bindings":[{"chars":"\x0c","key":"K","mods":"Control"}],"window":{"dimensions":{"columns":200,"lines":3}}} \ No newline at end of file diff --git a/tests/modules/programs/alacritty/settings-merging.nix b/tests/modules/programs/alacritty/settings-merging.nix new file mode 100644 index 00000000..1b8559d6 --- /dev/null +++ b/tests/modules/programs/alacritty/settings-merging.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + config = { + programs.alacritty = { + enable = true; + package = pkgs.writeScriptBin "dummy-alacritty" ""; + + settings = { + window.dimensions = { + lines = 3; + columns = 200; + }; + + key_bindings = [{ + key = "K"; + mods = "Control"; + chars = "\\x0c"; + }]; + + font = let + defaultFont = + lib.mkMerge [ (lib.mkIf true "SFMono") (lib.mkIf false "Iosevka") ]; + in { + normal.family = defaultFont; + bold.family = defaultFont; + }; + }; + }; + + nmt.script = '' + assertFileContent \ + home-files/.config/alacritty/alacritty.yml \ + ${./settings-merging-expected.yml} + ''; + }; +} diff --git a/tests/modules/programs/vscode/keybindings.nix b/tests/modules/programs/vscode/keybindings.nix index 420b212d..d1ab38d3 100644 --- a/tests/modules/programs/vscode/keybindings.nix +++ b/tests/modules/programs/vscode/keybindings.nix @@ -27,7 +27,25 @@ let else ".config/Code/User/keybindings.json"; - expectedJson = pkgs.writeText "expected.json" (builtins.toJSON bindings); + expectedJson = pkgs.writeText "expected.json" '' + [ + { + "command": "editor.action.clipboardCopyAction", + "key": "ctrl+c", + "when": "textInputFocus && false" + }, + { + "command": "deleteFile", + "key": "ctrl+c", + "when": "" + }, + { + "command": "deleteFile", + "key": "d", + "when": "explorerViewletVisible" + } + ] + ''; in { config = { programs.vscode = {