feat: zsh default shell + starship/bat/eza/zoxide shell experience

zsh is now the default login shell (programs.zsh.enable +
users.defaultUserShell, mkOverride 500 to beat bash.nix's mkDefault;
per-user shell= still overrides). modules/home/shell.nix configures the
interactive experience (nomarchy.shell.enable):

- zsh: completion, autosuggestions, syntax highlighting, big shared
  history, autocd.
- starship prompt themed from the palette (a `nomarchy` palette built
  from theme-state.json colors).
- bat as cat (theme "ansi" → tracks the terminal/theme palette), eza as
  ls (icons + git + dirs-first), zoxide as cd (--cmd cd).
- rg/fd shipped as themselves — deliberately NOT aliased over grep/find
  (flag differences surprise).

home.shell.enableZshIntegration = true is the single lever; starship,
eza, zoxide, ghostty and yazi all emit their zsh hooks from it (no
per-module edits). Verified: flake check green, default shell resolves
to zsh, .zshrc carries the starship/zoxide/eza/yazi hooks + aliases,
starship palette renders, all tools in the live ISO closure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-06-13 16:25:21 +01:00
parent f97054c804
commit df7c0ef7ae
5 changed files with 136 additions and 5 deletions

114
modules/home/shell.nix Normal file
View File

@@ -0,0 +1,114 @@
# Shell experience — zsh (the default login shell, set system-side) with
# autosuggestions + syntax highlighting, a themed starship prompt, and
# modern CLI tools wired in: bat (cat), eza (ls), zoxide (cd). bat uses
# the "ansi" theme so it follows the terminal palette (Ghostty is themed
# from the same JSON); starship is themed from the palette directly.
#
# home.shell.enableZshIntegration = true is the single lever that makes
# every integrating program (starship, eza, zoxide, ghostty, yazi) emit
# its zsh hooks — no per-module flags needed.
{ config, lib, pkgs, ... }:
let
cfg = config.nomarchy;
t = cfg.theme;
c = t.colors;
in
{
config = lib.mkIf cfg.shell.enable {
home.shell.enableZshIntegration = true;
# rg/fd as themselves (NOT aliased over grep/find — their flags
# differ enough to surprise). Available regardless of yazi/rofi.
home.packages = with pkgs; [ ripgrep fd ];
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
autocd = true;
history = {
size = 50000;
save = 50000;
ignoreDups = true;
ignoreSpace = true;
expireDuplicatesFirst = true;
};
shellAliases = {
cat = "bat --paging=never";
less = "bat";
grep = "grep --color=auto";
# eza enableZshIntegration aliases ls/ll/la; add a couple extras.
lt = "eza --tree --level=2 --icons=auto --group-directories-first";
tree = "eza --tree --icons=auto --group-directories-first";
".." = "cd ..";
"..." = "cd ../..";
};
};
programs.starship = {
enable = true;
settings = {
add_newline = false;
palette = "nomarchy";
# starship wants full #rrggbb (or names) — keep the leading #.
palettes.nomarchy = {
inherit (c) base text accent good warn bad subtext;
};
format = lib.concatStrings [
"[](accent)"
"$directory"
"$git_branch$git_status"
"$character"
];
directory = {
style = "fg:text bg:accent";
format = "[ $path ]($style)";
truncation_length = 3;
truncate_to_repo = true;
};
git_branch = {
style = "fg:base bg:warn";
format = "[ $symbol$branch ]($style)";
symbol = " ";
};
git_status = {
style = "fg:base bg:warn";
format = "[$all_status$ahead_behind ]($style)";
};
character = {
success_symbol = "[ ](good)";
error_symbol = "[ ](bad)";
};
cmd_duration = {
min_time = 2000;
style = "fg:subtext";
format = "[ $duration ]($style)";
};
};
};
# bat: "ansi" follows the terminal's 16-color palette → tracks the
# active Nomarchy theme (Ghostty bakes it) with no per-theme config.
programs.bat = {
enable = true;
config = {
theme = "ansi";
style = "numbers,changes,header";
};
};
programs.eza = {
enable = true;
icons = "auto";
git = true;
extraOptions = [ "--group-directories-first" ];
};
programs.zoxide = {
enable = true;
options = [ "--cmd cd" ]; # `cd` becomes the smart jumper (z under the hood)
};
};
}