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