Files
fish-config/docs/fish-config.1
T
2026-07-28 07:37:49 +00:00

4743 lines
127 KiB
Groff

'\" t
.\" Automatically generated by Pandoc 3.1.3
.\"
.\" Define V font for inline verbatim, using C font in formats
.\" that render this, and otherwise B font.
.ie "\f[CB]x\f[]"x" \{\
. ftr V B
. ftr VI BI
. ftr VB B
. ftr VBI BI
.\}
.el \{\
. ftr V CR
. ftr VI CI
. ftr VB CB
. ftr VBI CBI
.\}
.TH "FISH-CONFIG" "7" "June 2026" "" "Fish Shell Configuration User Manual"
.hy
.SH NAME
.PP
fish-config - personal fish shell configuration for Fish 4.x with modern
CLI tool integration
.SH SYNOPSIS
.IP
.nf
\f[C]
help config [SECTION]
\f[R]
.fi
.PP
Open this manual in the best available pager.
Optionally jump to a section by keyword:
.IP
.nf
\f[C]
help config keybindings
help config pkg
help config abbreviations
help config logs
\f[R]
.fi
.PP
The \f[V]help config\f[R] syntax integrates with fish\[cq]s built-in
help command.
The underlying \f[V]config-help\f[R] function is also available
directly.
.SH DESCRIPTION
.PP
A production-grade Fish shell configuration targeting Fish 4.x.
It provides:
.IP \[bu] 2
Drop-in replacements for common Unix tools (\f[V]ls\f[R], \f[V]cat\f[R],
\f[V]rm\f[R], \f[V]du\f[R], \f[V]ping\f[R], \f[V]less\f[R])
.IP \[bu] 2
Deep Kitty and WezTerm terminal integration: tab/window/pane management
from the command line
.IP \[bu] 2
Optional session logging: terminal scrollback, tmux/zellij panes, and
paru/yay output captured to \f[V]\[ti]/.terminal_history\f[R] (off by
default; see C5 Logging)
.IP \[bu] 2
Automatic Python virtualenv activation on directory change
.IP \[bu] 2
Cross-platform package management via pkg and fish-deps
.IP \[bu] 2
AI scaffolding helpers for Claude Code and Antigravity
.IP \[bu] 2
Catppuccin Mocha color theme throughout
.PP
The configuration uses a structured file tree:
.IP
.nf
\f[C]
\[ti]/.config/fish/
├── config.fish Main entry point; sets env vars and PATH
├── conf.d/
│ ├── abbr.fish All abbreviations
│ ├── autopair.fish Auto-pair brackets and quotes
│ ├── cheat.fish cheat.sh tab completions
│ ├── done.fish Desktop notifications for long commands
│ ├── first_run.fish One-time init: Fisher bootstrap, theme
│ ├── key_bindings.fish Custom key bindings and Vi mode
│ ├── logging-events.fish C5 event handlers; syncs logging state
│ ├── kitty-watcher-reminder.fish C5 per-session Kitty watcher reminder
│ ├── paru-wrapper.fish Auto-generates paru logging wrapper
│ ├── puffer.fish !! / !$ / ./ expansion
│ ├── tmux-logging.fish C5 starts tmux pipe-pane capture
│ ├── zellij-logging.fish C5 fish_exit handler for zellij
│ ├── sponge_privacy.fish Sponge privacy patterns
│ ├── starship.fish fish_prompt shell-integration markers
│ ├── tailscale.fish Tailscale CLI tab completions
│ ├── theme.fish Catppuccin syntax highlight colors
│ ├── tricks.fish PATH, bang-bang helpers, bat man pages
│ ├── wakatime.fish WakaTime shell hook
│ ├── yay-wrapper.fish Auto-generates yay logging wrapper
│ └── zoxide.fish Zoxide z/zi integration; overrides cd
├── functions/ Custom functions, one per file
├── completions/ Tab completion scripts
├── integrations/
│ └── fzf.fish FZF Catppuccin theme and key bindings
├── scripts/
│ ├── clean_progress_log.py Strips typescript animations for clean logs
│ └── agents-tools/ AGENTS.md scripts and git hooks
└── docs/ Offline documentation and man page
├── fish-config.md Primary source manual
├── fish-config.1 Compiled man page (auto-generated)
├── fish-config.index Section index for help config
├── html/ Chunked HTML docs (auto-generated)
└── wiki/ Markdown wiki (auto-generated)
\f[R]
.fi
.PP
* * * * *
.SH TABLE OF CONTENTS
.IP
.nf
\f[C]
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. Troubleshooting
11.1 Uninstalling and Reverting to Backup
11.2 Fish Version Requirement
11.3 Enable or Disable Session Logging
11.4 Change or Disable the Greeting
11.5 Secrets and Machine-Local Configuration
11.6 Tool Init Does Nothing (Return Sentinel)
11.7 Missing Dependencies
11.8 Vi Mode Keybindings
11.9 What\[aq]s with the C1-C6 stuff?
12. Viewing This Manual
\f[R]
.fi
.PP
* * * * *
.SH 1. CONFIGURATION VARIABLES
.PP
These variables are exported from config.fish on every interactive
session.
Override them in local.fish (see Section 10, Personalization).
.SS Environment Directories (XDG)
.PP
.TS
tab(@);
l l.
T{
Variable
T}@T{
Value
T}
_
T{
\f[V]XDG_CONFIG_HOME\f[R]
T}@T{
\f[V]\[ti]/.config\f[R]
T}
T{
\f[V]XDG_CACHE_HOME\f[R]
T}@T{
\f[V]\[ti]/.cache\f[R]
T}
T{
\f[V]XDG_DATA_HOME\f[R]
T}@T{
\f[V]\[ti]/.local/share\f[R]
T}
T{
\f[V]XDG_STATE_HOME\f[R]
T}@T{
\f[V]\[ti]/.local/state\f[R]
T}
.TE
.PP
Tools that respect XDG are directed to these paths rather than polluting
\f[V]$HOME\f[R].
.SS Tool Homes (XDG-compliant)
.PP
.TS
tab(@);
l l.
T{
Variable
T}@T{
Value
T}
_
T{
\f[V]CARGO_HOME\f[R]
T}@T{
\f[V]$XDG_DATA_HOME/cargo\f[R]
T}
T{
\f[V]RUSTUP_HOME\f[R]
T}@T{
\f[V]$XDG_DATA_HOME/rustup\f[R]
T}
T{
\f[V]GOPATH\f[R]
T}@T{
\f[V]$XDG_DATA_HOME/go\f[R]
T}
T{
\f[V]BUN_INSTALL\f[R]
T}@T{
\f[V]$XDG_DATA_HOME/bun\f[R]
T}
T{
\f[V]NPM_CONFIG_PREFIX\f[R]
T}@T{
\f[V]$XDG_DATA_HOME/npm-global\f[R]
T}
T{
\f[V]GNUPGHOME\f[R]
T}@T{
\f[V]$XDG_CONFIG_HOME/gnupg\f[R]
T}
T{
\f[V]WAKATIME_HOME\f[R]
T}@T{
\f[V]$XDG_CONFIG_HOME/wakatime\f[R]
T}
.TE
.SS Editor and Pager
.PP
.TS
tab(@);
lw(35.0n) lw(35.0n).
T{
Variable
T}@T{
Value / Notes
T}
_
T{
\f[V]EDITOR\f[R]
T}@T{
\f[V]nvim\f[R] (falls back to \f[V]vi\f[R] if \f[V]nvim\f[R] is absent)
T}
T{
\f[V]VISUAL\f[R]
T}@T{
unset by default; set a GUI editor via \f[V]local.fish\f[R] (the
\f[V]edit\f[R] function falls back to a GUI chain when \f[V]VISUAL\f[R]
is empty)
T}
T{
\f[V]SUDO_EDITOR\f[R]
T}@T{
same as \f[V]EDITOR\f[R]
T}
T{
\f[V]PAGER\f[R]
T}@T{
\f[V]ov\f[R] (falls back to \f[V]less\f[R])
T}
.TE
.SS Scrollback History
.PP
.TS
tab(@);
l l.
T{
Variable
T}@T{
Value / Notes
T}
_
T{
\f[V]__fish_scrollback_history_dir\f[R]
T}@T{
(unset → \f[V]\[ti]/.terminal_history\f[R])
T}
T{
\f[V]__fish_scrollback_history_max_files\f[R]
T}@T{
(unset → \f[V]100\f[R])
T}
T{
\f[V]SCROLLBACK_HISTORY_DIR\f[R]
T}@T{
\f[V]\[ti]/.terminal_history\f[R] (exported mirror)
T}
T{
\f[V]SCROLLBACK_HISTORY_MAX_FILES\f[R]
T}@T{
\f[V]100\f[R] (exported mirror)
T}
.TE
.PP
The \f[V]__fish_scrollback_history_*\f[R] universal variables are the
fish-style source of truth \[em] set them via \f[V]config-settings\f[R]
→ Paths, or \f[V]set -U\f[R] directly.
\f[V]config.fish\f[R] exports the \f[V]SCROLLBACK_HISTORY_*\f[R] mirrors
from them, because the POSIX wrapper scripts
(\f[V]paru\f[R]/\f[V]yay\f[R]/\f[V]tmux\f[R]/\f[V]zellij\f[R] logging
and \f[V]_prune_terminal_logs\f[R]) read the exported names from the
environment.
When the \f[V]__fish_\f[R] vars are unset, the documented defaults are
exported.
\f[V]config.fish\f[R] deliberately does not create a global source var,
which would shadow the universal and stop live edits from taking effect.
.PP
Scrollback logs accumulate in \f[V]SCROLLBACK_HISTORY_DIR\f[R] as
timestamped files.
When the count exceeds \f[V]SCROLLBACK_HISTORY_MAX_FILES\f[R] the oldest
are pruned automatically on exit.
Use \f[V]logs\f[R] to browse them interactively.
.SS Other
.PP
.TS
tab(@);
lw(23.3n) lw(23.3n) lw(23.3n).
T{
Variable
T}@T{
Value
T}@T{
Notes
T}
_
T{
\f[V]GPG_TTY\f[R]
T}@T{
\f[V]$(tty)\f[R]
T}@T{
ensures GPG passphrase prompts work
T}
T{
\f[V]CLAUDE_CODE_NO_FLICKER\f[R]
T}@T{
\f[V]1\f[R]
T}@T{
suppress terminal flicker in Claude Code
T}
T{
\f[V]CDPATH\f[R]
T}@T{
\f[V]. \[ti]/projects \[ti]\f[R]
T}@T{
T}
.TE
.PP
Opinionated defaults (\f[V]CDPATH\f[R],
\f[V]PAGER\f[R]/\f[V]MANPAGER\f[R], Vi mode, command shadows, terminal
integrations) can be switched off per category with universal variables
\[em] see Section 7, \[lq]Opinionated Components (Minimal Mode)\[rq].
.SS Pager Hierarchy
.PP
\f[V]$PAGER\f[R] is set to \f[V]ov\f[R] when available, falling back to
\f[V]less\f[R].
The \f[V]less\f[R] wrapper function extends this into a full chain so
anything that calls \f[V]less\f[R] directly also benefits:
.PP
\f[V]$PAGER\f[R] → \f[V]ov\f[R] → \f[V]less\f[R] → \f[V]more\f[R]
\f[V]cat\f[R]
.PP
When \f[V]bat\f[R] is installed, man pages are rendered with syntax
highlighting:
.PP
.TS
tab(@);
l l.
T{
Variable
T}@T{
Value
T}
_
T{
\f[V]MANROFFOPT\f[R]
T}@T{
\f[V]-c\f[R]
T}
T{
\f[V]MANPAGER\f[R]
T}@T{
\f[V]sh -c \[aq]col -bx \[rs]| bat -l man -p\[aq]\f[R]
T}
.TE
.SS Integrations
.SS Zoxide
.PP
\f[V]cd\f[R], \f[V]z\f[R], and \f[V]cdi\f[R]/\f[V]zi\f[R] are all mapped
to \f[V]zoxide\f[R]-backed navigation.
Tab completions for \f[V]cd\f[R] and \f[V]z\f[R] blend standard
directory entries (CWD and \f[V]CDPATH\f[R]) with frecency results so
both familiar and frequently-visited paths appear in one list.
.SS DirEnv
.PP
Automatically loads \f[V].envrc\f[R] files on directory change.
Takes priority over the auto-venv logic \[em] if a directory is managed
by \f[V]direnv\f[R], the auto-venv activation is skipped entirely.
.SS Auto Python Venv
.PP
When entering a directory that contains a \f[V].venv/\f[R], the
virtualenv is activated automatically and deactivated when you leave the
project tree.
.SS WakaTime
.PP
Every shell command is reported to WakaTime for time-tracking.
Set \f[V]FISH_WAKATIME_DISABLED=1\f[R] to disable without removing the
plugin.
.SS Tailscale
.PP
Full tab completion for the \f[V]tailscale\f[R] CLI is provided via
\f[V]conf.d/tailscale.fish\f[R].
.SS Done Notifications
.PP
Desktop notifications fire when a command takes longer than 10 seconds
and the terminal window is not focused.
Configured via fish universal variables:
.PP
.TS
tab(@);
l l.
T{
Variable
T}@T{
Value
T}
_
T{
\f[V]__done_min_cmd_duration\f[R]
T}@T{
\f[V]10000\f[R] ms
T}
T{
\f[V]__done_notification_urgency_level\f[R]
T}@T{
\f[V]low\f[R]
T}
.TE
.SS Scrollback History
.PP
When running inside Kitty, closing a shell session via \f[V]exit\f[R]
saves a timestamped scrollback snapshot to
\f[V]SCROLLBACK_HISTORY_DIR\f[R].
Files are named:
.PP
\f[V]scrollback_YYYY-MM-DD_HH-MM-SS.log\f[R]
.PP
The \f[V]paru\f[R] and \f[V]yay\f[R] wrappers (auto-generated in
\f[V]\[ti]/.local/bin/\f[R]) run the command inside a PTY via
\f[V]script(1)\f[R] so download progress bars are preserved on screen,
then render the captured terminal animation down to a clean static log
via \f[V]scripts/clean_progress_log.py\f[R] (a small terminal-screen
emulator that replays cursor movements, collapses repainted progress
frames to their final state, and preserves ANSI color).
If \f[V]python3\f[R] is unavailable the wrapper falls back to dropping
only the \f[V]script(1)\f[R] header/footer.
Output is saved to:
.IP \[bu] 2
\f[V]paru_YYYY-MM-DD_HH-MM-SS.log\f[R]
.IP \[bu] 2
\f[V]yay_YYYY-MM-DD_HH-MM-SS.log\f[R]
.PP
Before pruning, \f[V]_scrollback_prune_junk\f[R] silently removes empty
files, files with only a single meaningful line (e.g.\ bare
\f[V][exited]\f[R] captures), and Kitty tab-rename prompt captures.
Use \f[V]exit --no-log\f[R] (or \f[V]exit -n\f[R]) to skip capture.
.PP
* * * * *
.SH 2. PATH SETUP
.PP
Directories prepended to PATH in this order (first wins):
.PP
.TS
tab(@);
l l.
T{
Directory
T}@T{
Purpose
T}
_
T{
\f[V]\[ti]/.local/bin\f[R]
T}@T{
Standard user-local executables
T}
T{
\f[V]\[ti]/Applications\f[R]
T}@T{
User-installed standalone apps
T}
T{
\f[V]\[ti]/scripts\f[R]
T}@T{
Personal shell scripts
T}
T{
\f[V]\[ti]/bin\f[R]
T}@T{
Cargo binaries (appended \[em] lowest priority)
T}
T{
\f[V]$BUN_INSTALL/bin\f[R]
T}@T{
Bun runtime and global packages
T}
T{
\f[V]$NPM_CONFIG_PREFIX/bin\f[R]
T}@T{
Global npm packages
T}
T{
\f[V]\[ti]/.lmstudio/bin\f[R]
T}@T{
LM Studio CLI
T}
T{
\f[V]\[ti]/.resend/bin\f[R]
T}@T{
Resend CLI
T}
T{
\f[V]\[ti]/.fzf/bin\f[R]
T}@T{
\f[V]fzf\f[R] binary (git-installed)
T}
.TE
.PP
Cargo binaries are intentionally appended (lowest priority) to avoid
shadowing system-installed Rust tools.
.PP
NOTE: While these directories are merged with your system\[cq]s existing
\f[V]$PATH\f[R] values, any executables in the prepended directories
above will override (shadow) system binaries of the same name.
.PP
TIP: This standard PATH setup is gated behind the opinionated component
overrides toggle.
If you prefer to manage your PATH completely manually, you can disable
it by setting \f[V]__fish_config_op_overrides\f[R] to \f[V]0\f[R] (or
toggle it off in the \f[V]config-settings\f[R] menu).
.PP
* * * * *
.SH 3. KEY BINDINGS
.PP
The shell uses Vi key bindings (fish_vi_key_bindings).
All custom bindings are active in Insert, Normal, and Visual modes
unless noted.
.IP
.nf
\f[C]
Binding Action
─────────────────────────────────────────────────────────────────────
Ctrl+G Insert the head of the previous command\[aq]s last path
argument. Equivalent to !$:h in Bash.
Example: previous = \[dq]cd /usr/local/bin\[dq]
Ctrl+G inserts \[dq]/usr/local\[dq]
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 = \[dq]echo this is a test\[dq]
type \[dq]this is/that was\[dq], press Ctrl+F
result = \[dq]echo that was a test\[dq]
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: \[dq]mkdir new_folder\[dq] -> \[dq] new_folder\[dq]
Ctrl+Alt+= Evaluate the current command line buffer with
Qalculate! (qalc) and print the result inline.
Requires qalc to be installed.
Example: type \[dq]150 * 1.08\[dq], 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.).
\[at]\[at] FZF inline picker. Type \[at]\[at] anywhere on the command
line to open an fzf picker and insert a selection
at the cursor position.
Ctrl+Right Accept autosuggestion one word/directory segment
at a time. (Restores Fish 3.x behavior by binding
to nextd-or-forward-word).
\f[R]
.fi
.SS FZF Bindings (bundled from PatrickF1/fzf.fish)
.IP
.nf
\f[C]
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
\f[R]
.fi
.PP
* * * * *
.SH 4. ABBREVIATIONS
.PP
Abbreviations expand when you press Space or Enter.
They are terminal-aware: some expand differently in Kitty vs WezTerm vs
other terminals.
.SS 4.1 Editors
.IP
.nf
\f[C]
n / nv / neovim nvim
e edit
se sudoedit
k kate
editt Open new tab with nvim (terminal-aware)
cdnv cd \[ti]/.config/nvim
cdnvn cd \[ti]/.config/nvim; nvim
\f[R]
.fi
.SS 4.2 Navigation and Listing
.IP
.nf
\f[C]
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)
\f[R]
.fi
.SS 4.3 Git
.IP
.nf
\f[C]
g git
lg lazygit
gitig / git-ignore gi (generate .gitignore)
\f[R]
.fi
.SS 4.4 Terminal Windows, Tabs, and Panes
.PP
These abbreviations control the terminal emulator.
Each has a Kitty variant and a WezTerm variant; the correct one is
inserted based on \f[V]$TERM\f[R] or \f[V]$TERM_PROGRAM\f[R].
.IP
.nf
\f[C]
: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)
\f[R]
.fi
.PP
Quick-navigate shortcuts open windows/tabs/panes with preset working
dirs:
.IP
.nf
\f[C]
:tgk New tab at \[ti]/.config/kitty
:tgn New tab at \[ti]/.config/nvim
:tgf New tab at \[ti]/.config/fish
:tgh New tab at \[ti]
:tgcz New tab at chezmoi source dir
:tgcm New tab at chezmoi source dir
:tgp New tab at \[ti]/projects
:tgr New tab at / (root)
\f[R]
.fi
.PP
Prefixes :wg* and :wvg* / :whg* open OS windows or splits to the same
set of dirs, respectively.
.PP
Prefixes :cd* open tabs with a quick cd shortcut:
.IP
.nf
\f[C]
:cdn cd \[ti]/.config/nvim
:cdf cd \[ti]/.config/fish
:cdh cd \[ti]
:cdcz cd to chezmoi source
:cdp cd \[ti]/projects
\f[R]
.fi
.PP
Appending n to any :cd* abbreviation also runs nvim after changing dir.
.SS 4.5 Chezmoi
.IP
.nf
\f[C]
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
\f[R]
.fi
.SS 4.6 Docker
.IP
.nf
\f[C]
dcl docker context use default
dcls docker context ls
lzd ld (lazydocker)
\f[R]
.fi
.SS 4.7 Systemctl
.IP
.nf
\f[C]
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
\f[R]
.fi
.SS 4.8 AI Assistants
.IP
.nf
\f[C]
ag agy
ag. agy .
v antigravity-ide
s wezterm ssh (WezTerm only)
\f[R]
.fi
.SS 4.9 History Expansion
.PP
These are implemented as keybinding helpers, but can also be typed:
.IP
.nf
\f[C]
!\[ha] 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)
\f[R]
.fi
.SS 4.10 Miscellaneous
.IP
.nf
\f[C]
/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
\f[R]
.fi
.SS 4.11 Shell Aliases
.PP
These aliases are defined in conf.d/tricks.fish via alias (which creates
Fish functions).
They are active in all interactive sessions.
.SS Navigation
.IP
.nf
\f[C]
\&.. cd ..
\&... cd ../..
\&.... cd ../../..
\&..... cd ../../../..
\&...... cd ../../../../..
\f[R]
.fi
.SS Color Overrides
.PP
Force color output for common tools:
.IP
.nf
\f[C]
grep grep --color=auto
fgrep fgrep --color=auto
egrep egrep --color=auto
dir dir --color=auto
vdir vdir --color=auto
\f[R]
.fi
.SS Safety Wrappers
.PP
Add -i (interactive confirmation) to destructive commands:
.IP
.nf
\f[C]
cp cp -i
mv mv -i
\f[R]
.fi
.SS Archives and Networking
.IP
.nf
\f[C]
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
\f[R]
.fi
.SS System Logs
.IP
.nf
\f[C]
jctl journalctl -p 3 -xb Show priority-3 (error) journal entries
from the current boot
\f[R]
.fi
.PP
* * * * *
.SH 5. FUNCTIONS REFERENCE
.SS 5.1 File and Directory
.SS cat
.IP
.nf
\f[C]
Synopsis: cat [args...]
Enhanced cat replacement. Wraps bat for files, giving syntax highlighting
and line numbers; passes directories to ls; falls back to raw cat for
ANSI-colored log files, and finally to /usr/bin/cat if bat is not
installed.
Arguments:
args... Files or directories to display
Example:
cat README.md
cat \[ti]/projects/myapp
\f[R]
.fi
.SS copy
.IP
.nf
\f[C]
Synopsis: copy <source> <dest>
Wrapper for cp that strips trailing slashes from source directories,
preventing unwanted nested copies when the destination already exists.
Arguments:
source Source file or directory
dest Destination path
Example:
copy ./mydir/ \[ti]/backup
copy ./mydir/ \[ti]/backup # copies mydir INTO backup, not backup/mydir/
\f[R]
.fi
.SS du
.IP
.nf
\f[C]
Synopsis: du [--disk|--dir|--dua] [args...]
Smart disk-usage dispatcher. Without flags, routes to the most appropriate
tool by context; explicit flags force one. Falls back to system du when the
preferred tool is not installed.
Arguments:
--disk Force duf (disk-level free/used overview)
--dir Force dust (per-directory tree breakdown)
--dua Force dua (fast interactive space analyzer)
args... Files/directories or flags forwarded to the selected tool
Example:
du \[ti]/Downloads
du --disk
\f[R]
.fi
.SS dusize
.IP
.nf
\f[C]
Synopsis: dusize [dir]
Shows a human-readable disk usage summary using du -sh. Defaults to the
current directory if no argument is given.
Arguments:
dir Directory to summarize (defaults to current directory)
Example:
dusize \[ti]/Downloads
dusize \[ti]/Videos
\f[R]
.fi
.SS lD
.IP
.nf
\f[C]
Synopsis: lD [args...]
Lists only directories in long format with icons and hyperlinks. Uses eza,
falls back to lsd, then to system ls.
Arguments:
args... Arguments forwarded to the listing command
Example:
lD \[ti]/projects
\f[R]
.fi
.SS ls
.IP
.nf
\f[C]
Synopsis: ls [args...]
Lists all files in long format with icons and hyperlinks. Uses eza,
falls back to lsd, then to system ls.
Arguments:
args... Arguments forwarded to the listing command
Example:
ls \[ti]/projects
ls
ls -a \[ti]/projects
\f[R]
.fi
.SS lsr
.IP
.nf
\f[C]
Synopsis: lsr [args...]
Lists files sorted by modification time in reverse (oldest first), one
per line with icons. Uses eza, falls back to lsd, then to system ls.
Arguments:
args... Arguments forwarded to the listing command
Example:
lsr \[ti]/projects
\f[R]
.fi
.SS lss
.IP
.nf
\f[C]
Synopsis: lss [args...]
Lists all files sorted by size in long format with gradient color scaling.
Uses eza, falls back to lsd, then to system ls.
Arguments:
args... Arguments forwarded to the listing command
Example:
lss \[ti]/downloads
\f[R]
.fi
.SS lstree
.IP
.nf
\f[C]
Synopsis: lstree [args...]
Displays a full recursive tree of the current directory with icons.
Uses eza, falls back to lsd, then to system ls -R.
Arguments:
args... Arguments forwarded to the listing command
Example:
lstree \[ti]/projects/myapp
\f[R]
.fi
.SS lt
.IP
.nf
\f[C]
Synopsis: lt [args...]
Displays a directory tree limited to depth 2 with icons. Uses eza,
falls back to lsd, then to system ls -R.
Arguments:
args... Arguments forwarded to the listing command
Example:
lt \[ti]/projects
\f[R]
.fi
.SS ltr
.IP
.nf
\f[C]
Synopsis: ltr [args...]
Lists all files sorted by modification time in reverse (oldest first) in
long format with age-based gradient color scaling. Uses eza, falls back
to lsd, then to system ls.
Arguments:
args... Arguments forwarded to the listing command
Example:
ltr \[ti]/projects
\f[R]
.fi
.SS lx
.IP
.nf
\f[C]
Synopsis: lx [args...]
Lists all files sorted by file extension in long format with icons. Uses
eza, falls back to lsd, then to system ls -lX.
Arguments:
args... Arguments forwarded to the listing command
Example:
lx \[ti]/projects
\f[R]
.fi
.SS mkcd
.IP
.nf
\f[C]
Synopsis: mkcd [-s | --silent] <dir>
Creates a directory (including any missing parent directories) and
immediately changes into it. Prints a tree of created directories by
default, or suppresses output with -s. Delegates creation to
_fish_mkdir_p.
Arguments:
-h, --help Show usage help
-s, --silent Suppress directory creation output
<dir> Directory to create and enter
Exit Status:
0 Directory created (or already existed) and entered successfully
1 Directory creation or cd failed
Example:
mkcd \[ti]/projects/myapp
mkcd \[ti]/projects/newapp/src
\f[R]
.fi
.SS mkdir
.IP
.nf
\f[C]
Synopsis: mkdir [args...]
Interactive wrapper around mkdir that calls _fish_mkdir_p for each
directory argument to display created path components. Falls back to
command mkdir -p when flags (e.g. -m 755) are present, and to plain
command mkdir in non-interactive contexts.
Arguments:
args... Directories to create, or flags passed through to command mkdir
Example:
mkdir \[ti]/projects/myapp/src
\f[R]
.fi
.SS poke
.IP
.nf
\f[C]
Synopsis: poke <file> [file...]
Creates files using touch, automatically creating any missing parent
directories via _fish_mkdir_p with tree output.
Arguments:
file One or more file paths to create
Exit Status:
0 Files created
1 No file argument provided
Example:
poke \[ti]/projects/new/src/main.fish
\f[R]
.fi
.SS rg
.IP
.nf
\f[C]
Synopsis: rg [args...]
Wraps ripgrep with --hyperlink-format=kitty when running inside Kitty
terminal, enabling clickable file links in search results. Falls back
to plain rg on other terminals.
Arguments:
args... Arguments forwarded to ripgrep
Example:
rg \[dq]TODO\[dq] src/
rg \[dq]fish_greeting\[dq] \[ti]/.config/fish/
rg -l \[dq]TODO\[dq] \[ti]/projects/myapp
\f[R]
.fi
.SS rm
.IP
.nf
\f[C]
Synopsis: rm [-e [options] | -S | args...]
Enhanced rm that routes deletions through trash when safe. With no
arguments, lists current trash contents. -e/--empty empties the trash
(with optional trash-empty sub-arguments). -S/--secure permanently
deletes via rm -rf and triggers fstrim. Plain paths and -r/-R are sent
to trash put; any other flags fall back to system rm.
Opinionated component (C1): when disabled via __fish_config_op_aliases
(or the __fish_config_opinionated master), behaves exactly like bare
command rm \[em] no wrapper, no trash, no trapping.
Arguments:
(none) List current trash contents
-e, --empty [opts] Empty the trash; opts forwarded to trash empty
-S, --secure Permanently delete targets and run fstrim (irreversible)
-r, -R, --recursive Forwarded to trash put alongside path arguments
args... Files or paths to trash or remove
Exit Status:
0 Operation succeeded
1 trash put failed or file not found
Notes:
Falls back to /usr/bin/rm when trash is unavailable.
Example:
rm file.txt
rm -e
rm -S sensitive_key.pem
\f[R]
.fi
.SS scrub
.IP
.nf
\f[C]
Synopsis: scrub [-a] [-d] [-h]
Recursively finds and removes OS metadata, editor artifacts, compiler
garbage, and dev caches from the current directory using fd. Routes
deletions through the custom rm function, trashy, trash-cli, or system
rm -rf in that priority order. Aggressive mode adds node_modules, logs,
IDE directories, and AI tool artifacts.
Arguments:
-a, --aggressive Also purge node_modules, *.log, .cache, .idea, AI artifacts
-d, --dry-run Show targets without deleting
-h, --help Show usage help
Exit Status:
0 Sweep completed (or dry run shown)
1 fd not found, or unknown argument provided
Example:
scrub
scrub -a
scrub -d
\f[R]
.fi
.SS 5.2 Navigation
.SS cdi
.IP
.nf
\f[C]
Synopsis: cdi [query]
Alias for zi \[em] opens zoxide\[aq]s interactive directory picker for jumping to
frequently-visited directories using fzf.
Arguments:
query Optional search term to pre-filter the directory list
Example:
cdi myproject
\f[R]
.fi
.SS clone
.IP
.nf
\f[C]
Synopsis: clone [args...]
Alias for clone-in-kitty that clones a repository into a new Kitty terminal
window. Only works inside the Kitty terminal.
Arguments:
args... Arguments forwarded to clone-in-kitty (typically a repo URL)
Exit Status:
0 Repository cloned
1 Not running inside Kitty terminal
Example:
clone https://github.com/user/repo.git
\f[R]
.fi
.SS clonet
.IP
.nf
\f[C]
Synopsis: clonet [args...]
Alias for clone-in-kitty --type=tab that clones a repository into a new
Kitty terminal tab. Only works inside the Kitty terminal.
Arguments:
args... Arguments forwarded to clone-in-kitty (typically a repo URL)
Exit Status:
0 Repository cloned
1 Not running inside Kitty terminal
Example:
clonet https://github.com/user/repo.git
\f[R]
.fi
.SS 5.3 Editors and Viewers
.SS edit
.IP
.nf
\f[C]
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 get the terminal editor
($EDITOR), while detached invocations (desktop shortcuts) get 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
Arguments:
FILE... Files to open (any number)
-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, where supported)
-v, --verbose Print the launch command and let editor output through
-s, --silent Suppress all output, including the editor\[aq]s
-h, --help Show this help message
Exit Status:
0 Editor launched successfully
1 Conflicting flags, no editor found, or clipboard read failed
Example:
edit notes.txt
edit --visual \[ti]/.config/fish/config.fish
edit --terminal --new todo.md
edit --editor=code --clipboard
edit --text=\[dq]hello world\[dq]
\f[R]
.fi
.SS fc
.IP
.nf
\f[C]
Synopsis: fc [command_prefix]
Edits the last shell command -- or the most recent one matching a
prefix -- in $EDITOR, then executes the result. Bash-style fc
behaviour. Falls back to vi when $EDITOR is unset, and aborts without
executing if the buffer is left empty.
Arguments:
command_prefix Search history for the newest command matching this
Exit Status:
The edited command\[aq]s exit status, or a message when history lookup
found nothing.
Example:
fc
fc git
\f[R]
.fi
.SS less
.IP
.nf
\f[C]
Synopsis: less [args...]
Pager wrapper that tries $PAGER, then ov, then less, then more, then cat
as fallbacks in that order.
Arguments:
args... Files or options forwarded to the pager
Example:
less /var/log/syslog
\f[R]
.fi
.SS rawfish
.IP
.nf
\f[C]
Synopsis: rawfish [args...]
Launches a Fish shell with NO_TMUX=1 set, bypassing any tmux
auto-attach or session management hooks.
Arguments:
args... Arguments forwarded to fish
Example:
rawfish
\f[R]
.fi
.SS view
.IP
.nf
\f[C]
Synopsis: view [args...]
Opens files in nvim read-only mode (-R). Falls back to less if nvim
is not installed.
Arguments:
args... Files or options forwarded to nvim -R or less
Example:
view /etc/fstab
\f[R]
.fi
.SS 5.4 Git and Version Control
.SS auto-pull
.IP
.nf
\f[C]
Synopsis: auto-pull [list]
auto-pull add [PATH]
auto-pull remove <NAME|PATH>
auto-pull status
Manages the auto-pull registry: the list of repositories that are
background fast-forwarded when you enter them (see conf.d/auto-pull.fish
and _auto_pull_sync). The fish-config repo is always covered as a baseline
and does not need to be added. The registry is a plain text file, one
absolute git-toplevel path per line, stored machine-locally at
$__fish_user_dots_path/auto-pull.list (defaults to
\[ti]/.config/.user-dots/fish/auto-pull.list) and never committed.
Registry management works regardless of the C2 auto-execution guard; only
the background sync itself is gated by __fish_config_op_autoexec.
Arguments:
list Show registered repos (default when no subcommand given)
add [PATH] Register PATH\[aq]s git root; defaults to the current repo
remove <NAME|PATH> Unregister by basename or exact path
status Show enabled/disabled state, repo count, and registry path
-h, --help Show this help message
Exit Status:
0 Subcommand succeeded
1 Bad usage, target is not a git repo, or target not registered
Example:
cd \[ti]/src/qmk_firmware; and auto-pull add
auto-pull add \[ti]/work/api
auto-pull list
auto-pull remove qmk_firmware
\f[R]
.fi
.SS branch
.IP
.nf
\f[C]
Synopsis: branch <branch_name>
Switches to a local git branch, creating it if it does not already
exist. Extra arguments are forwarded to git checkout.
Arguments:
branch_name Branch to switch to or create
Exit Status:
0 Branch checked out or created
1 Not inside a git work tree
Example:
branch feature/new-ui
\f[R]
.fi
.SS gi
.IP
.nf
\f[C]
Synopsis: gi [-h] [-b] [-p] [-s] [-l] [targets...]
Generates .gitignore content by querying the gitignore.io API. Appends
results to the repository\[aq]s .gitignore with MD5-based deduplication \[em]
patterns already present are not re-appended \[em] or prints to stdout with
-s. Supports generic boilerplate and interactive prompt modes.
Arguments:
-h, --help Show help message
-d, --description Show the function description
-l, --list List all supported targets from the API
-b, --boilerplate Append boilerplate from $GITIGNORE_BOILERPLATE
-p, --prompt Prompt for patterns to append
-s, --stdout Print API output to stdout instead of .gitignore
targets Comma- or space-separated list of language/tool names
Exit Status:
0 Patterns appended, or resolved with -s/--stdout or -l/--list
1 Not in a git repository or API fetch failed
Returns:
With -s/--stdout, the fetched .gitignore pattern text, printed to stdout.
With -l/--list, the supported target list, printed to stdout.
Example:
gi python,venv
gi -b -p
gi -s node > .gitignore
\f[R]
.fi
.SS git-clean
.IP
.nf
\f[C]
Synopsis: git-clean [-h] [-f]
Fetches and prunes the remote, fast-forwards the current branch, and
deletes local branches whose tracking remote has been deleted. Switches to
main/master automatically if the current branch is orphaned.
Arguments:
-h, --help Show help message
-f, --force Force-delete unmerged orphaned branches (git branch -D)
Exit Status:
0 Cleanup complete
1 Argument parsing failed
Example:
git-clean --force
git-clean
\f[R]
.fi
.SS gitui
.IP
.nf
\f[C]
Synopsis: gitui [args...]
Launches gitui with the Catppuccin Frappe theme (frappe.ron), passing any
additional arguments through to the gitui command.
Arguments:
args... Arguments forwarded to the gitui command
Example:
gitui
\f[R]
.fi
.SS gitup
.IP
.nf
\f[C]
Synopsis: gitup [args...]
Fetches updates from the remote and shows git status. Extra arguments
are forwarded to git fetch.
Arguments:
args... Forwarded verbatim to git fetch
Exit Status:
0 Fetch and status succeeded
1 Not inside a git work tree
Example:
gitup
gitup --all
\f[R]
.fi
.SS hist
.IP
.nf
\f[C]
Synopsis: hist
Searches fish history interactively using fzf, inserts the selected command
into the command line, and copies it to the clipboard via wl-copy.
Example:
hist
\f[R]
.fi
.SS 5.5 Package Management
.SS cleanup
.IP
.nf
\f[C]
Synopsis: cleanup
Identifies and removes Arch Linux orphan packages using pacman. Logs
package names and versions to \[ti]/.removed_orphans before removal.
Example:
cleanup
\f[R]
.fi
.SS parur
.IP
.nf
\f[C]
Synopsis: parur
Presents an fzf picker of all installed packages (via pacman -Qqs) with
pacman -Qi previews, then removes the selected packages using paru or yay.
Arch Linux only.
Exit Status:
0 Packages removed or none selected
1 No AUR helper (paru or yay) found
Example:
parur
\f[R]
.fi
.SS pkg
.IP
.nf
\f[C]
Synopsis: pkg [-h] [-i|-u] <package> [package...]
Installs or removes packages using the system\[aq]s available package manager.
Supports paru, yay, pacman, apt, dnf, zypper, yum, brew, and pkg.
In auto mode (no flag), detects whether each package is installed and
toggles it \[em] installing if absent, removing if present.
The package-installed check uses the correct query for each manager:
pacman/paru/yay pacman -Qi
apt dpkg -s
dnf/zypper/yum rpm -q
brew brew list
pkg pkg info
Arguments:
-h, --help Show help message
-i, --install Force install mode
-u, --uninstall Force uninstall mode
package One or more package names to install or remove
Exit Status:
0 Operation completed
1 No supported package manager found, unknown flag, or package operation failed
Example:
pkg firefox
pkg -i ripgrep fd-find
pkg -u cowsay
\f[R]
.fi
.SS search
.IP
.nf
\f[C]
Synopsis: search [args...]
Delegates to paru or yay for interactive AUR package search and
installation. Falls back to yay if paru is not installed. Arch Linux only.
Arguments:
args... Arguments forwarded to paru or yay
Exit Status:
0 AUR helper ran successfully
1 No AUR helper (paru or yay) found
Example:
search neovim
\f[R]
.fi
.SS upgrade
.IP
.nf
\f[C]
Synopsis: upgrade
Runs a full system upgrade via paru or yay with --noconfirm. Falls
back to yay if paru is not installed. Arch Linux only.
Exit Status:
0 Upgrade completed successfully
1 No AUR helper (paru or yay) found
Example:
upgrade
\f[R]
.fi
.SS 5.6 Dependency Management
.SS check_fish_deps
.IP
.nf
\f[C]
Synopsis: check_fish_deps
Backwards-compatibility wrapper that delegates to fish-deps status to
report which fish shell dependencies are installed or missing.
Example:
check_fish_deps
\f[R]
.fi
.SS fish-deps
.IP
.nf
\f[C]
Synopsis: fish-deps [status|install|update|sync]
Unified command for managing all tools this configuration depends on,
dispatching to subcommand handlers. Defaults to status when no subcommand
is given.
Install method priority (highest to lowest):
1. git+cargo source build (fish shell itself)
2. cargo (Rust tools \[em] 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
Arguments:
status Report installed/missing deps (default)
install Install missing deps interactively
update Update all installed deps
sync Install missing deps, then update all
Exit Status:
0 Subcommand completed
1 Unknown subcommand
Example:
fish-deps sync
fish-deps
fish-deps install
fish-deps update
\f[R]
.fi
.SS fzf-update
.IP
.nf
\f[C]
Synopsis: fzf-update
Installs or upgrades fzf from git HEAD into \[ti]/.fzf. Pulls the latest
changes if \[ti]/.fzf already exists, or clones the repository if not.
Example:
fzf-update
\f[R]
.fi
.SS 5.7 System and Monitoring
.SS limine-edit
.IP
.nf
\f[C]
Synopsis: limine-edit
Opens /boot/limine.conf in sudoedit, then re-enrolls the config hash,
runs CachyOS boot hooks (limine-mkinitcpio), and re-signs all Secure Boot
files tracked by sbctl. Combines the edit and sign steps into a single
command.
Example:
limine-edit
\f[R]
.fi
.SS lock
.IP
.nf
\f[C]
Synopsis: lock
Locks the current desktop session using loginctl lock-session.
Example:
lock
\f[R]
.fi
.SS ports
.IP
.nf
\f[C]
Synopsis: ports
Lists all active TCP listeners on the system using lsof, showing
port numbers and addresses without hostname resolution.
Example:
ports
\f[R]
.fi
.SS sbver
.IP
.nf
\f[C]
Synopsis: sbver [--brief]
Verifies Secure Boot signatures on all EFI binaries tracked by sbctl,
filtering out \[dq]invalid PE header\[dq] noise. Color-codes each file as
verified (green ✓) or unsigned (red ✗) and prints a final summary
count.
Arguments:
--brief Suppress per-file output; show only the final summary
Exit Status:
0 All binaries verified (or summary shown)
1 sbctl is not installed
Example:
sbver
sbver --brief
\f[R]
.fi
.SS screensleep
.IP
.nf
\f[C]
Synopsis: screensleep
Turns off the display after a 1-second delay by invoking the KDE
PowerDevil \[dq]Turn Off Screen\[dq] global shortcut via busctl.
Example:
screensleep
\f[R]
.fi
.SS sudo-toggle
.IP
.nf
\f[C]
Synopsis: sudo-toggle
Toggles the sudo NOPASSWD rule on and off via
/etc/sudoers.d/nofail-toggle. Useful for automated tasks that would
otherwise require a password entry. Clears the sudo credential cache
when re-enabling, so the lockdown takes effect immediately.
Exit Status:
0 Rule toggled
Example:
sudo-toggle
\f[R]
.fi
.SS swapstat
.IP
.nf
\f[C]
Synopsis: swapstat
Displays a colorized memory report showing kernel swappiness,
zRAM compression ratio, zRAM device details (via zramctl), and
active swap priority (via swapon).
Example:
swapstat
\f[R]
.fi
.SS top
.IP
.nf
\f[C]
Synopsis: top [args...]
Wraps btop as a modern replacement for top. Falls back to system top
if btop is not installed.
Arguments:
args... Arguments forwarded to btop or system top
Example:
top
\f[R]
.fi
.SS 5.8 Terminal Management
.SS bkg
.IP
.nf
\f[C]
Synopsis: bkg <command> [args...]
Launches a command in the background, fully detached from the terminal
using nohup. All stdout and stderr output is discarded. Simpler than
detach; no --version flag.
Arguments:
command The command to run detached
args... Additional arguments for the command
Exit Status:
0 Command launched successfully
1 No command provided
Example:
bkg firefox
\f[R]
.fi
.SS detach
.IP
.nf
\f[C]
Synopsis: detach [-h] [--version] <command> [args...]
Runs a command in the background using nohup, fully detached from the
terminal with stdout/stderr discarded. The command survives the current
session.
Arguments:
-h, --help Show help message
--version Show version information
command The command to run detached
args... Additional arguments for the command
Exit Status:
0 Command launched or help/version shown
1 No command provided or unknown option
Example:
detach rsync -a ./data remote:/backup/
\f[R]
.fi
.SS fish_mode_prompt
.IP
.nf
\f[C]
Synopsis: fish_mode_prompt
Empty override. Suppresses fish\[aq]s built-in vi-mode prefix ([N]/[I]/etc.)
that would prepend to the prompt line and break the two-line nim layout.
Vi-mode display is handled inside fish_prompt itself.
Exit Status:
0 Always (function body is empty)
Example:
# Rendered automatically by fish; not called directly.
\f[R]
.fi
.SS fish_prompt
.IP
.nf
\f[C]
Synopsis: fish_prompt
Catppuccin Mocha fallback prompt (nim-style, two-line). Active whenever
the starship prompt is not available \[em] either starship is not installed or
C3 overrides are disabled. Has no external dependencies; uses only fish-provided functions
(set_color, fish_git_prompt, prompt_pwd, prompt_hostname).
Exit Status:
0 Always
Returns:
The rendered two-line prompt, printed to stdout
Example:
# Rendered automatically by fish; not called directly.
\f[R]
.fi
.SS fish_right_prompt
.IP
.nf
\f[C]
Synopsis: fish_right_prompt
Renders the right-side prompt. Always shows a dim timestamp. When the last
command failed, prefixes it with a red ✘ and the exit code. When starship
is installed and C3 overrides are enabled, also shows the active Docker
context (if non-default) \[em] that block is paired with the starship prompt
which already guards on both conditions.
Exit Status:
0 Always
Example:
# Rendered automatically by fish; not called directly.
\f[R]
.fi
.SS split
.IP
.nf
\f[C]
Synopsis: split [-h | -v] [command...]
Opens a new pane split in Kitty or WezTerm, optionally running a
command in it. Defaults to a horizontal (bottom) split. The new pane
inherits the current working directory.
Arguments:
-h, --horizontal Open a horizontal split (default)
-v, --vertical Open a vertical split
command... Command to run in the new pane; opens a bare fish
shell if omitted
Exit Status:
0 Pane opened successfully
1 Not running inside Kitty or WezTerm
Example:
split
split -v nvim README.md
\f[R]
.fi
.SS spwin
.IP
.nf
\f[C]
Synopsis: spwin [args...]
Spawns a new terminal OS window in Kitty (via spawn-window.sh if
present, otherwise kitty \[at] launch) or WezTerm (via wezterm cli spawn).
Arguments:
args... Arguments forwarded to the spawn command
Exit Status:
0 Window opened successfully
1 Not running inside Kitty or WezTerm
Example:
spwin
\f[R]
.fi
.SS ssh
.IP
.nf
\f[C]
Synopsis: ssh [args...]
Wraps ssh with kitten ssh inside Kitty terminal for better terminal
integration (terminfo forwarding, multiplexing, copy/paste support).
Falls back to system ssh on
other terminals.
Arguments:
args... Arguments forwarded to kitten ssh or system ssh
Example:
ssh user\[at]host
\f[R]
.fi
.SS tab
.IP
.nf
\f[C]
Synopsis: tab [args...]
Opens a new tab in Kitty, WezTerm, or Konsole using the current
working directory (or $cdto if set). Arguments are forwarded to the
terminal\[aq]s tab-open command.
Arguments:
args... Arguments forwarded to the terminal\[aq]s launch command
Exit Status:
0 Tab opened successfully
1 No supported terminal found
Example:
tab
\f[R]
.fi
.SS 5.9 Clipboard
.SS p
.IP
.nf
\f[C]
Synopsis: p [args...]
Outputs clipboard contents to stdout. Uses wl-paste on Wayland,
falls back to xclip on X11. Supports -h/--help for usage info.
Arguments:
-h, --help Show usage help
args... Arguments forwarded to the clipboard tool
Exit Status:
0 Clipboard contents read successfully
1 No supported clipboard tool found
Returns:
The clipboard contents, printed to stdout
Example:
p | grep foo
p > file.txt
\f[R]
.fi
.SS paste
.IP
.nf
\f[C]
Synopsis: paste [args...]
Outputs clipboard contents to stdout. Uses wl-paste on Wayland,
falls back to xclip on X11.
Arguments:
args... Arguments forwarded to the clipboard tool
Exit Status:
0 Clipboard contents read successfully
1 No supported clipboard tool found
Returns:
The clipboard contents, printed to stdout
Example:
paste > file.txt
\f[R]
.fi
.SS y
.IP
.nf
\f[C]
Synopsis: y [text...]
Copies text to the system clipboard using wl-copy (Wayland) or xclip (X11).
Reads from stdin when no arguments are given.
Arguments:
text Text to copy; reads from stdin if omitted
Exit Status:
0 Text copied to clipboard
1 No clipboard provider found
Example:
y \[dq]hello world\[dq]
ls | y
cat file.txt | y
\f[R]
.fi
.SS 5.10 Network
.SS fast
.IP
.nf
\f[C]
Synopsis: fast
Displays a styled message indicating that the fast command is unavailable
and suggests using fast-cli instead.
Example:
fast
\f[R]
.fi
.SS fast-cli
.IP
.nf
\f[C]
Synopsis: fast-cli [args...]
Runs a network speed test using the fast.com CLI tool.
Arguments:
args... Arguments forwarded to the fast command
Example:
fast-cli
\f[R]
.fi
.SS gip
.IP
.nf
\f[C]
Synopsis: gip
Fetches and prints both the public IPv4 and IPv6 addresses using
icanhazip.com. Shows \[dq]Not detected\[dq] for any address that times out.
Example:
gip
\f[R]
.fi
.SS gip4
.IP
.nf
\f[C]
Synopsis: gip4
Fetches and prints the machine\[aq]s public IPv4 address using icanhazip.com.
Example:
gip4
\f[R]
.fi
.SS gip6
.IP
.nf
\f[C]
Synopsis: gip6
Fetches and prints the machine\[aq]s public IPv6 address using icanhazip.com.
Prints an error message if IPv6 is unavailable on the current network.
Exit Status:
0 IPv6 address resolved
1 IPv6 unavailable or not supported on this network
Returns:
The machine\[aq]s public IPv6 address, printed to stdout
Example:
gip6
\f[R]
.fi
.SS ping
.IP
.nf
\f[C]
Synopsis: ping [args...]
Wraps prettyping with --nolegend by default for a cleaner display.
Pass --legend to show the legend. Falls back to system ping if
prettyping is not installed.
Arguments:
--legend Show the prettyping legend (overrides default --nolegend)
args... Arguments forwarded to prettyping or system ping
Example:
ping google.com
ping --legend google.com
\f[R]
.fi
.SS qr
.IP
.nf
\f[C]
Synopsis: qr [text...]
Generates a UTF-8 QR code from the given text or from stdin if no
argument is provided. Uses qrencode locally if available, otherwise
falls back to the qrenco.de API via curl.
Arguments:
text... Text to encode; reads from stdin if omitted
Example:
qr \[dq]https://example.com\[dq]
echo \[dq]hello\[dq] | qr
\f[R]
.fi
.SS 5.11 Pager and Logging
.SS logs
.IP
.nf
\f[C]
Synopsis: logs [-h] [-c <category>]
Interactively browses terminal log files (scrollback, paru, yay) sorted
newest-first using fzf. Supports viewing in $PAGER, editing, and deletion.
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.
Arguments:
-h, --help Show help message
-c, --category cat Filter to one category: scrollback, paru, or yay
Exit Status:
0 File viewed or no file selected
1 No log files found
Example:
logs -c paru
logs
logs -c scrollback
\f[R]
.fi
.SS smart_exit
.IP
.nf
\f[C]
Synopsis: smart_exit [-h] [-n]
Closes the shell session. In Kitty, captures the terminal scrollback to a
timestamped log file in $SCROLLBACK_HISTORY_DIR before exiting.
Automatically prunes junk and the oldest logs when the count exceeds
$SCROLLBACK_HISTORY_MAX_FILES.
Arguments:
-h, --help Show help message
-n, --no-log Exit without saving a scrollback log
Exit Status:
0 Shell session exited
1 Argument parsing failed
Notes:
The exit builtin is wired to smart_exit for interactive sessions. Typing
\[ga]exit\[ga] or Ctrl+D behaves identically to calling smart_exit directly.
Example:
smart_exit
smart_exit --no-log
\f[R]
.fi
.SS sponge_filter_secrets
.IP
.nf
\f[C]
Synopsis: sponge_filter_secrets <command> <exit_code> <previously_in_history>
Custom sponge filter that prevents commands from being stored in history
when they contain the literal value of any exported environment variable
whose name indicates it holds a credential (TOKEN, PASSWORD, SECRET,
API_KEY, etc.). This catches shell-expansion leakage where a variable
value is embedded directly in the command string at execution time \[em] a
case that static regex patterns cannot cover.
Any variable whose name matches the sensitive-name heuristic and whose
value is longer than 8 characters (excluding bare paths) is checked.
The value is escaped for literal regex matching before comparison.
Arguments:
command The exact command that was entered
exit_code Exit code of the command (unused)
previously_in_history \[dq]true\[dq]/\[dq]false\[dq] flag (unused)
Exit Status:
0 Command contains a secret value \[em] filter out of history
1 No secret value found \[em] keep in history
Example:
# Register with sponge (done automatically by conf.d/sponge_privacy.fish):
set -U -a sponge_filters sponge_filter_secrets
\f[R]
.fi
.SS 5.12 AI and Developer Tools
.SS agents-init
.IP
.nf
\f[C]
Synopsis: agents-init [-a | --agents] [-p | --plugins] [-v | --verbose]
[-q | --quiet] [-s | --silent] [-h | --help]
Scaffolds an AGENTS/ sub-repository inside a project directory. Creates
a self-contained git repo for agent specifications, moves any existing
agent-related files into it, and replaces them with symlinks so the outer
project never tracks agent files directly.
File layout after setup:
AGENTS/AGENTS.md canonical agent spec (real file)
AGENTS/CLAUDE.md real file (if CLAUDE.md existed separately)
or symlink → AGENTS.md (single-source case)
<root>/AGENTS.md → AGENTS/AGENTS.md
<root>/CLAUDE.md → AGENTS/CLAUDE.md
AGENTS/plans superpowers plans (real dir, .gitkeep)
AGENTS/specs superpowers specs (real dir, .gitkeep)
AGENTS/devlogs agent development logs (real dir, .gitkeep)
AGENTS/.version MAJOR.MINOR.PATCH structure version (seed 1.0.0)
AGENTS/.agents-tools/ committed version-bump script + git hook shims
docs/superpowers/plans → ../../AGENTS/plans (always)
docs/superpowers/specs → ../../AGENTS/specs (always)
docs/plans → ../AGENTS/plans (only if docs/plans existed)
docs/specs → ../AGENTS/specs (only if docs/specs existed)
docs/devlogs → ../AGENTS/devlogs (only if docs/devlogs existed)
plans/ and specs/ are merged from every legacy location (docs/<tgt>,
docs/superpowers/<tgt>, and the old AGENTS/plugins/ layout) into the
canonical AGENTS/<tgt>; the AGENTS/plugins/ layer is removed.
Each AGENTS repo carries a self-contained version bumper wired via
core.hooksPath: a pre-commit hook bumps AGENTS/.version on every commit
(MINOR when the tracked directory set changes, PATCH otherwise; MAJOR is
manual-only), and a prepare-commit-msg hook appends \[dq](vX.Y.Z)\[dq] to the
commit subject. Each shim then chains (execs) to the global/system
core.hooksPath hook of the same name, so this local override does not
shadow global hooks (e.g. ggshield, Git LFS). The script/hooks are
version-managed from scripts/agents-tools/ and refreshed when their marker
is stale.
Downstream tooling can read AGENTS/.version directly \[em] a changed MINOR
field signals a structure change.
With no flags, runs both --agents and --plugins setup; --agents re-runs
only the AGENTS.md / symlink step and --plugins only the plans/specs/
devlogs wiring step. Managed paths are added to .gitignore. The sub-repo
is pulled first when it has an upstream, and at the end of every
invocation any uncommitted changes inside it are auto-committed so
agent-made edits are captured automatically. Fully idempotent: a second
run produces no output and no new commits.
Called automatically by the claude and agy wrappers on every invocation.
Arguments:
-a, --agents Set up AGENTS/ repo + AGENTS.md / CLAUDE.md symlinks only
-p, --plugins Set up AGENTS/ repo + plans/specs/devlogs dirs + docs/ symlinks only
-v, --verbose Print all per-step output (default)
-q, --quiet Print one summary line only if changes were made
-s, --silent Suppress all output; errors only (standard UNIX convention)
-h, --help Show this help message and exit
Exit Status:
0 Setup completed successfully
1 Fatal error (git init failed, move failed, etc.)
Example:
agents-init
agents-init --agents
agents-init --plugins
agents-init --quiet
\f[R]
.fi
.PP
\f[B]Used by:\f[R] \f[V]agy\f[R], \f[V]claude\f[R]
.SS agy
.IP
.nf
\f[C]
Synopsis: agy [ARGS...]
Wrapper for the agy Antigravity AI CLI that ensures the AGENTS/
sub-repository is initialized and any agent-made changes are committed
before launch. Delegates all scaffold and commit logic to agents-init
--quiet (full setup), which ensures AGENTS/ is scaffolded and CLAUDE.md
is symlinked to AGENTS/AGENTS.md in the current project. Arguments are
forwarded verbatim to the real agy binary, except for -r/--resume which
are translated to -c/--continue.
Opinionated component (C1): when disabled via __fish_config_op_aliases
(or the __fish_config_opinionated master), the command is passed through
to the real agy binary unchanged.
Arguments:
ARGS Arguments forwarded to the underlying agy binary (-r translates to -c)
Exit Status:
Exit status of the underlying agy binary
Example:
agy
agy --resume
agy -i \[dq]initial prompt\[dq]
agy models
\f[R]
.fi
.PP
\f[B]Dependencies:\f[R] \f[V]agents-init\f[R]
.SS antigravity-ide
.IP
.nf
\f[C]
Synopsis: antigravity-ide [args...]
Wrapper for the antigravity-ide command that filters a known noisy warning
about an unrecognized \[aq]app\[aq] option from stderr.
Arguments:
args... Arguments passed through to the antigravity-ide command
Example:
antigravity-ide
\f[R]
.fi
.SS claude
.IP
.nf
\f[C]
Synopsis: claude [ARGS...]
Wrapper for the claude CLI that ensures the AGENTS/ sub-repository is
initialized and any agent-made changes are committed before launch.
Delegates all scaffold and commit logic to agents-init --quiet (full
setup), which ensures AGENTS/ is scaffolded and CLAUDE.md is symlinked
to AGENTS/AGENTS.md in the current project.
All arguments are forwarded verbatim to the real claude binary.
Opinionated component (C1): when disabled via __fish_config_op_aliases
(or the __fish_config_opinionated master), the command is passed through
to the real claude binary unchanged.
Arguments:
ARGS Any arguments forwarded verbatim to the underlying claude binary
Exit Status:
Exit status of the underlying claude binary
Example:
claude
claude --resume
claude \[dq]Explain the recent changes\[dq]
\f[R]
.fi
.PP
\f[B]Dependencies:\f[R] \f[V]agents-init\f[R]
.SS claude-docs
.IP
.nf
\f[C]
Synopsis: claude-docs
Invokes Claude Code to analyze recent repository changes and update
README.md, ensuring all features and examples are accurate and pruning
obsolete content.
Example:
claude-docs
\f[R]
.fi
.SS claude-pr
.IP
.nf
\f[C]
Synopsis: claude-pr
Invokes Claude Code to perform a full PR workflow: create a kebab-case
branch, write a Conventional Commit, run verification, push, and open a
pull request with a manual verification checklist.
Example:
claude-pr
\f[R]
.fi
.SS dops
.IP
.nf
\f[C]
Synopsis: docker [subcommand] [args...]
Wrapper for docker that intercepts the ps subcommand and redirects it to
the dops function for enhanced container listing. All other subcommands are
passed through to the real docker binary.
Arguments:
subcommand Docker subcommand (ps is redirected to dops)
args... Arguments forwarded to docker or dops
Example:
docker ps
\f[R]
.fi
.SS qc
.IP
.nf
\f[C]
Synopsis: qc [prompt...]
Quick-chat wrapper around the aichat LLM CLI that defaults to the \[dq]cli\[dq]
role \[em] a system prompt tuned for concise, terminal-friendly output.
Resolves the aichat config directory (honoring $XDG_CONFIG_HOME), creates
it if missing, and on first use installs the bundled role by symlinking
scripts/cli-agent.md to $XDG_CONFIG_HOME/aichat/roles/cli.md. 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 \[ga]qc --help\[ga] for
aichat\[aq]s full flag reference with the command name rewritten to qc.
Arguments:
prompt... Prompt forwarded to aichat
-h, --help Show usage help
Exit Status:
aichat\[aq]s exit status.
Example:
qc \[dq]how do I list open ports on linux?\[dq]
qc -m ollama:llama3 \[dq]explain this error\[dq]
qc --role coder \[dq]refactor this function\[dq]
\f[R]
.fi
.SS superpowers
.IP
.nf
\f[C]
Synopsis: superpowers [on|off] [-g]
Enables or disables the superpowers plugin for both antigravity-cli
(workspace scope) and Claude (project scope). Use -g/--global to apply
at the user scope instead of workspace/project.
Arguments:
on Enable superpowers for both tools
off Disable superpowers for both tools
-g, --global Apply at user/global scope instead of workspace/project
-h, --help Show usage help
Exit Status:
0 Mode applied successfully
1 No on/off mode specified
Example:
superpowers on
superpowers off -g
\f[R]
.fi
.SS 5.13 Media and Utilities
.SS dng2avif
.IP
.nf
\f[C]
Synopsis: dng2avif [-h] [-i <file>] [-o <file>] [-q <n>] [-s <n>] [input.dng]
Converts a DNG raw image to a 10-bit HDR AVIF using a three-step pipeline:
develop with ImageMagick, encode with ffmpeg+avifenc, sync metadata with
exiftool. Requires magick, ffmpeg, avifenc, and exiftool.
Arguments:
-i, --input FILE Input DNG file
-o, --output FILE Output AVIF file (defaults to input basename)
-q, --quality N Encoding quality 0-100 (default: 92)
-s, --speed N Encoder speed 0-10 (default: 3, 0 = slowest)
-h, --help Show help message
Exit Status:
0 Conversion complete
1 File not found, missing dependency, or encode step failed
Example:
dng2avif photo.dng
dng2avif -q 85 -s 5 -i shot.dng -o out.avif
\f[R]
.fi
.SS spark
.IP
.nf
\f[C]
Synopsis: spark [--min=<n>] [--max=<n>] [numbers...]
Renders a Unicode sparkline bar chart for a sequence of numbers.
Reads numbers from arguments or from stdin if none are provided.
Optional --min and --max clamp the scale range.
Arguments:
--min=<n> Minimum value for scale (default: list minimum)
--max=<n> Maximum value for scale (default: list maximum)
numbers... Space-separated numbers to chart; reads stdin if omitted
-v, --version Print version
-h, --help Show usage help
Example:
spark 1 1 2 5 14 42
seq 64 | sort --random-sort | spark
echo \[dq]3 7 2 9 1\[dq] | spark
\f[R]
.fi
.SS steam-dl
.IP
.nf
\f[C]
Synopsis: steam-dl
Launches Steam with systemd-inhibit to prevent the system from idling
or sleeping during active downloads.
Example:
steam-dl
\f[R]
.fi
.SS yt-dlp
.IP
.nf
\f[C]
Synopsis: yt-dlp [args...] URL [URL...]
Wraps yt-dlp, injecting sane embedding + SponsorBlock defaults
(--sponsorblock-remove all, --embed-subs, --embed-metadata,
--embed-thumbnail). Each default is suppressed if the user already
passes that flag, its alias, or its negation (e.g. --no-embed-thumbnail
drops our --embed-thumbnail; --no-sponsorblock or your own
--sponsorblock-remove drops ours). All other arguments pass through
untouched. --help and friends fall through to real yt-dlp.
Opinionated component (C1): when disabled via __fish_config_op_aliases
(or the __fish_config_opinionated master), passes straight through to
the system yt-dlp with no defaults injected.
Arguments:
args... Arguments forwarded to yt-dlp (defaults prepended)
--no-embed-thumbnail Skip thumbnail embedding for this run
Example:
yt-dlp dQw4w9WgXcQ
yt-dlp --no-embed-thumbnail dQw4w9WgXcQ # drops our thumbnail default
\f[R]
.fi
.SS 5.14 Miscellaneous
.SS bash
.IP
.nf
\f[C]
Synopsis: bash [args...]
Switches the current shell session to bash, loading config from the XDG
config directory. Resets $SHELL back to fish on exit.
Arguments:
args... Arguments passed through to the bash command
Example:
bash
\f[R]
.fi
.SS bd-pull
.IP
.nf
\f[C]
Synopsis: bd-pull <owner/repo>
Fetches unlinked issues from a Gitea repository, creates corresponding local
Beads entries, and updates the Gitea issue titles to include the new Bead IDs.
Requires $GITEA_TOKEN and $GITEA_URL to be set.
Arguments:
owner/repo The repository path in owner/name format
Exit Status:
0 Issues linked and synced (or no unlinked issues found)
1 Missing required argument or environment variables
Example:
bd-pull myuser/myproject
bd-pull rootiest/fish-config
\f[R]
.fi
.SS cffetch
.IP
.nf
\f[C]
Synopsis: cffetch [args...]
Clears the screen and displays system information using fastfetch with a
custom config if available. Falls back to neofetch if fastfetch is not installed.
Arguments:
args... Additional arguments forwarded to fastfetch or neofetch
Example:
cffetch
\f[R]
.fi
.SS cheat
.IP
.nf
\f[C]
Synopsis: cheat <topic> [args...]
Displays colorized cheatsheets using cheat -c. Falls back to tldr, then
man, if cheat is not installed.
Arguments:
topic The command or topic to look up
args... Additional arguments forwarded to cheat, tldr, or man
Example:
cheat tar
cheat git
\f[R]
.fi
.SS config-help
.IP
.nf
\f[C]
Synopsis: config-help [section]
config-help --html
config-help [section] --man
config-help --help
Opens the offline fish shell configuration manual in the best available
pager. Falls back through ov -> bat -> man -> less -> cat.
If a section keyword is provided, the pager opens at the first heading
that matches the keyword. Lookup order: docs/fish-config.index (exact
keyword aliases), then a normalized heading scan as fallback.
When opened with ov a sticky navigation hint is shown at the top of the
screen. Section matching is case-insensitive. Pass --html / -w to open
the published documentation website (https://fish.rootiest.fyi/)
in the default browser via xdg-open \[em] deep links to a section aren\[aq]t
supported there, so if a keyword is given a note points you to the site\[aq]s
search box instead. Pass --man / -m to open the compiled man page
(docs/fish-config.1) via \[ga]man -l\[ga]; if a section keyword is given, the
pager opens at the nearest match. Pass --help or -h for usage and the
navigation key reference.
Arguments:
section Optional keyword to jump to a matching section heading
-w, --html Open the published documentation website in the default browser
-m, --man Open the compiled man page via man -l
-h, --help Print usage and navigation reference, then exit
Exit Status:
0 Manual displayed
1 Documentation file not found, or required tool not available
Returns:
With -h/--help, the usage and navigation reference, printed to stdout.
Otherwise, the manual is shown via the resolved pager (not captured stdout).
Notes:
The preferred invocation is \[ga]help config [...]\[ga] \[em] this function is
registered as a handler in the help wrapper so that syntax works
transparently. Direct \[ga]config-help\[ga] calls are also valid.
Example:
config-help
config-help keybindings
config-help pkg
config-help fish-deps
config-help --html
config-help --man
config-help keys --man
config-help --help
config-help pkg --man
\f[R]
.fi
.SS config-settings
.IP
.nf
\f[C]
Synopsis: config-settings [-h | --help]
Opens an interactive full-screen TUI for managing fish config settings
across four pages, without having to type or remember variable names:
Universal \[em] opinionated-category toggles (C1\[en]C6) + master, persistent (set -U)
Session \[em] the same toggles, current shell only (set -g)
Sponge \[em] sponge history-scrubbing settings: delay, successful exit
codes, purge-only-on-exit, allow-previously-successful, and
extra sensitive variable-name tokens
Paths \[em] 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) to step OFF ← DEFAULT → ON; DEFAULT erases
the variable so the master switch / built-in default applies. Value rows
(Sponge, Paths) use Enter to edit inline; ← / h clears to default. List rows
(e.g. Extra secret, OK codes) accept values separated by commas and/or
whitespace \[em] \[dq]A, B\[dq], \[dq]A,B\[dq] and \[dq]A B\[dq] all yield the same two entries.
Tab / Shift-Tab cycle forward / backward through pages.
Changes apply immediately \[em] no confirm step. Always available regardless of
__fish_config_opinionated state.
The Sponge and Paths pages always write universal variables \[em] 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
\[ti]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
Arguments:
-h, --help Print usage and exit
Exit Status:
0 Exited normally (q or Escape pressed)
1 Unknown flag passed
Example:
config-settings
\f[R]
.fi
.PP
\f[B]Used by:\f[R] \f[V]config-toggle\f[R]
.SS config-toggle
.IP
.nf
\f[C]
Synopsis: config-toggle [args...]
Deprecated alias for config-settings. Prints a one-line deprecation
notice to stderr, then delegates all arguments to config-settings.
Arguments:
args Passed through verbatim to config-settings
Exit Status:
Same as config-settings
Example:
config-toggle # opens config-settings with a deprecation notice
\f[R]
.fi
.PP
\f[B]Dependencies:\f[R] \f[V]config-settings\f[R]
.SS config-update
.IP
.nf
\f[C]
Synopsis: config-update [-h | --help] [-f | --force] [-n | --dry-run]
Pulls the latest fish shell configuration from the upstream repository
into \[ti]/.config/fish. Git output is suppressed; status is reported
through colored messages. After a successful pull the function prints a
short summary of changed files; run \[ga]exec fish\[ga] to reload the shell.
Arguments:
-h, --help Show this help message and exit
-f, --force Stash local changes before pulling, then pop the stash
-n, --dry-run Check for upstream changes without applying them
Exit Status:
0 Config updated (or already up to date)
1 Update failed (network error, merge conflict, or not a git repo)
Example:
config-update
config-update --dry-run
config-update --force
\f[R]
.fi
.SS dockup
.IP
.nf
\f[C]
Synopsis: dockup [-h] [directory]
Pulls the latest Docker images and restarts all services in a Docker Compose
project, then prunes dangling images. Accepts an optional target directory.
Arguments:
-h, --help Show help message
directory Path to the compose project (defaults to current directory)
Exit Status:
0 Services updated and running
1 Directory not found or no docker-compose.yml present
Example:
dockup \[ti]/myapp
\f[R]
.fi
.SS ffetch
.IP
.nf
\f[C]
Synopsis: ffetch [args...]
Alias for fastfetch that loads a custom config from \[ti]/.fastfetch.jsonc when
present. Falls back to neofetch if fastfetch is not installed.
Arguments:
args... Arguments forwarded to fastfetch or neofetch
Example:
ffetch
\f[R]
.fi
.SS fzf_configure_bindings
.IP
.nf
\f[C]
Synopsis: fzf_configure_bindings [--directory=<key>] [--git_log=<key>] [--git_status=<key>]
[--history=<key>] [--processes=<key>] [--variables=<key>] [-h]
Installs key bindings for fzf.fish in both insert and default vi modes.
Each binding can be overridden with a custom key or disabled by passing an
empty string. Only runs in interactive mode.
Arguments:
--directory=key Override the directory search binding (default: Ctrl-Alt-F)
--git_log=key Override the git log search binding (default: Ctrl-Alt-L)
--git_status=key Override the git status binding (default: Ctrl-Alt-S)
--history=key Override the history search binding (default: Ctrl-R)
--processes=key Override the processes search binding (default: Ctrl-Alt-P)
--variables=key Override the variables search binding (default: Ctrl-V)
-h, --help Show help message
Exit Status:
0 Bindings installed or help shown
22 Invalid option or positional argument provided
Example:
fzf_configure_bindings --history=ctrl-h
\f[R]
.fi
.SS joplin
.IP
.nf
\f[C]
Synopsis: joplin [args...]
Runs the Joplin CLI with Node deprecation warnings suppressed via
NODE_OPTIONS=--no-deprecation.
Arguments:
args... Arguments forwarded to the joplin command
Exit Status:
0 Joplin ran successfully
1 joplin binary not found in PATH
Example:
joplin ls
\f[R]
.fi
.SS kitty-logging
.IP
.nf
\f[C]
Synopsis: kitty-logging [install | uninstall | status | dismiss] [-h]
Manages the fish-config Kitty scrollback watcher that powers C5 logging.
\[ga]install\[ga] symlinks the canonical watcher into the Kitty config dir (so it
always tracks the source) and wires it into kitty.conf via a
sentinel-marked managed block, commenting out any conflicting active
watcher line to avoid double-capture. \[ga]uninstall\[ga] reverses it. \[ga]status\[ga]
reports wiring, installed watcher version, and C5 logging state. \[ga]dismiss\[ga]
silences 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.
Arguments:
install Symlink the watcher and add the managed block to kitty.conf
uninstall Remove the managed block and the watcher symlink
status Report wiring, watcher version, and C5 logging state
dismiss Stop the per-session reminder
-h, --help Show this help
Exit Status:
0 Success
1 Unknown subcommand/flag, kitty missing, or a write failure
Example:
kitty-logging install
kitty-logging status
\f[R]
.fi
.SS ld
.IP
.nf
\f[C]
Synopsis: ld
Launches lazydocker targeting the currently active Docker context by
resolving the host endpoint from docker context inspect.
Example:
ld
\f[R]
.fi
.SS open-url
.IP
.nf
\f[C]
Synopsis: open-url [-s|--silent] [-v|--verbose] <url>
open-url --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);
--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)
Arguments:
url The URL or file:// URI to open (required)
-s, --silent Suppress success output (the default)
-v, --verbose Print which browser is being launched
-h, --help Print usage and exit
Exit Status:
0 Browser launched
1 No URL given, invalid $BROWSER, or no browser found
Notes:
Typo abbreviation: url-open (expands to open-url on space/enter).
Example:
open-url https://git.rootiest.dev/rootiest/fish-config
open-url -v https://fish.rootiest.fyi/
\f[R]
.fi
.PP
\f[B]Used by:\f[R] \f[V]repo-open\f[R]
.SS replay
.IP
.nf
\f[C]
Synopsis: replay <commands>
Runs the given commands in Bash and replays any resulting environment
variable, alias, and directory changes back into the current Fish
session. Useful for sourcing Bash-only scripts.
Arguments:
commands Bash command string to execute and replay
Exit Status:
0 Commands ran successfully and changes were replayed
1 Bash command exited with a non-zero status
Example:
replay \[dq]source \[ti]/.bashrc\[dq]
replay \[dq]export FOO=bar\[dq]
\f[R]
.fi
.SS repo-open
.IP
.nf
\f[C]
Synopsis: repo-open [-p|--print] [-r|--root]
repo-open --help
Opens the web page for the current repository\[aq]s \[ga]origin\[ga] remote in a
browser (via open-url). Deep-links to the current branch when it exists
on the remote, falling back to the remote\[aq]s default branch (main/master)
otherwise, and to the current sub-directory when invoked below the repo
root.
The remote URL is normalized from both HTTPS and SSH/scp forms
(git\[at]host:owner/repo.git, ssh://\&..., https://\&...). The web path layout is
provider-specific; the provider is resolved in this 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
For a self-hosted host the heuristic can\[aq]t classify (e.g. a Gitea or
GitLab instance on a custom domain), set the provider once:
git config browse.provider gitea
Arguments:
-p, --print Print the resolved URL instead of opening it
-r, --root Ignore the current sub-directory; link to the repo root
-h, --help Print usage and exit
Exit Status:
0 URL opened, or resolved with -p/--print
1 Not a git repo, no origin remote, or browser launch failed
Returns:
With -p/--print, the resolved repository URL, printed to stdout
Notes:
Typo abbreviation: open-repo (expands to repo-open on space/enter).
Example:
repo-open # open current branch (+ subdir) in browser
repo-open --print # just print the URL
repo-open --root # repo home page for the current branch
\f[R]
.fi
.PP
\f[B]Dependencies:\f[R] \f[V]open-url\f[R]
.SS tmux-clean
.IP
.nf
\f[C]
Synopsis: tmux-clean
Kills all detached (unattached) tmux sessions, leaving any currently
attached sessions running.
Example:
tmux-clean
\f[R]
.fi
.SS wake-lock
.IP
.nf
\f[C]
Synopsis: wake-lock <command> [args...]
Runs a command under systemd-inhibit to prevent the system from idling
or sleeping for the duration of the command.
Arguments:
command Command to run with sleep inhibition active
args... Arguments forwarded to the command
Exit Status:
0 Command ran and completed
1 No command provided
Example:
wake-lock rsync -avz src/ dest/
\f[R]
.fi
.SH 6. DEPENDENCY CATALOG
.PP
fish-deps manages these tools.
Run \f[V]fish-deps\f[R] to check status, or \f[V]fish-deps install\f[R]
to install missing ones.
.SS Required
.PP
.TS
tab(@);
l l.
T{
Tool
T}@T{
Description
T}
_
T{
\f[V]fish\f[R]
T}@T{
Fish shell >= 4.0
T}
T{
\f[V]fzf\f[R]
T}@T{
Fuzzy finder
T}
.TE
.SS Integrations
.PP
.TS
tab(@);
l l.
T{
Tool
T}@T{
Description
T}
_
T{
\f[V]wakatime\f[R]
T}@T{
Developer time tracking
T}
T{
\f[V]tailscale\f[R]
T}@T{
Mesh VPN client
T}
.TE
.SS Recommended
.PP
.TS
tab(@);
lw(35.0n) lw(35.0n).
T{
Tool
T}@T{
Description
T}
_
T{
\f[V]cargo\f[R]
T}@T{
Rust toolchain (via rustup); used by \f[V]fish-deps\f[R] to install
Rust-based tools and to build fish from source.
All paths are gated on \f[V]type -q cargo\f[R] and degrade gracefully.
T}
T{
\f[V]starship\f[R]
T}@T{
Cross-shell prompt; loaded via \f[V]type -q starship\f[R] guard.
Without it the Catppuccin nim-style fallback prompt activates.
T}
T{
\f[V]uv\f[R]
T}@T{
Python package and project manager (Astral); used by the
fish-from-source build path in \f[V]fish-deps\f[R].
All consumers degrade gracefully without it.
T}
T{
\f[V]direnv\f[R]
T}@T{
Per-directory environment loading; integration is fully guarded with
\f[V]type -q direnv\f[R].
Without it the direnv hook is simply not loaded and auto-venv activates
normally.
T}
T{
\f[V]paru\f[R]
T}@T{
AUR helper (Arch only; preferred); guarded throughout \[em] non-Arch
systems silently skip AUR-specific paths.
T}
T{
\f[V]yay\f[R]
T}@T{
AUR helper (Arch only; fallback to paru); same guards apply.
T}
T{
\f[V]eza\f[R]
T}@T{
Modern \f[V]ls\f[R] replacement
T}
T{
\f[V]zoxide\f[R]
T}@T{
Smart cd with frecency
T}
T{
\f[V]lsd\f[R]
T}@T{
\f[V]ls\f[R] replacement (fallback to \f[V]eza\f[R])
T}
T{
\f[V]bat\f[R]
T}@T{
Syntax-highlighted \f[V]cat\f[R]
T}
T{
\f[V]btop\f[R]
T}@T{
Modern resource monitor
T}
T{
\f[V]dust\f[R]
T}@T{
Disk usage tree (Rust)
T}
T{
\f[V]duf\f[R]
T}@T{
Disk usage/free overview
T}
T{
\f[V]prettyping\f[R]
T}@T{
Colorized ping wrapper
T}
T{
\f[V]ov\f[R]
T}@T{
Modern pager (replaces \f[V]less\f[R])
T}
T{
\f[V]ripgrep\f[R]
T}@T{
Fast line search
T}
T{
\f[V]lazygit\f[R]
T}@T{
Terminal git UI
T}
T{
\f[V]lazydocker\f[R]
T}@T{
Terminal docker UI
T}
T{
\f[V]trash\f[R]
T}@T{
Safe delete (\f[V]trash-cli\f[R])
T}
T{
\f[V]kitty\f[R]
T}@T{
GPU-accelerated terminal (primary)
T}
T{
\f[V]wezterm\f[R]
T}@T{
GPU-accelerated terminal (alternative)
T}
T{
\f[V]python3\f[R]
T}@T{
Standalone interpreter \[em] used by the \f[V]paru\f[R]/\f[V]yay\f[R]
log cleaner.
Note: \f[V]uv\f[R] does not provide \f[V]python3\f[R] on PATH, and
Arch\[cq]s base does not include it, so it is listed separately.
All consumers degrade gracefully without it.
T}
T{
\f[V]yt-dlp\f[R]
T}@T{
Video/media downloader; backs the \f[V]yt-dlp\f[R] wrapper function.
Optional \[em] the wrapper falls back to the system \f[V]yt-dlp\f[R] and
the rest of the config works without it.
T}
.TE
.SS Install Methods
.PP
The install priority for each tool:
.PP
.TS
tab(@);
lw(35.0n) lw(35.0n).
T{
Method
T}@T{
Packages
T}
_
T{
\f[V]cargo\f[R]
T}@T{
Rust tools (\f[V]eza\f[R], \f[V]lsd\f[R], \f[V]bat\f[R], \f[V]dust\f[R],
\f[V]ov\f[R], \f[V]ripgrep\f[R], \f[V]trashy\f[R], \f[V]zoxide\f[R],
\f[V]starship\f[R]) \[em] always gets the latest crate version
T}
T{
system PM
T}@T{
\f[V]paru\f[R] / \f[V]apt\f[R] / \f[V]brew\f[R] / \f[V]dnf\f[R] / etc.
\[em] for tools without a crate
T}
T{
\f[V]git clone\f[R]
T}@T{
\f[V]fzf\f[R] \[em] installed from GitHub to \f[V]\[ti]/.fzf/\f[R]
T}
T{
\f[V]curl\f[R]
T}@T{
\f[V]starship\f[R] installer, \f[V]fisher\f[R] bootstrap, \f[V]uv\f[R]
installer
T}
.TE
.PP
* * * * *
.SH 7. CUSTOMIZATION
.PP
This section explains how to adapt the configuration to your specific
workflow, including local machine overrides and opinionated component
toggles.
.SS Machine-local Configuration
.PP
Place machine-specific settings that should not be committed to git in:
.IP
.nf
\f[C]
$__fish_user_dots_path/local.fish
\f[R]
.fi
.PP
\f[V]__fish_user_dots_path\f[R] defaults to
\f[V]\[ti]/.config/.user-dots/fish\f[R].
Set a custom location with:
.IP
.nf
\f[C]
set -U __fish_user_dots_path /path/to/your/dots/fish
\f[R]
.fi
.PP
Typical uses: additional PATH entries, local aliases, hostname-specific
env vars, work-specific tool configs.
.PP
For convenience, a git-ignored \f[V]user-dots\f[R] symlink in the fish
config directory tracks \f[V]$__fish_user_dots_path\f[R] so the overlay
can be browsed from \f[V]\[ti]/.config/fish/\f[R].
It is created if missing and repointed if the path changes.
Opt out by setting \f[V]__fish_user_dots_symlink\f[R] to a falsy value,
or toggling \[lq]Dots link\[rq] off on the config-settings Paths page
\[em] 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.
.SS Secrets and API Keys
.IP
.nf
\f[C]
$__fish_user_dots_path/secrets.fish
\f[R]
.fi
.PP
Store API tokens, GPG keys, private credentials here.
This file is never committed.
It is sourced by local.fish directly, not by config.fish.
.PP
\f[V]local.fish\f[R] is sourced at the end of config.fish on every
interactive session, so it and its companion secrets.fish can override
anything set earlier.
.SS Overriding Configuration Variables
.PP
Any variable set in local.fish after the main config loads takes effect.
Example: to increase the scrollback history limit:
.IP
.nf
\f[C]
# in local.fish
set -gx SCROLLBACK_HISTORY_MAX_FILES 200
\f[R]
.fi
.SS Fish Universal Variables
.PP
Some settings (fzf colors, theme) are stored in fish_variables via
\f[V]set -U\f[R].
These are machine-local and git-ignored.
Do not commit fish_variables.
.SS Opinionated Components (Minimal Mode)
.PP
Every opinionated piece of this config is active by default but can be
switched off through six category opt-out variables, each evaluated via
\f[V]__fish_variable_check\f[R].
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 \[em] except for C5 logging, which is opt-in (see
below).
.PP
An explicit per-category truthy value takes precedence over the master
switch: setting \f[V]__fish_config_opinionated\f[R]=0 disables all unset
categories, but a category with an explicit truthy value remains enabled
regardless.
.PP
C5 (logging) is the one exception to \[lq]unset means enabled\[rq].
Because it writes terminal output to disk, it is opt-in: unset means
disabled, and the master switch cannot enable it.
Only an explicit truthy value turns logging on.
.IP
.nf
\f[C]
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 (OPT-IN \[em] this one
is off unless explicitly enabled):
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
\f[R]
.fi
.PP
Examples:
.IP
.nf
\f[C]
# Disable command shadows only (rm becomes plain rm again):
set -U __fish_config_op_aliases off
# Turn session logging on (opt-in; off until you do this):
set -U __fish_config_op_logging on
# Full minimal mode \[em] disable all six categories at once:
set -U __fish_config_opinionated 0
# Re-enable everything (except C5 logging, which stays opt-in):
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)
\f[R]
.fi
.PP
For an interactive alternative to setting these variables by hand, run
config-settings \[em] a full-screen TUI that flips any category
(including C5 logging) on or off, per session or universally.
See its entry in Section 5.
.PP
NOTE: - 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 \f[V]command rm\f[R]
\[em] 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\[cq]s own aliases, history
override, and bang-bang bindings are stripped per category as well.
.SS Prompt and Theme
.SS Starship
.PP
The primary prompt is Starship, initialized by conf.d/starship.fish.
Configure it via \[ti]/.config/starship.toml.
.PP
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\[cq]s built-in prompt handles these markers
automatically.
.SS Catppuccin Fallback Prompt
.PP
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 \[em] fish builtins only.
.PP
Layout:
.IP
.nf
\f[C]
┬─[user\[at]host:\[ti]/path] (main)
╰─>$
\f[R]
.fi
.PP
Elements:
.IP
.nf
\f[C]
user Yellow (Catppuccin Yellow); red if root
\[at]host Blue (local) or Teal (SSH)
\[ti]/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
\f[R]
.fi
.PP
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):
.IP
.nf
\f[C]
✘ 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 ✘)
\f[R]
.fi
.SS FZF
.PP
FZF is themed to Catppuccin Mocha via FZF_DEFAULT_OPTS set in
integrations/fzf.fish.
The colors applied:
.IP
.nf
\f[C]
Background: #1E1E2E (base) #313244 (surface0)
Foreground: #CDD6F4 (text)
Highlights: #F38BA8 (red) #CBA6F7 (mauve) #B4BEFE (lavender)
\f[R]
.fi
.PP
To customize, override FZF_DEFAULT_OPTS in local.fish.
.SS Catppuccin Mocha Syntax Highlighting
.PP
The Catppuccin Mocha theme ships with this config in themes/ and is
applied on first run via \f[V]conf.d/first_run.fish\f[R].
Colors are stored in fish_variables (universal).
To switch variants, install a different theme from themes/:
.IP
.nf
\f[C]
fish_config theme save \[dq]Catppuccin Latte\[dq]
\f[R]
.fi
.PP
\f[V]---\f[R]
.SH 8. COMPONENTS REFERENCE
.PP
The following tables detail every component in each category.
Use this reference to understand exactly which behaviors change when you
toggle a category variable.
.IP
.nf
\f[C]
Category Description
──────────────────────────────────────────────────────────────────────────
C1 Command Shadows \[em] Wraps destructive commands (\[ga]rm\[ga], \[ga]cp\[ga]) to be safe by default
C2 Startup Side-Effects \[em] Bootstraps Fisher, generates wrappers, auto-activates venvs
C3 Overrides \[em] Overrides \[ga]cd\[ga], sets Vi mode, binds \[ga]<CR>\[ga] to \[ga]smart_enter\[ga]
C4 Integrations \[em] Kitty/Wezterm integrations, starship hooks, fzf theme
C5 Logging and Capture \[em] Session logs, command duration
C6 Greeting & First-Run UI \[em] Custom startup banner
\f[R]
.fi
.SS C1 \[em] Command Shadows
.PP
Disabling \f[V]__fish_config_op_aliases\f[R] restores standard system
behavior for all of these commands.
.IP
.nf
\f[C]
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 \[dq]help config\[dq] → 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
\f[R]
.fi
.PP
When C1 is disabled, \f[V]rm\f[R] uses bare \f[V]command rm\f[R] with no
wrapper \[em] files are permanently deleted, not trashed.
There is no intermediate safety net.
.SS C2 \[em] Startup Side-Effects
.PP
These run automatically without any user action.
Disabling \f[V]__fish_config_op_autoexec\f[R] prevents all of them.
.IP
.nf
\f[C]
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 \[ti]/.local/bin/paru wrapper
yay wrapper Every startup Writes \[ti]/.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
\f[R]
.fi
.PP
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 \[em] a
real file or directory at that path is left untouched.
The symlink has its own opt-out independent of C2: set
\f[V]__fish_user_dots_symlink\f[R] to a falsy value (or toggle \[lq]Dots
link\[rq] off on the config-settings Paths page) to stop generating it
and remove any existing link \[em] honoured even when C2 is enabled.
Managed by the \f[V]__fish_user_dots_link\f[R] helper.
The first-run completion marker
(\f[V]__fish_config_first_run_complete\f[R]) is still set so the init
does not re-run on subsequent shells.
.PP
Python venv activation fires on every directory change.
If a directory uses direnv (\f[V].envrc\f[R] present), direnv takes
priority and auto-venv is skipped for that directory.
.PP
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
\f[V]auto-pull\f[R] command (see its entry in the functions reference).
It only ever fast-forwards a clean repo whose branch has an upstream
\[em] never rebases, merges, or overwrites work \[em] 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
\f[V]cd\f[R]).
The registry is machine-local at
\f[V]$__fish_user_dots_path/auto-pull.list\f[R] (defaults to
\f[V]\[ti]/.config/.user-dots/fish/auto-pull.list\f[R]) and is never
committed.
.SS C3 \[em] Key and Environment Overrides
.PP
These change fundamental shell behavior: how keys work, which pager
opens, and what the prompt looks like.
Disabling \f[V]__fish_config_op_overrides\f[R] removes all of them.
.IP
.nf
\f[C]
Override What it replaces or sets
───────────────────────────────────────────────────────────────────────────
Vi mode fish_vi_key_bindings replaces default Emacs mode
PATH setup Prepends custom bin directories to the PATH
exit → smart_exit exit wrapper that captures scrollback before closing
PAGER=ov ov used by git, man, and all $PAGER-aware tools
EDITOR=nvim nvim fallback to vi for git commit, etc.
GPG_TTY Sets GPG_TTY to current terminal tty
MANPAGER=bat pipeline man pages rendered with syntax highlighting
CDPATH=. \[ti]/projects \[ti] bare dir names resolve against \[ti]/projects and \[ti]
Bang-bang system ! and $ keys expand history; !\[ha], !*, !-N, !?str?,
\[ha]old\[ha]new abbreviations; six expand_bang_* helpers
Autopair ( [ { \[dq] \[aq] auto-close to (), [], {}, \[dq]\[dq], \[aq]\[aq]
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
\f[R]
.fi
.PP
The bang-bang system spans \f[V]key_bindings.fish\f[R],
\f[V]abbr.fish\f[R], \f[V]puffer.fish\f[R], and six
\f[V]expand_bang_*.fish\f[R] functions.
All are gated together \[em] disabling C3 removes the entire
bang-expansion system at once.
.PP
When C3 is disabled, \f[V]exit\f[R] falls back to \f[V]builtin exit\f[R]
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).
.SS C4 \[em] Terminal and Tool Integration
.PP
These features couple the shell to specific external tools.
Disabling \f[V]__fish_config_op_integrations\f[R] disables all of them.
.IP
.nf
\f[C]
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 \[ti]/.terminal_history/
upgrade paru or yay (Arch Linux only)
WakaTime hook wakatime CLI and a configured API key
\f[R]
.fi
.PP
Disabled integration commands (\f[V]spwin\f[R], \f[V]tab\f[R],
\f[V]split\f[R], \f[V]hist\f[R], \f[V]logs\f[R], \f[V]upgrade\f[R])
print a colored error to stderr naming the variable that disabled them
rather than silently failing.
.SS C5 \[em] Logging and Capture
.PP
Five components capture shell output to disk.
Unlike every other category, C5 is opt-in: it stays off until
\f[V]__fish_config_op_logging\f[R] is set to an explicit truthy value,
and a truthy master switch does not enable it.
While it is off, all capture is skipped and the logging wrappers are
removed.
.PP
CAUTION: This configuration is capable of silently recording terminal
output and secrets directly to disk.
See below for details on how this capture mechanism works, where files
are stored, and how to manage its state.
.IP
.nf
\f[C]
# Turn it on (persistently, in every shell):
set -U __fish_config_op_logging on
# Turn it back off:
set -U __fish_config_op_logging off # or: set -Ue __fish_config_op_logging
Component What it captures
───────────────────────────────────────────────────────────────────────────
Scrollback capture Terminal session output saved to:
\[ga]\[ti]/.terminal_history/scrollback_YYYY-MM-DD_HH-MM-SS.log\[ga]
tmux pane capture Continuous pane stream via pipe-pane, saved to:
\[ga]\[ti]/.terminal_history/tmux_<session>-w<win>-p<pane>_YYYY-MM-DD_HH-MM-SS.log\[ga]
zellij pane capture Pane scrollback snapshot on shell exit, saved to:
\[ga]\[ti]/.terminal_history/zellij_<session>-p<pane>_YYYY-MM-DD_HH-MM-SS.log\[ga]
paru wrapper All paru/AUR output captured to:
\[ga]\[ti]/.terminal_history/paru_YYYY-MM-DD_HH-MM-SS.log\[ga]
yay wrapper All yay/AUR output captured to:
\[ga]\[ti]/.terminal_history/yay_YYYY-MM-DD_HH-MM-SS.log\[ga]
Kitty watcher \[ga]watcher.py\[ga] captures scrollback when Kitty closes
\f[R]
.fi
.PP
NOTE: \f[B]Turning off logging does not delete any existing logs.\f[R]
.PD 0
.P
.PD
They remain in \f[V]$SCROLLBACK_HISTORY_DIR\f[R] (defaults to:
\f[V]\[ti]/.terminal_history/\f[R]) until you remove them manually.
.PP
The tmux capture starts automatically when fish launches inside any tmux
pane (\f[V]$TMUX\f[R] is set).
It uses tmux\[cq]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 \f[V]tmux_*.log\f[R] files are pruned
(by modification time) to keep the total within
\f[V]SCROLLBACK_HISTORY_MAX_FILES\f[R], matching the paru/yay wrapper
behaviour.
.PP
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
\f[V]zellij action dump-screen --full --ansi\f[R] (the \f[V]--ansi\f[R]
flag preserves color).
The dump is captured on the fish process\[cq]s stdout and written to the
log file by fish itself (not via \f[V]--path\f[R], which would make the
zellij server write the file).
A fish_exit handler (registered whenever \f[V]$ZELLIJ\f[R] is set)
writes the pane\[cq]s full scrollback and then prunes old
\f[V]zellij_*.log\f[R] files the same way.
Because the capture happens at exit, toggling
\f[V]__fish_config_op_logging\f[R] takes effect on the next exit with no
restart or sentinel coordination needed \[em] the C5 guard is re-checked
when the handler fires.
.PP
LIMITATION \[em] zellij capture only fires on a clean shell exit (typing
\f[V]exit\f[R], 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:
.IP \[bu] 2
Closing a pane signals the shell and tears the pane down concurrently,
so even if the handler runs, \f[V]dump-screen\f[R] may find the pane
buffer already gone.
.IP \[bu] 2
Quitting zellij kills the zellij server, and \f[V]dump-screen\f[R] needs
a live server to read from \[em] there is nothing left to snapshot.
.PP
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
\f[V]exit\f[R] or Ctrl-D rather than zellij\[cq]s close-pane or quit
actions.
.PP
The Kitty watcher is managed by the kitty-logging command: it symlinks
the watcher (\f[V]fish-config-watcher.py\f[R]) into the Kitty config
directory and wires it into \f[V]kitty.conf\f[R] via a managed block.
Inside Kitty, a non-blocking per-session reminder points first-time
users at \f[V]kitty-logging install\f[R] until they install or run
\f[V]kitty-logging dismiss\f[R]; the reminder is itself gated on C5, so
it stays silent until you enable logging.
Install affects new Kitty windows only; runtime disable is still handled
by the \f[V].logging_disabled\f[R] sentinel.
.PP
Logging coordination via sentinel file
.PP
C5 uses a sentinel file to synchronize state between the shell and
out-of-process components (the Kitty watcher and all running shells):
.IP
.nf
\f[C]
\[ti]/.config/fish/.logging_disabled
\f[R]
.fi
.PP
Because C5 is off by default, the sentinel is present on a fresh install
\[em] the startup sync in \f[V]conf.d/logging-events.fish\f[R]
reconciles it on every shell start, so it appears without any action on
your part.
.PP
Disabling \f[V]__fish_config_op_logging\f[R] (or leaving it unset): 1.
Creates the sentinel immediately in every open shell.
2.
Removes \f[V]\[ti]/.local/bin/paru\f[R] and
\f[V]\[ti]/.local/bin/yay\f[R] logging wrappers; bare
\f[V]/usr/bin/paru\f[R] and \f[V]/usr/bin/yay\f[R] are used instead.
3.
Kitty\[cq]s \f[V]watcher.py\f[R] reads the sentinel on each save attempt
and skips capture \[em] no Kitty restart required.
4.
smart_exit stops saving scrollback logs.
5.
Stops \f[V]tmux pipe-pane\f[R] capture in every open fish shell inside
tmux.
.PP
Enabling \f[V]__fish_config_op_logging\f[R]: 1.
Removes the sentinel in every open shell.
2.
Regenerates paru/yay logging wrappers in \f[V]\[ti]/.local/bin/\f[R].
3.
Kitty watcher resumes capture on the next session exit.
4.
Restarts tmux pipe-pane capture in every open fish shell inside tmux.
.PP
Changes propagate to all running shells through an event handler that
fires whenever \f[V]__fish_config_op_logging\f[R] changes \[em] no shell
restart needed.
.PP
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.
.SS C6 \[em] Greeting and First-Run UI
.IP
.nf
\f[C]
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)
\f[R]
.fi
.PP
When C6 is disabled, no greeting is printed by this config.
Any greeting set by the distro or other configs runs normally \[em] this
config simply does not override it.
.SH 9. FISHER PLUGINS
.PP
Fisher is bootstrapped automatically on the \f[B]first interactive
session\f[R] via \f[V]conf.d/first_run.fish\f[R].
This also applies the Catppuccin Mocha theme and prints a one-time
welcome message (gated by \f[V]__fish_config_op_greeting\f[R]; set it to
0 to suppress).
Subsequent sessions skip all first-run logic with zero overhead.
.PP
To re-trigger first-run initialization (e.g., after a fresh install or
for testing), run:
.IP
.nf
\f[C]
set -Ue __fish_config_first_run_complete
\f[R]
.fi
.PP
Then open a new shell.
.SS Fisher-Managed Plugins
.PP
The following plugins are fully managed by Fisher.
Their files are installed into the repo directory by Fisher and are
listed in \f[V].gitignore\f[R] \[em] do not commit them.
Fisher installs and updates them automatically.
.IP
.nf
\f[C]
jorgebucaran/fisher Plugin manager itself
meaningful-ooo/sponge Remove failed commands from history
\f[R]
.fi
.SS Sponge History Filtering
.PP
Sponge removes failed commands from history and, via
conf.d/sponge_privacy.fish, also filters privacy-sensitive commands
through three layers:
.PP
Layer 1 \[em] Static patterns (universal, persistent across sessions):
Commands matching any of these structural signatures are never recorded:
.IP
.nf
\f[C]
--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\[at]host
HTTP Authorization headers: curl -H \[dq]Authorization: ...\[dq]
Basic auth flags: curl -u user:pass
sshpass, docker login -p, openssl -passin/-passout
\f[R]
.fi
.PP
Layer 2 \[em] 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.
.PP
Layer 3 \[em] Per-command filter (sponge_filter_secrets): Catches
credentials in variables exported after login, such as tokens sourced
from a project .env file mid-session.
.PP
To add your own persistent patterns:
.IP
.nf
\f[C]
set -U -a sponge_regex_patterns \[aq]your-regex-here\[aq]
\f[R]
.fi
.PP
To mark additional variable NAMES as credential-bearing (so Layer 2
scrubs their values), add name tokens \[em] via
\f[V]config-settings\f[R] → Sponge, or directly:
.IP
.nf
\f[C]
set -U -a __fish_sponge_extra_sensitive ACME_API VAULT_PW
\f[R]
.fi
.PP
Tokens are folded into the Layer 2 name match case-insensitively as
substrings, so ACME_API also covers ACME_API_KEY.
(The match uses \f[V]--entire\f[R] to return the full variable name, so
partial-name tokens dereference the right value.)
.PP
The \f[V]config-settings\f[R] Sponge page also surfaces sponge\[cq]s own
tuning variables \[em] sponge_delay, sponge_successful_exit_codes,
sponge_purge_only_on_exit, and sponge_allow_previously_successful \[em]
so they can be changed without typing variable names.
.SS Bundled Plugin Functionality
.PP
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.
.PP
Bundled components and their upstream origins:
.IP
.nf
\f[C]
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
\f[R]
.fi
.PP
Do not run \f[V]fisher install\f[R] for these \[em] it will overwrite
the customized versions.
To update their behavior, edit the relevant bundled files directly.
.SS fish_plugins Manifest
.PP
The \f[V]fish_plugins\f[R] file at the config root:
.IP
.nf
\f[C]
jorgebucaran/fisher Plugin manager itself
meaningful-ooo/sponge Remove failed commands from history
\f[R]
.fi
.PP
To update all Fisher-managed plugins, run \f[V]fisher update\f[R] or
\f[V]fish-deps update\f[R] which calls it as its first step.
.PP
* * * * *
.SH 10. INSTALLATION
.PP
This configuration is managed as a git repository.
To deploy on a new machine:
.IP
.nf
\f[C]
mv \[ti]/.config/fish \[ti]/.config/fish.bak # back up any existing config
git clone https://git.rootiest.dev/rootiest/fish-config.git \[ti]/.config/fish
\f[R]
.fi
.PP
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.
.SS Return Sentinel
.PP
config.fish ends with a return sentinel guard.
Any lines appended after it by a tool\[cq]s setup command (starship init
fish | source, zoxide init fish | source, etc.)
will have no effect.
All integrations are managed via conf.d/ files.
.PP
If a new tool\[cq]s shell integration appears to do nothing, check
whether its setup command appended an init line below the sentinel and
create a dedicated \f[V]conf.d/<tool>.fish\f[R] instead.
.SS Updating
.PP
Pull the latest changes from the upstream repository without needing a
configured git remote:
.IP
.nf
\f[C]
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
\f[R]
.fi
.PP
All git output is suppressed.
Run exec fish after a successful update to reload.
.PP
* * * * *
.SH 11. PERSONALIZATION
.PP
Sensitive credentials and machine-specific settings are kept out of
version control in a private directory.
The path defaults to \f[V]\[ti]/.config/.user-dots/fish/\f[R] but can be
overridden:
.IP
.nf
\f[C]
set -U __fish_user_dots_path /path/to/your/dots/fish
\f[R]
.fi
.PP
Or use the interactive TUI \[em] run \f[V]config-settings\f[R] and
navigate to the \[lq]Dots Path\[rq] row (last row).
Press Enter to type a new path, or ← / h to reset to the default.
.PP
config.fish sources local.fish from that directory on every interactive
session.
local.fish is responsible for sourcing its own secrets.fish:
.IP
.nf
\f[C]
$__fish_user_dots_path/
├── secrets.fish API keys, tokens, passwords, personal identifiers
└── local.fish Machine-specific paths, env vars, and sourcing secrets
\f[R]
.fi
.PP
fish_variables (auto-managed by fish) is excluded from this repo via
\&.gitignore.
Do not commit it.
.SS secrets.fish
.PP
Store anything you would not commit to a public repo: API keys, auth
tokens, passwords, and personal identifiers.
.IP
.nf
\f[C]
# secrets.fish
set -gx MY_NAME \[dq]Your Name\[dq]
set -gx MY_EMAIL \[dq]you\[at]example.com\[dq]
set -gx GPG_RECIPIENT \[dq]you\[at]example.com\[dq]
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
\f[R]
.fi
.SS local.fish
.PP
Store paths and variables specific to one machine \[em] things that
would be wrong on any other system.
.IP
.nf
\f[C]
# CDPATH \[em] directories searched by cd
set -gx CDPATH . /home/youruser/projects /home/youruser
# Path to your shared .gitignore boilerplate
set -gx GITIGNORE_BOILERPLATE \[ti]/.config/git/gitignore_boilerplate
# SSH shortcuts
abbr -a sshr \[aq]ssh you\[at]your-server.local\[aq]
abbr -a sshw \[aq]ssh you\[at]work-server.example.com\[aq]
# Docker context shortcuts
abbr -a dcr \[aq]docker context use my-remote-server\[aq]
abbr -a dcw \[aq]docker context use work-server\[aq]
\f[R]
.fi
.PP
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.
.PP
* * * * *
.SH 12. TROUBLESHOOTING
.PP
This section covers common issues, their solutions, and how to safely
revert changes or uninstall the configuration entirely.
.SS Uninstalling and Reverting to Backup
.PP
The installation step backs up any existing config to
\f[V]\[ti]/.config/fish.bak\f[R].
To revert:
.IP
.nf
\f[C]
rm -rf \[ti]/.config/fish
mv \[ti]/.config/fish.bak \[ti]/.config/fish
\f[R]
.fi
.PP
If no backup exists, remove the directory and let Fish regenerate a
default config on next launch:
.IP
.nf
\f[C]
rm -rf \[ti]/.config/fish
fish -c \[aq]fish_config theme choose \[dq]Fish default\[dq]\[aq]
\f[R]
.fi
.PP
Clean up files generated outside the config directory:
.IP
.nf
\f[C]
rm -f \[ti]/.local/bin/paru \[ti]/.local/bin/yay # AUR log wrappers
rm -f \[ti]/.local/share/man/man1/fish-config.1 # man page symlink
rm -f \[ti]/.config/fish/.logging_disabled # C5 sentinel
\f[R]
.fi
.PP
Erase universal variables set by this config:
.IP
.nf
\f[C]
for v in (set -Un | string match \[aq]__fish_config*\[aq])
set -Ue $v
end
for v in __done_min_cmd_duration __done_notification_urgency_level
set -Ue $v
end
for v in (set -Un | string match \[aq]sponge_*\[aq])
set -Ue $v
end
\f[R]
.fi
.PP
The \f[V]\[ti]/.terminal_history/\f[R] log directory contains your
session logs.
Remove it only if you do not want to keep them.
.SS Fish Version Requirement
.PP
This config requires Fish 4.x or newer.
Check your version:
.IP
.nf
\f[C]
fish --version
\f[R]
.fi
.PP
Run \f[V]fish-deps\f[R] to see a status report \[em] an outdated Fish
shows ⚠ with an upgrade message.
.PP
Upgrading Fish by distribution:
.IP
.nf
\f[C]
# Arch / AUR
pacman -S fish # or paru -S fish
# Ubuntu / Debian (PPA)
sudo apt-add-repository ppa:fish-shell/release-4
sudo apt update && sudo apt install fish
# Fedora
sudo dnf install fish
# macOS
brew install fish
\f[R]
.fi
.PP
For other systems or building from source, see https://fishshell.com.
.SS Enable or Disable Session Logging
.PP
Session logging is opt-in: it is off until you turn it on.
To enable all logging and capture (scrollback, tmux/zellij pane logs,
AUR helper wrappers, Kitty watcher):
.IP
.nf
\f[C]
set -U __fish_config_op_logging on
\f[R]
.fi
.PP
Or toggle it interactively: run \f[V]config-settings\f[R] and flip the
Logging row.
.PP
Disable it again \[em] either an explicit falsy value or erasing the
variable returns you to the default off state:
.IP
.nf
\f[C]
set -U __fish_config_op_logging off
set -Ue __fish_config_op_logging
\f[R]
.fi
.PP
This takes effect immediately in all running shells \[em] no restart
needed.
The sentinel file, wrapper removal, and pipe-pane teardown happen
automatically.
.PP
See C5 \[em] Logging and Capture for the full component breakdown.
.SS Change or Disable the Greeting
.PP
This config suppresses the distro greeting (e.g.\ CachyOS fastfetch) by
default.
To let the distro greeting through:
.IP
.nf
\f[C]
set -U __fish_config_op_greeting off
\f[R]
.fi
.PP
To set a custom greeting, define fish_greeting in your local.fish:
.IP
.nf
\f[C]
# in $__fish_user_dots_path/local.fish
function fish_greeting
echo \[dq]Hello, world!\[dq]
end
\f[R]
.fi
.PP
The first-run welcome banner runs exactly once.
To re-trigger it (e.g.\ for testing):
.IP
.nf
\f[C]
set -Ue __fish_config_first_run_complete
\f[R]
.fi
.PP
See C6 \[em] Greeting and First-Run UI for details.
.SS Secrets and Machine-Local Configuration
.PP
Machine-specific config goes in
\f[V]$__fish_user_dots_path/local.fish\f[R] (defaults to
\f[V]\[ti]/.config/.user-dots/fish/local.fish\f[R]).
Secrets go in \f[V]secrets.fish\f[R] in the same directory.
.PP
If local.fish is not loading, verify the path:
.IP
.nf
\f[C]
echo $__fish_user_dots_path
test -f \[dq]$__fish_user_dots_path/local.fish\[dq]; and echo exists; or echo missing
\f[R]
.fi
.PP
Change the path via variable or TUI:
.IP
.nf
\f[C]
set -U __fish_user_dots_path /new/path/to/dots/fish
\f[R]
.fi
.PP
Or run \f[V]config-settings\f[R], navigate to the Paths page, and edit
\[lq]Dots path\[rq].
.PP
The \f[V]user-dots\f[R] convenience symlink in the config directory
tracks this path.
Disable it with:
.IP
.nf
\f[C]
set -U __fish_user_dots_symlink false
\f[R]
.fi
.PP
See Personalization for the full \f[V]local.fish\f[R] /
\f[V]secrets.fish\f[R] layout.
.SS Tool Init Does Nothing (Return Sentinel)
.PP
Symptom: you ran a tool\[cq]s setup command (e.g.
\f[V]starship init fish >> \[ti]/.config/fish/config.fish\f[R]) and
nothing changed.
.PP
Cause: \f[V]config.fish\f[R] ends with a \f[V]return\f[R] guard.
Any lines appended after it are never executed.
.PP
Fix: create a dedicated \f[V]conf.d/\f[R] file instead of appending to
\f[V]config.fish\f[R]:
.IP
.nf
\f[C]
# \[ti]/.config/fish/conf.d/mytool.fish
mytool init fish | source
\f[R]
.fi
.PP
All existing integrations (starship, zoxide, direnv) already have
\f[V]conf.d/\f[R] files.
See Return Sentinel for background.
.SS Missing Dependencies
.PP
Run \f[V]fish-deps\f[R] (defaults to \f[V]fish-deps status\f[R]) to see
what is installed and what is missing.
Common symptoms and their missing tools:
.IP
.nf
\f[C]
Symptom Missing tool
─────────────────────────────────────────────────────
ls output has no icons or colors eza (or lsd)
cd does not remember directories zoxide
cat shows no syntax highlighting bat
fzf keybindings do nothing fzf
Starship prompt not appearing starship
\f[R]
.fi
.PP
Install missing dependencies interactively:
.IP
.nf
\f[C]
fish-deps install
\f[R]
.fi
.PP
Or install everything missing and update what is installed:
.IP
.nf
\f[C]
fish-deps sync
\f[R]
.fi
.PP
See Dependency Catalog for the full list grouped by tier (required,
integrations, recommended).
.SS Vi Mode Keybindings
.PP
This config enables Vi mode by default (via C3 overrides), replacing the
standard Emacs-style bindings.
If Vi mode interferes with your workflow, override it in
\f[V]local.fish\f[R] (See Personalization):
.IP
.nf
\f[C]
# $__fish_user_dots_path/local.fish
fish_default_key_bindings
\f[R]
.fi
.PP
This restores Emacs-style bindings without disabling the rest of C3
(bang-bang, autopair, starship prompt, pager settings, etc.).
.PP
To disable the entire C3 category (Vi mode and all other key/environment
overrides):
.IP
.nf
\f[C]
set -U __fish_config_op_overrides off
\f[R]
.fi
.PP
See C3 \[em] Key and Environment Overrides for the full list of what C3
controls.
.SS What\[cq]s with the C1-C6 stuff?
.PP
This configuration groups its opinionated behaviors into six categories
(C1\[en]C6), allowing you to selectively disable features that conflict
with your workflow.
The \f[B]C\f[R]ategory numbers are used as shorthand when referencing
these.
Disabling all of them leaves you with a \[lq]Minimal Mode\[rq] shell
that only manages basic features like \f[V]XDG\f[R] variables, and your
\f[V]local.fish\f[R] overrides.
.IP
.nf
\f[C]
Category Description
──────────────────────────────────────────────────────────────────────────
C1 Command Shadows \[em] Wraps destructive commands (\[ga]rm\[ga], \[ga]cp\[ga]) to be safe by default
C2 Startup Side-Effects \[em] Bootstraps Fisher, generates wrappers, auto-activates venvs
C3 Overrides \[em] Overrides \[ga]cd\[ga], sets Vi mode, binds \[ga]<CR>\[ga] to \[ga]smart_enter\[ga]
C4 Integrations \[em] Kitty/Wezterm integrations, starship hooks, fzf theme
C5 Logging and Capture \[em] Session logs, command duration
C6 Greeting & First-Run UI \[em] Custom startup banner
\f[R]
.fi
.PP
Disable all opinionated features at once (Minimal Mode):
.IP
.nf
\f[C]
set -U __fish_config_opinionated 0
\f[R]
.fi
.PP
Disable a single category:
.IP
.nf
\f[C]
set -U __fish_config_op_aliases off # C1
set -U __fish_config_op_autoexec off # C2
set -U __fish_config_op_overrides off # C3
set -U __fish_config_op_integrations off # C4
set -U __fish_config_op_logging off # C5 (already off by default)
set -U __fish_config_op_greeting off # C6
\f[R]
.fi
.PP
Keep one category active under a master disable:
.IP
.nf
\f[C]
set -U __fish_config_opinionated 0
set -U __fish_config_op_aliases 1 # only C1 stays on
\f[R]
.fi
.PP
Re-enable everything:
.IP
.nf
\f[C]
set -Ue __fish_config_opinionated
\f[R]
.fi
.PP
For an interactive alternative to setting these variables by hand, run
\f[V]config-settings\f[R].
.PP
* * * * *
.SH 13. VIEWING THIS MANUAL
.PP
There are four ways to read this manual.
.SS The documentation website
.IP
.nf
\f[C]
help config --html
\f[R]
.fi
.PP
Opens https://fish.rootiest.fyi/ in the default browser \[em] the
Starlight-powered site built from \f[V]docs/manual/**\f[R] on every push
to \f[V]main\f[R].
It has a section sidebar and full-text search.
Deep links to a specific section aren\[cq]t supported from the command
line; once the site opens, use its search box to jump straight to what
you need.
.SS As a man page
.IP
.nf
\f[C]
help config --man
help config pkg --man
\f[R]
.fi
.PP
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:
.IP
.nf
\f[C]
man fish-config
\f[R]
.fi
.PP
NOTE: fish-config (hyphen) is this config\[cq]s man page.
fish_config (underscore) is fish\[cq]s built-in browser-based
configuration tool \[em] a completely separate command.
Do not mix them up.
.SS In the terminal
.IP
.nf
\f[C]
help config
help config keybindings
\f[R]
.fi
.PP
Without a pager available beyond the basics,
\f[V]help config [SECTION]\f[R] opens the Markdown manual in the best
available viewer, falling back through:
.IP
.nf
\f[C]
1. ov + bat section navigation + syntax highlighting (best)
2. ov alone section navigation, raw Markdown
3. bat alone syntax highlighting, use / to search
4. man -l pre-compiled man page (if available)
5. less plain text with line-jump
6. cat plain output
\f[R]
.fi
.PP
With ov, the Markdown renders with syntax highlighting and section-based
navigation:
.IP
.nf
\f[C]
Space next section
\[ha] 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 \[aq]section\[aq])
q quit
\f[R]
.fi
.PP
If SECTION is given, the pager opens at the first heading that matches
the keyword (case-insensitive; checks \f[V]docs/fish-config.index\f[R]
aliases first, then falls back to a normalized heading scan):
.IP
.nf
\f[C]
help config keybindings
help config abbreviations
help config pkg
help config logs
help config fish-deps
\f[R]
.fi
.SS Reading the source directly
.PP
\f[V]docs/manual/**\f[R] is the single source of truth this manual, the
man page, and the website are all generated from.
Numbered files and directories correspond to the numbered sections in
this manual \[em] browse them in any editor, or from a shell:
.IP
.nf
\f[C]
cd \[ti]/.config/fish/docs/manual
grep -rn \[dq]keybindings\[dq] .
\f[R]
.fi
.PP
Section 5 is the exception.
Function entries are generated from the man-page-style comment header
above each function in \f[V]functions/*.fish\f[R], so the documentation
for a command lives beside the code that implements it and cannot drift
from it.
To read the source for a single function, or to correct its
documentation, open the function itself:
.IP
.nf
\f[C]
functions/git-clean.fish
\f[R]
.fi
.PP
The files under \f[V]docs/manual/05-functions/\f[R] carry only the
category titles, ordering, and search keywords.
.SH AUTHORS
Rootiest.