From a1df6c4c76a839661207105daa519e3de3b5fe15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Tri=C3=B1anes?= Date: Sun, 8 Dec 2024 00:56:22 +0100 Subject: [PATCH 1/4] nushell: slight refactor - Remove 'with lib' - More idiomatic lib calls - Update config file examples with current best practices --- modules/programs/nushell.nix | 99 +++++++++---------- .../programs/nushell/config-expected.nu | 2 +- 2 files changed, 49 insertions(+), 52 deletions(-) diff --git a/modules/programs/nushell.nix b/modules/programs/nushell.nix index ec00210af..34f76d2dc 100644 --- a/modules/programs/nushell.nix +++ b/modules/programs/nushell.nix @@ -1,9 +1,7 @@ { config, lib, pkgs, ... }: - -with lib; - let - + inherit (lib) types; + inherit (lib.hm.nushell) toNushell; cfg = config.programs.nushell; configDir = if pkgs.stdenv.isDarwin && !config.xdg.enable then @@ -14,13 +12,13 @@ let linesOrSource = name: types.submodule ({ config, ... }: { options = { - text = mkOption { + text = lib.mkOption { type = types.lines; default = if config.source != null then builtins.readFile config.source else ""; - defaultText = literalExpression + defaultText = lib.literalExpression "if source is defined, the content of source, otherwise empty"; description = '' Text of the nushell {file}`${name}` file. @@ -28,7 +26,7 @@ let ''; }; - source = mkOption { + source = lib.mkOption { type = types.nullOr types.path; default = null; description = '' @@ -39,11 +37,14 @@ let }; }); in { - meta.maintainers = - [ maintainers.Philipp-M maintainers.joaquintrinanes maintainers.aidalgol ]; + meta.maintainers = with lib.maintainers; [ + Philipp-M + joaquintrinanes + aidalgol + ]; imports = [ - (mkRemovedOptionModule [ "programs" "nushell" "settings" ] '' + (lib.mkRemovedOptionModule [ "programs" "nushell" "settings" ] '' Please use 'programs.nushell.configFile' and 'programs.nushell.envFile' @@ -53,25 +54,22 @@ in { ]; options.programs.nushell = { - enable = mkEnableOption "nushell"; + enable = lib.mkEnableOption "nushell"; - package = mkOption { - type = types.package; - default = pkgs.nushell; - defaultText = literalExpression "pkgs.nushell"; - description = "The package to use for nushell."; - }; + package = lib.mkPackageOption pkgs "nushell" { }; - configFile = mkOption { + configFile = lib.mkOption { type = types.nullOr (linesOrSource "config.nu"); default = null; - example = literalExpression '' - { text = ''' - let $config = { - filesize_metric: false - table_mode: rounded - use_ls_colors: true + example = lib.literalExpression '' + { + text = ''' + const NU_LIB_DIRS = $NU_LIB_DIRS ++ ''${ + lib.hm.nushell.toNushell (lib.concatStringsSep ":" [ ./scripts ]) } + $env.config.filesize_metric = false + $env.config.table_mode = 'rounded' + $env.config.use_ls_colors = true '''; } ''; @@ -82,7 +80,7 @@ in { ''; }; - envFile = mkOption { + envFile = lib.mkOption { type = types.nullOr (linesOrSource "env.nu"); default = null; example = '' @@ -95,7 +93,7 @@ in { ''; }; - loginFile = mkOption { + loginFile = lib.mkOption { type = types.nullOr (linesOrSource "login.nu"); default = null; example = '' @@ -111,7 +109,7 @@ in { ''; }; - extraConfig = mkOption { + extraConfig = lib.mkOption { type = types.lines; default = ""; description = '' @@ -119,7 +117,7 @@ in { ''; }; - extraEnv = mkOption { + extraEnv = lib.mkOption { type = types.lines; default = ""; description = '' @@ -127,7 +125,7 @@ in { ''; }; - extraLogin = mkOption { + extraLogin = lib.mkOption { type = types.lines; default = ""; description = '' @@ -135,7 +133,7 @@ in { ''; }; - plugins = mkOption { + plugins = lib.mkOption { type = types.listOf types.package; default = [ ]; example = lib.literalExpression "[ pkgs.nushellPlugins.formats ]"; @@ -144,7 +142,7 @@ in { ''; }; - shellAliases = mkOption { + shellAliases = lib.mkOption { type = types.attrsOf types.str; default = { }; example = { ll = "ls -l"; }; @@ -154,14 +152,13 @@ in { ''; }; - environmentVariables = mkOption { - type = types.attrsOf hm.types.nushellValue; + environmentVariables = lib.mkOption { + type = types.attrsOf lib.hm.types.nushellValue; default = { }; - example = literalExpression '' + example = lib.literalExpression '' { FOO = "BAR"; LIST_VALUE = [ "foo" "bar" ]; - NU_LIB_DIRS = lib.concatStringsSep ":" [ ./scripts ]; PROMPT_COMMAND = lib.hm.nushell.mkNushellInline '''{|| "> "}'''; ENV_CONVERSIONS.PATH = { from_string = lib.hm.nushell.mkNushellInline "{|s| $s | split row (char esep) }"; @@ -177,19 +174,19 @@ in { }; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { home.packages = [ cfg.package ]; - home.file = mkMerge [ + home.file = lib.mkMerge [ (let writeConfig = cfg.configFile != null || cfg.extraConfig != "" || aliasesStr != ""; - aliasesStr = concatStringsSep "\n" - (mapAttrsToList (k: v: "alias ${k} = ${v}") cfg.shellAliases); - in mkIf writeConfig { - "${configDir}/config.nu".text = mkMerge [ - (mkIf (cfg.configFile != null) cfg.configFile.text) + aliasesStr = lib.concatLines + (lib.mapAttrsToList (k: v: "alias ${k} = ${v}") cfg.shellAliases); + in lib.mkIf writeConfig { + "${configDir}/config.nu".text = lib.mkMerge [ + (lib.mkIf (cfg.configFile != null) cfg.configFile.text) cfg.extraConfig aliasesStr ]; @@ -198,18 +195,18 @@ in { (let hasEnvVars = cfg.environmentVariables != { }; envVarsStr = '' - load-env ${hm.nushell.toNushell { } cfg.environmentVariables} + load-env ${toNushell { } cfg.environmentVariables} ''; - in mkIf (cfg.envFile != null || cfg.extraEnv != "" || hasEnvVars) { - "${configDir}/env.nu".text = mkMerge [ - (mkIf (cfg.envFile != null) cfg.envFile.text) + in lib.mkIf (cfg.envFile != null || cfg.extraEnv != "" || hasEnvVars) { + "${configDir}/env.nu".text = lib.mkMerge [ + (lib.mkIf (cfg.envFile != null) cfg.envFile.text) cfg.extraEnv envVarsStr ]; }) - (mkIf (cfg.loginFile != null || cfg.extraLogin != "") { - "${configDir}/login.nu".text = mkMerge [ - (mkIf (cfg.loginFile != null) cfg.loginFile.text) + (lib.mkIf (cfg.loginFile != null || cfg.extraLogin != "") { + "${configDir}/login.nu".text = lib.mkMerge [ + (lib.mkIf (cfg.loginFile != null) cfg.loginFile.text) cfg.extraLogin ]; }) @@ -220,11 +217,11 @@ in { ${lib.getExe cfg.package} \ --plugin-config "$out/plugin.msgpackz" \ --commands '${ - concatStringsSep "; " + lib.concatStringsSep "; " (map (plugin: "plugin add ${lib.getExe plugin}") cfg.plugins) }' ''; - in mkIf (cfg.plugins != [ ]) { + in lib.mkIf (cfg.plugins != [ ]) { "${configDir}/plugin.msgpackz".source = "${msgPackz}/plugin.msgpackz"; }) ]; diff --git a/tests/modules/programs/nushell/config-expected.nu b/tests/modules/programs/nushell/config-expected.nu index a306fabd8..3ab5d2de1 100644 --- a/tests/modules/programs/nushell/config-expected.nu +++ b/tests/modules/programs/nushell/config-expected.nu @@ -6,4 +6,4 @@ let $config = { alias ll = ls -a -alias lsname = (ls | get name) \ No newline at end of file +alias lsname = (ls | get name) From 46c83c07b9a97a8f7633dd162dd9a3bbe511195b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Tri=C3=B1anes?= Date: Sun, 8 Dec 2024 01:00:45 +0100 Subject: [PATCH 2/4] nushell: add settings option --- modules/lib/nushell.nix | 5 +- modules/programs/nushell.nix | 59 +++++++++++++++---- .../programs/nushell/config-expected.nu | 8 ++- .../programs/nushell/example-settings.nix | 9 ++- 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/modules/lib/nushell.nix b/modules/lib/nushell.nix index e831380cd..5ef5ad36d 100644 --- a/modules/lib/nushell.nix +++ b/modules/lib/nushell.nix @@ -1,7 +1,9 @@ { lib }: rec { mkNushellInline = expr: lib.setType "nushell-inline" { inherit expr; }; - toNushell = { indent ? "", multiline ? true, asBindings ? false }@args: + isNushellInline = lib.isType "nushell-inline"; + + toNushell = { indent ? "", multiline ? true, asBindings ? false, }@args: v: let innerIndent = "${indent} "; @@ -18,7 +20,6 @@ asBindings = false; }; concatItems = lib.concatStringsSep introSpace; - isNushellInline = lib.isType "nushell-inline"; generatedBindings = assert lib.assertMsg (badVarNames == [ ]) "Bad Nushell variable names: ${ diff --git a/modules/programs/nushell.nix b/modules/programs/nushell.nix index 34f76d2dc..b1f906580 100644 --- a/modules/programs/nushell.nix +++ b/modules/programs/nushell.nix @@ -1,7 +1,7 @@ { config, lib, pkgs, ... }: let inherit (lib) types; - inherit (lib.hm.nushell) toNushell; + inherit (lib.hm.nushell) isNushellInline toNushell; cfg = config.programs.nushell; configDir = if pkgs.stdenv.isDarwin && !config.xdg.enable then @@ -43,16 +43,6 @@ in { aidalgol ]; - imports = [ - (lib.mkRemovedOptionModule [ "programs" "nushell" "settings" ] '' - Please use - - 'programs.nushell.configFile' and 'programs.nushell.envFile' - - instead. - '') - ]; - options.programs.nushell = { enable = lib.mkEnableOption "nushell"; @@ -142,6 +132,35 @@ in { ''; }; + settings = lib.mkOption { + type = types.attrsOf lib.hm.types.nushellValue; + default = { }; + example = { + show_banner = false; + history.format = "sqlite"; + }; + description = '' + Nushell settings. These will be flattened and assigned one by one to `$env.config` to avoid overwriting the default or existing options. + + For example: + ```nix + { + show_banner = false; + completions.external = { + enable = true; + max_results = 200; + }; + } + ``` + becomes: + ```nushell + $env.config.completions.external.enable = true + $env.config.completions.external.max_results = 200 + $env.config.show_banner = false + ``` + ''; + }; + shellAliases = lib.mkOption { type = types.attrsOf types.str; default = { }; @@ -180,12 +199,28 @@ in { home.file = lib.mkMerge [ (let writeConfig = cfg.configFile != null || cfg.extraConfig != "" - || aliasesStr != ""; + || aliasesStr != "" || cfg.settings != { }; aliasesStr = lib.concatLines (lib.mapAttrsToList (k: v: "alias ${k} = ${v}") cfg.shellAliases); in lib.mkIf writeConfig { "${configDir}/config.nu".text = lib.mkMerge [ + (let + flattenSettings = let + joinDot = a: b: "${if a == "" then "" else "${a}."}${b}"; + unravel = prefix: value: + if lib.isAttrs value && !isNushellInline value then + lib.concatMap (key: unravel (joinDot prefix key) value.${key}) + (builtins.attrNames value) + else + [ (lib.nameValuePair prefix value) ]; + in unravel ""; + mkLine = { name, value }: '' + $env.config.${name} = ${toNushell { } value} + ''; + settingsLines = + lib.concatMapStrings mkLine (flattenSettings cfg.settings); + in lib.mkIf (cfg.settings != { }) settingsLines) (lib.mkIf (cfg.configFile != null) cfg.configFile.text) cfg.extraConfig aliasesStr diff --git a/tests/modules/programs/nushell/config-expected.nu b/tests/modules/programs/nushell/config-expected.nu index 3ab5d2de1..6d5b09b26 100644 --- a/tests/modules/programs/nushell/config-expected.nu +++ b/tests/modules/programs/nushell/config-expected.nu @@ -1,4 +1,10 @@ -let $config = { +$env.config.display_errors.exit_code = false +$env.config.hooks.pre_execution = [ + ({|| "pre_execution hook"}) +] +$env.config.show_banner = false + +let config = { filesize_metric: false table_mode: rounded use_ls_colors: true diff --git a/tests/modules/programs/nushell/example-settings.nix b/tests/modules/programs/nushell/example-settings.nix index e758000bf..598a7bd85 100644 --- a/tests/modules/programs/nushell/example-settings.nix +++ b/tests/modules/programs/nushell/example-settings.nix @@ -5,7 +5,7 @@ enable = true; configFile.text = '' - let $config = { + let config = { filesize_metric: false table_mode: rounded use_ls_colors: true @@ -30,6 +30,13 @@ "ll" = "ls -a"; }; + settings = { + show_banner = false; + display_errors.exit_code = false; + hooks.pre_execution = + [ (lib.hm.nushell.mkNushellInline ''{|| "pre_execution hook"}'') ]; + }; + environmentVariables = { FOO = "BAR"; LIST_VALUE = [ "foo" "bar" ]; From 709aaab1a5c35a8d1f1e7546efa226e09f3316fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Tri=C3=B1anes?= Date: Sat, 28 Dec 2024 20:52:56 +0100 Subject: [PATCH 3/4] nushell: set env in config.nu file --- modules/programs/nushell.nix | 15 ++++++++------- tests/modules/programs/nushell/config-expected.nu | 15 +++++++++++++++ tests/modules/programs/nushell/env-expected.nu | 15 --------------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/modules/programs/nushell.nix b/modules/programs/nushell.nix index b1f906580..92a8f4e9d 100644 --- a/modules/programs/nushell.nix +++ b/modules/programs/nushell.nix @@ -205,6 +205,12 @@ in { (lib.mapAttrsToList (k: v: "alias ${k} = ${v}") cfg.shellAliases); in lib.mkIf writeConfig { "${configDir}/config.nu".text = lib.mkMerge [ + (let + hasEnvVars = cfg.environmentVariables != { }; + envVarsStr = '' + load-env ${toNushell { } cfg.environmentVariables} + ''; + in lib.mkIf hasEnvVars envVarsStr) (let flattenSettings = let joinDot = a: b: "${if a == "" then "" else "${a}."}${b}"; @@ -220,6 +226,7 @@ in { ''; settingsLines = lib.concatMapStrings mkLine (flattenSettings cfg.settings); + in lib.mkIf (cfg.settings != { }) settingsLines) (lib.mkIf (cfg.configFile != null) cfg.configFile.text) cfg.extraConfig @@ -227,16 +234,10 @@ in { ]; }) - (let - hasEnvVars = cfg.environmentVariables != { }; - envVarsStr = '' - load-env ${toNushell { } cfg.environmentVariables} - ''; - in lib.mkIf (cfg.envFile != null || cfg.extraEnv != "" || hasEnvVars) { + (lib.mkIf (cfg.envFile != null || cfg.extraEnv != "") { "${configDir}/env.nu".text = lib.mkMerge [ (lib.mkIf (cfg.envFile != null) cfg.envFile.text) cfg.extraEnv - envVarsStr ]; }) (lib.mkIf (cfg.loginFile != null || cfg.extraLogin != "") { diff --git a/tests/modules/programs/nushell/config-expected.nu b/tests/modules/programs/nushell/config-expected.nu index 6d5b09b26..4578f9531 100644 --- a/tests/modules/programs/nushell/config-expected.nu +++ b/tests/modules/programs/nushell/config-expected.nu @@ -1,3 +1,18 @@ +load-env { + "ENV_CONVERSIONS": { + "PATH": { + "from_string": ({|s| $s | split row (char esep) }) + "to_string": ({|v| $v | str join (char esep) }) + } + } + "FOO": "BAR" + "LIST_VALUE": [ + "foo" + "bar" + ] + "PROMPT_COMMAND": ({|| "> "}) +} + $env.config.display_errors.exit_code = false $env.config.hooks.pre_execution = [ ({|| "pre_execution hook"}) diff --git a/tests/modules/programs/nushell/env-expected.nu b/tests/modules/programs/nushell/env-expected.nu index 50f6f767b..aacc37925 100644 --- a/tests/modules/programs/nushell/env-expected.nu +++ b/tests/modules/programs/nushell/env-expected.nu @@ -1,17 +1,2 @@ $env.FOO = 'BAR' - -load-env { - "ENV_CONVERSIONS": { - "PATH": { - "from_string": ({|s| $s | split row (char esep) }) - "to_string": ({|v| $v | str join (char esep) }) - } - } - "FOO": "BAR" - "LIST_VALUE": [ - "foo" - "bar" - ] - "PROMPT_COMMAND": ({|| "> "}) -} From 82455a84e32af01c66e326e5a188795f324975a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Tri=C3=B1anes?= Date: Sun, 5 Jan 2025 13:39:08 +0100 Subject: [PATCH 4/4] nushell: allow multi-word aliases Also fix invalid alias in test --- modules/programs/nushell.nix | 8 ++++++-- tests/modules/programs/nushell/config-expected.nu | 5 +++-- tests/modules/programs/nushell/example-settings.nix | 3 ++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/modules/programs/nushell.nix b/modules/programs/nushell.nix index 92a8f4e9d..a4e767c8a 100644 --- a/modules/programs/nushell.nix +++ b/modules/programs/nushell.nix @@ -164,7 +164,10 @@ in { shellAliases = lib.mkOption { type = types.attrsOf types.str; default = { }; - example = { ll = "ls -l"; }; + example = { + ll = "ls -l"; + g = "git"; + }; description = '' An attribute set that maps aliases (the top level attribute names in this option) to command strings or directly to build outputs. @@ -202,7 +205,8 @@ in { || aliasesStr != "" || cfg.settings != { }; aliasesStr = lib.concatLines - (lib.mapAttrsToList (k: v: "alias ${k} = ${v}") cfg.shellAliases); + (lib.mapAttrsToList (k: v: "alias ${toNushell { } k} = ${v}") + cfg.shellAliases); in lib.mkIf writeConfig { "${configDir}/config.nu".text = lib.mkMerge [ (let diff --git a/tests/modules/programs/nushell/config-expected.nu b/tests/modules/programs/nushell/config-expected.nu index 4578f9531..57bc16ee8 100644 --- a/tests/modules/programs/nushell/config-expected.nu +++ b/tests/modules/programs/nushell/config-expected.nu @@ -26,5 +26,6 @@ let config = { } -alias ll = ls -a -alias lsname = (ls | get name) +alias "ll" = ls -a +alias "multi word alias" = cd - +alias "z" = __zoxide_z diff --git a/tests/modules/programs/nushell/example-settings.nix b/tests/modules/programs/nushell/example-settings.nix index 598a7bd85..9f0108a30 100644 --- a/tests/modules/programs/nushell/example-settings.nix +++ b/tests/modules/programs/nushell/example-settings.nix @@ -26,8 +26,9 @@ plugins = [ pkgs.nushellPlugins.formats ]; shellAliases = { - "lsname" = "(ls | get name)"; "ll" = "ls -a"; + "multi word alias" = "cd -"; + "z" = "__zoxide_z"; }; settings = {