From 61a82540fbbe42733b538e4cb7e04d44cc366334 Mon Sep 17 00:00:00 2001 From: rootiest Date: Sat, 25 Jul 2026 21:21:37 -0400 Subject: [PATCH] feat(docs): split fish-config.md into docs/manual SSOT tree --- docs/manual/00-name.md | 8 + docs/manual/00-synopsis.md | 19 + docs/manual/00-table-of-contents.md | 45 ++ docs/manual/01-configuration-variables.md | 142 ++++++ docs/manual/02-path-setup.md | 25 + docs/manual/03-key-bindings.md | 58 +++ docs/manual/04-abbreviations.md | 193 ++++++++ .../05-functions/01-file-and-directory.md | 164 +++++++ docs/manual/05-functions/02-navigation.md | 32 ++ .../05-functions/03-editors-and-viewers.md | 71 +++ .../04-git-and-version-control.md | 90 ++++ .../05-functions/05-package-management.md | 60 +++ .../05-functions/06-dependency-management.md | 47 ++ .../05-functions/07-system-and-monitoring.md | 63 +++ .../05-functions/08-terminal-management.md | 60 +++ docs/manual/05-functions/09-clipboard.md | 32 ++ docs/manual/05-functions/10-network.md | 44 ++ .../05-functions/11-pager-and-logging.md | 47 ++ .../05-functions/12-ai-and-developer-tools.md | 116 +++++ .../05-functions/13-media-and-utilities.md | 54 +++ docs/manual/05-functions/14-miscellaneous.md | 286 ++++++++++++ docs/manual/05-functions/index.md | 10 + docs/manual/06-dependency-catalog.md | 73 +++ docs/manual/07-customization.md | 438 ++++++++++++++++++ docs/manual/08-fisher-plugins.md | 107 +++++ docs/manual/09-installation.md | 43 ++ docs/manual/10-personalization.md | 68 +++ docs/manual/11-viewing-this-manual.md | 78 ++++ docs/manual/index.md | 77 +++ docs/manualtools.py | 9 +- docs/split-manual.py | 149 ++++++ docs/verify-manual.py | 20 + 32 files changed, 2726 insertions(+), 2 deletions(-) create mode 100644 docs/manual/00-name.md create mode 100644 docs/manual/00-synopsis.md create mode 100644 docs/manual/00-table-of-contents.md create mode 100644 docs/manual/01-configuration-variables.md create mode 100644 docs/manual/02-path-setup.md create mode 100644 docs/manual/03-key-bindings.md create mode 100644 docs/manual/04-abbreviations.md create mode 100644 docs/manual/05-functions/01-file-and-directory.md create mode 100644 docs/manual/05-functions/02-navigation.md create mode 100644 docs/manual/05-functions/03-editors-and-viewers.md create mode 100644 docs/manual/05-functions/04-git-and-version-control.md create mode 100644 docs/manual/05-functions/05-package-management.md create mode 100644 docs/manual/05-functions/06-dependency-management.md create mode 100644 docs/manual/05-functions/07-system-and-monitoring.md create mode 100644 docs/manual/05-functions/08-terminal-management.md create mode 100644 docs/manual/05-functions/09-clipboard.md create mode 100644 docs/manual/05-functions/10-network.md create mode 100644 docs/manual/05-functions/11-pager-and-logging.md create mode 100644 docs/manual/05-functions/12-ai-and-developer-tools.md create mode 100644 docs/manual/05-functions/13-media-and-utilities.md create mode 100644 docs/manual/05-functions/14-miscellaneous.md create mode 100644 docs/manual/05-functions/index.md create mode 100644 docs/manual/06-dependency-catalog.md create mode 100644 docs/manual/07-customization.md create mode 100644 docs/manual/08-fisher-plugins.md create mode 100644 docs/manual/09-installation.md create mode 100644 docs/manual/10-personalization.md create mode 100644 docs/manual/11-viewing-this-manual.md create mode 100644 docs/manual/index.md create mode 100644 docs/split-manual.py diff --git a/docs/manual/00-name.md b/docs/manual/00-name.md new file mode 100644 index 0000000..11f3751 --- /dev/null +++ b/docs/manual/00-name.md @@ -0,0 +1,8 @@ +--- +title: Name +manTitle: NAME +man: true +site: false +--- + +fish-config - personal fish shell configuration for Fish 4.x with modern CLI tool integration diff --git a/docs/manual/00-synopsis.md b/docs/manual/00-synopsis.md new file mode 100644 index 0000000..5d2fa97 --- /dev/null +++ b/docs/manual/00-synopsis.md @@ -0,0 +1,19 @@ +--- +title: Synopsis +manTitle: SYNOPSIS +man: true +site: false +--- + +help config [SECTION] + +Open this manual in the best available pager. Optionally jump to a section +by keyword: + + help config keybindings + help config pkg + help config abbreviations + help config logs + +The `help config` syntax integrates with fish's built-in help command. +The underlying `config-help` function is also available directly. diff --git a/docs/manual/00-table-of-contents.md b/docs/manual/00-table-of-contents.md new file mode 100644 index 0000000..52d2205 --- /dev/null +++ b/docs/manual/00-table-of-contents.md @@ -0,0 +1,45 @@ +--- +title: Table Of Contents +manTitle: TABLE OF CONTENTS +man: true +site: false +--- + +1. Configuration Variables + 2. PATH Setup + 3. Key Bindings + 4. Abbreviations + 4.1 Editors + 4.2 Navigation and Listing + 4.3 Git + 4.4 Terminal Windows, Tabs, and Panes + 4.5 Chezmoi + 4.6 Docker + 4.7 Systemctl + 4.8 AI Assistants + 4.9 History Expansion + 4.10 Miscellaneous + 4.11 Shell Aliases + 5. Functions Reference + 5.1 File and Directory + 5.2 Navigation + 5.3 Editors and Viewers + 5.4 Git and Version Control + 5.5 Package Management + 5.6 Dependency Management + 5.7 System and Monitoring + 5.8 Terminal Management + 5.9 Clipboard + 5.10 Network + 5.11 Pager and Logging + 5.12 AI and Developer Tools + 5.13 Media and Utilities + 5.14 Miscellaneous + 6. Dependency Catalog + 7. Customization + 8. Fisher Plugins + 9. Installation + 10. Personalization + 11. Viewing This Manual + +--- diff --git a/docs/manual/01-configuration-variables.md b/docs/manual/01-configuration-variables.md new file mode 100644 index 0000000..65aad02 --- /dev/null +++ b/docs/manual/01-configuration-variables.md @@ -0,0 +1,142 @@ +--- +title: Configuration Variables +manTitle: 1. CONFIGURATION VARIABLES +sidebar: + order: 1 +helpKeywords: +- variables +- config +--- + +These variables are exported from config.fish on every interactive session. +Override them in local.fish (see Section 10, Personalization). + +## Environment Directories (XDG) + + XDG_CONFIG_HOME ~/.config + XDG_CACHE_HOME ~/.cache + XDG_DATA_HOME ~/.local/share + XDG_STATE_HOME ~/.local/state + +Tools that respect XDG are directed to these paths rather than polluting $HOME. + +## Tool Homes (XDG-compliant) + + CARGO_HOME $XDG_DATA_HOME/cargo + RUSTUP_HOME $XDG_DATA_HOME/rustup + GOPATH $XDG_DATA_HOME/go + BUN_INSTALL $XDG_DATA_HOME/bun + NPM_CONFIG_PREFIX $XDG_DATA_HOME/npm-global + GNUPGHOME $XDG_CONFIG_HOME/gnupg + WAKATIME_HOME $XDG_CONFIG_HOME/wakatime + +## Editor and Pager + + EDITOR nvim (falls back to vi if nvim is absent) + VISUAL unset by default; set a GUI editor via local.fish (the edit + function falls back to a GUI chain when VISUAL is empty) + SUDO_EDITOR same as EDITOR + PAGER ov (falls back to less) + +## Scrollback History + + __fish_scrollback_history_dir (unset → ~/.terminal_history) + __fish_scrollback_history_max_files (unset → 100) + SCROLLBACK_HISTORY_DIR ~/.terminal_history (exported mirror) + SCROLLBACK_HISTORY_MAX_FILES 100 (exported mirror) + +The __fish_scrollback_history_* universal variables are the fish-style source +of truth — set them via `config-settings` → Paths, or `set -U` directly. +config.fish exports the SCROLLBACK_HISTORY_* mirrors from them, because the +POSIX wrapper scripts (paru/yay/tmux/zellij logging and _prune_terminal_logs) +read the exported names from the environment. When the __fish_ vars are unset, +the documented defaults are exported. config.fish deliberately does not create +a global source var, which would shadow the universal and stop live edits from +taking effect. + +Scrollback logs accumulate in SCROLLBACK_HISTORY_DIR as timestamped files. +When the count exceeds SCROLLBACK_HISTORY_MAX_FILES the oldest are pruned +automatically on exit. Use `logs` to browse them interactively. + +## Other + + GPG_TTY $(tty) — ensures GPG passphrase prompts work + CLAUDE_CODE_NO_FLICKER 1 — suppress terminal flicker in Claude Code + CDPATH . ~/projects ~ + +Opinionated defaults (CDPATH, PAGER/MANPAGER, Vi mode, command shadows, +terminal integrations) can be switched off per category with universal +variables — see Section 7, "Opinionated Components (Minimal Mode)". + +## Pager Hierarchy + +$PAGER is set to ov when available, falling back to less. The less wrapper +function extends this into a full chain so anything that calls less directly +also benefits: + + $PAGER → ov → less → more → cat + +When bat is installed, man pages are rendered with syntax highlighting: + + MANROFFOPT -c + MANPAGER sh -c 'col -bx | bat -l man -p' + +## Integrations + +### Zoxide + +cd, z, and cdi/zi are all mapped to zoxide-backed navigation. Tab completions +for cd and z blend standard directory entries (CWD and CDPATH) with frecency +results so both familiar and frequently-visited paths appear in one list. + +### DirEnv + +Automatically loads .envrc files on directory change. Takes priority over +the auto-venv logic — if a directory is managed by direnv, the auto-venv +activation is skipped entirely. + +### Auto Python Venv + +When entering a directory that contains a .venv/, the virtualenv is activated +automatically and deactivated when you leave the project tree. + +### WakaTime + +Every shell command is reported to WakaTime for time-tracking. Set +FISH_WAKATIME_DISABLED=1 to disable without removing the plugin. + +### Tailscale + +Full tab completion for the tailscale CLI is provided via conf.d/tailscale.fish. + +### Done Notifications + +Desktop notifications fire when a command takes longer than 10 seconds and +the terminal window is not focused. Configured via fish universal variables: + + __done_min_cmd_duration 10000 ms + __done_notification_urgency_level low + +### Scrollback History + +When running inside Kitty, closing a shell session via exit saves a timestamped +scrollback snapshot to SCROLLBACK_HISTORY_DIR. Files are named: + + scrollback_YYYY-MM-DD_HH-MM-SS.log + +The paru and yay wrappers (auto-generated in ~/.local/bin/) run the command +inside a PTY via script(1) so download progress bars are preserved on screen, +then render the captured terminal animation down to a clean static log via +scripts/clean_progress_log.py (a small terminal-screen emulator that replays +cursor movements, collapses repainted progress frames to their final state, +and preserves ANSI color). If python3 is unavailable the wrapper falls back to +dropping only the script(1) header/footer. Output is saved to: + + paru_YYYY-MM-DD_HH-MM-SS.log + yay_YYYY-MM-DD_HH-MM-SS.log + +Before pruning, _scrollback_prune_junk silently removes empty files, files +with only a single meaningful line (e.g. bare [exited] captures), and Kitty +tab-rename prompt captures. Use exit --no-log (or exit -n) to skip capture. + +--- diff --git a/docs/manual/02-path-setup.md b/docs/manual/02-path-setup.md new file mode 100644 index 0000000..78f8680 --- /dev/null +++ b/docs/manual/02-path-setup.md @@ -0,0 +1,25 @@ +--- +title: Path Setup +manTitle: 2. PATH SETUP +sidebar: + order: 2 +helpKeywords: +- path +--- + +Directories prepended to PATH in this order (first wins): + + ~/.local/bin Standard user-local executables + ~/Applications User-installed standalone apps + ~/scripts Personal shell scripts + ~/bin Cargo binaries (appended — lowest priority) + $BUN_INSTALL/bin Bun runtime and global packages + $NPM_CONFIG_PREFIX/bin Global npm packages + ~/.lmstudio/bin LM Studio CLI + ~/.resend/bin Resend CLI + ~/.fzf/bin fzf binary (git-installed) + +Cargo binaries are intentionally appended (lowest priority) to avoid +shadowing system-installed Rust tools. + +--- diff --git a/docs/manual/03-key-bindings.md b/docs/manual/03-key-bindings.md new file mode 100644 index 0000000..68c4f5f --- /dev/null +++ b/docs/manual/03-key-bindings.md @@ -0,0 +1,58 @@ +--- +title: Key Bindings +manTitle: 3. KEY BINDINGS +sidebar: + order: 3 +helpKeywords: +- keybindings +- bindings +- key-bindings +- keys +--- + +The shell uses Vi key bindings (fish_vi_key_bindings). All custom bindings +are active in Insert, Normal, and Visual modes unless noted. + + Binding Action + ───────────────────────────────────────────────────────────────────── + Ctrl+G Insert the head of the previous command's last path + argument. Equivalent to !$:h in Bash. + Example: previous = "cd /usr/local/bin" + Ctrl+G inserts "/usr/local" + + Ctrl+F Interactive history substitution. Type old/new then + press Ctrl+F to apply s/old/new/ to the previous + command. Equivalent to !!:s/old/new/ in Bash. + Example: previous = "echo this is a test" + type "this is/that was", press Ctrl+F + result = "echo that was a test" + + Ctrl+Alt+U Strip the first token of the current command line, + leaving arguments in place with the cursor at the + start. Useful for quickly retyping the command. + Example: "mkdir new_folder" -> " new_folder" + + Ctrl+Alt+= Evaluate the current command line buffer with + Qalculate! (qalc) and print the result inline. + Requires qalc to be installed. + Example: type "150 * 1.08", press Ctrl+Alt+= + prints 162 + + Ctrl+Enter Smart execute: runs commands instantly without + pressing Enter a second time for certain fast-path + commands (speedtest-fast, etc.). + + @@ FZF inline picker. Type @@ anywhere on the command + line to open an fzf picker and insert a selection + at the cursor position. + +## FZF Bindings (bundled from PatrickF1/fzf.fish) + + Ctrl+R Search command history + Ctrl+Alt+F Search git-tracked files + Ctrl+Alt+L Search git log + Ctrl+Alt+S Search git status + Ctrl+V Search shell variables + Ctrl+Alt+P Search running processes + +--- diff --git a/docs/manual/04-abbreviations.md b/docs/manual/04-abbreviations.md new file mode 100644 index 0000000..f647a14 --- /dev/null +++ b/docs/manual/04-abbreviations.md @@ -0,0 +1,193 @@ +--- +title: Abbreviations +manTitle: 4. ABBREVIATIONS +sidebar: + order: 4 +helpKeywords: +- abbreviations +- abbr +- abbrs +--- + +Abbreviations expand when you press Space or Enter. They are terminal-aware: +some expand differently in Kitty vs WezTerm vs other terminals. + +## 4.1 Editors + + n / nv / neovim nvim + e edit + se sudoedit + k kate + editt Open new tab with nvim (terminal-aware) + cdnv cd ~/.config/nvim + cdnvn cd ~/.config/nvim; nvim + +## 4.2 Navigation and Listing + + l ls + lS lss (sort by size) + lsR lsr (sort by time, oldest first) + lX lx (sort by extension) + lT lt (tree, depth 2) + lsT lstree (full recursive tree) + lzd ld (lazydocker) + cdi zi (interactive zoxide picker) + +## 4.3 Git + + g git + lg lazygit + gitig / git-ignore gi (generate .gitignore) + +## 4.4 Terminal Windows, Tabs, and Panes + +These abbreviations control the terminal emulator. Each has a Kitty +variant and a WezTerm variant; the correct one is inserted based on +$TERM or $TERM_PROGRAM. + + :w New OS window + :wv Split pane horizontally (new pane below) + :wh Split pane vertically (new pane to the right) + :wo Detach current window to its own OS window + :wot Move current pane to a new tab + :t New tab + :tl Set tab title + :tw Set window title + :twk Rename workspace (WezTerm only) + :tp Focus previous tab + :tn Focus next tab + :q Close current pane/window + :Q Close current tab + :sw spwin (spawn new OS window) + +Quick-navigate shortcuts open windows/tabs/panes with preset working dirs: + + :tgk New tab at ~/.config/kitty + :tgn New tab at ~/.config/nvim + :tgf New tab at ~/.config/fish + :tgh New tab at ~ + :tgcz New tab at chezmoi source dir + :tgcm New tab at chezmoi source dir + :tgp New tab at ~/projects + :tgr New tab at / (root) + +Prefixes :wg* and :wvg* / :whg* open OS windows or splits to the same +set of dirs, respectively. + +Prefixes :cd* open tabs with a quick cd shortcut: + + :cdn cd ~/.config/nvim + :cdf cd ~/.config/fish + :cdh cd ~ + :cdcz cd to chezmoi source + :cdp cd ~/projects + +Appending n to any :cd* abbreviation also runs nvim after changing dir. + +## 4.5 Chezmoi + + cm / cme / cmi / cmap / cmad / cmrm / cmcd / + cz / cze / czi / czap / czad / czrm / czcd + + cm / cz chezmoi + cmcd / czcd chezmoi cd + cme / cze chezmoi edit + cmad / czad chezmoi add + cmap / czap chezmoi apply + cmrm / cmf / czrm / czf chezmoi forget + cmi / czi chezmoi init + +## 4.6 Docker + + dcl docker context use default + dcls docker context ls + lzd ld (lazydocker) + +## 4.7 Systemctl + + sc systemctl + ssc sudo systemctl + scu systemctl --user + st systemctl status + scs sudo systemctl start + scr sudo systemctl restart + ssct sudo systemctl start + sscs sudo systemctl stop + sscr sudo systemctl restart + +## 4.8 AI Assistants + + ag agy + ag. agy . + v antigravity-ide + s wezterm ssh (WezTerm only) + +## 4.9 History Expansion + +These are implemented as keybinding helpers, but can also be typed: + + !^ Expand to first argument of previous command + !* Expand to all arguments of previous command + typo_sub Interactive typo substitution (Ctrl+F) + bang_string !string expansion + bang_search !?string search + bang_minus_n !-n (nth-previous command) + +## 4.10 Miscellaneous + + /exit exit + :q Close pane (alias for terminal close) + :Q Close tab + sudu sudo -s + kt kitty (Kitty only) + c cat + speedtest-fast fast-cli + bl bd list + bs bd sync + bC bd create --title + bsh bd show + lb lazybeads + +## 4.11 Shell Aliases + +These aliases are defined in conf.d/tricks.fish via alias (which creates Fish +functions). They are active in all interactive sessions. + +### Navigation + + .. cd .. + ... cd ../.. + .... cd ../../.. + ..... cd ../../../.. + ...... cd ../../../../.. + +### Color Overrides + +Force color output for common tools: + + grep grep --color=auto + fgrep fgrep --color=auto + egrep egrep --color=auto + dir dir --color=auto + vdir vdir --color=auto + +### Safety Wrappers + +Add -i (interactive confirmation) to destructive commands: + + cp cp -i + mv mv -i + +### Archives and Networking + + tarnow tar -acf Create compressed archive (auto-detects format) + untar tar -zxvf Extract a gzip-compressed archive + wget wget -c Resume interrupted downloads by default + tb nc termbin.com 9999 Pipe content to termbin.com for quick sharing + +### System Logs + + jctl journalctl -p 3 -xb Show priority-3 (error) journal entries + from the current boot + +--- diff --git a/docs/manual/05-functions/01-file-and-directory.md b/docs/manual/05-functions/01-file-and-directory.md new file mode 100644 index 0000000..80d3219 --- /dev/null +++ b/docs/manual/05-functions/01-file-and-directory.md @@ -0,0 +1,164 @@ +--- +title: File and Directory +manTitle: 5.1 File and Directory +sidebar: + order: 1 +helpKeywords: +- files +--- + +## cat + + Synopsis: cat [args...] + Wraps bat for files with syntax highlighting and line numbers. + Passes directories to ls. Falls back to /usr/bin/cat. + + cat README.md + cat ~/projects/myapp + +## copy + + Synopsis: copy + Wraps cp, stripping trailing slashes from source directories to + prevent unintended nesting inside the destination. + + copy ./mydir/ ~/backup # copies mydir INTO backup, not backup/mydir/ + +## du + + Synopsis: du [--disk|--dir|--dua] [args...] + Smart disk-usage dispatcher: + --disk force duf (disk-level free/used overview) + --dir force dust (per-directory tree breakdown) + --dua force dua (fast space analyzer) + Without flags, routes to the most appropriate tool by context. + + du ~/Downloads + du --disk + +## dusize + + Synopsis: dusize [dir] + Human-readable disk usage for a directory via du -sh. Defaults to cwd. + + dusize ~/Videos + +## lD + + Synopsis: lD [args...] + Lists directories only in long format with icons. Uses eza, falls back + to lsd, then system ls. + + lD ~/projects + +## ls + + Synopsis: ls [args...] + Lists files in long format with icons and hyperlinks. Uses eza, falls + back to lsd, then system ls. + + ls + ls -a ~/projects + +## lsr + + Synopsis: lsr [args...] + Lists files sorted by modification time, oldest first. Uses eza. + +## lss + + Synopsis: lss [args...] + Lists files sorted by size with gradient color scaling. Uses eza. + +## lstree + + Synopsis: lstree [args...] + Full recursive tree view with icons. Uses eza. + + lstree ~/projects/myapp + +## lt + + Synopsis: lt [args...] + Tree view limited to depth 2 with icons. Uses eza. + + lt ~/projects + +## ltr + + Synopsis: ltr [args...] + Lists files sorted by modification time, oldest first, long format with + age-based gradient scaling. Uses eza. + +## lx + + Synopsis: lx [args...] + Lists files sorted by extension, long format. Uses eza. + +## mkdir + + Synopsis: mkdir [args...] + Interactive mkdir that prints a tree of created directories. + Falls back to mkdir -p silently. + + mkdir ~/projects/myapp/src + +## mkcd + + Synopsis: mkcd [-s] + Creates a directory (including parents) and cd into it. Prints a tree + of created dirs by default; -s/--silent suppresses output. + + mkcd ~/projects/newapp/src + +## poke + + Synopsis: poke [file...] + Creates files via touch, automatically creating any missing parent + directories first. + + poke ~/projects/new/src/main.fish + +## rm + + Synopsis: rm [-e [opts] | -S | args...] + Safe rm wrapper routing to trash: + + (no args) List current trash contents + -e/--empty Empty the trash (pass options to trash-empty) + -S/--secure Permanently delete via rm -rf + fstrim (irreversible) + -r/-R/--recursive Move to trash + Move to trash (safe delete) + + Falls back to /usr/bin/rm when trash is unavailable. + + rm file.txt # moves to trash + rm -e # empty trash + rm -S sensitive.pem # permanent delete + +## rg + + Synopsis: rg [args...] + In Kitty, wraps ripgrep with --hyperlink-format=kitty so search + results are clickable file links in the terminal. Falls back to + system rg in any other terminal. All other arguments pass through + unchanged. + + rg "fish_greeting" ~/.config/fish/ + rg -l "TODO" ~/projects/myapp + +## scrub + + Synopsis: scrub [-a] [-d] [-h] + Recursively removes OS metadata, editor artifacts, compiler output, + and dev caches using fd. + + -a/--aggressive Also removes node_modules, logs, .cache, IDE dirs, + AI session artifacts + -d/--dry-run Print what would be removed without deleting + + scrub + scrub -a + scrub -d + +--- diff --git a/docs/manual/05-functions/02-navigation.md b/docs/manual/05-functions/02-navigation.md new file mode 100644 index 0000000..0cc6ff6 --- /dev/null +++ b/docs/manual/05-functions/02-navigation.md @@ -0,0 +1,32 @@ +--- +title: Navigation +manTitle: 5.2 Navigation +sidebar: + order: 2 +helpKeywords: +- nav-fns +--- + +## cdi + + Synopsis: cdi [query] + Interactive directory picker combining zoxide frecency with fzf. + Equivalent to zi. + + cdi myproject + +## clone + + Synopsis: clone [args...] + Clone a git repository into a new Kitty window. Kitty-only. + + clone https://github.com/user/repo.git + +## clonet + + Synopsis: clonet [args...] + Clone a git repository into a new Kitty tab. Kitty-only. + + clonet https://github.com/user/repo.git + +--- diff --git a/docs/manual/05-functions/03-editors-and-viewers.md b/docs/manual/05-functions/03-editors-and-viewers.md new file mode 100644 index 0000000..58caadf --- /dev/null +++ b/docs/manual/05-functions/03-editors-and-viewers.md @@ -0,0 +1,71 @@ +--- +title: Editors and Viewers +manTitle: 5.3 Editors and Viewers +sidebar: + order: 3 +helpKeywords: +- editors +--- + +## edit + + Synopsis: edit [-V|-t] [-e EDITOR] [-c] [-x TEXT] [-n] [-v|-s] [FILE...] + + Opens files in a text editor, choosing a terminal or GUI editor and + resolving a rich chain of fallbacks. With no --visual/--terminal flag the + mode is auto-detected: interactive terminals use the terminal editor + ($EDITOR), while detached invocations (e.g. desktop shortcuts) use the GUI + editor ($VISUAL). Clipboard contents and literal strings can be opened as + throwaway temp files. Editor output is suppressed unless --verbose. + + GUI fallback chain: zed → antigravity-ide → code → kate → kwrite → + gnome-text-editor → gedit + Terminal fallback chain: nvim → vim → micro → nano → vi + + Options: + -V, --visual Force the GUI editor ($VISUAL or fallbacks) + -t, --terminal Force the terminal editor ($EDITOR or fallbacks) + -e, --editor=X Use a specific editor binary X + -c, --clipboard Open the clipboard contents (as a temp file) + -x, --text=STR Open STR as the contents of a new temp file + -n, --new Force a new window/instance (best-effort) + -v, --verbose Print the launch command and editor output + -s, --silent Suppress all output, including the editor's + -h, --help Show this help message + + edit ~/.config/fish/config.fish + edit --visual notes.txt + edit --terminal --new todo.md + edit --editor=code --clipboard + edit --text="hello world" + +## fc + + Synopsis: fc [command_prefix] + Edit the last shell command (or one matching a prefix) in $EDITOR, + then execute the result. Bash-style fc behaviour. + + fc + fc git + +## less + + Synopsis: less [args...] + Pager wrapper with fallback chain: $PAGER -> ov -> less -> more -> cat. + + less /var/log/syslog + +## rawfish + + Synopsis: rawfish [args...] + Launches Fish with NO_TMUX=1, bypassing any tmux auto-attach logic. + Useful when you need a clean shell without session management. + +## view + + Synopsis: view [args...] + Opens files in nvim read-only mode (-R). Falls back to less. + + view /etc/fstab + +--- diff --git a/docs/manual/05-functions/04-git-and-version-control.md b/docs/manual/05-functions/04-git-and-version-control.md new file mode 100644 index 0000000..bf2e8f6 --- /dev/null +++ b/docs/manual/05-functions/04-git-and-version-control.md @@ -0,0 +1,90 @@ +--- +title: Git and Version Control +manTitle: 5.4 Git and Version Control +sidebar: + order: 4 +helpKeywords: +- git +--- + +## auto-pull + + Synopsis: auto-pull [list] + auto-pull add [PATH] + auto-pull remove + auto-pull status + + Manages the registry of repositories that are background fast-forwarded + when you enter them (see "Auto-pull fast-forward" under the C2 component + reference). The fish-config repo is always covered as a baseline. The + registry is machine-local at `$__fish_user_dots_path/auto-pull.list` (defaults + to `~/.config/.user-dots/fish/auto-pull.list`), one absolute path per line, + and is never committed. Registry management works + even when C2 auto-execution is disabled; only the background sync is gated. + + list Show registered repos (default) + add [PATH] Register PATH's git root (default: current repo) + remove Unregister by basename or exact path + status Show enabled/disabled state, repo count, list path + + cd ~/src/qmk_firmware; and auto-pull add + auto-pull add ~/work/api + auto-pull list + auto-pull remove qmk_firmware + +## branch + + Synopsis: branch + Switches to a local branch, or creates it if it does not exist. + + branch feature/new-ui + +## gi + + Synopsis: gi [-h] [-b] [-p] [-s] [-l] [targets...] + Generates .gitignore content from the gitignore.io API with MD5-based + deduplication (patterns already present are not re-appended). + + -b/--boilerplate Append generic boilerplate first + -p/--prompt Prompt interactively for targets + -s/--stdout Print to stdout instead of appending to .gitignore + -l/--list List all available targets + targets Comma-separated or space-separated target names + + gi python,venv + gi -b -p + gi -s node > .gitignore + +## git-clean + + Synopsis: git-clean [-f] + Fetches and prunes the remote, fast-forwards the current branch, then + deletes local branches whose remote tracking branch has been deleted. + Switches to main/master automatically if the current branch is orphaned. + + -f/--force Force-delete unmerged branches too + + git-clean + git-clean --force + +## gitup + + Synopsis: gitup [args...] + Fetches updates from the remote and shows git status. Extra args are + forwarded to git fetch. + + gitup + gitup --all + +## gitui + + Synopsis: gitui [args...] + Launches gitui with the Catppuccin Frappe theme pre-applied. + +## hist + + Synopsis: hist + Searches shell history with fzf, inserts the selection into the command + line, and copies it to the clipboard via wl-copy. + +--- diff --git a/docs/manual/05-functions/05-package-management.md b/docs/manual/05-functions/05-package-management.md new file mode 100644 index 0000000..9c15231 --- /dev/null +++ b/docs/manual/05-functions/05-package-management.md @@ -0,0 +1,60 @@ +--- +title: Package Management +manTitle: 5.5 Package Management +sidebar: + order: 5 +helpKeywords: +- package-manager +- packages +--- + +## pkg + + Synopsis: pkg [-h] [-i|-u] [package...] + Installs or removes packages using the detected system package manager. + Supports: paru, yay, pacman, apt, dnf, zypper, yum, brew, pkg. + + (no flag) Auto mode: installs missing packages, removes installed ones + -i/--install Force install + -u/--uninstall Force uninstall + + pkg firefox # auto: install if missing, remove if present + pkg -i ripgrep fd # force install + pkg -u cowsay # force uninstall + + The package-installed check uses the correct query for each PM: + pacman/paru/yay pacman -Qi + apt dpkg -s + dnf/zypper/yum rpm -q + brew brew list + pkg pkg info + +## search + + Synopsis: search [args...] + Interactive AUR package search and install via paru or yay. + Arch Linux only. + + search neovim + +## upgrade + + Synopsis: upgrade + Full system upgrade via paru -Syu --noconfirm or yay -Syu --noconfirm. + Arch Linux only. + +## cleanup + + Synopsis: cleanup + Lists and removes orphan packages via pacman, logging their names to + ~/.removed_orphans. Arch Linux only. + +## parur + + Synopsis: parur + Opens an fzf picker of all installed packages (with pacman -Qi previews), + then removes the selected packages via paru or yay. Arch Linux only. + + parur + +--- diff --git a/docs/manual/05-functions/06-dependency-management.md b/docs/manual/05-functions/06-dependency-management.md new file mode 100644 index 0000000..e9b4882 --- /dev/null +++ b/docs/manual/05-functions/06-dependency-management.md @@ -0,0 +1,47 @@ +--- +title: Dependency Management +manTitle: 5.6 Dependency Management +sidebar: + order: 6 +helpKeywords: +- deps +--- + +## fish-deps + + Synopsis: fish-deps [status|install|update|sync] + Unified command for managing all tools this configuration depends on. + + status (default) Show installed/missing status grouped by tier + install Interactively install each missing dependency + update Update all installed dependencies + sync Install missing deps, then update all + + Install method priority (highest to lowest): + 1. git+cargo source build (fish shell itself) + 2. cargo (Rust tools — gets latest crate version) + 3. system PM (paru/apt/brew/etc.) + 4. git clone (fzf) + 5. curl installer (starship, fisher, uv) + + When multiple methods are available you are prompted to choose. + + Dependencies are grouped into three tiers: + + Required fish, fzf, zoxide + Integrations wakatime, tailscale + Recommended cargo, starship, uv, direnv, paru, yay, eza, lsd, bat, + btop, dust, duf, prettyping, ov, ripgrep, lazygit, + lazydocker, trash, kitty, wezterm, python3, yt-dlp + + fish-deps + fish-deps install + fish-deps update + fish-deps sync + +## check_fish_deps + + Synopsis: check_fish_deps + Backwards-compatibility alias for `fish-deps status`. + +--- diff --git a/docs/manual/05-functions/07-system-and-monitoring.md b/docs/manual/05-functions/07-system-and-monitoring.md new file mode 100644 index 0000000..9f47fc3 --- /dev/null +++ b/docs/manual/05-functions/07-system-and-monitoring.md @@ -0,0 +1,63 @@ +--- +title: System and Monitoring +manTitle: 5.7 System and Monitoring +sidebar: + order: 7 +helpKeywords: +- system +--- + +## top + + Synopsis: top [args...] + Launches btop as a modern resource monitor. Falls back to system top. + +## swapstat + + Synopsis: swapstat + Displays a colorized memory report: kernel swappiness, zRAM compression + ratio, zRAM device details, and active swap priorities. + +## sbver + + Synopsis: sbver [--brief] + Verifies Secure Boot signatures on all EFI binaries tracked by sbctl. + Color-codes results: green checkmark (verified), red X (unsigned). + Prints a pass/fail summary. + + --brief Suppress per-file output, show only the summary + + sbver + sbver --brief + +## ports + + Synopsis: ports + Lists active TCP listeners with lsof, showing port/address without + hostname resolution. + +## screensleep + + Synopsis: screensleep + Turns off the display via KDE PowerDevil's "Turn Off Screen" action, + invoked through busctl. + +## lock + + Synopsis: lock + Locks the current desktop session using loginctl lock-session. + +## sudo-toggle + + Synopsis: sudo-toggle + Toggles the sudo NOPASSWD rule on/off via /etc/sudoers.d/nofail-toggle. + Useful for automated tasks that would otherwise require password entry. + +## limine-edit + + Synopsis: limine-edit + Opens /boot/limine.conf in sudoedit, then automatically re-enrolls the + config hash, runs CachyOS boot hooks, and re-signs Secure Boot files. + Combines the edit and sign steps into a single command. + +--- diff --git a/docs/manual/05-functions/08-terminal-management.md b/docs/manual/05-functions/08-terminal-management.md new file mode 100644 index 0000000..a4193df --- /dev/null +++ b/docs/manual/05-functions/08-terminal-management.md @@ -0,0 +1,60 @@ +--- +title: Terminal Management +manTitle: 5.8 Terminal Management +sidebar: + order: 8 +helpKeywords: +- terminal-mgmt +--- + +## tab + + Synopsis: tab [args...] + Opens a new tab in Kitty (kitty @ launch --type=tab), WezTerm + (wezterm cli spawn), or Konsole. Uses current working directory, + or $cdto if set. + + tab + +## split + + Synopsis: split [-h|-v] [command...] + Opens a new pane in Kitty or WezTerm, optionally running a command. + + -h/--horizontal (default) Split below + -v/--vertical Split to the right + + split + split -v nvim README.md + +## spwin + + Synopsis: spwin [args...] + Spawns a new terminal OS window in Kitty (via spawn-window.sh or + kitty @ launch --type=os-window) or WezTerm (wezterm cli spawn --new-window). + +## detach + + Synopsis: detach [-h] [--version] [args...] + Runs a command fully detached via nohup with stdout/stderr discarded. + The command survives the current session. + + detach rsync -a ./data remote:/backup/ + +## bkg + + Synopsis: bkg [args...] + Launches a command in the background via nohup with output discarded. + Simpler than detach; no version flag. + + bkg firefox + +## ssh + + Synopsis: ssh [args...] + In Kitty, wraps ssh with kitten ssh for better terminal integration + (multiplexing, copy/paste support). Falls back to system ssh elsewhere. + + ssh user@host + +--- diff --git a/docs/manual/05-functions/09-clipboard.md b/docs/manual/05-functions/09-clipboard.md new file mode 100644 index 0000000..c2fe7f0 --- /dev/null +++ b/docs/manual/05-functions/09-clipboard.md @@ -0,0 +1,32 @@ +--- +title: Clipboard +manTitle: 5.9 Clipboard +sidebar: + order: 9 +helpKeywords: +- clipboard +--- + +## y + + Synopsis: y [text...] + Copies text to the clipboard via wl-copy (Wayland) or xclip (X11). + Reads from stdin if no arguments given. + + y "hello world" + ls | y + cat file.txt | y + +## p + + Synopsis: p [args...] + Outputs clipboard contents to stdout. + + p | grep foo + p > file.txt + +## paste + + Alias for p. Identical behaviour. + +--- diff --git a/docs/manual/05-functions/10-network.md b/docs/manual/05-functions/10-network.md new file mode 100644 index 0000000..46dd3de --- /dev/null +++ b/docs/manual/05-functions/10-network.md @@ -0,0 +1,44 @@ +--- +title: Network +manTitle: 5.10 Network +sidebar: + order: 10 +helpKeywords: +- network +--- + +## gip + + Synopsis: gip + Fetches and prints both the public IPv4 and IPv6 address via + icanhazip.com. + +## gip4 + + Synopsis: gip4 + Fetches and prints the public IPv4 address. + +## gip6 + + Synopsis: gip6 + Fetches and prints the public IPv6 address. Returns 1 if IPv6 is + unavailable. + +## ping + + Synopsis: ping [args...] + Wraps prettyping with --nolegend. Pass --legend to show the legend. + Falls back to system ping. + + ping google.com + +## qr + + Synopsis: qr [text...] + Generates a UTF-8 QR code from text or stdin. Uses qrencode locally; + falls back to the qrenco.de API. + + qr "https://example.com" + echo "https://example.com" | qr + +--- diff --git a/docs/manual/05-functions/11-pager-and-logging.md b/docs/manual/05-functions/11-pager-and-logging.md new file mode 100644 index 0000000..872fca6 --- /dev/null +++ b/docs/manual/05-functions/11-pager-and-logging.md @@ -0,0 +1,47 @@ +--- +title: Pager and Logging +manTitle: 5.11 Pager and Logging +sidebar: + order: 11 +helpKeywords: +- logging +--- + +## logs + + Synopsis: logs [-c ] + Interactively browses terminal log files sorted newest-first using fzf. + + -c/--category Filter to: scrollback, paru, or yay + + Keybindings inside the fzf browser: + Enter Open in $PAGER + Ctrl+E Open in $EDITOR + Ctrl+D Delete (with confirmation) + ? Toggle keybind help overlay + + Paru and yay logs open in ov with syntax highlighting and sticky section + headers. Scrollback logs open in ov with per-command sticky prompt headers + based on OSC 133 markers. + + logs + logs -c paru + logs -c scrollback + +## smart_exit + + Synopsis: smart_exit [-n] + Closes the shell session. In Kitty, captures the terminal scrollback to + a timestamped log file in $SCROLLBACK_HISTORY_DIR before exiting. + Automatically prunes the oldest logs when the count exceeds + $SCROLLBACK_HISTORY_MAX_FILES. + + -n/--no-log Exit without saving a scrollback log + + The exit builtin is wired to smart_exit for interactive sessions. + Typing exit or Ctrl+D behaves identically to smart_exit. + + smart_exit + smart_exit --no-log + +--- diff --git a/docs/manual/05-functions/12-ai-and-developer-tools.md b/docs/manual/05-functions/12-ai-and-developer-tools.md new file mode 100644 index 0000000..21bbf6b --- /dev/null +++ b/docs/manual/05-functions/12-ai-and-developer-tools.md @@ -0,0 +1,116 @@ +--- +title: AI and Developer Tools +manTitle: 5.12 AI and Developer Tools +sidebar: + order: 12 +helpKeywords: +- ai +--- + +## agy + + Synopsis: agy [args...] + Wrapper for the agy Antigravity AI CLI. Before launching, delegates to + agents-init --agents to ensure AGENTS/ is scaffolded and CLAUDE.md is + symlinked to AGENTS/AGENTS.md in the current project, then forwards all + arguments verbatim to the real agy binary. Command shadow (C1): when + __fish_config_op_aliases (or the master) is disabled, the call is + passed through to the real agy binary unchanged. + + agy chat + agy resume + +## antigravity-ide + + Synopsis: antigravity-ide [args...] + Runs the antigravity-ide editor with warnings filtered. + +## agents-init + + Synopsis: agents-init [--agents | --plugins] + Scaffold an AGENTS/ sub-repository for tracking agent specs, plans, specs, + and dev logs. Creates AGENTS/ as a standalone git repo, moves any existing + AGENTS.md into it, and replaces it with a relative symlink (plus + CLAUDE.md -> AGENTS/AGENTS.md so Claude Code picks up the shared agent + instructions). Consolidates plans/ and specs/ directly under AGENTS/ + (merging any legacy docs/plans, docs/superpowers/plans, or old + AGENTS/plugins/ locations into the canonical AGENTS/), creates + AGENTS/devlogs/, and wires docs/superpowers/{plans,specs} symlinks back to + them. Adds managed paths to .gitignore and auto-commits every change inside + the AGENTS/ sub-repo; pulls first when the sub-repo has an upstream. + Fully idempotent: a second run produces no output and no new commits. + Flags: --agents re-runs only the AGENTS.md / symlink step; --plugins + re-runs only the plans/specs/devlogs wiring step. Called automatically by + the claude and agy wrappers on every invocation. + + Structure versioning: each AGENTS/ repo carries a self-contained version + bumper. AGENTS/.version holds MAJOR.MINOR.PATCH (seeded 1.0.0). Committed + git hooks under AGENTS/.agents-tools/ (wired via core.hooksPath) bump it on + every commit: MINOR (resetting PATCH) when the tracked directory set + changes, PATCH otherwise; MAJOR is manual-only. A prepare-commit-msg hook + appends "(vX.Y.Z)" to the commit subject. Downstream tooling can read + AGENTS/.version - a changed MINOR field signals a structure change. Because + core.hooksPath is a single setting, the local override would otherwise + shadow your global hooks; after bumping the version, each shim chains + (execs) to the global/system core.hooksPath hook of the same name so global + pre-commit / prepare-commit-msg hooks (e.g. ggshield, Git LFS) still run. + The script and hooks are shipped from scripts/agents-tools/ and refreshed + when their version marker is stale. + + agents-init + agents-init --agents + agents-init --plugins + +## claude + + Synopsis: claude [args...] + Wrapper for the claude CLI. Before launching, delegates to agents-init + --agents to ensure AGENTS/ is scaffolded and CLAUDE.md is symlinked to + AGENTS/AGENTS.md in the current project, then forwards all arguments + verbatim to the real claude binary. Command shadow (C1): when + __fish_config_op_aliases (or the master) is disabled, the call is + passed through to the real claude binary unchanged. + + claude + claude --resume + +## claude-docs + + Synopsis: claude-docs + Invokes Claude Code to analyze recent repository changes and update + README.md, ensuring all documented features and examples are accurate. + +## claude-pr + + Synopsis: claude-pr + Invokes Claude Code to run the full PR workflow: create branch, + conventional commit, verification, push, and open a PR with a manual + verification checklist. + +## qc + + Synopsis: qc [prompt...] + Quick-chat wrapper around the aichat LLM CLI that defaults to the "cli" + role - a system prompt tuned for concise, terminal-friendly output. On + first use it installs the bundled role by symlinking + scripts/cli-agent.md to $XDG_CONFIG_HOME/aichat/roles/cli.md (creating + the directory if needed). Inherits every aichat flag and tab completion + (--wraps aichat); passing --role/-r overrides the default role, so qc + forwards to aichat unchanged. The function is only defined when aichat + is installed. Run qc --help for aichat's full flag reference with the + command name rewritten to qc. + + qc "how do I list open ports on linux?" + qc -m ollama:llama3 "explain this error" + qc --role coder "refactor this function" + +## superpowers + + Synopsis: superpowers [on|off] [-g] + Enables or disables the Superpowers plugin for Antigravity and Claude + Code at workspace/project scope (default) or user scope (-g/--global). + + superpowers on + superpowers off -g + +--- diff --git a/docs/manual/05-functions/13-media-and-utilities.md b/docs/manual/05-functions/13-media-and-utilities.md new file mode 100644 index 0000000..49c7f58 --- /dev/null +++ b/docs/manual/05-functions/13-media-and-utilities.md @@ -0,0 +1,54 @@ +--- +title: Media and Utilities +manTitle: 5.13 Media and Utilities +sidebar: + order: 13 +helpKeywords: +- media +--- + +## dng2avif + + Synopsis: dng2avif [-i ] [-o ] [-q ] [-s ] [input.dng] + Converts a DNG raw image to a 10-bit HDR AVIF using an ImageMagick, + ffmpeg, avifenc pipeline with metadata sync via exiftool. + + -i/--input Input file (or positional arg) + -o/--output Output file (default: same name, .avif extension) + -q/--quality Quality 0-100 (default 92) + -s/--speed Encoding speed 0-10 (default 3) + + dng2avif photo.dng + dng2avif -q 85 -s 5 -i shot.dng -o out.avif + +## steam-dl + + Synopsis: steam-dl + Launches Steam under systemd-inhibit, preventing the system from going + idle or sleeping while a download is in progress. + +## spark + + Synopsis: spark [--min=] [--max=] [numbers...] + Renders a Unicode sparkline bar chart for a sequence of numbers. + Reads from stdin if no numbers are given. + + spark 1 1 2 5 14 42 + echo "3 7 2 9 1" | spark + +## yt-dlp + + Synopsis: yt-dlp [args...] URL [URL...] + Wraps yt-dlp, prepending sane defaults: --sponsorblock-remove all, + --embed-subs, --embed-metadata, and --embed-thumbnail. Each default + is suppressed when you already pass that flag, its alias, or its + negation (e.g. --no-embed-thumbnail drops the thumbnail default; + --no-sponsorblock or your own --sponsorblock-remove drops ours). All + other arguments pass through unchanged, and --help falls through to + real yt-dlp. Opinionated component (C1 aliases); when disabled it + passes straight through to the system yt-dlp. + + yt-dlp dQw4w9WgXcQ + yt-dlp --no-embed-thumbnail dQw4w9WgXcQ + +--- diff --git a/docs/manual/05-functions/14-miscellaneous.md b/docs/manual/05-functions/14-miscellaneous.md new file mode 100644 index 0000000..f7049db --- /dev/null +++ b/docs/manual/05-functions/14-miscellaneous.md @@ -0,0 +1,286 @@ +--- +title: Miscellaneous +manTitle: 5.14 Miscellaneous +sidebar: + order: 14 +helpKeywords: +- miscfns +--- + +## config-help + + Synopsis: config-help [SECTION] + config-help [SECTION] --html + config-help [SECTION] --man + config-help -h | --help + + Opens the offline fish shell configuration manual. Without flags, opens + the Markdown source in the best available pager (ov > bat > man > less > + cat). If SECTION is given, jumps to the first heading matching that + keyword (case-insensitive; checks fish-config.index aliases first). + + Flags: + --html / -w Open docs/html/index.html in the default browser. + If SECTION is given, opens at the matching anchor. + Detects the browser via xdg-mime x-scheme-handler/https, + then known binaries, then xdg-open as last resort. + Respects $fish_help_browser and $BROWSER. + --man / -m Open docs/fish-config.1 via man -l directly. + If SECTION is given, jumps to the nearest match. + --help / -h Print usage and navigation key reference. + + config-help keybindings + config-help pkg + config-help --html + config-help pkg --html + config-help --man + config-help pkg --man + + Also available as: help config [SECTION] [FLAGS] + +## open-url + + Synopsis: open-url [-s|--silent] [-v|--verbose] + open-url -h | --help + + Opens a URL or file:// URI in the best available graphical web browser, + backgrounded so it never blocks the terminal. Resolves a real browser + binary rather than deferring to xdg-open, whose MIME dispatch can hand + local text/html files to non-browser apps (e.g. ebook readers). + + Silent by default: prints nothing on success (errors always go to + stderr). Pass --verbose / -v to report which browser is launched; + --silent / -s is accepted for explicitness. + + Resolution order: + 1. $fish_help_browser (explicit override) + 2. $BROWSER (validated; errors if not a command) + 3. xdg-mime default handler for x-scheme-handler/https + 4. First known browser binary found in a built-in list + 5. xdg-open (last resort) + + open-url https://git.rootiest.dev/rootiest/fish-config + open-url "file://$HOME/.config/fish/docs/html/index.html" + + Used internally by config-help --html. + + Typo abbreviation: url-open (expands to open-url on space/enter). + +## repo-open + + Synopsis: repo-open [-p|--print] [-r|--root] + repo-open -h | --help + + Opens the web page for the current repository's `origin` remote in a + browser (via open-url). Deep-links to the current branch when it exists + on the remote — falling back to the remote's default branch (main/master) + otherwise — and to the current sub-directory when run below the repo root. + + The remote URL is normalized from HTTPS and SSH/scp forms + (git@host:owner/repo.git, ssh://…, https://…). The web path layout is + provider-specific; the provider is resolved in order: + + 1. git config browse.provider (per-repo or --global override) + 2. Hostname heuristic (github / gitlab / gitea / bitbucket; + codeberg → gitea) + 3. Default: github-style layout + + Self-hosted hosts the heuristic can't classify (a Gitea/GitLab instance + on a custom domain) need a one-time override: + + git config browse.provider gitea + + Flags: + --print / -p Print the resolved URL instead of opening it. + --root / -r Ignore the current sub-directory; link to the repo root. + --help / -h Show usage. + + repo-open + repo-open --print + repo-open --root + + Typo abbreviation: open-repo (expands to repo-open on space/enter). + +## config-update + + Synopsis: config-update [-h] [-n] [-f] + + Pulls the latest fish configuration from the upstream repository + (https://git.rootiest.dev/rootiest/fish-config.git) into ~/.config/fish. + The remote URL is hard-coded, so this works on fresh clones with no git + remote configured. All git output is suppressed; colored messages report + fetch and merge status. After a successful pull, run `exec fish` to + reload. + + Flags: + --dry-run / -n Fetch and show available commits without applying them. + --force / -f Stash local changes, pull, then restore the stash. + --help / -h Show usage. + + config-update + config-update --dry-run + config-update --force + +## config-settings + + Synopsis: config-settings [-h] + + Opens an interactive TUI for managing fish configuration settings across + four pages, without having to type or remember variable names. Tab cycles + forward through the pages; Shift-Tab cycles backward. + + Universal — opinionated category toggles (C1–C6) + master, persistent (set -U) + Session — the same toggles, current shell only (set -g) + Sponge — sponge history-scrubbing settings: delay, successful exit + codes, purge-only-on-exit, allow-previously-successful, and + extra sensitive variable-name tokens + Paths — scrollback log directory, scrollback max files, the + user-dots path, and the user-dots convenience symlink toggle + (Dots link) + + Toggle rows use ← → (or h/l) along an OFF ← DEFAULT → ON scale; DEFAULT + erases the variable so the master switch / built-in default applies. Value + rows (the path/int/list settings on the Sponge and Paths pages) use Enter to + edit inline; ← / h clears the value back to its default. List rows (e.g. + Extra secret, OK codes) accept values separated by commas and/or whitespace + — "A, B", "A,B" and "A B" all yield the same two entries. Changes apply + immediately. Always available regardless of the __fish_config_opinionated + master state. + + The Sponge and Paths pages always write universal variables — these are + persistent, set-and-forget settings with no per-session scope. Editing a + scrollback row updates both the __fish_scrollback_history_* source-of-truth + variables and the exported SCROLLBACK_HISTORY_* mirrors, so the AUR/tmux/ + zellij log wrappers (which read the exported names) see the change in the + running session. + + The panel adapts to the terminal width automatically, selecting from + four layout tiers (with a 6-column buffer on each side before stepping + up to the next tier) and horizontally centering the box. The panel + redraws within ~0.3 s of a terminal resize with no keypress required. + + COLUMNS >= 90 → 78-wide panel (most detail) + COLUMNS >= 86 → 74-wide panel + COLUMNS >= 82 → 70-wide panel + COLUMNS < 82 → 52-wide panel (default) + + Navigation: + ↑ ↓ / k j Move cursor + ← → / h l Toggle rows: OFF ← DEFAULT → ON + ← / h Value rows: clear to default + Enter Value rows: edit inline (Sponge / Paths pages) + Tab / S-Tab Next / previous page + q / Escape Exit + + Flags: + --help / -h Show usage. + + config-settings + +## config-toggle (deprecated) + + Deprecated alias for config-settings. Prints a deprecation notice to + stderr, then delegates all arguments to config-settings. + + config-toggle + +## bash + + Synopsis: bash [args...] + Switches to bash, with XDG config applied. On exit, $SHELL is reset + back to fish. + +## bd-pull + + Synopsis: bd-pull + Fetches unlinked Gitea issues and creates local Beads entries, updating + issue titles with the assigned Beads IDs. + Requires $GITEA_TOKEN and $GITEA_URL to be set. + + bd-pull rootiest/fish-config + +## cheat + + Synopsis: cheat [args...] + Displays a colorized cheatsheet using cheat -c, falls back to tldr, + then man. + + cheat tar + cheat git + +## cffetch / ffetch + + Synopsis: cffetch [args...] / ffetch [args...] + Clears the screen and displays system information via fastfetch with + the custom config at ~/.fastfetch.jsonc. Falls back to neofetch. + +## dockup + + Synopsis: dockup [-h] [directory] + Pulls latest Docker images, restarts services in the given Docker + Compose project, and prunes dangling images. + + dockup ~/myapp + +## joplin + + Synopsis: joplin [args...] + Runs the Joplin CLI with Node.js deprecation warnings suppressed. + + joplin ls + +## ld + + Synopsis: ld + Launches lazydocker targeting the currently active Docker context, + detected via docker context inspect. + +## replay + + Synopsis: replay + Runs Bash commands and replays any resulting changes to environment + variables, aliases, and the working directory back into the current + Fish session. Useful for sourcing Bash scripts. + + replay "source ~/.bashrc" + replay "export FOO=bar" + +## kitty-logging + + Synopsis: kitty-logging [install|uninstall|status|dismiss] [-h] + + Manages the Kitty scrollback watcher that powers C5 logging. Ships a + canonical watcher and symlinks it into the Kitty config directory (so it + always tracks the source), wiring it into kitty.conf through a + sentinel-marked managed block. Commenting out any conflicting watcher line + avoids double-capture. + + Commands: + install Symlink the watcher and add the managed block + uninstall Remove the managed block and the watcher symlink + status Show wiring, installed watcher version, and C5 state + dismiss Stop the per-session setup reminder + + Runtime capture stays governed by the C5 .logging_disabled sentinel, so + disabling __fish_config_op_logging makes the watcher inert without + uninstalling. Install affects new Kitty windows only. + + Example: + kitty-logging install + kitty-logging status + +## tmux-clean + + Synopsis: tmux-clean + Kills all detached (unattached) tmux sessions, leaving attached ones + running. + +## wake-lock + + Synopsis: wake-lock [args...] + Runs a command under systemd-inhibit, preventing the system from going + idle or sleeping until the command completes. + + wake-lock rsync -avz src/ dest/ + +--- diff --git a/docs/manual/05-functions/index.md b/docs/manual/05-functions/index.md new file mode 100644 index 0000000..de97101 --- /dev/null +++ b/docs/manual/05-functions/index.md @@ -0,0 +1,10 @@ +--- +title: Functions Reference +manTitle: 5. FUNCTIONS REFERENCE +sidebar: + order: 5 +helpKeywords: +- functions +--- + + diff --git a/docs/manual/06-dependency-catalog.md b/docs/manual/06-dependency-catalog.md new file mode 100644 index 0000000..760c5ce --- /dev/null +++ b/docs/manual/06-dependency-catalog.md @@ -0,0 +1,73 @@ +--- +title: Dependency Catalog +manTitle: 6. DEPENDENCY CATALOG +sidebar: + order: 6 +helpKeywords: +- catalog +- deps-catalog +--- + +fish-deps manages these tools. Run `fish-deps` to check status, or +`fish-deps install` to install missing ones. + +## Required + + fish Fish shell >= 4.0 + fzf Fuzzy finder + zoxide Smart cd with frecency + +## Integrations + + wakatime Developer time tracking + tailscale Mesh VPN client + +## Recommended + + cargo Rust toolchain (via rustup); used by fish-deps to install + Rust-based tools and to build fish from source. All paths + are gated on type -q cargo and degrade gracefully. + starship Cross-shell prompt; loaded via type -q starship guard. + Without it the Catppuccin nim-style fallback prompt activates. + uv Python package and project manager (Astral); used by the + fish-from-source build path in fish-deps. All consumers + degrade gracefully without it. + direnv Per-directory environment loading; integration is fully + guarded with type -q direnv. Without it the direnv hook + is simply not loaded and auto-venv activates normally. + paru AUR helper (Arch only; preferred); guarded throughout — + non-Arch systems silently skip AUR-specific paths. + yay AUR helper (Arch only; fallback to paru); same guards apply. + eza Modern ls replacement + lsd ls replacement (fallback to eza) + bat Syntax-highlighted cat + btop Modern resource monitor + dust Disk usage tree (Rust) + duf Disk usage/free overview + prettyping Colorized ping wrapper + ov Modern pager (replaces less) + ripgrep Fast line search + lazygit Terminal git UI + lazydocker Terminal docker UI + trash Safe delete (trash-cli) + kitty GPU-accelerated terminal (primary) + wezterm GPU-accelerated terminal (alternative) + python3 Standalone interpreter — used by the paru/yay log cleaner. + Note: uv does not provide python3 on PATH, and Arch's base + does not include it, so it is listed separately. All + consumers degrade gracefully without it. + yt-dlp Video/media downloader; backs the yt-dlp wrapper function. + Optional — the wrapper falls back to the system yt-dlp and + the rest of the config works without it. + +## Install Methods + +The install priority for each tool: + + cargo Rust tools (eza, lsd, bat, dust, ov, ripgrep, trashy, zoxide, + starship) — always gets the latest crate version + system PM paru / apt / brew / dnf / etc. — for tools without a crate + git clone fzf — installed from GitHub to ~/.fzf/ + curl starship installer, fisher bootstrap, uv installer + +--- diff --git a/docs/manual/07-customization.md b/docs/manual/07-customization.md new file mode 100644 index 0000000..c802fc7 --- /dev/null +++ b/docs/manual/07-customization.md @@ -0,0 +1,438 @@ +--- +title: Customization +manTitle: 7. CUSTOMIZATION +sidebar: + order: 7 +helpKeywords: +- customization +- customize +--- + +## Machine-local Configuration + +Place machine-specific settings that should not be committed to git in: + + $__fish_user_dots_path/local.fish + +`__fish_user_dots_path` defaults to `~/.config/.user-dots/fish`. Set a +custom location with: + + set -U __fish_user_dots_path /path/to/your/dots/fish + +Typical uses: additional PATH entries, local aliases, hostname-specific env +vars, work-specific tool configs. + +For convenience, a git-ignored `user-dots` symlink in the fish config +directory tracks `$__fish_user_dots_path` so the overlay can be browsed from +`~/.config/fish/`. It is created if missing and repointed if the path changes. +Opt out by setting `__fish_user_dots_symlink` to a falsy value, or toggling +"Dots link" off on the config-settings Paths page — this stops generation and +removes any existing link. It only ever manages a symlink and never clobbers a +real file or directory at that path. + +## Secrets and API Keys + + $__fish_user_dots_path/secrets.fish + +Store API tokens, GPG keys, private credentials here. This file is never +committed. It is sourced by local.fish directly, not by config.fish. + +`local.fish` is sourced at the end of config.fish on every interactive +session, so it and its companion secrets.fish can override anything set +earlier. + +## Overriding Configuration Variables + +Any variable set in local.fish after the main config loads takes effect. +Example: to increase the scrollback history limit: + + # in local.fish + set -gx SCROLLBACK_HISTORY_MAX_FILES 200 + +## Fish Universal Variables + +Some settings (fzf colors, theme) are stored in fish_variables via +`set -U`. These are machine-local and git-ignored. Do not commit +fish_variables. + +## Opinionated Components (Minimal Mode) + +Every opinionated piece of this config is active by default but can be +switched off through six category opt-out variables, each evaluated via +__fish_variable_check. Set a variable to any falsy value (0, false, no, +off, n) to disable its category; erase it or set a truthy value (1, true, +yes, on, y) to re-enable. Unset means enabled. + +An explicit per-category truthy value takes precedence over the master +switch: setting __fish_config_opinionated=0 disables all unset categories, +but a category with an explicit truthy value remains enabled regardless. + + Variable Disables + ------------------------------ ------------------------------------ + __fish_config_op_aliases Command shadows and flag injection: + ls->eza, cat->bat, cd->zoxide, + rm->trash, less->ov, top->btop, + ping->prettyping, ssh->kitten, + du->duf/dust, mkdir/bash wrappers, + history timestamps, grep/cp/mv/wget + flag injection, help intercept, claude + AGENTS.md auto-link + __fish_config_op_autoexec Startup side-effects: Fisher + bootstrap, theme apply, paru/yay + wrapper generation, auto venv + activation, WakaTime hook + __fish_config_op_overrides Key and env overrides: Vi mode, + exit->smart_exit, PAGER/MANPAGER, + CDPATH, bang-bang system, autopair, + puffer, starship prompt, theme + colors, FZF_DEFAULT_OPTS, right + prompt + __fish_config_op_integrations Terminal/tool coupling: Kitty/ + WezTerm window abbreviations, done + notifications, spwin/tab/split, + hist, logs, upgrade, WakaTime + __fish_config_op_logging Logging & capture: scrollback + capture on exit, paru/yay AUR log + wrappers, Kitty watcher capture; + sentinel file coordinates + cross-process state + __fish_config_op_greeting Greeting & first-run UI: per-session + fish_greeting override (defines empty + function late in config.fish to + suppress distro greetings such as + CachyOS fastfetch); first-run welcome + banner in conf.d/first_run.fish + +Examples: + + # Disable command shadows only (rm becomes plain rm again): + set -U __fish_config_op_aliases off + + # Full minimal mode — disable all six categories at once: + set -U __fish_config_opinionated 0 + + # Re-enable everything: + set -Ue __fish_config_opinionated + + # Minimal mode but keep the greeting: + set -U __fish_config_opinionated 0 + set -U __fish_config_op_greeting 1 + # (erase both to go back to full-flavor defaults) + +For an interactive alternative to setting these variables by hand, run +config-settings — a full-screen TUI that flips any category (including C5 +logging) on or off, per session or universally. See its entry in Section 5. + +Notes: + + - Command shadows (rm, cat, ls, ...) react immediately; conf.d-level + components (bindings, prompt, abbreviations, hooks) take effect in + new shells. + - With aliases disabled, rm falls back to bare `command rm` — files + are deleted permanently, not trashed. + - Disabled integration commands (spwin, tab, split, hist, logs, + upgrade) print an error naming the variable that disabled them. + - On CachyOS, the distro fish config's own aliases, history override, + and bang-bang bindings are stripped per category as well. + +### Component Reference + +The following tables detail every component in each category. Use this +reference to understand exactly which behaviors change when you toggle a +category variable. + +#### C1 — Command Shadows + +Disabling __fish_config_op_aliases restores standard system behavior for +all of these commands. + + Command / Alias Active behavior Disabled fallback + ─────────────────────────────────────────────────────────────────────────── + ls eza -l -a --icons --hyperlink system ls + cat bat syntax-highlighted; dirs → ls /usr/bin/cat + cd zoxide frecency-based navigation fish builtin cd + rm moves files to trash (recoverable) command rm (permanent) + less $PAGER → ov → less → more → cat system less + du duf (disk overview) or dust (dir tree) system du + top btop resource monitor system top + ping prettyping --nolegend animation system ping + ssh kitten ssh in Kitty terminal system ssh + rg rg --hyperlink-format=kitty system rg + mkdir verbose path-tree display on creation mkdir -p silently + bash XDG bashrc + $SHELL reset on exit system bash + history timestamps prepended to every entry fish builtin history + cp / mv forced -i confirmation prompt cp / mv unmodified + wget forced --continue (resume downloads) system wget + grep/fgrep/egrep forced --color=auto system grep variants + dir / vdir forced --color=auto system dir / vdir + help config intercepts "help config" → config-help fish builtin help + claude auto-links AGENTS.md as CLAUDE.md before launch command claude + edit multi-editor launcher (GUI/term + fallbacks) $EDITOR/nvim/nano/vi + +When C1 is disabled, `rm` uses bare `command rm` with no wrapper — files +are permanently deleted, not trashed. There is no intermediate safety net. + +#### C2 — Startup Side-Effects + +These run automatically without any user action. Disabling +__fish_config_op_autoexec prevents all of them. + + Component Trigger What it does + ─────────────────────────────────────────────────────────────────────────── + Fisher bootstrap First shell only Downloads and installs fisher + Fisher update After bootstrap Installs all fish_plugins entries + Catppuccin Mocha theme First shell only Applies theme via fish_config + paru wrapper Every startup Writes ~/.local/bin/paru wrapper + yay wrapper Every startup Writes ~/.local/bin/yay wrapper + Python venv activation On every cd Sources .venv/bin/activate.fish + WakaTime command hook On every command Reports to WakaTime API + Auto-pull fast-forward On entering a repo Background ff-only git pull + user-dots symlink Every startup Links $__fish_config_dir/user-dots + to $__fish_user_dots_path + +When C2 is disabled: no Fisher install, no theme application, no paru/yay +wrapper generation, no automatic venv activation, no WakaTime reporting, +no auto-pull (the PWD handler is never registered), and the user-dots +convenience symlink is not created. The symlink is git-ignored and only ever +managed as a symlink — a real file or directory at that path is left untouched. +The symlink has its own opt-out independent of C2: set __fish_user_dots_symlink +to a falsy value (or toggle "Dots link" off on the config-settings Paths page) +to stop generating it and remove any existing link — honoured even when C2 is +enabled. Managed by the __fish_user_dots_link helper. +The first-run completion marker (__fish_config_first_run_complete) is still +set so the init does not re-run on subsequent shells. + +Python venv activation fires on every directory change. If a directory uses +direnv (.envrc present), direnv takes priority and auto-venv is skipped for +that directory. + +Auto-pull fast-forwards opted-in repositories in the background when you cd +into them. The fish-config repo is always covered; other repos are added with +the `auto-pull` command (see its entry in the functions reference). It only +ever fast-forwards a clean repo whose branch has an upstream — never rebases, +merges, or overwrites work — so it is a no-op on dirty trees, divergent +branches, or repos without a remote. The handler fires once per repo entry +(not on every sub-directory cd). The registry is machine-local at +`$__fish_user_dots_path/auto-pull.list` (defaults to `~/.config/.user-dots/fish/auto-pull.list`) and is never committed. + +#### C3 — Key and Environment Overrides + +These change fundamental shell behavior: how keys work, which pager opens, +and what the prompt looks like. Disabling __fish_config_op_overrides removes +all of them. + + Override What it replaces or sets + ─────────────────────────────────────────────────────────────────────────── + Vi mode fish_vi_key_bindings replaces default Emacs mode + exit → smart_exit exit wrapper that captures scrollback before closing + PAGER=ov ov used by git, man, and all $PAGER-aware tools + MANPAGER=bat pipeline man pages rendered with syntax highlighting + CDPATH=. ~/projects ~ bare dir names resolve against ~/projects and ~ + Bang-bang system ! and $ keys expand history; !^, !*, !-N, !?str?, + ^old^new abbreviations; six expand_bang_* helpers + Autopair ( [ { " ' auto-close to (), [], {}, "", '' + Puffer key intercepts . ! $ * keys intercepted for smart expansion + Starship prompt fish_prompt replaced by Starship + OSC 133 markers + Catppuccin colors 30+ fish_color_* variables set to Mocha palette + FZF_DEFAULT_OPTS FZF themed to Catppuccin Mocha colors + Right prompt fish_right_prompt: exit code (on failure) + dim timestamp; always rendered; Docker context added when starship+C3 active + +The bang-bang system spans key_bindings.fish, abbr.fish, puffer.fish, and +six expand_bang_*.fish functions. All are gated together — disabling C3 +removes the entire bang-expansion system at once. + +When C3 is disabled, `exit` falls back to `builtin exit` with no scrollback +capture, no Kitty IPC, and no file I/O on exit. The scrollback capture block +is independently controlled by C5 (see below). + +#### C4 — Terminal and Tool Integration + +These features couple the shell to specific external tools. Disabling +__fish_config_op_integrations disables all of them. + + Component Requires + ─────────────────────────────────────────────────────────────────────────── + ~60 Kitty/WezTerm abbrs Active Kitty or WezTerm session + (:w, :wv, :wh, :t, etc.) + Done desktop notifications Graphical desktop with a notification daemon + spwin Kitty or WezTerm + tab Kitty, WezTerm, or Konsole + split Kitty or WezTerm + hist fzf + wl-copy (Wayland clipboard) + logs fzf + ov; reads from ~/.terminal_history/ + upgrade paru or yay (Arch Linux only) + WakaTime hook wakatime CLI and a configured API key + +Disabled integration commands (spwin, tab, split, hist, logs, upgrade) print +a colored error to stderr naming the variable that disabled them rather than +silently failing. + +#### C5 — Logging and Capture + +Five components capture shell output to disk. Disabling +__fish_config_op_logging skips all capture and removes the logging wrappers. + + Component What it captures + ─────────────────────────────────────────────────────────────────────────── + Scrollback capture Terminal session output saved to: + ~/.terminal_history/scrollback_YYYY-MM-DD_HH-MM-SS.log + tmux pane capture Continuous pane stream via pipe-pane, saved to: + ~/.terminal_history/tmux_-w-p_YYYY-MM-DD_HH-MM-SS.log + zellij pane capture Pane scrollback snapshot on shell exit, saved to: + ~/.terminal_history/zellij_-p_YYYY-MM-DD_HH-MM-SS.log + paru wrapper All paru/AUR output captured to: + ~/.terminal_history/paru_YYYY-MM-DD_HH-MM-SS.log + yay wrapper All yay/AUR output captured to: + ~/.terminal_history/yay_YYYY-MM-DD_HH-MM-SS.log + Kitty watcher watcher.py captures scrollback when Kitty closes + +The tmux capture starts automatically when fish launches inside any tmux +pane ($TMUX is set). It uses tmux's native pipe-pane to stream all pane +output directly to disk without an intermediate process. Each fish shell +session gets its own log file; a new log is created on each shell start +(including exec fish and new splits). Before each new log, the oldest +tmux_*.log files are pruned (by modification time) to keep the total within +SCROLLBACK_HISTORY_MAX_FILES, matching the paru/yay wrapper behaviour. + +The zellij capture works differently: Zellij has no live output-streaming +facility like pipe-pane, so the log is taken as a one-shot snapshot when the +shell exits, via `zellij action dump-screen --full --ansi` (the --ansi flag +preserves color). The dump is captured on the fish process's stdout and +written to the log file by fish itself (not via `--path`, which would make the +zellij server write the file). A fish_exit handler (registered whenever +$ZELLIJ is set) writes the pane's full scrollback and then prunes old +zellij_*.log files the same way. Because the capture happens at exit, toggling +__fish_config_op_logging takes effect on the next exit with no restart or +sentinel coordination needed — the C5 guard is re-checked when the handler +fires. + +LIMITATION — zellij capture only fires on a clean shell exit (typing `exit`, +Ctrl-D, or a logout), because that is when the fish_exit handler runs. It does +NOT capture when you close a pane or quit zellij through zellij itself: + + - Closing a pane signals the shell and tears the pane down concurrently, so + even if the handler runs, `dump-screen` may find the pane buffer already + gone. + - Quitting zellij kills the zellij server, and `dump-screen` needs a live + server to read from — there is nothing left to snapshot. + +This is a structural difference from tmux, NOT a bug. tmux streams pane output +to disk continuously via pipe-pane, so whatever was printed is already saved +no matter how the pane dies. Zellij can only snapshot, and the only reliable +snapshot point from the shell is a clean exit. To guarantee a zellij pane is +logged, end the session with `exit` or Ctrl-D rather than zellij's close-pane +or quit actions. + +The Kitty watcher is managed by the kitty-logging command: it symlinks the +watcher (fish-config-watcher.py) into the Kitty config directory and wires it +into kitty.conf via a managed block. Inside Kitty, a non-blocking +per-session reminder points first-time users at `kitty-logging install` until +they install or run `kitty-logging dismiss`. Install affects new Kitty windows +only; runtime disable is still handled by the .logging_disabled sentinel. + +Logging coordination via sentinel file + +C5 uses a sentinel file to synchronize state between the shell and +out-of-process components (the Kitty watcher and all running shells): + + ~/.config/fish/.logging_disabled + +Disabling __fish_config_op_logging: + 1. Creates the sentinel immediately in every open shell. + 2. Removes ~/.local/bin/paru and ~/.local/bin/yay logging wrappers; + bare /usr/bin/paru and /usr/bin/yay are used instead. + 3. Kitty's watcher.py reads the sentinel on each save attempt and + skips capture — no Kitty restart required. + 4. smart_exit stops saving scrollback logs. + 5. Stops tmux pipe-pane capture in every open fish shell inside tmux. + +Re-enabling __fish_config_op_logging: + 1. Removes the sentinel in every open shell. + 2. Regenerates paru/yay logging wrappers in ~/.local/bin/. + 3. Kitty watcher resumes capture on the next session exit. + 4. Restarts tmux pipe-pane capture in every open fish shell inside tmux. + +Changes propagate to all running shells through an event handler that fires +whenever __fish_config_op_logging changes — no shell restart needed. + +Note: C3 and C5 compose independently. C3 controls whether the smart_exit +wrapper is active at all; C5 controls only the scrollback-capture block +inside it. With C3 disabled, exit is plain builtin exit regardless of C5. + +#### C6 — Greeting and First-Run UI + + Component What it shows + ─────────────────────────────────────────────────────────────────────────── + First-run welcome banner One-time message on first interactive session + fish_greeting override Empty function defined late in config.fish to + suppress distro greetings (e.g. CachyOS sets + fish_greeting to fastfetch by default) + +When C6 is disabled, no greeting is printed by this config. Any greeting +set by the distro or other configs runs normally — this config simply does +not override it. + +## Prompt and Theme + +### Starship + +The primary prompt is Starship, initialized by conf.d/starship.fish. +Configure it via ~/.config/starship.toml. + +conf.d/starship.fish defines a fish_prompt wrapper that only activates when +starship is in PATH. It emits OSC 133;A (prompt start) immediately before +Starship renders and OSC 133;B (input start) immediately after, placing both +markers on the prompt line itself. This allows ov to use them as sticky +section headers when browsing scrollback logs. Without Starship, fish's +built-in prompt handles these markers automatically. + +### Catppuccin Fallback Prompt + +When Starship is absent or C3 overrides are disabled, a built-in nim-style +two-line prompt activates from functions/fish_prompt.fish. No external +dependencies — fish builtins only. + +Layout: + + ┬─[user@host:~/path] (main) + ╰─>$ + +Elements: + + user Yellow (Catppuccin Yellow); red if root + @host Blue (local) or Teal (SSH) + ~/path prompt_pwd abbreviation (Catppuccin Text) + (main) Current git branch in Catppuccin Pink; omitted outside repos + ─[V:name] Active Python venv basename; omitted when none + ─[N/I/R/V] Vi-mode indicator when vi bindings are active + ┬─ / ╰─> Connector lines: Catppuccin Green on success, Red on failure + +The right prompt (fish_right_prompt.fish) always renders, regardless of C3 +state. On failure it shows a red ✘ and the exit code; on success it shows +only the dim timestamp. When starship is installed and C3 is enabled, the +active Docker context is also shown (if non-default): + + ✘ 1 󰡨 myctx Fri Jun 12 00:51:21 2026 ← failed, starship+C3 active + ✘ 1 Fri Jun 12 00:51:21 2026 ← failed, fallback prompt + Fri Jun 12 00:51:21 2026 ← success (no ✘) + +### FZF + +FZF is themed to Catppuccin Mocha via FZF_DEFAULT_OPTS set in +integrations/fzf.fish. The colors applied: + + Background: #1E1E2E (base) #313244 (surface0) + Foreground: #CDD6F4 (text) + Highlights: #F38BA8 (red) #CBA6F7 (mauve) #B4BEFE (lavender) + +To customize, override FZF_DEFAULT_OPTS in local.fish. + +### Catppuccin Mocha Syntax Highlighting + +The Catppuccin Mocha theme ships with this config in themes/ and is applied +on first run via `conf.d/first_run.fish`. Colors are stored in fish_variables +(universal). To switch variants, install a different theme from themes/: + + fish_config theme save "Catppuccin Latte" + +--- diff --git a/docs/manual/08-fisher-plugins.md b/docs/manual/08-fisher-plugins.md new file mode 100644 index 0000000..9d3edd6 --- /dev/null +++ b/docs/manual/08-fisher-plugins.md @@ -0,0 +1,107 @@ +--- +title: Fisher Plugins +manTitle: 8. FISHER PLUGINS +sidebar: + order: 8 +helpKeywords: +- plugins +- fisher +--- + +Fisher is bootstrapped automatically on the **first interactive session** via +`conf.d/first_run.fish`. This also applies the Catppuccin Mocha theme and +prints a one-time welcome message (gated by __fish_config_op_greeting; set +it to 0 to suppress). Subsequent sessions skip all first-run logic with zero +overhead. + +To re-trigger first-run initialization (e.g., after a fresh install or for +testing), run: + + set -Ue __fish_config_first_run_complete + +Then open a new shell. + +## Fisher-Managed Plugins + +The following plugins are fully managed by Fisher. Their files are installed +into the repo directory by Fisher and are listed in `.gitignore` — do not +commit them. Fisher installs and updates them automatically. + + jorgebucaran/fisher Plugin manager itself + meaningful-ooo/sponge Remove failed commands from history + +## Sponge History Filtering + +Sponge removes failed commands from history and, via conf.d/sponge_privacy.fish, +also filters privacy-sensitive commands through three layers: + +Layer 1 — Static patterns (universal, persistent across sessions): +Commands matching any of these structural signatures are never recorded: + + --password / --token / --passphrase / --api-key flags with values + Inline env assignments: GITHUB_TOKEN=xxx, MY_API_KEY=abc + Fish set with sensitive names: set -gx GITHUB_TOKEN xxx + URLs with embedded credentials: https://user:pass@host + HTTP Authorization headers: curl -H "Authorization: ..." + Basic auth flags: curl -u user:pass + sshpass, docker login -p, openssl -passin/-passout + +Layer 2 — Dynamic secret values (session globals, refreshed each login): +On the first prompt, after secrets.fish has loaded, the literal values of +all exported variables whose names suggest credentials (TOKEN, PASSWORD, +SECRET, API_KEY, etc.) are collected, regex-escaped, and added as a +session-scoped overlay. Because globals shadow universals in Fish, the +combined list is what sponge sees. Rotating a token takes effect on the +next login automatically. + +Layer 3 — Per-command filter (sponge_filter_secrets): +Catches credentials in variables exported after login, such as tokens +sourced from a project .env file mid-session. + +To add your own persistent patterns: + + set -U -a sponge_regex_patterns 'your-regex-here' + +To mark additional variable NAMES as credential-bearing (so Layer 2 scrubs +their values), add name tokens — via `config-settings` → Sponge, or directly: + + set -U -a __fish_sponge_extra_sensitive ACME_API VAULT_PW + +Tokens are folded into the Layer 2 name match case-insensitively as substrings, +so ACME_API also covers ACME_API_KEY. (The match uses `--entire` to return the +full variable name, so partial-name tokens dereference the right value.) + +The `config-settings` Sponge page also surfaces sponge's own tuning variables — +sponge_delay, sponge_successful_exit_codes, sponge_purge_only_on_exit, and +sponge_allow_previously_successful — so they can be changed without typing +variable names. + +## Bundled Plugin Functionality + +The remaining plugin functionality is bundled directly with this config rather +than managed through Fisher. The bundled versions include customizations for +Fish 4.x compatibility and improved behavior that differ from their upstream +releases. Installing them through Fisher would overwrite these customizations. + +Bundled components and their upstream origins: + + catppuccin/fish → themes/ + conf.d/theme.fish + PatrickF1/fzf.fish → functions/_fzf_*.fish + conf.d/fzf.fish + franciscolourenco/done → conf.d/done.fish + jorgebucaran/autopair.fish → functions/_autopair_*.fish + conf.d/autopair.fish + nickeb96/puffer-fish → functions/_puffer_fish_*.fish + conf.d/puffer.fish + +Do not run `fisher install` for these — it will overwrite the customized +versions. To update their behavior, edit the relevant bundled files directly. + +## fish_plugins Manifest + +The `fish_plugins` file at the config root: + + jorgebucaran/fisher Plugin manager itself + meaningful-ooo/sponge Remove failed commands from history + +To update all Fisher-managed plugins, run `fisher update` or `fish-deps +update` which calls it as its first step. + +--- diff --git a/docs/manual/09-installation.md b/docs/manual/09-installation.md new file mode 100644 index 0000000..554f2ab --- /dev/null +++ b/docs/manual/09-installation.md @@ -0,0 +1,43 @@ +--- +title: Installation +manTitle: 9. INSTALLATION +sidebar: + order: 9 +helpKeywords: +- installation +- install +--- + +This configuration is managed as a git repository. To deploy on a new machine: + + mv ~/.config/fish ~/.config/fish.bak # back up any existing config + git clone https://git.rootiest.dev/rootiest/fish-config.git ~/.config/fish + +Then open a new Fish shell. Fisher installs automatically on first launch +and the Catppuccin Mocha theme is applied. All other plugin functionality is +bundled directly with this config and requires no additional installation. + +## Return Sentinel + +config.fish ends with a return sentinel guard. Any lines appended after it by +a tool's setup command (starship init fish | source, zoxide init fish | source, +etc.) will have no effect. All integrations are managed via conf.d/ files. + +If a new tool's shell integration appears to do nothing, check whether its +setup command appended an init line below the sentinel and create a dedicated +conf.d/.fish instead. + +## Updating + +Pull the latest changes from the upstream repository without needing a +configured git remote: + + config-update Fetch and apply the latest commits from upstream + config-update --dry-run Preview available changes without applying them + config-update --force Stash local changes, pull, then restore the stash + +The remote URL (https://git.rootiest.dev/rootiest/fish-config.git) is +hard-coded, so this works on a fresh clone with no origin configured. All +git output is suppressed. Run exec fish after a successful update to reload. + +--- diff --git a/docs/manual/10-personalization.md b/docs/manual/10-personalization.md new file mode 100644 index 0000000..71b093a --- /dev/null +++ b/docs/manual/10-personalization.md @@ -0,0 +1,68 @@ +--- +title: Personalization +manTitle: 10. PERSONALIZATION +sidebar: + order: 10 +helpKeywords: +- personalization +- personalize +--- + +Sensitive credentials and machine-specific settings are kept out of version +control in a private directory. The path defaults to +`~/.config/.user-dots/fish/` but can be overridden: + + set -U __fish_user_dots_path /path/to/your/dots/fish + +Or use the interactive TUI — run `config-settings` and navigate to the +"Dots Path" row (last row). Press Enter to type a new path, or ← / h to +reset to the default. + +config.fish sources local.fish from that directory on every interactive +session. local.fish is responsible for sourcing its own secrets.fish: + + $__fish_user_dots_path/ + ├── secrets.fish API keys, tokens, passwords, personal identifiers + └── local.fish Machine-specific paths, env vars, and sourcing secrets + +fish_variables (auto-managed by fish) is excluded from this repo via +.gitignore. Do not commit it. + +## secrets.fish + +Store anything you would not commit to a public repo: API keys, auth tokens, +passwords, and personal identifiers. + + set -gx MY_NAME "Your Name" + set -gx MY_EMAIL "you@example.com" + set -gx GPG_RECIPIENT "you@example.com" + set -gx GITHUB_TOKEN ghp_yourTokenHere + set -gx OPENAI_API_KEY sk-proj-yourKeyHere + set -gx GITEA_TOKEN yourGiteaTokenHere + set -gx GITEA_CHOSEN_LOGIN your.gitea.instance + set -gx KOPIA_PASSWORD yourKopiaPassword + +## local.fish + +Store paths and variables specific to one machine — things that would be +wrong on any other system. + + # CDPATH — directories searched by cd + set -gx CDPATH . /home/youruser/projects /home/youruser + + # Path to your shared .gitignore boilerplate + set -gx GITIGNORE_BOILERPLATE ~/.config/git/gitignore_boilerplate + + # SSH shortcuts + abbr -a sshr 'ssh you@your-server.local' + abbr -a sshw 'ssh you@work-server.example.com' + + # Docker context shortcuts + abbr -a dcr 'docker context use my-remote-server' + abbr -a dcw 'docker context use work-server' + +local.fish is sourced at the end of config.fish with an existence check so +the public config works cleanly on any machine without the private repo. +local.fish in turn sources secrets.fish when it exists. + +--- diff --git a/docs/manual/11-viewing-this-manual.md b/docs/manual/11-viewing-this-manual.md new file mode 100644 index 0000000..41340d3 --- /dev/null +++ b/docs/manual/11-viewing-this-manual.md @@ -0,0 +1,78 @@ +--- +title: Viewing This Manual +manTitle: 11. VIEWING THIS MANUAL +sidebar: + order: 11 +helpKeywords: +- viewing +- manual +--- + +## With ov (recommended) + + help config + +ov renders the Markdown with syntax highlighting and section-based +navigation. + + Space next section + ^ previous section + Alt+u toggle section list sidebar + / search forward + n / N next / previous search match + g go to line number + j interactive jump target (line, %, or 'section') + q quit + +## With bat + + bat --language=markdown --paging=always ~/.config/fish/docs/fish-config.md + +## As a man page + + help config --man + help config pkg --man + +Opens the compiled docs/fish-config.1 directly via man -l, bypassing +the pager fallback chain. If a section keyword is given, the pager opens +at the nearest matching heading. The symlink is created once on first +run (like an install step) and MANPATH is set each session, enabling +the standard invocation: + + man fish-config + +NOTE: fish-config (hyphen) is this config's man page. fish_config +(underscore) is fish's built-in browser-based configuration tool — +a completely separate command. Do not mix them up. + +## In the browser (HTML) + + help config --html + help config pkg --html + +Opens docs/html/index.html in the default web browser. If a section +keyword is given, the browser opens directly at the matching anchor +(resolved via docs/html/sitemap.json). Browser detection queries the +system's x-scheme-handler/https MIME entry (via xdg-mime) to find the +real browser binary, then falls back through known browser binaries +(firefox, chromium, vivaldi, etc.), and finally xdg-open as a last +resort. Set $fish_help_browser or $BROWSER to override. + +## As a wiki + +The generated Markdown wiki lives in docs/wiki/. index.md provides the +project overview and a full table of contents. Each section page has a +navigation bar at the top linking to every other section. + +The wiki is auto-generated from this file by the CI pipeline on every +push to main that changes docs/fish-config.md. + +## Jumping to a section + + help config keybindings + help config abbreviations + help config pkg + help config logs + help config fish-deps + +The keyword is matched case-insensitively against section headings. diff --git a/docs/manual/index.md b/docs/manual/index.md new file mode 100644 index 0000000..8385cf4 --- /dev/null +++ b/docs/manual/index.md @@ -0,0 +1,77 @@ +--- +title: Fish Shell Configuration +description: Reference manual for the rootiest fish configuration. +manTitle: DESCRIPTION +sidebar: + order: 0 +helpKeywords: +- description +- autopair +- puffer +- puffer-fish +- logging-events +--- + +A production-grade Fish shell configuration targeting Fish 4.x. It provides: + +- Drop-in replacements for common Unix tools (ls, cat, rm, du, ping, less) +- Deep Kitty and WezTerm terminal integration: tab/window/pane management from + the command line +- Automatic session logging: terminal scrollback, tmux/zellij panes, and + paru/yay output captured to ~/.terminal_history (on by default; see below) +- Automatic Python virtualenv activation on directory change +- Cross-platform package management via pkg and fish-deps +- AI session helpers for Claude Code and Antigravity +- Catppuccin Mocha color theme throughout + +> **CAUTION - SESSION LOGGING IS ON BY DEFAULT** +> +> This configuration silently records terminal output to `~/.terminal_history`: +> Kitty scrollback on window close, live tmux pane streams, zellij pane +> snapshots on exit, and full paru/yay output. These logs can contain command +> output, file contents, and secrets printed to the terminal. Nothing leaves +> your machine, but the files persist locally. +> +> - Disable all logging with: `set -U __fish_config_op_logging off` +> - Prefer a menu? Run the interactive picker: `config-settings` +> - See Section 7 (C5 - Logging and Capture) for the full breakdown. + +The configuration is split across: + + config.fish Main entry point; sets env vars and PATH + conf.d/ + abbr.fish All abbreviations + autopair.fish Auto-pair brackets and quotes (bundled from jorgebucaran/autopair.fish) + cheat.fish cheat.sh tab completions + done.fish Desktop notifications for long commands + first_run.fish One-time init: Fisher bootstrap, theme, welcome + key_bindings.fish Custom key bindings and Vi mode + logging-events.fish C5 --on-variable event handlers; syncs logging state at startup + kitty-watcher-reminder.fish C5 per-session reminder to set up the Kitty watcher + paru-wrapper.fish Auto-generates ~/.local/bin/paru logging wrapper + puffer.fish !! / !$ / ./ expansion (bundled from nickeb96/puffer-fish) + tmux-logging.fish C5 starts tmux pipe-pane capture when fish runs inside tmux + zellij-logging.fish C5 fish_exit handler dumping zellij pane scrollback on exit + sponge_privacy.fish Sponge privacy patterns; filters credentials from history + starship.fish fish_prompt with OSC 133 shell-integration markers + tailscale.fish Tailscale CLI tab completions + theme.fish Catppuccin syntax highlight colors + tricks.fish PATH, bang-bang helpers, bat man pages, aliases + wakatime.fish WakaTime shell hook + yay-wrapper.fish Auto-generates ~/.local/bin/yay logging wrapper + zoxide.fish Zoxide z/zi integration; overrides cd + functions/ Custom functions, one per file, autoloaded + completions/ Tab completion scripts + integrations/ + fzf.fish FZF Catppuccin theme and key binding config + scripts/ + clean_progress_log.py Strips paru/yay typescript animations to clean static logs + agents-tools/ AGENTS.md version-bump script and git hooks (wired via core.hooksPath) + docs/ Offline documentation and compiled man page + fish-config.md Primary source manual (terminal-readable) + fish-config.1 Compiled man page (auto-generated by CI) + fish-config.index Section index for help config navigation + html/ Chunked HTML docs (auto-generated by CI) + wiki/ Markdown wiki (auto-generated by CI) + +--- diff --git a/docs/manualtools.py b/docs/manualtools.py index 58bda76..9f76e59 100644 --- a/docs/manualtools.py +++ b/docs/manualtools.py @@ -39,7 +39,10 @@ def serialize(fm: dict, body: str) -> str: def shift_headings(body: str, by: int) -> str: - """Add `by` levels to every ATX heading, ignoring fenced code blocks.""" + """Add `by` levels to every ATX heading, ignoring fenced code blocks. + + Negative values promote headings. Level is clamped to [1, 6]. + """ if by == 0: return body out, in_fence = [], False @@ -47,7 +50,9 @@ def shift_headings(body: str, by: int) -> str: if FENCE_RE.match(line): in_fence = not in_fence if not in_fence: - line = HEADING_RE.sub(lambda m: "#" * (len(m.group(1)) + by) + m.group(2), line) + line = HEADING_RE.sub( + lambda m: "#" * max(1, min(6, len(m.group(1)) + by)) + m.group(2), line + ) out.append(line) return "\n".join(out) diff --git a/docs/split-manual.py b/docs/split-manual.py new file mode 100644 index 0000000..50fdaa7 --- /dev/null +++ b/docs/split-manual.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 +# Copyright (C) 2026 Rootiest +# SPDX-License-Identifier: AGPL-3.0-or-later +"""One-shot migration: docs/fish-config.md -> docs/manual/**. + +Run once, verify with verify-manual.py, then delete this script. +""" + +import re +import shutil +import sys +from pathlib import Path + +import manualtools as mt + +DOCS = Path(__file__).parent +SRC = DOCS / "fish-config.md" +OUT = DOCS / "manual" +INDEX = DOCS / "fish-config.index" + +MAN_ONLY = {"NAME", "SYNOPSIS", "TABLE OF CONTENTS"} +LANDING = "DESCRIPTION" +FUNCTIONS_TITLE_RE = re.compile(r"^\d+\.\s+FUNCTIONS REFERENCE$", re.I) +NUM_PREFIX_RE = re.compile(r"^\d+(\.\d+)*\.?\s+") + + +def slugify(title: str) -> str: + s = NUM_PREFIX_RE.sub("", title).lower() + s = re.sub(r"[^\w\s-]", "", s) + return re.sub(r"[\s_]+", "-", s).strip("-") + + +def display_title(heading: str) -> str: + """Strip leading numbering and normalise SHOUTING to Title Case.""" + t = NUM_PREFIX_RE.sub("", heading).strip() + return t.title() if t.isupper() else t + + +def load_keywords() -> dict[str, list[str]]: + """Reverse fish-config.index into {heading text: [keywords]}.""" + mapping: dict[str, list[str]] = {} + if not INDEX.exists(): + return mapping + for line in INDEX.read_text().splitlines(): + line = line.strip() + if not line or line.startswith("#") or "=" not in line: + continue + keyword, heading = line.split("=", 1) + mapping.setdefault(heading.strip().lstrip("# ").strip(), []).append(keyword.strip()) + return mapping + + +def split_h1(text: str) -> list[tuple[str, str]]: + parts = re.split(r"^# (.+)$", text, flags=re.MULTILINE) + return [(parts[i].strip(), parts[i + 1].strip()) for i in range(1, len(parts), 2)] + + +def split_h2(body: str) -> tuple[str, list[tuple[str, str]]]: + parts = re.split(r"^## (.+)$", body, flags=re.MULTILINE) + intro = parts[0].strip() + subs = [(parts[i].strip(), parts[i + 1].strip()) for i in range(1, len(parts), 2)] + return intro, subs + + +def main() -> int: + if not SRC.exists(): + print(f"error: {SRC} not found", file=sys.stderr) + return 1 + if OUT.exists(): + shutil.rmtree(OUT) + OUT.mkdir(parents=True) + + keywords = load_keywords() + sections = split_h1(SRC.read_text()) + order = 0 + + for heading, body in sections: + kw = keywords.get(heading, []) + if heading in MAN_ONLY: + path = OUT / f"00-{slugify(heading)}.md" + fm = { + "title": display_title(heading), + "manTitle": heading, + "man": True, + "site": False, + } + path.write_text(mt.serialize(fm, body)) + continue + + if heading == LANDING: + fm = { + "title": "Fish Shell Configuration", + "description": "Reference manual for the rootiest fish configuration.", + "manTitle": heading, + "sidebar": {"order": 0}, + } + if kw: + fm["helpKeywords"] = kw + (OUT / "index.md").write_text(mt.serialize(fm, body)) + continue + + order += 1 + if FUNCTIONS_TITLE_RE.match(heading): + # Section 5 explodes into a directory of category files. + d = OUT / f"{order:02d}-functions" + d.mkdir() + intro, subs = split_h2(body) + fm = { + "title": display_title(heading), + "manTitle": heading, + "sidebar": {"order": order}, + } + if kw: + fm["helpKeywords"] = kw + (d / "index.md").write_text(mt.serialize(fm, intro)) + + for i, (sub_heading, sub_body) in enumerate(subs, start=1): + sub_fm = { + "title": display_title(sub_heading), + "manTitle": sub_heading, + "sidebar": {"order": i}, + } + sub_kw = keywords.get(sub_heading, []) + if sub_kw: + sub_fm["helpKeywords"] = sub_kw + # H3 function entries -> H2 so --site can split on them. + promoted = mt.shift_headings(sub_body, -1) + (d / f"{i:02d}-{slugify(sub_heading)}.md").write_text( + mt.serialize(sub_fm, promoted) + ) + continue + + fm = { + "title": display_title(heading), + "manTitle": heading, + "sidebar": {"order": order}, + } + if kw: + fm["helpKeywords"] = kw + (OUT / f"{order:02d}-{slugify(heading)}.md").write_text(mt.serialize(fm, body)) + + count = sum(1 for _ in OUT.rglob("*.md")) + print(f"wrote {count} files to {OUT}") + return 0 + + +if __name__ == "__main__": + sys.path.insert(0, str(Path(__file__).parent)) + raise SystemExit(main()) diff --git a/docs/verify-manual.py b/docs/verify-manual.py index ea44cdf..ec4f3bb 100644 --- a/docs/verify-manual.py +++ b/docs/verify-manual.py @@ -84,6 +84,26 @@ def test_parse_roundtrip_body_with_leading_blank_line(): assert got_body == body, f"body mismatch: expected {body!r}, got {got_body!r}" +def test_manual_tree_exists(): + root = Path(__file__).parent / "manual" + assert root.is_dir(), "docs/manual/ not generated" + assert (root / "index.md").exists(), "docs/manual/index.md missing" + fn = root / "05-functions" + assert fn.is_dir(), "docs/manual/05-functions/ missing" + cats = sorted(p.name for p in fn.glob("*.md") if p.name != "index.md") + assert len(cats) == 14, f"expected 14 function categories, got {len(cats)}: {cats}" + + +def test_function_entries_promoted_to_h2(): + root = Path(__file__).parent / "manual" / "05-functions" + for path in root.glob("*.md"): + if path.name == "index.md": + continue + _, body = mt.parse(path) + assert "\n### " not in f"\n{body}", f"{path.name} still has H3 entries" + assert "\n## " in f"\n{body}", f"{path.name} has no H2 function entries" + + TESTS = [v for k, v in sorted(globals().items()) if k.startswith("test_")]