blob: 46166690724d1563621e94a7fc1c47e80d549ecd (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.starship;
settingsFormat = pkgs.formats.toml { };
userSettingsFile = settingsFormat.generate "starship.toml" cfg.settings;
settingsFile =
if cfg.presets == [ ] then
userSettingsFile
else
pkgs.runCommand "starship.toml"
{
nativeBuildInputs = [ pkgs.yq ];
}
''
tomlq -s -t 'reduce .[] as $item ({}; . * $item)' \
${
lib.concatStringsSep " " (map (f: "${cfg.package}/share/starship/presets/${f}.toml") cfg.presets)
} \
${userSettingsFile} \
> $out
'';
initOption = if cfg.interactiveOnly then "promptInit" else "shellInit";
in
{
options.programs.starship = {
enable = lib.mkEnableOption "the Starship shell prompt";
package = lib.mkPackageOption pkgs "starship" { };
enableBashIntegration = lib.mkEnableOption "Bash integration" // {
default = true;
};
enableFishIntegration = lib.mkEnableOption "Fish integration" // {
default = true;
};
enableZshIntegration = lib.mkEnableOption "zsh integration" // {
default = true;
};
enableXonshIntegration = lib.mkEnableOption "Xonsh integration" // {
default = true;
};
interactiveOnly =
lib.mkEnableOption ''
starship only when the shell is interactive.
Some plugins require this to be set to false to function correctly
''
// {
default = true;
};
presets = lib.mkOption {
default = [ ];
example = [ "nerd-font-symbols" ];
type = with lib.types; listOf str;
description = ''
Presets files to be merged with settings in order.
'';
};
settings = lib.mkOption {
inherit (settingsFormat) type;
default = { };
description = ''
Configuration included in {file}`starship.toml`.
See <https://starship.rs/config/#prompt> for documentation.
'';
};
transientPrompt =
let
mkTransientPromptOption =
side:
lib.mkOption {
type =
with lib.types;
nullOr (str // { description = "Fish shell code concatenated with \"\\n\""; });
description =
let
function = "`starship_transient_${lib.optionalString (side == "right") "r"}prompt_func` function";
in
''
Fish code composing the body of the ${function}. The output of
this code will become the ${side} side of the transient prompt.
Not setting this option (or setting it to `null`) will prevent
the ${function} from being generated. By default, the ${side}
prompt is ${if (side == "right") then "empty" else "a bold-green '❯' character"}.
'';
example = "starship module ${if (side == "right") then "time" else "character"}";
default = null;
};
in
{
enable = lib.mkEnableOption ''
Starship's [transient prompt](https://starship.rs/advanced-config/#transientprompt-and-transientrightprompt-in-fish)
feature in `fish` shells. After a command has been entered, Starship
replaces the usual prompt with the terminal output of the commands
defined in the `programs.starship.transientPrompt.left`
and `programs.starship.transientPrompt.right` options.
This option only works with `fish`, as `bash` requires a
[custom configuration](https://starship.rs/advanced-config/#transientprompt-and-transientrightprompt-in-bash)
involving [Ble.sh](https://github.com/akinomyoga/ble.sh), which can be
enabled with `programs.bash.blesh.enable`, but not configured using NixOS
'';
left = mkTransientPromptOption "left";
right = mkTransientPromptOption "right";
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
programs.bash.${initOption} = lib.mkIf cfg.enableBashIntegration ''
if [[ $TERM != "dumb" ]]; then
# don't set STARSHIP_CONFIG automatically if there's a user-specified
# config file. starship appears to use a hardcoded config location
# rather than one inside an XDG folder:
# https://github.com/starship/starship/blob/686bda1706e5b409129e6694639477a0f8a3f01b/src/configure.rs#L651
if [[ ! -f "''${STARSHIP_CONFIG:-$HOME/.config/starship.toml}" ]]; then
export STARSHIP_CONFIG=${settingsFile}
fi
eval "$(${cfg.package}/bin/starship init bash --print-full-init)"
fi
'';
programs.fish.${initOption} = lib.mkIf cfg.enableFishIntegration ''
if test "$TERM" != "dumb"
# don't set STARSHIP_CONFIG automatically if there's a user-specified
# config file. starship appears to use a hardcoded config location
# rather than one inside an XDG folder:
# https://github.com/starship/starship/blob/686bda1706e5b409129e6694639477a0f8a3f01b/src/configure.rs#L651
set -q STARSHIP_CONFIG; or set STARSHIP_CONFIG "$HOME/.config/starship.toml"
if not test -f "$STARSHIP_CONFIG"
set -x STARSHIP_CONFIG ${settingsFile}
end
${lib.optionalString (!isNull cfg.transientPrompt.left) ''
function starship_transient_prompt_func
${cfg.transientPrompt.left}
end
''}
${lib.optionalString (!isNull cfg.transientPrompt.right) ''
function starship_transient_rprompt_func
${cfg.transientPrompt.right}
end
''}
eval (${cfg.package}/bin/starship init fish)
${lib.optionalString cfg.transientPrompt.enable "enable_transience"}
end
'';
programs.zsh.${initOption} = lib.mkIf cfg.enableZshIntegration ''
if [[ $TERM != "dumb" ]]; then
# don't set STARSHIP_CONFIG automatically if there's a user-specified
# config file. starship appears to use a hardcoded config location
# rather than one inside an XDG folder:
# https://github.com/starship/starship/blob/686bda1706e5b409129e6694639477a0f8a3f01b/src/configure.rs#L651
if [[ ! -f "''${STARSHIP_CONFIG:-$HOME/.config/starship.toml}" ]]; then
export STARSHIP_CONFIG=${settingsFile}
fi
eval "$(${cfg.package}/bin/starship init zsh)"
fi
'';
# use `config` instead of `${initOption}` because `programs.xonsh` doesn't have `shellInit` or `promptInit`
programs.xonsh.config = lib.mkIf cfg.enableXonshIntegration ''
if $TERM != "dumb":
# don't set STARSHIP_CONFIG automatically if there's a user-specified
# config file. starship appears to use a hardcoded config location
# rather than one inside an XDG folder:
# https://github.com/starship/starship/blob/686bda1706e5b409129e6694639477a0f8a3f01b/src/configure.rs#L651
import os as _os
_sc = _os.environ.get('STARSHIP_CONFIG', _os.path.join(_os.environ['HOME'], '.config/starship.toml'))
if not _os.path.isfile(_sc):
$STARSHIP_CONFIG = ('${settingsFile}')
del _os, _sc
execx($(${cfg.package}/bin/starship init xonsh))
'';
};
meta.maintainers = pkgs.starship.meta.maintainers;
}
|