Add a native fish Module and set it as neogaia's login shell
Translate the CachyOS fish snapshot into a home-manager Module: the fastfetch greeting, the bat-backed manpager, the done and bang-bang plugins (from nixpkgs, not a plugin manager), the history/backup/copy helper functions, and the eza and navigation aliases. Pacman-specific aliases are dropped or replaced with NixOS equivalents (update -> nixos-rebuild switch, cleanup -> nix-collect-garbage). Enabling the Module also makes fish the user's default login shell.
This commit is contained in:
34
.claude/tasks/0005-fish-shell-module.md
Normal file
34
.claude/tasks/0005-fish-shell-module.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
spec: laptop-mvi
|
||||||
|
blocked-by: 0001-skeleton-and-building-host
|
||||||
|
---
|
||||||
|
|
||||||
|
## What to build
|
||||||
|
|
||||||
|
A fish `Module`, configured natively via home-manager, that makes the shell feel like the current CachyOS setup but is correct for NixOS. Translate the existing `cachyos-config.fish` and the rest of the fish snapshot under `reference/home/.config/fish/`: the greeting, the bat-manpager, the `done` and bang-bang plugins, the helper functions, and the eza/nav aliases. Drop or replace every Arch/pacman-specific part with its NixOS equivalent. Set fish as the default login shell.
|
||||||
|
|
||||||
|
Configure the plugins natively through home-manager rather than a fish plugin manager.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [x] A fish `Module` (following the `Enable convention`) is enabled on `neogaia` and configured natively via home-manager.
|
||||||
|
- [x] The greeting, bat-manpager, `done` and bang-bang plugins, helper functions, and eza/nav aliases from the reference config are reproduced.
|
||||||
|
- [x] All Arch/pacman-specific parts are dropped or replaced with NixOS equivalents.
|
||||||
|
- [x] fish is the user's default login shell.
|
||||||
|
- [x] The `neogaia` toplevel still builds with the fish `Module` enabled.
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
|
||||||
|
- **Plugins are native, not inlined.** `done` and `bang-bang` come from `pkgs.fishPlugins.*` via `programs.fish.plugins`; home-manager drops them into `~/.config/fish/conf.d/` where fish auto-sources them.
|
||||||
|
The reference config inlined the bang-bang `__history_previous_command` functions and binds by hand; the plugin supplies those, so they are not re-inlined.
|
||||||
|
- **`done` tuning uses `set -g`, not `set -U`.** The reference set `__done_min_cmd_duration`/`__done_notification_urgency_level` as universal variables, which persist to the universal-variable file and then ignore config changes.
|
||||||
|
A declarative config must own these each session, so they are set global (`set -g`) in `interactiveShellInit`.
|
||||||
|
- **Arch/pacman aliases dropped:** `grubup`, `fixpacman`, `mirror` (`cachyos-rate-mirrors`), `apt`/`apt-get` (`man pacman`), `big` (`expac`), `gitpkg`, `rip` (`expac`).
|
||||||
|
**Replaced with NixOS equivalents:** `update` → `sudo nixos-rebuild switch` (was `pacman -Syu`), `cleanup` → `sudo nix-collect-garbage -d` (was `pacman -Rns`).
|
||||||
|
- **Machine-specific PATH hacks dropped, per spec story 6 ("no impure environment lookup").** The hardcoded `BUN_INSTALL`, the `node-v24...` tarball path, and `~/Applications/depot_tools` from `config.fish` are absolute/impure and are not reproduced; such tooling should be Nix-provided when its own Module arrives.
|
||||||
|
The portable bits are kept: `~/.local/bin` on PATH (guarded) and sourcing `~/.fish_profile`.
|
||||||
|
- **`env.fish` and `rustup.fish` deliberately not carried over.** `ANDROID_HOME`/platform-tools (Android SDK) and `source ~/.cargo/env.fish` (rust) are dev-toolchain integrations outside the MVI's core tooling (fish/tmux/nvim/Claude Code); they belong to future per-toolchain Modules that provide those tools through Nix rather than sourcing an impure env file.
|
||||||
|
- **`hw` (`hwinfo --short`) and `tb` (`nc termbin.com 9999`) dropped.** These are generic rather than pacman-specific, but each needs an extra package (`hwinfo`, a `netcat`) that the minimal install does not otherwise pull in; left out of the MVI and easy to add later.
|
||||||
|
- **`copy` kept verbatim** (including the upstream `trim-right` call) to preserve exact parity with the current shell.
|
||||||
|
- **Verification.** The `neogaia` system toplevel builds (the spec's primary seam).
|
||||||
|
The rendered `~/.config/fish/` was inspected in the build output: aliases, the three helper functions, the `fastfetch` greeting, the bat manpager, the `done` tuning vars, and the `conf.d/plugin-done.fish` + `conf.d/plugin-bang-bang.fish` plugin files are all present; `users.users.alexion.shell` resolves to `pkgs.fish`.
|
||||||
@@ -35,6 +35,9 @@
|
|||||||
# An SSH daemon so the rest of the setup can be driven over the network.
|
# An SSH daemon so the rest of the setup can be driven over the network.
|
||||||
services.openssh.enable = true;
|
services.openssh.enable = true;
|
||||||
|
|
||||||
|
# fish as the login shell.
|
||||||
|
modules.fish.enable = true;
|
||||||
|
|
||||||
# Locale preferences for the base system.
|
# Locale preferences for the base system.
|
||||||
time.timeZone = "America/New_York";
|
time.timeZone = "America/New_York";
|
||||||
i18n.defaultLocale = "en_GB.UTF-8";
|
i18n.defaultLocale = "en_GB.UTF-8";
|
||||||
|
|||||||
141
modules/fish.nix
Normal file
141
modules/fish.nix
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
# fish for the primary user, configured natively through home-manager and set
|
||||||
|
# as their default login shell. Wires the done and bang-bang plugins, a
|
||||||
|
# fastfetch greeting, a bat-backed manpager, helper functions, and the eza and
|
||||||
|
# navigation aliases.
|
||||||
|
let
|
||||||
|
cfg = config.modules.fish;
|
||||||
|
user = config.user.name;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.modules.fish.enable = lib.mkEnableOption "fish as the user's shell, configured via home-manager";
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
# System-level fish: registers it in /etc/shells and installs vendor
|
||||||
|
# completions.
|
||||||
|
programs.fish.enable = true;
|
||||||
|
users.users.${user}.shell = pkgs.fish;
|
||||||
|
|
||||||
|
home-manager.users.${user} = {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
eza
|
||||||
|
bat
|
||||||
|
fastfetch
|
||||||
|
wget
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.fish = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# done notifies when a long command finishes; bang-bang restores the !!
|
||||||
|
# and !$ history bindings.
|
||||||
|
plugins = [
|
||||||
|
{
|
||||||
|
name = "done";
|
||||||
|
src = pkgs.fishPlugins.done.src;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "bang-bang";
|
||||||
|
src = pkgs.fishPlugins.bang-bang.src;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
shellAliases = {
|
||||||
|
# Replace ls with eza.
|
||||||
|
ls = "eza -al --color=always --group-directories-first --icons";
|
||||||
|
la = "eza -a --color=always --group-directories-first --icons";
|
||||||
|
ll = "eza -l --color=always --group-directories-first --icons";
|
||||||
|
lt = "eza -aT --color=always --group-directories-first --icons";
|
||||||
|
"l." = "eza -a | grep -e '^\\.'";
|
||||||
|
|
||||||
|
# Walk up the tree.
|
||||||
|
".." = "cd ..";
|
||||||
|
"..." = "cd ../..";
|
||||||
|
"...." = "cd ../../..";
|
||||||
|
"....." = "cd ../../../..";
|
||||||
|
"......" = "cd ../../../../..";
|
||||||
|
|
||||||
|
vi = "nvim";
|
||||||
|
vim = "nvim";
|
||||||
|
cp = "cp -v";
|
||||||
|
tmx = "tmux new-session -A -s";
|
||||||
|
|
||||||
|
tarnow = "tar -acf ";
|
||||||
|
untar = "tar -zxvf ";
|
||||||
|
wget = "wget -c ";
|
||||||
|
psmem = "ps auxf | sort -nr -k 4";
|
||||||
|
psmem10 = "ps auxf | sort -nr -k 4 | head -10";
|
||||||
|
dir = "dir --color=auto";
|
||||||
|
vdir = "vdir --color=auto";
|
||||||
|
grep = "grep --color=auto";
|
||||||
|
fgrep = "fgrep --color=auto";
|
||||||
|
egrep = "egrep --color=auto";
|
||||||
|
jctl = "journalctl -p 3 -xb";
|
||||||
|
please = "sudo";
|
||||||
|
|
||||||
|
# Rebuild the system, and reclaim disk from old generations.
|
||||||
|
update = "sudo nixos-rebuild switch";
|
||||||
|
cleanup = "sudo nix-collect-garbage -d";
|
||||||
|
};
|
||||||
|
|
||||||
|
functions = {
|
||||||
|
# Run fastfetch as the welcome message.
|
||||||
|
fish_greeting = "fastfetch";
|
||||||
|
|
||||||
|
history = {
|
||||||
|
description = "Show command history with timestamps";
|
||||||
|
body = "builtin history --show-time='%F %T '";
|
||||||
|
};
|
||||||
|
|
||||||
|
backup = {
|
||||||
|
description = "Copy <file> to <file>.bak";
|
||||||
|
argumentNames = "filename";
|
||||||
|
body = "cp $filename $filename.bak";
|
||||||
|
};
|
||||||
|
|
||||||
|
copy = {
|
||||||
|
description = "Copy a file, or recursively copy a source directory into a destination";
|
||||||
|
body = ''
|
||||||
|
set count (count $argv | tr -d \n)
|
||||||
|
if test "$count" = 2; and test -d "$argv[1]"
|
||||||
|
set from (echo $argv[1] | trim-right /)
|
||||||
|
set to (echo $argv[2])
|
||||||
|
command cp -r $from $to
|
||||||
|
else
|
||||||
|
command cp $argv
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
interactiveShellInit = ''
|
||||||
|
set -gx EDITOR nvim
|
||||||
|
set -gx VISUAL nvim
|
||||||
|
|
||||||
|
# Render man pages through bat.
|
||||||
|
set -x MANROFFOPT "-c"
|
||||||
|
set -x MANPAGER "sh -c 'col -bx | bat -l man -p'"
|
||||||
|
|
||||||
|
# Tune the done plugin: only notify for commands past 10s, at low urgency.
|
||||||
|
set -g __done_min_cmd_duration 10000
|
||||||
|
set -g __done_notification_urgency_level low
|
||||||
|
|
||||||
|
# Prepend ~/.local/bin to PATH when it exists.
|
||||||
|
if test -d ~/.local/bin
|
||||||
|
fish_add_path ~/.local/bin
|
||||||
|
end
|
||||||
|
|
||||||
|
# Apply fish-compatible profile overrides if present.
|
||||||
|
if test -f ~/.fish_profile
|
||||||
|
source ~/.fish_profile
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user