diff --git a/home-manager/home.nix b/home-manager/home.nix index 3ebd3ae..e3ff1d4 100644 --- a/home-manager/home.nix +++ b/home-manager/home.nix @@ -19,6 +19,7 @@ ./modules/packages.nix ./modules/shells.nix + ./modules/fish.nix ./modules/git.nix ./modules/kitty.nix diff --git a/home-manager/modules/doom-emacs.nix b/home-manager/modules/doom-emacs.nix index 8e5d78f..a20b0fe 100644 --- a/home-manager/modules/doom-emacs.nix +++ b/home-manager/modules/doom-emacs.nix @@ -19,8 +19,8 @@ in { doomDir = ../../doom.d; # Where Doom stores local state (cache, etc.) - # Supports ~ expansion but NOT shell variables like $XDG_DATA_HOME - doomLocalDir = "~/.local/share/nix-doom"; + # Must be an absolute path + doomLocalDir = "${config.home.homeDirectory}/.local/share/nix-doom"; # Use emacs-pgtk for better Wayland support on Linux # On macOS, falls back to regular emacs diff --git a/home-manager/modules/fish.nix b/home-manager/modules/fish.nix new file mode 100644 index 0000000..1f00345 --- /dev/null +++ b/home-manager/modules/fish.nix @@ -0,0 +1,289 @@ +# Fish shell configuration - batteries included +# A comprehensive, quality-of-life focused fish setup with useful plugins +{ + inputs, + lib, + config, + pkgs, + ... +}: { + programs.fish = { + enable = true; + + # ═══════════════════════════════════════════════════════════════════════════ + # SHELL ALIASES + # ═══════════════════════════════════════════════════════════════════════════ + shellAliases = { + # Navigation + ".." = "cd .."; + "..." = "cd ../.."; + "...." = "cd ../../.."; + "....." = "cd ../../../.."; + + # Listings (eza integration handled by programs.eza) + ll = "ls -la"; + la = "ls -a"; + lt = "ls --tree"; + + # Git shortcuts + gs = "git status"; + gd = "git diff"; + gds = "git diff --staged"; + ga = "git add"; + gc = "git commit"; + gp = "git push"; + gl = "git pull"; + glog = "git log --oneline --graph --decorate"; + gco = "git checkout"; + gb = "git branch"; + + # Nix shortcuts + nix-gc = "nix-collect-garbage -d"; + nix-search = "nix search nixpkgs"; + nrs = "sudo nixos-rebuild switch --flake ."; + drs = "darwin-rebuild switch --flake ."; + hms = "home-manager switch --flake ."; + + # Safety nets + rm = "rm -i"; + cp = "cp -i"; + mv = "mv -i"; + + # Modern replacements (when available) + cat = "bat --paging=never"; + grep = "rg"; + find = "fd"; + + # Misc + c = "clear"; + q = "exit"; + h = "history"; + j = "jobs -l"; + path = "echo $PATH | tr ':' '\\n'"; + week = "date +%V"; + myip = "curl -s https://ipinfo.io/ip"; + }; + + # ═══════════════════════════════════════════════════════════════════════════ + # SHELL ABBREVIATIONS (expand as you type, more powerful than aliases) + # ═══════════════════════════════════════════════════════════════════════════ + shellAbbrs = { + # Git abbreviations (expand to full commands) + gst = "git status"; + gaa = "git add --all"; + gcm = "git commit -m"; + gca = "git commit --amend"; + gcan = "git commit --amend --no-edit"; + gpf = "git push --force-with-lease"; + grb = "git rebase"; + grbi = "git rebase -i"; + gsta = "git stash"; + gstp = "git stash pop"; + + # Docker + dps = "docker ps"; + dpa = "docker ps -a"; + di = "docker images"; + dcu = "docker-compose up"; + dcd = "docker-compose down"; + + # Kubernetes + k = "kubectl"; + kg = "kubectl get"; + kd = "kubectl describe"; + kl = "kubectl logs"; + kx = "kubectl exec -it"; + }; + + # ═══════════════════════════════════════════════════════════════════════════ + # CUSTOM FUNCTIONS + # ═══════════════════════════════════════════════════════════════════════════ + functions = { + # Create directory and cd into it + mkcd = "mkdir -p $argv[1]; and cd $argv[1]"; + + # Quick extract - handles multiple archive formats + extract = '' + if test -f $argv[1] + switch $argv[1] + case '*.tar.bz2' + tar xjf $argv[1] + case '*.tar.gz' + tar xzf $argv[1] + case '*.tar.xz' + tar xJf $argv[1] + case '*.bz2' + bunzip2 $argv[1] + case '*.rar' + unrar x $argv[1] + case '*.gz' + gunzip $argv[1] + case '*.tar' + tar xf $argv[1] + case '*.tbz2' + tar xjf $argv[1] + case '*.tgz' + tar xzf $argv[1] + case '*.zip' + unzip $argv[1] + case '*.Z' + uncompress $argv[1] + case '*.7z' + 7z x $argv[1] + case '*' + echo "'$argv[1]' cannot be extracted via extract()" + end + else + echo "'$argv[1]' is not a valid file" + end + ''; + + # Git clone and cd + gcl = '' + git clone $argv[1] + cd (basename $argv[1] .git) + ''; + + # Quick backup file + bak = "cp $argv[1] $argv[1].bak.(date +%Y%m%d_%H%M%S)"; + + # Find process by name + psg = "ps aux | grep -v grep | grep -i $argv[1]"; + + # Quick HTTP server + serve = '' + set port (test -n "$argv[1]"; and echo $argv[1]; or echo 8000) + echo "Serving on http://localhost:$port" + python3 -m http.server $port + ''; + + # Weather + weather = '' + set location (test -n "$argv[1]"; and echo $argv[1]; or echo "") + curl -s "wttr.in/$location?format=3" + ''; + + # Quick nix shell + nsh = "nix-shell -p $argv"; + + # Reload fish config + reload = "source ~/.config/fish/config.fish; echo 'Fish config reloaded!'"; + + # Show path entries one per line + pathlist = "echo $PATH | tr ':' '\\n' | nl"; + + # Create a quick note + note = '' + set note_dir "$HOME/notes" + mkdir -p $note_dir + set note_file "$note_dir/(date +%Y-%m-%d).md" + if test -n "$argv" + echo "- (date +%H:%M) $argv" >> $note_file + echo "Note added to $note_file" + else + $EDITOR $note_file + end + ''; + + # Show disk usage for current directory, sorted + duf = "du -sh * 2>/dev/null | sort -h"; + + + }; + + # ═══════════════════════════════════════════════════════════════════════════ + # 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; } + + # ── Fuzzy Finding ───────────────────────────────────────────────────────── + # fzf-fish: Superior fzf integration - Ctrl+R history, Ctrl+Alt+F files, Ctrl+V vars + { + name = "fuck.fzf.fish"; + src = pkgs.fetchFromGitHub { + owner = "PatrickF1"; + repo = "fzf.fish"; + rev = "v10.3"; + hash = "sha256-T8KYLA/r/gOKvAivKRoeqIwE2pINlxFQtZJHpOy9GMM="; + }; + } + + { name = "tide"; src = tide.src; } + + # forgit: Interactive git with fzf (ga, glo, gi, gd, grh, gcf, gss, gclean) + { name = "forgit"; src = forgit.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; } + + # colored-man-pages: Colorize man pages for better readability + { name = "colored-man-pages"; src = colored-man-pages.src; } + + # ── Git Enhancement ─────────────────────────────────────────────────────── + # plugin-git: Git aliases and status helpers (similar to oh-my-zsh git) + { name = "plugin-git"; src = plugin-git.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; } + + # ── Utility ─────────────────────────────────────────────────────────────── + # grc: Colorize output of common commands (ping, traceroute, make, etc.) + { name = "grc"; src = grc.src; } + ]; + + # ═══════════════════════════════════════════════════════════════════════════ + # INTERACTIVE SHELL INITIALIZATION + # ═══════════════════════════════════════════════════════════════════════════ + interactiveShellInit = '' + 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 + ''; + + # ═══════════════════════════════════════════════════════════════════════════ + # 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) + ]; +} diff --git a/home-manager/modules/packages.nix b/home-manager/modules/packages.nix index 7ada7dd..1431597 100644 --- a/home-manager/modules/packages.nix +++ b/home-manager/modules/packages.nix @@ -121,7 +121,7 @@ in { # add packages w3m - emacs + # emacs is provided by doom-emacs module (programs.doom-emacs) parinfer-rust sshuttle diff --git a/home-manager/modules/shells.nix b/home-manager/modules/shells.nix index c77ec28..5980800 100644 --- a/home-manager/modules/shells.nix +++ b/home-manager/modules/shells.nix @@ -49,22 +49,7 @@ ''; }; - # Fish configuration - programs.fish = { - enable = true; - - shellAliases = { - ll = "ls -la"; - ".." = "cd .."; - "..." = "cd ../.."; - gs = "git status"; - gd = "git diff"; - }; - - functions = { - mkcd = "mkdir -p $argv[1]; and cd $argv[1]"; - }; - }; + # Fish configuration is in ./fish.nix # Starship prompt (works with all shells) programs.starship = {