/ modules / common / nushell / default.nix
default.nix
  1  {
  2    config,
  3    lib,
  4    pkgs,
  5    ...
  6  }:
  7  let
  8    inherit (lib)
  9      attrValues
 10      enabled
 11      filter
 12      first
 13      foldl'
 14      getExe
 15      last
 16      match
 17      mkIf
 18      nameValuePair
 19      optionalAttrs
 20      readFile
 21      removeAttrs
 22      splitString
 23      ;
 24  in
 25  {
 26    environment =
 27      optionalAttrs config.isLinux {
 28        sessionVariables.SHELLS = getExe pkgs.nushell;
 29      }
 30      // {
 31        shells = mkIf config.isDarwin [ pkgs.nushell ];
 32  
 33        shellAliases = {
 34          la = "ls --all";
 35          lla = "ls --long --all";
 36          sl = "ls";
 37  
 38          cp = "cp --recursive --verbose --progress";
 39          mk = "mkdir";
 40          mv = "mv --verbose";
 41          rm = "rm --recursive --verbose";
 42  
 43          pstree = "pstree -g 3";
 44          tree = "eza --tree --git-ignore --group-directories-first";
 45  
 46          # Essential aliases (these should be available system-wide)
 47          cat = "bat";
 48          ff = "fastfetch";
 49          jj = "jujutsu";
 50          ls = "eza";
 51  
 52          # Git aliases
 53          g = "git";
 54          ga = "git add";
 55          gad = "git add .";
 56          gb = "git branch";
 57          gc = "git commit";
 58          gcm = "git commit --message";
 59          gcl = "git clone";
 60          gd = "git diff";
 61          gp = "git push";
 62          gpr = "git push rad";
 63          gprm = "git push rad main";
 64          gpl = "git pull";
 65          gs = "git status";
 66  
 67          # nh (darwin) aliases
 68          nix-rebuild = "nh darwin switch ~/_"; # Replace old darwin-rebuild alias
 69          nix-build = "nh darwin build ~/_"; # Build without switching
 70          nix-test = "nh darwin test ~/_"; # Test configuration
 71          nix-diff = "nh darwin switch ~/_ --diff"; # Show diff before switching
 72          nix-dry = "nh darwin switch ~/_ --dry"; # Dry run
 73          nix-gc = "nix-collect-garbage --delete-old"; # Delete old generations
 74  
 75          # Short NH aliases
 76          nhs = "nh darwin switch ~/_"; # Quick switch
 77          nhb = "nh darwin build ~/_"; # Quick build
 78          nht = "nh darwin test ~/_"; # Quick test
 79          nhd = "nh darwin switch ~/_ --diff"; # Quick diff
 80          nhr = "nh darwin switch ~/_ --dry"; # Quick dry run
 81  
 82          # NH utilities
 83          nh-search = "nh search"; # Fast package search
 84          nh-clean = "nh clean all --keep 3"; # Clean old generations
 85          nh-clean-old = "nh clean all --keep-since 7d"; # Clean week-old builds
 86        };
 87  
 88        systemPackages = attrValues {
 89          inherit (pkgs)
 90            zoxide # For completions and better cd
 91            ;
 92        };
 93  
 94        variables.STARSHIP_LOG = "error";
 95      };
 96  
 97    nixpkgs.overlays = [
 98      (self: super: {
 99        zoxide = super.zoxide.overrideAttrs (old: {
100          src = self.fetchFromGitHub {
101            owner = "Bahex";
102            repo = "zoxide";
103            rev = "0450775af9b1430460967ba8fb5aa434f95c4bc4";
104            hash = "sha256-WhACxJMuhI9HGohcwg+ztZpQCVUZ4uibIQqGfJEEp/Y=";
105          };
106  
107          cargoDeps = self.rustPlatform.fetchCargoVendor {
108            inherit (self.zoxide) src;
109            hash = "sha256-v3tcQaEXfGyt1j2fShvxxrA9Xc90AWxEzEUT09cQ+is=";
110          };
111        });
112  
113        starship = super.starship.overrideAttrs (old: {
114          src = self.fetchFromGitHub {
115            owner = "poliorcetics";
116            repo = "starship";
117            rev = "92aba18381994599850053ba667c25017566b8ee";
118            hash = "sha256-FKDvkDcxUPDLcjFQzvqsGXeJUm0Dq8TcA4edf5OkdWo=";
119          };
120  
121          cargoDeps = self.rustPlatform.fetchCargoVendor {
122            inherit (self.starship) src;
123            hash = "sha256-nH1iYjKw/GbYKadoymH3onWBbMzuMUaRCSTNWVE+A9E=";
124          };
125  
126          nativeBuildInputs = old.nativeBuildInputs ++ [
127            pkgs.cmake
128            pkgs.zlib-ng
129          ];
130        });
131      })
132    ];
133  
134    home-manager.sharedModules = [
135      (
136        homeArgs:
137        let
138          homeConfig = homeArgs.config;
139        in
140        {
141          xdg.configFile = {
142            "nushell/zoxide.nu".source = pkgs.runCommand "zoxide.nu" { } ''
143              ${getExe pkgs.zoxide} init nushell --cmd cd > $out
144            '';
145  
146            # Use ThemeNix generated LS_COLORS
147            "nushell/ls_colors.txt".text = ''
148              NO_COLOR=0
149              LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32"
150            '';
151  
152            "nushell/starship.nu".source = pkgs.runCommand "starship.nu" { } ''
153              ${getExe pkgs.starship} init nu > $out
154            '';
155          };
156  
157          programs.starship = enabled {
158            # No because we are doing it at build time instead of the way
159            # this module does it. Why the hell do you generate
160            # the config every time the shell is launched?
161            enableNushellIntegration = false;
162            settings = with config.theme; {
163              add_newline = true;
164              format = "$directory$git_branch$git_status$git_metrics$fill$cmd_duration$rust$line_break$character";
165  
166              character = {
167                success_symbol = "[λ](bold #${base0D})"; # Blue lambda for success
168                error_symbol = "[λ](bold #${base08})"; # Red lambda for error
169              };
170  
171              directory = {
172                style = "#${base03}"; # Comments color for directory
173                truncation_length = 1;
174                truncate_to_repo = true;
175                format = "[$path]($style) ";
176              };
177  
178              fill = {
179                symbol = "─";
180                style = "#${base03}"; # Comments color for fill
181              };
182  
183              git_branch = {
184                style = "#${base0A}"; # Yellow for git branch
185                format = "[($symbol$branch)]($style)";
186              };
187  
188              git_metrics = {
189                format = "([+$added]($added_style)([-$deleted]($deleted_style) ))";
190                added_style = "#${base0B}"; # Green for additions
191                deleted_style = "#${base08}"; # Red for deletions
192                disabled = false;
193              };
194  
195              git_status = {
196                format = " [$all_status$ahead_behind]($style) ";
197                style = "#${base08}"; # Red for git status
198                ahead = "⇡ $count";
199                behind = "⇣ $count";
200                diverged = "⇕$count";
201                untracked = "?$count";
202                stashed = "≡$count";
203                modified = "!$count";
204                staged = "+$count";
205                renamed = "→$count";
206                deleted = "×$count";
207              };
208  
209              cmd_duration = {
210                min_time = 0;
211                format = " [󱫑 $duration]($style) ";
212                style = "#${base0F}"; # Brown for duration
213                show_milliseconds = false;
214              };
215  
216              rust = {
217                format = "[$symbol $version ]($style)";
218                symbol = "🦀";
219                style = "#${base08}"; # Red for rust
220                disabled = false;
221              };
222  
223              vcs.disabled = false;
224              command_timeout = 100;
225              scan_timeout = 20;
226              cmd_duration.show_notifications = config.isDesktop;
227              package.disabled = config.isServer;
228            };
229          };
230  
231          programs.nushell = enabled {
232            configFile.text = readFile ./config.nu;
233            envFile.text = readFile ./environment.nu;
234  
235            environmentVariables =
236              let
237                environmentVariables = config.environment.variables;
238                homeVariables = homeConfig.home.sessionVariables;
239              in
240              environmentVariables // homeVariables;
241  
242            shellAliases =
243              removeAttrs config.environment.shellAliases [
244                "l"
245              ]
246              // {
247                cdtmp = "cd (mktemp --directory)";
248                ll = "ls --long";
249              };
250          };
251        }
252      )
253    ];
254  }