# Fish shell configuration - batteries included # A comprehensive, quality-of-life focused fish setup with useful plugins { inputs, lib, config, pkgs, ... }: { programs.fish = { enable = true; # ═══════════════════════════════════════════════════════════════════════════ # PLUGINS - Curated selection for productivity # ═══════════════════════════════════════════════════════════════════════════ plugins = with pkgs.fishPlugins; [ # ── Directory Navigation ────────────────────────────────────────────────── # z: Jump to frequently used directories (like autojump/zoxide but pure fish) { name = "z"; src = z.src; } # fish-bd: Quickly go back to a parent directory in your working tree { name = "fish-bd"; src = fish-bd.src; } # ── Prompt ──────────────────────────────────────────────────────────────── # tide: Modern, extensible prompt { name = "tide"; src = tide.src; } # ── Fuzzy Finding ───────────────────────────────────────────────────────── # fzf-fish: Superior fzf integration - Ctrl+R history, Ctrl+Alt+F files, Ctrl+V vars { name = "fzf.fish"; src = fzf-fish.src; } # fifc: Fzf powers on top of fish completion engine with customizable rules { name = "fifc"; src = fifc.src; } # ── Git Integration ─────────────────────────────────────────────────────── # forgit: Interactive git with fzf (ga, glo, gi, gd, grh, gcf, gss, gclean) { name = "forgit"; src = forgit.src; } # plugin-git: Git aliases and status helpers (similar to oh-my-zsh git) { name = "plugin-git"; src = plugin-git.src; } # ── Quality of Life ─────────────────────────────────────────────────────── # autopair: Auto-insert matching brackets, quotes, etc. { name = "autopair"; src = autopair.src; } # done: Notifications when long-running commands complete { name = "done"; src = done.src; } # sponge: Remove failed commands and typos from history automatically { name = "sponge"; src = sponge.src; } # puffer: Text expansions (!! for last command, !$ for last argument) { name = "puffer"; src = puffer.src; } # fish-you-should-use: Reminds you to use your aliases { name = "fish-you-should-use"; src = fish-you-should-use.src; } # ── Shell Compatibility ─────────────────────────────────────────────────── # bass: Run bash scripts and capture environment changes { name = "bass"; src = bass.src; } # foreign-env: Source files from other shells (bash, zsh env files) { name = "foreign-env"; src = foreign-env.src; } # plugin-sudope: Quickly put 'sudo' in your command { name = "plugin-sudope"; src = plugin-sudope.src; } # ── Utility ─────────────────────────────────────────────────────────────── # grc: Colorize output of common commands (ping, traceroute, make, etc.) { name = "grc"; src = grc.src; } # colored-man-pages: Colorize man pages for better readability { name = "colored-man-pages"; src = colored-man-pages.src; } # spark: Sparklines for Fish { name = "spark"; src = spark.src; } # humantime-fish: Turn milliseconds into a human-readable string { name = "humantime-fish"; src = humantime-fish.src; } ] ++ lib.optionals pkgs.stdenv.isDarwin [ # ── Platform-Specific (macOS) ───────────────────────────────────────────── # macos: MacOS functions for Fish { name = "macos"; src = macos.src; } ]; # ═══════════════════════════════════════════════════════════════════════════ # INTERACTIVE SHELL INITIALIZATION # ═══════════════════════════════════════════════════════════════════════════ interactiveShellInit = '' # Set up fzf.fish key bindings (Ctrl+R history, Ctrl+Alt+F files, etc.) fzf_configure_bindings echo "🐟 "(set_color cyan)(whoami)(set_color normal)" @ "(set_color yellow)(hostname -s)(set_color normal)" in "(set_color green)(prompt_pwd)(set_color normal) ''; # ═══════════════════════════════════════════════════════════════════════════ # SHELL INIT (runs for all shells, including non-interactive) # ═══════════════════════════════════════════════════════════════════════════ shellInit = '' # Ensure locale is set properly for UTF-8 if test -z "$LANG" set -gx LANG en_US.UTF-8 end if test -z "$LC_ALL" set -gx LC_ALL en_US.UTF-8 end # Bun global bin directory fish_add_path -g $HOME/.bun/bin ''; # ═══════════════════════════════════════════════════════════════════════════ # LOGIN SHELL INIT # ═══════════════════════════════════════════════════════════════════════════ loginShellInit = '' # Add any login-specific initialization here # This runs only for login shells ''; }; # ═════════════════════════════════════════════════════════════════════════════ # ADDITIONAL PACKAGES needed for fish plugins and functions # ═════════════════════════════════════════════════════════════════════════════ home.packages = with pkgs; [ grc # Generic colorizer (for grc plugin) libnotify # For done plugin notifications (Linux) ] ++ lib.optionals pkgs.stdenv.isDarwin [ terminal-notifier # For done plugin notifications (macOS) ]; }