1
0
Fork 0
mirror of https://github.com/nix-community/home-manager synced 2025-02-07 00:35:04 +01:00

nushell: structured settings and more

PR #6184
This commit is contained in:
Robert Helgesson 2025-01-29 20:18:27 +01:00
commit 420a0d9506
No known key found for this signature in database
GPG key ID: 96E745BD17AA17ED
5 changed files with 141 additions and 88 deletions

View file

@ -1,7 +1,9 @@
{ lib }: rec { { lib }: rec {
mkNushellInline = expr: lib.setType "nushell-inline" { inherit expr; }; 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: v:
let let
innerIndent = "${indent} "; innerIndent = "${indent} ";
@ -18,7 +20,6 @@
asBindings = false; asBindings = false;
}; };
concatItems = lib.concatStringsSep introSpace; concatItems = lib.concatStringsSep introSpace;
isNushellInline = lib.isType "nushell-inline";
generatedBindings = assert lib.assertMsg (badVarNames == [ ]) generatedBindings = assert lib.assertMsg (badVarNames == [ ])
"Bad Nushell variable names: ${ "Bad Nushell variable names: ${

View file

@ -1,9 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib;
let let
inherit (lib) types;
inherit (lib.hm.nushell) isNushellInline toNushell;
cfg = config.programs.nushell; cfg = config.programs.nushell;
configDir = if pkgs.stdenv.isDarwin && !config.xdg.enable then configDir = if pkgs.stdenv.isDarwin && !config.xdg.enable then
@ -14,13 +12,13 @@ let
linesOrSource = name: linesOrSource = name:
types.submodule ({ config, ... }: { types.submodule ({ config, ... }: {
options = { options = {
text = mkOption { text = lib.mkOption {
type = types.lines; type = types.lines;
default = if config.source != null then default = if config.source != null then
builtins.readFile config.source builtins.readFile config.source
else else
""; "";
defaultText = literalExpression defaultText = lib.literalExpression
"if source is defined, the content of source, otherwise empty"; "if source is defined, the content of source, otherwise empty";
description = '' description = ''
Text of the nushell {file}`${name}` file. Text of the nushell {file}`${name}` file.
@ -28,7 +26,7 @@ let
''; '';
}; };
source = mkOption { source = lib.mkOption {
type = types.nullOr types.path; type = types.nullOr types.path;
default = null; default = null;
description = '' description = ''
@ -39,39 +37,29 @@ let
}; };
}); });
in { in {
meta.maintainers = meta.maintainers = with lib.maintainers; [
[ maintainers.Philipp-M maintainers.joaquintrinanes maintainers.aidalgol ]; Philipp-M
joaquintrinanes
imports = [ aidalgol
(mkRemovedOptionModule [ "programs" "nushell" "settings" ] ''
Please use
'programs.nushell.configFile' and 'programs.nushell.envFile'
instead.
'')
]; ];
options.programs.nushell = { options.programs.nushell = {
enable = mkEnableOption "nushell"; enable = lib.mkEnableOption "nushell";
package = mkOption { package = lib.mkPackageOption pkgs "nushell" { };
type = types.package;
default = pkgs.nushell;
defaultText = literalExpression "pkgs.nushell";
description = "The package to use for nushell.";
};
configFile = mkOption { configFile = lib.mkOption {
type = types.nullOr (linesOrSource "config.nu"); type = types.nullOr (linesOrSource "config.nu");
default = null; default = null;
example = literalExpression '' example = lib.literalExpression ''
{ text = ''' {
let $config = { text = '''
filesize_metric: false const NU_LIB_DIRS = $NU_LIB_DIRS ++ ''${
table_mode: rounded lib.hm.nushell.toNushell (lib.concatStringsSep ":" [ ./scripts ])
use_ls_colors: true
} }
$env.config.filesize_metric = false
$env.config.table_mode = 'rounded'
$env.config.use_ls_colors = true
'''; ''';
} }
''; '';
@ -82,7 +70,7 @@ in {
''; '';
}; };
envFile = mkOption { envFile = lib.mkOption {
type = types.nullOr (linesOrSource "env.nu"); type = types.nullOr (linesOrSource "env.nu");
default = null; default = null;
example = '' example = ''
@ -95,7 +83,7 @@ in {
''; '';
}; };
loginFile = mkOption { loginFile = lib.mkOption {
type = types.nullOr (linesOrSource "login.nu"); type = types.nullOr (linesOrSource "login.nu");
default = null; default = null;
example = '' example = ''
@ -111,7 +99,7 @@ in {
''; '';
}; };
extraConfig = mkOption { extraConfig = lib.mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
description = '' description = ''
@ -119,7 +107,7 @@ in {
''; '';
}; };
extraEnv = mkOption { extraEnv = lib.mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
description = '' description = ''
@ -127,7 +115,7 @@ in {
''; '';
}; };
extraLogin = mkOption { extraLogin = lib.mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
description = '' description = ''
@ -135,7 +123,7 @@ in {
''; '';
}; };
plugins = mkOption { plugins = lib.mkOption {
type = types.listOf types.package; type = types.listOf types.package;
default = [ ]; default = [ ];
example = lib.literalExpression "[ pkgs.nushellPlugins.formats ]"; example = lib.literalExpression "[ pkgs.nushellPlugins.formats ]";
@ -144,24 +132,55 @@ in {
''; '';
}; };
shellAliases = mkOption { 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; type = types.attrsOf types.str;
default = { }; default = { };
example = { ll = "ls -l"; }; example = {
ll = "ls -l";
g = "git";
};
description = '' description = ''
An attribute set that maps aliases (the top level attribute names in An attribute set that maps aliases (the top level attribute names in
this option) to command strings or directly to build outputs. this option) to command strings or directly to build outputs.
''; '';
}; };
environmentVariables = mkOption { environmentVariables = lib.mkOption {
type = types.attrsOf hm.types.nushellValue; type = types.attrsOf lib.hm.types.nushellValue;
default = { }; default = { };
example = literalExpression '' example = lib.literalExpression ''
{ {
FOO = "BAR"; FOO = "BAR";
LIST_VALUE = [ "foo" "bar" ]; LIST_VALUE = [ "foo" "bar" ];
NU_LIB_DIRS = lib.concatStringsSep ":" [ ./scripts ];
PROMPT_COMMAND = lib.hm.nushell.mkNushellInline '''{|| "> "}'''; PROMPT_COMMAND = lib.hm.nushell.mkNushellInline '''{|| "> "}''';
ENV_CONVERSIONS.PATH = { ENV_CONVERSIONS.PATH = {
from_string = lib.hm.nushell.mkNushellInline "{|s| $s | split row (char esep) }"; from_string = lib.hm.nushell.mkNushellInline "{|s| $s | split row (char esep) }";
@ -177,39 +196,57 @@ in {
}; };
}; };
config = mkIf cfg.enable { config = lib.mkIf cfg.enable {
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
home.file = mkMerge [ home.file = lib.mkMerge [
(let (let
writeConfig = cfg.configFile != null || cfg.extraConfig != "" writeConfig = cfg.configFile != null || cfg.extraConfig != ""
|| aliasesStr != ""; || aliasesStr != "" || cfg.settings != { };
aliasesStr = concatStringsSep "\n" aliasesStr = lib.concatLines
(mapAttrsToList (k: v: "alias ${k} = ${v}") cfg.shellAliases); (lib.mapAttrsToList (k: v: "alias ${toNushell { } k} = ${v}")
in mkIf writeConfig { cfg.shellAliases);
"${configDir}/config.nu".text = mkMerge [ in lib.mkIf writeConfig {
(mkIf (cfg.configFile != null) cfg.configFile.text) "${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}";
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 cfg.extraConfig
aliasesStr aliasesStr
]; ];
}) })
(let (lib.mkIf (cfg.envFile != null || cfg.extraEnv != "") {
hasEnvVars = cfg.environmentVariables != { }; "${configDir}/env.nu".text = lib.mkMerge [
envVarsStr = '' (lib.mkIf (cfg.envFile != null) cfg.envFile.text)
load-env ${hm.nushell.toNushell { } cfg.environmentVariables}
'';
in mkIf (cfg.envFile != null || cfg.extraEnv != "" || hasEnvVars) {
"${configDir}/env.nu".text = mkMerge [
(mkIf (cfg.envFile != null) cfg.envFile.text)
cfg.extraEnv cfg.extraEnv
envVarsStr
]; ];
}) })
(mkIf (cfg.loginFile != null || cfg.extraLogin != "") { (lib.mkIf (cfg.loginFile != null || cfg.extraLogin != "") {
"${configDir}/login.nu".text = mkMerge [ "${configDir}/login.nu".text = lib.mkMerge [
(mkIf (cfg.loginFile != null) cfg.loginFile.text) (lib.mkIf (cfg.loginFile != null) cfg.loginFile.text)
cfg.extraLogin cfg.extraLogin
]; ];
}) })
@ -220,11 +257,11 @@ in {
${lib.getExe cfg.package} \ ${lib.getExe cfg.package} \
--plugin-config "$out/plugin.msgpackz" \ --plugin-config "$out/plugin.msgpackz" \
--commands '${ --commands '${
concatStringsSep "; " lib.concatStringsSep "; "
(map (plugin: "plugin add ${lib.getExe plugin}") cfg.plugins) (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"; "${configDir}/plugin.msgpackz".source = "${msgPackz}/plugin.msgpackz";
}) })
]; ];

View file

@ -1,9 +1,31 @@
let $config = { 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"})
]
$env.config.show_banner = false
let config = {
filesize_metric: false filesize_metric: false
table_mode: rounded table_mode: rounded
use_ls_colors: true use_ls_colors: true
} }
alias ll = ls -a alias "ll" = ls -a
alias lsname = (ls | get name) alias "multi word alias" = cd -
alias "z" = __zoxide_z

View file

@ -1,17 +1,2 @@
$env.FOO = 'BAR' $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": ({|| "> "})
}

View file

@ -5,7 +5,7 @@
enable = true; enable = true;
configFile.text = '' configFile.text = ''
let $config = { let config = {
filesize_metric: false filesize_metric: false
table_mode: rounded table_mode: rounded
use_ls_colors: true use_ls_colors: true
@ -26,8 +26,16 @@
plugins = [ pkgs.nushellPlugins.formats ]; plugins = [ pkgs.nushellPlugins.formats ];
shellAliases = { shellAliases = {
"lsname" = "(ls | get name)";
"ll" = "ls -a"; "ll" = "ls -a";
"multi word alias" = "cd -";
"z" = "__zoxide_z";
};
settings = {
show_banner = false;
display_errors.exit_code = false;
hooks.pre_execution =
[ (lib.hm.nushell.mkNushellInline ''{|| "pre_execution hook"}'') ];
}; };
environmentVariables = { environmentVariables = {