diff --git a/ci/flake.lock b/ci/flake.lock index bb9eaf1a..25f9b721 100644 --- a/ci/flake.lock +++ b/ci/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1777548390, - "narHash": "sha256-WacE23EbHTsBKvr8cu+1DFNbP6Rh1brHUH5SDUI0NQI=", + "lastModified": 1778274207, + "narHash": "sha256-I4puXmX1iovcCHZlRmztO3vW0mAbbRvq4F8wgIMQ1MM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "7aaa00e7cc9be6c316cb5f6617bd740dd435c59d", + "rev": "b3da656039dc7a6240f27b2ef8cc6a3ef3bccae7", "type": "github" }, "original": { diff --git a/ci/test-lib.nix b/ci/test-lib.nix index 225c9ea1..92731b17 100644 --- a/ci/test-lib.nix +++ b/ci/test-lib.nix @@ -10,7 +10,7 @@ let wlib = self.lib; - errMsg = msg: "(echo ${renderMsg msg} >&2 && return 1)"; + errMsg = msg: "(echo \"${renderMsg msg}\" >&2 && return 1)"; indentBlock = str: num: @@ -280,10 +280,27 @@ in msg = "File ${path} should not exist"; }; + /** + Returns an `Assertion` that checks whether `path` does **not** exist as a directory. + + # Type + ``` + notIsFile :: String -> Assertion + ``` + + # Arguments + path + : The filesystem path that should be absent. + */ + notIsDirectory = path: { + cond = ''[ ! -d "${path}" ]''; + msg = "Directory ${path} should not exist"; + }; + /** Returns an `Assertion` that checks whether `file` contains a line matching `pattern`. - The check is performed with `grep -q`, so `pattern` is treated as a basic regular expression. + The check is performed with `grep -Eq`, so `pattern` is treated as an extended regular expression. # Type ``` @@ -295,10 +312,10 @@ in : Path to the file to search. pattern - : Basic regular expression to search for. + : Extended regular expression to search for. */ fileContains = file: pattern: { - cond = ''grep -q '${pattern}' "${file}"''; + cond = ''grep -Eq -- '${pattern}' "${file}"''; msg = "Pattern '${pattern}' not found in ${file}"; }; diff --git a/flake.lock b/flake.lock index bb9eaf1a..25f9b721 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1777548390, - "narHash": "sha256-WacE23EbHTsBKvr8cu+1DFNbP6Rh1brHUH5SDUI0NQI=", + "lastModified": 1778274207, + "narHash": "sha256-I4puXmX1iovcCHZlRmztO3vW0mAbbRvq4F8wgIMQ1MM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "7aaa00e7cc9be6c316cb5f6617bd740dd435c59d", + "rev": "b3da656039dc7a6240f27b2ef8cc6a3ef3bccae7", "type": "github" }, "original": { diff --git a/lib/types.nix b/lib/types.nix index 376d19a8..3ea07e52 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -516,4 +516,41 @@ in Like `wlib.types.attrsRecursive`, but uses `lib.types.lazyAttrsOf` instead. */ lazyAttrsRecursive = attrsRecursive true; + + /** + Creates a value type suitable for serialization formats. + + Parameters: + - typeName: String describing the format (e.g. "JSON", "YAML", "XML") + - nullable: Whether the structured value type allows `null` values. + - extraValueTypes: List of extra value types to allow, e.g. "[ lib.types.luaInline ]" + + Returns a type suitable for structured data formats that supports: + - Basic types: boolean, integer, float, string, path + - Complex types: attribute sets and lists + - Other user provided value types + */ + structuredValueWith = + { + typeName, + nullable ? true, + extraValueTypes ? [ ], + }: + let + baseType = lib.types.oneOf ( + (lib.toList extraValueTypes) + ++ [ + lib.types.bool + lib.types.int + lib.types.float + wlib.types.stringable + (lib.types.attrsOf valueType) + (lib.types.listOf valueType) + ] + ); + valueType = (if nullable then lib.types.nullOr baseType else baseType) // { + description = "${typeName} value"; + }; + in + valueType; } diff --git a/wrapperModules/a/alacritty/module.nix b/wrapperModules/a/alacritty/module.nix index d6d88771..fcb53ce8 100644 --- a/wrapperModules/a/alacritty/module.nix +++ b/wrapperModules/a/alacritty/module.nix @@ -5,14 +5,14 @@ pkgs, ... }: -let - tomlFmt = pkgs.formats.toml { }; -in { imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - type = tomlFmt.type; + type = wlib.types.structuredValueWith { + nullable = false; + typeName = "TOML"; + }; default = { }; description = '' Configuration of alacritty. diff --git a/wrapperModules/a/atuin/module.nix b/wrapperModules/a/atuin/module.nix index d5a31a3c..6f6a00c6 100644 --- a/wrapperModules/a/atuin/module.nix +++ b/wrapperModules/a/atuin/module.nix @@ -6,21 +6,24 @@ ... }: let - tomlFmt = pkgs.formats.toml { }; + tomlFmtType = wlib.types.structuredValueWith { + nullable = false; + typeName = "TOML"; + }; in { imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; default = { }; description = '' Atuin configuration options. ''; }; server-settings = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; default = { }; description = '' Atuin server configuration options. diff --git a/wrapperModules/b/bottom/module.nix b/wrapperModules/b/bottom/module.nix index a018c707..8aa1d549 100644 --- a/wrapperModules/b/bottom/module.nix +++ b/wrapperModules/b/bottom/module.nix @@ -5,14 +5,14 @@ pkgs, ... }: -let - tomlFmt = pkgs.formats.toml { }; -in { imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - type = tomlFmt.type; + type = wlib.types.structuredValueWith { + nullable = false; + typeName = "TOML"; + }; default = { }; description = '' Configuration passed to `btm` using `--config_location` flag. diff --git a/wrapperModules/c/claude-code/module.nix b/wrapperModules/c/claude-code/module.nix index 4d4c8743..59cbd30d 100644 --- a/wrapperModules/c/claude-code/module.nix +++ b/wrapperModules/c/claude-code/module.nix @@ -6,7 +6,7 @@ ... }: let - jsonFmt = pkgs.formats.json { }; + jsonFmtType = wlib.types.structuredValueWith { typeName = "JSON"; }; in { imports = [ wlib.modules.default ]; @@ -14,7 +14,7 @@ in options = { agents = lib.mkOption { - type = jsonFmt.type; + type = jsonFmtType; default = { }; description = '' Custom agents to add to Claude Code. @@ -37,7 +37,7 @@ in }; mcpConfig = lib.mkOption { - type = jsonFmt.type; + type = jsonFmtType; default = { }; description = '' MCP Server configuration @@ -71,7 +71,7 @@ in }; settings = lib.mkOption { - type = jsonFmt.type; + type = jsonFmtType; default = { }; description = '' Claude Code settings diff --git a/wrapperModules/d/direnv/check.nix b/wrapperModules/d/direnv/check.nix new file mode 100644 index 00000000..b7e22f44 --- /dev/null +++ b/wrapperModules/d/direnv/check.nix @@ -0,0 +1,150 @@ +{ + pkgs, + self, + tlib, +}: + +let + inherit (tlib) + fileContains + isDirectory + isFile + notIsFile + test + ; + + lib = pkgs.lib; + + getDotdir = + wrapper: + let + cfg = (wrapper.eval { }).config; + dotdir = "${wrapper}/${cfg.configDirname}"; + in + dotdir; +in +test { wrapper = "direnv"; } { + + "direnv wrapper should be created" = + let + wrapper = self.wrappers.direnv.wrap { + inherit pkgs; + nix-direnv.enable = true; + }; + in + '' + "${wrapper}/bin/direnv" --version | grep -q "${wrapper.version}" + ''; + + "if nix-direnv is enabled then lib/nix-direnv.sh should exists" = + let + wrapper = self.wrappers.direnv.wrap { + inherit pkgs; + nix-direnv.enable = true; + }; + in + [ + (isDirectory (getDotdir wrapper)) + (isFile "${getDotdir wrapper}/lib/nix-direnv.sh") + ]; + + "if nix-direnv is disabled then lib/nix-direnv.sh should not exist" = + let + wrapper = self.wrappers.direnv.wrap { + inherit pkgs; + nix-direnv.enable = false; + }; + in + [ + (isDirectory (getDotdir wrapper)) + (notIsFile "${getDotdir wrapper}/lib/nix-direnv.sh") + ]; + + "if mise is enabled then lib/mise.sh should exists" = + let + wrapper = self.wrappers.direnv.wrap { + inherit pkgs; + mise.enable = true; + }; + in + [ + (isDirectory (getDotdir wrapper)) + (isFile "${getDotdir wrapper}/lib/mise.sh") + ]; + + "if mise is disabled then lib/mise.sh should not exist" = + let + wrapper = self.wrappers.direnv.wrap { + inherit pkgs; + mise.enable = false; + }; + in + [ + (isDirectory (getDotdir wrapper)) + (notIsFile "${getDotdir wrapper}/lib/mise.sh") + ]; + + "if a lib-script is set then it should be generated" = + let + libScriptFile = "${getDotdir wrapper}/lib/foo.sh"; + libScriptContent = "echo foo"; + wrapper = self.wrappers.direnv.wrap { + inherit pkgs; + lib."foo.sh" = libScriptContent; + }; + in + [ + (isDirectory (getDotdir wrapper)) + (isFile libScriptFile) + (fileContains libScriptFile libScriptContent) + ]; + + "if silent mode is enabled then log settings should be set" = + let + direnvTomlFile = "${getDotdir wrapper}/direnv.toml"; + wrapper = self.wrappers.direnv.wrap { + inherit pkgs; + silent = true; + }; + in + [ + (isDirectory (getDotdir wrapper)) + (isFile direnvTomlFile) + (fileContains direnvTomlFile "log_format") + (fileContains direnvTomlFile "log_filter") + + ]; + + "if extraConfig is working" = + let + direnvTomlFile = "${getDotdir wrapper}/direnv.toml"; + wrapper = self.wrappers.direnv.wrap { + inherit pkgs; + extraConfig = { + fooSection.fooKey = "fooValue"; + }; + }; + in + [ + (isDirectory (getDotdir wrapper)) + (isFile direnvTomlFile) + (fileContains direnvTomlFile "\\[fooSection\\]") + (fileContains direnvTomlFile "fooKey.*fooValue") + ]; + + "if direnvrc is working" = + let + direnvrcFile = "${getDotdir wrapper}/direnvrc"; + direnvrcContent = "echo foo"; + + wrapper = self.wrappers.direnv.wrap { + inherit pkgs; + direnvrc = direnvrcContent; + }; + in + [ + (isDirectory (getDotdir wrapper)) + (isFile direnvrcFile) + (fileContains direnvrcFile direnvrcContent) + ]; +} diff --git a/wrapperModules/d/direnv/module.nix b/wrapperModules/d/direnv/module.nix new file mode 100644 index 00000000..762128d1 --- /dev/null +++ b/wrapperModules/d/direnv/module.nix @@ -0,0 +1,119 @@ +{ + config, + lib, + wlib, + pkgs, + ... +}: +let + tomlFmt = pkgs.formats.toml { }; + direnvDotdir = "${config.wrapper.${config.outputName}}/${config.configDirname}"; +in +{ + imports = [ wlib.modules.default ]; + options = { + configDirname = lib.mkOption { + type = lib.types.str; + default = "${config.binName}-dot-dir"; + description = "Name of the directory which is created as the dotdir in the wrapper output"; + }; + silent = lib.mkEnableOption "silent mode, that is, disabling direnv logging"; + direnvrc = lib.mkOption { + type = lib.types.lines; + description = "Content of `$DIRENV_CONFIG/direnv`"; + default = ""; + }; + nix-direnv = { + enable = lib.mkEnableOption "nix-direnv integration"; + package = lib.mkPackageOption pkgs "nix-direnv" { }; + }; + mise = { + enable = lib.mkEnableOption "mise integration"; + package = lib.mkPackageOption pkgs "mise" { }; + }; + lib = lib.mkOption { + type = with lib.types; attrsOf lines; + description = '' + Configuration of [extension files](https://direnv.net/#the-stdlib) + that will be created at `$DIRENV_CONFIG/lib/*.sh` + ''; + example = { + "my-lib-script.sh" = "echo 'content of my-lib-script.sh'"; + }; + default = { }; + }; + extraConfig = lib.mkOption { + inherit (tomlFmt) type; + default = { }; + description = '' + Configuration of direnv.toml. + See + ''; + }; + }; + config = { + package = lib.mkDefault pkgs.direnv; + env = { + # We currently do not inject `DIRENV_CONFIG` for the reasons outlined in + # meta.description.pre. + + # **IMPORTANT** Using `placeholder "out"` here seems to cause issues if this wrapper is + # built inside a subWrapperModule (for example within the zshWrapper) as it refers + # to the build zsh output in that context. The passthru variants seems to solve this issue. + DIRENV_CONFIG = "${placeholder "out"}/${config.configDirname}"; + }; + passthru.DIRENV_CONFIG = direnvDotdir; + lib = { + "nix-direnv.sh" = lib.mkIf config.nix-direnv.enable '' + source ${config.nix-direnv.package}/share/nix-direnv/direnvrc + ''; + "mise.sh" = lib.mkIf config.mise.enable '' + eval "$(${lib.getExe config.mise.package} direnv activate)" + ''; + }; + extraConfig = { + global = lib.mkIf (config.silent) { + log_format = "-"; + log_filter = "^$"; + }; + }; + constructFiles = { + direnvToml = { + content = builtins.toJSON config.extraConfig; + relPath = "${config.configDirname}/direnv.toml"; + builder = ''mkdir -p "$(dirname "$2")" && ${pkgs.remarshal}/bin/json2toml "$1" "$2"''; + }; + direnvRc = { + content = config.direnvrc; + relPath = "${config.configDirname}/direnvrc"; + }; + } + // lib.mapAttrs (name: value: { + content = value; + relPath = "${config.configDirname}/lib/${name}"; + }) config.lib; + meta.maintainers = [ wlib.maintainers.zenoli ]; + meta.description.pre = '' + **IMPORTANT** In order to use this wrapper, `DIRENV_CONFIG` needs to be explicitly + set in your shells environment: + + ```shell + DIRENV_CONFIG="''${direnvWrapper.passthru.DIRENV_CONFIG}" + ``` + + This is because right now, direnv will use the original `direnv` binary in its shell hook + and not the wrapper script. So injecting `DIRENV_CONFIG` currently has no effect. + + If the PR below will ever be merged, this issue can be fixed by setting: + + ```nix + env.DIRENV_EXE_PATH = "''${placeholder "out"}/bin/direnv"; + ``` + + This would make the direnv hook use the wrapper instead of the original binary and + injecting `DIRENV_CONFIG` into the wrapper would start to take effect. + + https://github.com/direnv/direnv/pull/1564 + ''; + }; +} diff --git a/wrapperModules/f/fastfetch/module.nix b/wrapperModules/f/fastfetch/module.nix index 7627c83f..db21c4a6 100644 --- a/wrapperModules/f/fastfetch/module.nix +++ b/wrapperModules/f/fastfetch/module.nix @@ -9,7 +9,7 @@ imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - type = lib.types.json or (pkgs.formats.json { }).type; + type = wlib.types.structuredValueWith { typeName = "JSON"; }; default = { }; description = '' Configuration passed to fastfetch using `--config` flag diff --git a/wrapperModules/f/fish/module.nix b/wrapperModules/f/fish/module.nix index 290d6a0e..b24dbe05 100644 --- a/wrapperModules/f/fish/module.nix +++ b/wrapperModules/f/fish/module.nix @@ -457,8 +457,7 @@ in (foldl' ( acc: elem: acc + " " + (mkAbbrArg elem abbr) ) "abbr --add ${abbr.word} ${mkCursorArg abbr}" abbrArgs) - + " " - + "\"${abbr.expansion}\""; + + optionalString (abbr.function == null) " \"${abbr.expansion}\""; abbrs = concatStringsSep "\n" (map mkAbbrStr (attrValues cfg.abbreviations)); aliases = concatStringsSep "\n" ( diff --git a/wrapperModules/g/glance/module.nix b/wrapperModules/g/glance/module.nix index cab1eb13..cfabbaf3 100644 --- a/wrapperModules/g/glance/module.nix +++ b/wrapperModules/g/glance/module.nix @@ -9,7 +9,7 @@ imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - inherit (pkgs.formats.yaml { }) type; + type = wlib.types.structuredValueWith { typeName = "YAML 1.1"; }; default = { }; description = '' Configuration for glance. diff --git a/wrapperModules/h/halloy/module.nix b/wrapperModules/h/halloy/module.nix index 9854f238..c2004ae2 100644 --- a/wrapperModules/h/halloy/module.nix +++ b/wrapperModules/h/halloy/module.nix @@ -6,13 +6,16 @@ ... }: let - tomlFmt = pkgs.formats.toml { }; + tomlFmtType = wlib.types.structuredValueWith { + nullable = false; + typeName = "TOML"; + }; in { imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - inherit (tomlFmt) type; + type = tomlFmtType; default = { }; description = '' Configuration settings for halloy. All available options can be @@ -31,7 +34,7 @@ in themes = lib.mkOption { type = lib.types.attrsOf ( lib.types.oneOf [ - tomlFmt.type + tomlFmtType lib.types.lines lib.types.path ] diff --git a/wrapperModules/h/helix/module.nix b/wrapperModules/h/helix/module.nix index 905a4c31..e5156664 100644 --- a/wrapperModules/h/helix/module.nix +++ b/wrapperModules/h/helix/module.nix @@ -6,7 +6,10 @@ ... }: let - tomlFmt = pkgs.formats.toml { }; + tomlFmtType = wlib.types.structuredValueWith { + nullable = false; + typeName = "TOML"; + }; hasConfig = config.settings != { } || config.extraSettings != "" @@ -18,7 +21,7 @@ in imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' General settings See @@ -33,7 +36,7 @@ in ''; }; languages = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Language specific settings See @@ -43,7 +46,7 @@ in themes = lib.mkOption { type = lib.types.attrsOf ( lib.types.oneOf [ - tomlFmt.type + tomlFmtType lib.types.lines ] ); diff --git a/wrapperModules/h/himalaya/module.nix b/wrapperModules/h/himalaya/module.nix index 8ad80c4c..6320fc2d 100644 --- a/wrapperModules/h/himalaya/module.nix +++ b/wrapperModules/h/himalaya/module.nix @@ -5,15 +5,15 @@ lib, ... }: -let - tomlFmt = pkgs.formats.toml { }; -in { imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - type = tomlFmt.type; + type = wlib.types.structuredValueWith { + nullable = false; + typeName = "TOML"; + }; default = { }; description = '' Configuration for himalaya mail client CLI diff --git a/wrapperModules/h/hyfetch/module.nix b/wrapperModules/h/hyfetch/module.nix index c72fa21d..c541f0b5 100644 --- a/wrapperModules/h/hyfetch/module.nix +++ b/wrapperModules/h/hyfetch/module.nix @@ -5,14 +5,11 @@ pkgs, ... }: -let - jsonFormat = pkgs.formats.json { }; -in { imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - type = jsonFormat.type; + type = wlib.types.structuredValueWith { typeName = "JSON"; }; default = { }; description = "JSON config for HyFetch"; example = lib.literalExpression '' diff --git a/wrapperModules/j/jujutsu/module.nix b/wrapperModules/j/jujutsu/module.nix index d0a84ec4..23f9d736 100644 --- a/wrapperModules/j/jujutsu/module.nix +++ b/wrapperModules/j/jujutsu/module.nix @@ -5,14 +5,14 @@ pkgs, ... }: -let - tomlFmt = pkgs.formats.toml { }; -in { imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - type = tomlFmt.type; + type = wlib.types.structuredValueWith { + nullable = false; + typeName = "TOML"; + }; default = { }; description = '' Configuration for jujutsu. diff --git a/wrapperModules/m/mdbook/module.nix b/wrapperModules/m/mdbook/module.nix index 8b91c2fb..9184e5b4 100644 --- a/wrapperModules/m/mdbook/module.nix +++ b/wrapperModules/m/mdbook/module.nix @@ -188,9 +188,7 @@ let linkCmds = builtins.concatStringsSep "\n" (map mkLink sortedBook); }; - tomltype = (lib.types.json or (pkgs.formats.json { }).type) // { - description = "nullable TOML value"; - }; + tomltype = wlib.types.structuredValueWith { typeName = "nullable TOML"; }; book-out-dir = "${top.config.binName}-book-dir"; in diff --git a/wrapperModules/m/mpv/module.nix b/wrapperModules/m/mpv/module.nix index b1d8314c..8e25e3ae 100644 --- a/wrapperModules/m/mpv/module.nix +++ b/wrapperModules/m/mpv/module.nix @@ -273,12 +273,12 @@ in lib.mkIf (scriptsData != [ ] && (config.configDir == { } || !builtins.isAttrs config.configDir)) { sep = "="; - ifs = ":"; + ifs = null; data = scriptsData; }; "--script-opts-append" = lib.mkIf (scriptOptsData != [ ]) { sep = "="; - ifs = ","; + ifs = null; data = scriptOptsData; }; } diff --git a/wrapperModules/n/neovim/module.nix b/wrapperModules/n/neovim/module.nix index a506f78e..f3dda407 100644 --- a/wrapperModules/n/neovim/module.nix +++ b/wrapperModules/n/neovim/module.nix @@ -8,23 +8,10 @@ let makeWrapper = import wlib.modules.makeWrapper; inherit (lib) types; - luaType = - types.nullOr ( - types.oneOf [ - types.bool - types.float - types.int - types.path - types.str - types.luaInline - (types.attrsOf luaType) - (types.listOf luaType) - ] - ) - // { - description = "lua value"; - descriptionClass = "noun"; - }; + luaType = wlib.types.structuredValueWith { + typeName = "lua"; + extraValueTypes = lib.types.luaInline; + }; hostPropagatedOptions = name: hostConfig: lib.types.submoduleWith { diff --git a/wrapperModules/n/noctalia-shell/module.nix b/wrapperModules/n/noctalia-shell/module.nix index ab29e35e..ec81a010 100644 --- a/wrapperModules/n/noctalia-shell/module.nix +++ b/wrapperModules/n/noctalia-shell/module.nix @@ -101,7 +101,7 @@ in ''; }; settings = lib.mkOption { - type = lib.types.json or (pkgs.formats.json { }).type; + type = wlib.types.structuredValueWith { typeName = "JSON"; }; default = { }; example = lib.literalExpression '' { @@ -127,7 +127,7 @@ in }; colors = lib.mkOption { - type = lib.types.json or (pkgs.formats.json { }).type; + type = wlib.types.structuredValueWith { typeName = "JSON"; }; default = { }; example = lib.literalExpression '' { @@ -155,7 +155,10 @@ in user-templates = lib.mkOption { default = { }; - type = (pkgs.formats.toml { }).type; + type = wlib.types.structuredValueWith { + nullable = false; + typeName = "TOML"; + }; example = lib.literalExpression '' { templates = { @@ -175,7 +178,7 @@ in }; plugins = lib.mkOption { - type = lib.types.json or (pkgs.formats.json { }).type; + type = wlib.types.structuredValueWith { typeName = "JSON"; }; default = { }; example = lib.literalExpression '' { @@ -202,7 +205,7 @@ in }; pluginSettings = lib.mkOption { - type = lib.types.attrsOf (lib.types.json or (pkgs.formats.json { }).type); + type = lib.types.attrsOf (wlib.types.structuredValueWith { typeName = "JSON"; }); default = { }; example = lib.literalExpression '' { @@ -275,7 +278,7 @@ in ''; }; settings = lib.mkOption { - type = lib.types.json or (pkgs.formats.json { }).type; + type = wlib.types.structuredValueWith { typeName = "JSON"; }; default = { }; description = '' Settings to add to `$NOCTALIA_CONFIG_DIR/plugins/plugin-name/settings.json` diff --git a/wrapperModules/o/oh-my-posh/check.nix b/wrapperModules/o/oh-my-posh/check.nix new file mode 100644 index 00000000..cbdd1bad --- /dev/null +++ b/wrapperModules/o/oh-my-posh/check.nix @@ -0,0 +1,332 @@ +{ + pkgs, + self, + tlib, + writeText, + ... +}: + +let + inherit (tlib) + fileContains + isFile + isDirectory + notIsFile + notIsDirectory + test + ; + wm = self.wrappers.oh-my-posh; +in +test { wrapper = "oh-my-posh"; } { + + "wrapper should output correct version" = + let + wrapper = wm.wrap { + inherit pkgs; + }; + in + '' + "${wrapper}/bin/oh-my-posh" --version | + grep -q "${wrapper.version}" + ''; + + "If config is provided then config.json is properly set up" = + let + wrapper = wm.wrap { + inherit pkgs; + theme = "jandedobbeleer"; + }; + configFile = "${wrapper}/config.json"; + in + [ + (isFile configFile) + (fileContains "${wrapper}/bin/oh-my-posh" "--config.*${configFile}") + ]; + + "If no config is provided then no config.json is set up" = + let + wrapper = wm.wrap { + inherit pkgs; + }; + configFile = "${wrapper}/config.json"; + in + notIsFile configFile; + + "config chains" = + let + baseWrapper = wm.wrap { + inherit pkgs; + theme = [ + "aliens" + "agnoster" + ]; + settings.foo = "foo"; + configFile = writeText "file-config.yaml" "bar: bar"; + }; + nixStoreFile = name: "/nix/store/[[:alnum:]]{32}-.*${name}"; + extendsPattern = path: ''"extends": "${path}"''; + in + { + "theme > file > settings (default order)" = + let + wrapper = baseWrapper; + configChainDir = "${wrapper}/config-chain"; + + nixSettingsFile = "${configChainDir}/settings.json"; + fileSettingsFile = "${configChainDir}/file-config.json"; + agnosterFile = "${configChainDir}/agnoster.omp.json"; + in + [ + "[[ -h ${wrapper}/config.json ]]" + "[[ $(readlink -f ${wrapper}/config.json) == ${nixSettingsFile} ]]" + (fileContains nixSettingsFile (extendsPattern fileSettingsFile)) + (fileContains fileSettingsFile (extendsPattern agnosterFile)) + (fileContains agnosterFile (extendsPattern (nixStoreFile "aliens.omp.json"))) + ]; + + "file > theme > settings" = + let + wrapper = baseWrapper.wrap { + order = [ + "file" + "theme" + "settings" + ]; + }; + configChainDir = "${wrapper}/config-chain"; + + nixSettingsFile = "${configChainDir}/settings.json"; + agnosterFile = "${configChainDir}/agnoster.omp.json"; + aliensFile = "${configChainDir}/aliens.omp.json"; + in + [ + "[[ -h ${wrapper}/config.json ]]" + "[[ $(readlink -f ${wrapper}/config.json) == ${nixSettingsFile} ]]" + (fileContains nixSettingsFile (extendsPattern agnosterFile)) + (fileContains agnosterFile (extendsPattern aliensFile)) + (fileContains aliensFile (extendsPattern (nixStoreFile "file-config.json"))) + ]; + + "file > settings > theme" = + let + wrapper = baseWrapper.wrap { + order = [ + "file" + "settings" + "theme" + ]; + }; + configChainDir = "${wrapper}/config-chain"; + + agnosterFile = "${configChainDir}/agnoster.omp.json"; + aliensFile = "${configChainDir}/aliens.omp.json"; + nixSettingsFile = "${configChainDir}/settings.json"; + in + [ + "[[ -h ${wrapper}/config.json ]]" + "[[ $(readlink -f ${wrapper}/config.json) == ${agnosterFile} ]]" + (fileContains agnosterFile (extendsPattern aliensFile)) + (fileContains aliensFile (extendsPattern nixSettingsFile)) + (fileContains nixSettingsFile (extendsPattern (nixStoreFile "file-config.json"))) + ]; + + "settings > theme > file" = + let + wrapper = baseWrapper.wrap { + order = [ + "settings" + "theme" + "file" + ]; + }; + configChainDir = "${wrapper}/config-chain"; + + fileSettingsFile = "${configChainDir}/file-config.json"; + agnosterFile = "${configChainDir}/agnoster.omp.json"; + aliensFile = "${configChainDir}/aliens.omp.json"; + in + [ + "[[ -h ${wrapper}/config.json ]]" + "[[ $(readlink -f ${wrapper}/config.json) == ${fileSettingsFile} ]]" + (fileContains fileSettingsFile (extendsPattern agnosterFile)) + (fileContains agnosterFile (extendsPattern aliensFile)) + (fileContains aliensFile (extendsPattern (nixStoreFile "settings.json"))) + ]; + + "theme > settings > file" = + let + wrapper = baseWrapper.wrap { + order = [ + "theme" + "settings" + "file" + ]; + }; + configChainDir = "${wrapper}/config-chain"; + + fileSettingsFile = "${configChainDir}/file-config.json"; + nixSettingsFile = "${configChainDir}/settings.json"; + agnosterFile = "${configChainDir}/agnoster.omp.json"; + in + [ + "[[ -h ${wrapper}/config.json ]]" + "[[ $(readlink -f ${wrapper}/config.json) == ${fileSettingsFile} ]]" + (fileContains fileSettingsFile (extendsPattern nixSettingsFile)) + (fileContains nixSettingsFile (extendsPattern agnosterFile)) + (fileContains agnosterFile (extendsPattern (nixStoreFile "aliens.omp.json"))) + ]; + + "settings > file > theme" = + let + wrapper = baseWrapper.wrap { + order = [ + "settings" + "file" + "theme" + ]; + }; + configChainDir = "${wrapper}/config-chain"; + + agnosterFile = "${configChainDir}/agnoster.omp.json"; + aliensFile = "${configChainDir}/aliens.omp.json"; + fileSettingsFile = "${configChainDir}/file-config.json"; + in + [ + "[[ -h ${wrapper}/config.json ]]" + "[[ $(readlink -f ${wrapper}/config.json) == ${agnosterFile} ]]" + (fileContains agnosterFile (extendsPattern aliensFile)) + (fileContains aliensFile (extendsPattern fileSettingsFile)) + (fileContains fileSettingsFile (extendsPattern (nixStoreFile "settings.json"))) + ]; + }; + + "config file formats" = + let + key = "dummy_key"; + value = "dummy_value"; + in + { + "json configFile is loaded" = + let + wrapper = wm.wrap { + inherit pkgs; + configFile = writeText "config.json" ''{"${key}": "${value}"}''; + }; + generatedConfig = "${wrapper}/config.json"; + in + [ + (isFile generatedConfig) + (fileContains generatedConfig key) + (fileContains generatedConfig value) + ]; + + "yaml configFile is loaded" = + let + wrapper = wm.wrap { + inherit pkgs; + configFile = writeText "config.yaml" "${key}: ${value}"; + }; + generatedConfig = "${wrapper}/config.json"; + in + [ + (isFile generatedConfig) + (fileContains generatedConfig key) + (fileContains generatedConfig value) + ]; + + "toml configFile is loaded" = + let + wrapper = wm.wrap { + inherit pkgs; + configFile = writeText "config.toml" ''${key} = "${value}"''; + }; + generatedConfig = "${wrapper}/config.json"; + in + [ + (isFile generatedConfig) + (fileContains generatedConfig key) + (fileContains generatedConfig value) + ]; + }; + + "explicit `extends` in settings breaks the config chain" = + let + wrapper = wm.wrap { + inherit pkgs; + theme = [ + "aliens" + "agnoster" + ]; + settings.extends = "foo"; + }; + configChainDir = "${wrapper}/config-chain"; + in + [ + (isFile "${configChainDir}/settings.json") + (notIsFile "${configChainDir}/agnoster.omp.json") + (notIsFile "${configChainDir}/aliens.omp.json") + ]; + + "If a single config is provided then no config-chain dir is created" = + let + wrapper = wm.wrap { + inherit pkgs; + settings.extends = "foo"; + }; + in + [ + (isFile "${wrapper}/config.json") + (notIsDirectory "${wrapper}/config-chain") + ]; + + "extending segments works as expected" = + let + wrapper = wm.wrap { + inherit pkgs; + configFile = writeText "config.yaml" '' + blocks: + - type: prompt + alignment: left + segments: + - type: text + style: plain + template: "[b1s1]" + - type: text + style: plain + template: "[b1s2]" + - type: prompt + alignment: right + segments: + - type: text + style: plain + template: "[b2s1]" + - type: text + style: plain + template: "[b2s2]" + alias: foo + ''; + settings.blocks = [ + { + type = "prompt"; + alignment = "right"; + segments = [ + { + type = "text"; + style = "plain"; + alias = "foo"; + template = "foo"; + } + ]; + } + ]; + }; + in + # '[b2s2]' should be overridden with 'foo' + [ + "${wrapper}/bin/oh-my-posh print primary | grep -Fq '[b1s1]'" + "${wrapper}/bin/oh-my-posh print primary | grep -Fq '[b1s2]'" + "${wrapper}/bin/oh-my-posh print primary | grep -Fq '[b2s1]'" + "${wrapper}/bin/oh-my-posh print primary | grep -Fqv '[b2s2]'" + "${wrapper}/bin/oh-my-posh print primary | grep -Fq 'foo'" + ]; +} diff --git a/wrapperModules/o/oh-my-posh/module.nix b/wrapperModules/o/oh-my-posh/module.nix new file mode 100644 index 00000000..65688845 --- /dev/null +++ b/wrapperModules/o/oh-my-posh/module.nix @@ -0,0 +1,296 @@ +{ + wlib, + lib, + config, + pkgs, + ... +}: +let + jsonFmt = pkgs.formats.json { }; + + themeKey = "theme"; + fileKey = "file"; + settingsKey = "settings"; + + defaultOrder = [ + themeKey + fileKey + settingsKey + ]; +in +{ + imports = [ wlib.modules.default ]; + + options = { + settings = lib.mkOption { + inherit (jsonFmt) type; + default = { }; + description = '' + Pure nix configuration oh-my-posh. + See + ''; + example = { + console_title_template = "{{ .Folder }}"; + }; + }; + configFile = lib.mkOption { + type = with lib.types; nullOr (either path package); + default = null; + description = '' + Path to an oh-my-posh configuration file. + Supported formats are JSON (`.json`), TOML (`.toml`), and YAML (`.yaml`, `.yml`). + See + ''; + example = lib.literalExpression "./config.yaml"; + }; + theme = lib.mkOption { + type = with lib.types; either str (listOf str); + default = [ ]; + apply = lib.toList; + description = '' + One or more built-in oh-my-posh themes to use as configuration. + When a list is provided, they will be merged by chaining them with + [`.extends`](https://ohmyposh.dev/docs/configuration/general#extends). + Themes later in the list take precedence. + + See . + ''; + example = [ + "1_shell" + "agnoster" + ]; + }; + order = lib.mkOption { + type = with lib.types; wlib.types.fixedList 3 (enum defaultOrder); + default = defaultOrder; + description = '' + The order in which the specified settings are merged. + Values later in the list will take precedence. + + The allowed keys are: + + - "${themeKey}": Settings from the the specified theme (`config.theme`) + - "${fileKey}": Settings from the specified config file (`config.configFile`) + - "${settingsKey}": Settings specified as a nix attrs (`config.settings`) + ''; + }; + }; + + config = + let + nixSettingsFile = pkgs.writeText "settings.json" (builtins.toJSON config.settings); + + stripStoreHash = + name: + let + m = builtins.match "[a-z0-9]{32}-(.*)" name; + in + if m != null then builtins.head m else name; + + normalizedConfigFile = + if config.configFile == null then + null + else + let + path = toString config.configFile; + baseName = stripStoreHash (baseNameOf path); + isJson = lib.hasSuffix ".json" baseName; + isToml = lib.hasSuffix ".toml" baseName; + isYaml = lib.hasSuffix ".yaml" baseName || lib.hasSuffix ".yml" baseName; + configFileName = + lib.pipe baseName [ + (lib.removeSuffix ".toml") + (lib.removeSuffix ".yaml") + (lib.removeSuffix ".yml") + ] + + ".json"; + in + if isJson then + config.configFile + else if isToml || isYaml then + pkgs.runCommand configFileName { } '' + ${pkgs.yq-go}/bin/yq -o=json '.' ${lib.escapeShellArg "${config.configFile}"} > $out + '' + else + throw "oh-my-posh: configFile must have a .json, .toml, .yaml, or .yml extension, got: ${path}"; + + # List of { srcPath, name } in precedence order (lowest to highest) + orderedConfigs = lib.concatMap ( + key: + { + ${themeKey} = map (p: { + srcPath = "${config.package}/share/oh-my-posh/themes/${p}.omp.json"; + name = "${p}.omp.json"; + }) config.theme; + ${fileKey} = lib.optional (config.configFile != null) { + srcPath = "${normalizedConfigFile}"; + name = stripStoreHash (baseNameOf (toString normalizedConfigFile)); + }; + ${settingsKey} = lib.optional (config.settings != { }) { + srcPath = "${nixSettingsFile}"; + name = "settings.json"; + }; + } + .${key} + ) config.order; + + jq = "${pkgs.jq}/bin/jq"; + + # Build constructFile entries for the config chain. + # + # `curr`: the current (higher-precedence) config being processed. + # `configs`: remaining configs in descending precedence order. + # + # The builder for `curr` will add an ".extends" key to the json which will + # point to the next (lower-precedence) entry in the `configs` list + generateConstructFileEntries = + curr: configs: + let + relPath = "config-chain/${curr.name}"; + prev = builtins.head configs; + + # If currPath already has an "extends" key, symlink it as-is. + # Otherwise, add prevPath as the "extends" value. + generateBuilderScript = currPath: prevPath: '' + mkdir -p "$(dirname "$2")" + if [ "$(${jq} 'has("extends")' ${lib.escapeShellArg currPath})" = "true" ]; then + ln -s ${lib.escapeShellArg currPath} "$2" + else + ${jq} --arg ext ${lib.escapeShellArg prevPath} '. + {extends: $ext}' ${lib.escapeShellArg currPath} > "$2" + fi + ''; + + in + if builtins.length configs == 1 then + # Base: prev is the lowest-precedence config — point directly to its source + { + ${relPath} = { + inherit relPath; + builder = generateBuilderScript curr.srcPath prev.srcPath; + }; + } + else + # Recursive: prev will itself be a generated file in config-chain + { + ${relPath} = { + inherit relPath; + builder = generateBuilderScript curr.srcPath "${placeholder "out"}/config-chain/${prev.name}"; + }; + } + // generateConstructFileEntries prev (builtins.tail configs); + + n = builtins.length orderedConfigs; + + constructFiles = + if n == 0 then + { } + else if n == 1 then + let + cfg = builtins.head orderedConfigs; + in + { + "config.json" = { + relPath = "config.json"; + builder = '' + mkdir -p "$(dirname "$2")" + ln -s ${lib.escapeShellArg cfg.srcPath} "$2" + ''; + }; + } + else + let + reversed = lib.reverseList orderedConfigs; + lastConfig = lib.last orderedConfigs; + in + generateConstructFileEntries (builtins.head reversed) (builtins.tail reversed) + // { + "config.json" = { + relPath = "config.json"; + builder = + let + chainDir = "${placeholder "out"}/config-chain"; + lastConfigPath = "${chainDir}/${lastConfig.name}"; + in + '' + # Follow the extends chain and remove files in config-chain that are + # no longer reachable (cut off by a config that already had "extends") + declare -A reachable + current=${lib.escapeShellArg lastConfigPath} + while [ -f "$current" ]; do + reachable["$current"]=1 + ext=$(${jq} -r '.extends // empty' "$current") + [[ "$ext" == ${lib.escapeShellArg chainDir}/* ]] || break + current="$ext" + done + for f in ${lib.escapeShellArg chainDir}/*; do + [ -v 'reachable[$f]' ] || rm "$f" + done + rmdir ${lib.escapeShellArg chainDir} 2>/dev/null || true + + mkdir -p "$(dirname "$2")" + ln -s ${lib.escapeShellArg lastConfigPath} "$2" + ''; + }; + }; + in + { + inherit constructFiles; + package = lib.mkDefault pkgs.oh-my-posh; + flags."--config" = lib.mkIf (n > 0) config.constructFiles."config.json".path; + meta = { + maintainers = with wlib.maintainers; [ + zenoli + ]; + description = '' + Wrapper Module for the [Oh-My-Posh Prompt](https://ohmyposh.dev/). + + Oh-My-Posh is configured via a [JSON/YAML/TOML file](https://ohmyposh.dev/docs/configuration/general). + This module provides three ways to do this: + + - By specifying one (or many) of the [built-in themes](https://ohmyposh.dev/docs/themes/). + - By pointing to a JSON, TOML, or YAML configuration file. + - By using pure Nix to write an attribute set that gets converted to JSON. + + These options are not mutually exclusive. If multiple are defined, + they will be merged according to the order specified in `config.order`. + + Merging is done using Oh-My-Posh's native + [extends](https://ohmyposh.dev/docs/configuration/general#extends) mechanic, + which allows a configuration file to inherit from another and override individual values. + + Configs will be modified during build-time to add an `.extends` key + pointing to the next config in the list. If a config already has an `.extends` key present, + it is used as-is and the remaining lower-precedence configs are ignored. + + **Example** + + ```nix + theme = "jandedobbeleer"; + configFile = ./my-config.yaml; + settings.console_title_template = "{{ .Folder }}"; + ``` + + With the default order (`theme < file < settings`), this produces the chain: + + ``` + settings.json → my-config.json → jandedobbeleer.omp.json + (highest precedence) (lowest precedence) + ``` + + `settings.json` has an `extends` key pointing to `my-config.json`, + which in turn extends `jandedobbeleer.omp.json`. + + If `my-config.yaml` already contains an `extends` key (e.g. pointing to another theme), + it is left unchanged and the chain stops there: + + ``` + settings.json → my-config.json -x- jandedobbeleer.omp.json + (highest precedence) ↓ + (its own extends) + ``` + + `jandedobbeleer.omp.json` is dropped entirely — `my-config.yaml`'s own `extends` takes over as the base. + ''; + }; + }; +} diff --git a/wrapperModules/o/opencode/module.nix b/wrapperModules/o/opencode/module.nix index 0e9b0e4f..537754fe 100644 --- a/wrapperModules/o/opencode/module.nix +++ b/wrapperModules/o/opencode/module.nix @@ -8,7 +8,7 @@ { imports = [ wlib.modules.default ]; options.settings = lib.mkOption { - type = (pkgs.formats.json { }).type; + type = wlib.types.structuredValueWith { typeName = "JSON"; }; default = { }; description = "Sets OPENCODE_CONFIG for github:sst/opencode"; }; diff --git a/wrapperModules/o/ov/module.nix b/wrapperModules/o/ov/module.nix index 36cfb754..1e0704b4 100644 --- a/wrapperModules/o/ov/module.nix +++ b/wrapperModules/o/ov/module.nix @@ -5,14 +5,11 @@ pkgs, ... }: -let - yamlFmt = pkgs.formats.yaml { }; -in { imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - type = yamlFmt.type; + type = wlib.types.structuredValueWith { typeName = "YAML 1.1"; }; default = { }; description = '' Configuration of ov. diff --git a/wrapperModules/s/starship/module.nix b/wrapperModules/s/starship/module.nix index 121fbedd..1a8b3afe 100644 --- a/wrapperModules/s/starship/module.nix +++ b/wrapperModules/s/starship/module.nix @@ -6,8 +6,6 @@ ... }: let - tomlFmt = pkgs.formats.toml { }; - presetKey = "preset"; settingsKey = "settings"; @@ -21,7 +19,10 @@ in options = { settings = lib.mkOption { - inherit (tomlFmt) type; + type = wlib.types.structuredValueWith { + nullable = false; + typeName = "TOML"; + }; default = { }; description = '' Pure nix configuration of starship.toml. diff --git a/wrapperModules/t/tealdeer/module.nix b/wrapperModules/t/tealdeer/module.nix index 63b36725..ebf0b0b4 100644 --- a/wrapperModules/t/tealdeer/module.nix +++ b/wrapperModules/t/tealdeer/module.nix @@ -5,14 +5,14 @@ pkgs, ... }: -let - tomlFmt = pkgs.formats.toml { }; -in { imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - inherit (tomlFmt) type; + type = wlib.types.structuredValueWith { + nullable = false; + typeName = "TOML"; + }; default = { }; description = '' Configuration of tealdeer. diff --git a/wrapperModules/w/waybar/module.nix b/wrapperModules/w/waybar/module.nix index a10e3e2f..800f9bec 100644 --- a/wrapperModules/w/waybar/module.nix +++ b/wrapperModules/w/waybar/module.nix @@ -4,15 +4,12 @@ lib, ... }: -let - jsonFmt = config.pkgs.formats.json { }; -in { imports = [ wlib.modules.default ]; options = { settings = lib.mkOption { - type = jsonFmt.type; + type = wlib.types.structuredValueWith { typeName = "JSON"; }; default = { }; description = '' Waybar configuration settings. diff --git a/wrapperModules/w/wezterm/module.nix b/wrapperModules/w/wezterm/module.nix index 7cb0b349..706d35bc 100644 --- a/wrapperModules/w/wezterm/module.nix +++ b/wrapperModules/w/wezterm/module.nix @@ -46,7 +46,10 @@ ''; }; options.luaInfo = lib.mkOption { - inherit (pkgs.formats.lua { }) type; + type = wlib.types.structuredValueWith { + typeName = "lua"; + extraValueTypes = lib.types.luaInline; + }; default = { }; description = '' Defines attributes which are converted to Lua. diff --git a/wrapperModules/w/wlr-which-key/module.nix b/wrapperModules/w/wlr-which-key/module.nix index e1b8241b..bb2e77b7 100644 --- a/wrapperModules/w/wlr-which-key/module.nix +++ b/wrapperModules/w/wlr-which-key/module.nix @@ -6,7 +6,6 @@ ... }: let - yamlFmt = pkgs.formats.yaml { }; in { imports = [ wlib.modules.default ]; @@ -19,7 +18,7 @@ in }; settings = lib.mkOption { - type = yamlFmt.type; + type = wlib.types.structuredValueWith { typeName = "YAML 1.1"; }; default = { }; description = '' Configuration for wlr-which-key. diff --git a/wrapperModules/x/xplr/module.nix b/wrapperModules/x/xplr/module.nix index 48d01ddb..deb58580 100644 --- a/wrapperModules/x/xplr/module.nix +++ b/wrapperModules/x/xplr/module.nix @@ -6,7 +6,10 @@ ... }: let - luaType = (pkgs.formats.lua { }).type; + luaType = wlib.types.structuredValueWith { + typeName = "lua"; + extraValueTypes = lib.types.luaInline; + }; enabledDagOf = wlib.types.dagOf // { modules = [ { diff --git a/wrapperModules/y/yazi/module.nix b/wrapperModules/y/yazi/module.nix index 95b7ee36..45e6b70e 100644 --- a/wrapperModules/y/yazi/module.nix +++ b/wrapperModules/y/yazi/module.nix @@ -6,7 +6,10 @@ ... }: let - tomlFmt = pkgs.formats.toml { }; + tomlFmtType = wlib.types.structuredValueWith { + nullable = false; + typeName = "TOML"; + }; in { imports = [ wlib.modules.default ]; @@ -21,10 +24,10 @@ in ''; type = lib.types.submodule { - freeformType = tomlFmt.type; + freeformType = tomlFmtType; options = { mgr = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Manager settings See @@ -33,7 +36,7 @@ in }; preview = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Preview settings See @@ -42,7 +45,7 @@ in }; opener = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Opener settings See @@ -51,7 +54,7 @@ in }; open = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Open settings See @@ -60,7 +63,7 @@ in }; plugin = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Plugin settings See @@ -69,7 +72,7 @@ in }; input = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Input settings See @@ -78,7 +81,7 @@ in }; confirm = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Confirm settings See @@ -87,7 +90,7 @@ in }; pick = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Pick settings See @@ -96,7 +99,7 @@ in }; which = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Which settings See @@ -116,10 +119,10 @@ in ''; type = lib.types.submodule { - freeformType = tomlFmt.type; + freeformType = tomlFmtType; options = { mgr = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Keymap mgr settings See @@ -129,7 +132,7 @@ in }; tasks = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Keymap tasks settings See @@ -139,7 +142,7 @@ in }; spot = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Keymap spot settings See @@ -149,7 +152,7 @@ in }; pick = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Keymap pick settings See @@ -159,7 +162,7 @@ in }; input = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Keymap input settings See @@ -169,7 +172,7 @@ in }; confirm = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Keymap confirm settings See < https://yazi-rs.github.io/docs/configuration/keymap#confirm> @@ -179,7 +182,7 @@ in }; cmp = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Keymap cmp settings See < https://yazi-rs.github.io/docs/configuration/keymap#cmp> @@ -189,7 +192,7 @@ in }; help = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Keymap help settings See < https://yazi-rs.github.io/docs/configuration/keymap#help> @@ -209,10 +212,10 @@ in ''; type = lib.types.submodule { - freeformType = tomlFmt.type; + freeformType = tomlFmtType; options = { flavor = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme flawor settings See < https://yazi-rs.github.io/docs/configuration/theme#flavor> @@ -221,7 +224,7 @@ in }; app = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme app settings See < https://yazi-rs.github.io/docs/configuration/theme#app> @@ -230,7 +233,7 @@ in }; mgr = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme mgr settings See < https://yazi-rs.github.io/docs/configuration/theme#mgr> @@ -240,7 +243,7 @@ in }; indicator = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme indicator settings See < https://yazi-rs.github.io/docs/configuration/theme#indicator> @@ -249,7 +252,7 @@ in }; tabs = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme tabs settings See < https://yazi-rs.github.io/docs/configuration/theme#tabs> @@ -258,7 +261,7 @@ in }; mode = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme mode settings See < https://yazi-rs.github.io/docs/configuration/theme#mode> @@ -267,7 +270,7 @@ in }; status = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme status settings See < https://yazi-rs.github.io/docs/configuration/theme#status> @@ -276,7 +279,7 @@ in }; which = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme which settings See < https://yazi-rs.github.io/docs/configuration/theme#which> @@ -285,7 +288,7 @@ in }; confirm = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme confirm settings See < https://yazi-rs.github.io/docs/configuration/theme#confirm> @@ -294,7 +297,7 @@ in }; spot = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme spot settings See < https://yazi-rs.github.io/docs/configuration/theme#spot> @@ -303,7 +306,7 @@ in }; notify = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme notify settings See < https://yazi-rs.github.io/docs/configuration/theme#notify> @@ -312,7 +315,7 @@ in }; pick = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme pick settings See < https://yazi-rs.github.io/docs/configuration/theme#pick> @@ -321,7 +324,7 @@ in }; input = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme input settings See < https://yazi-rs.github.io/docs/configuration/theme#input> @@ -331,7 +334,7 @@ in }; cmp = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme cmp settings See < https://yazi-rs.github.io/docs/configuration/theme#cmp> @@ -340,7 +343,7 @@ in }; tasks = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme tasks settings See < https://yazi-rs.github.io/docs/configuration/theme#tasks> @@ -349,7 +352,7 @@ in }; help = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme help settings See < https://yazi-rs.github.io/docs/configuration/theme#help> @@ -358,7 +361,7 @@ in }; filetype = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme filetype settings See < https://yazi-rs.github.io/docs/configuration/theme#filetype> @@ -367,7 +370,7 @@ in }; icon = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Theme icon settings See < https://yazi-rs.github.io/docs/configuration/theme#icon> @@ -385,10 +388,10 @@ in See configuration reference at ''; type = lib.types.submodule { - freeformType = tomlFmt.type; + freeformType = tomlFmtType; options = { services = lib.mkOption { - type = tomlFmt.type; + type = tomlFmtType; description = '' Vfs settings See < https://yazi-rs.github.io/docs/configuration/vfs> @@ -407,7 +410,7 @@ in ''; type = lib.types.submodule { - freeformType = tomlFmt.type; + freeformType = tomlFmtType; options = { plugin = lib.mkOption { description = '' @@ -416,9 +419,9 @@ in ''; default = { }; type = lib.types.submodule { - freeformType = tomlFmt.type; + freeformType = tomlFmtType; options.deps = lib.mkOption { - type = lib.types.listOf tomlFmt.type; + type = lib.types.listOf tomlFmtType; default = [ ]; description = '' List of plugins and dependencies.