5826 lines
173 KiB
Groff
5826 lines
173 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,
|
||
\f[V]tmux\f[R]/\f[V]zellij\f[R] panes, and \f[V]paru\f[R]/\f[V]yay\f[R]
|
||
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 \f[V]fish-deps\f[R]
|
||
.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
|
||
│ ├── 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
|
||
│ ├── 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, autoloaded on demand
|
||
├── 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
|
||
- Editors
|
||
- Navigation and Listing
|
||
- Git
|
||
- Terminal Windows, Tabs, and Panes
|
||
- Chezmoi
|
||
- Docker
|
||
- Systemctl
|
||
- AI Assistants
|
||
- History Expansion
|
||
- Miscellaneous
|
||
- Shell Aliases
|
||
5. Functions Reference
|
||
- File and Directory
|
||
- Navigation
|
||
- Editors and Viewers
|
||
- Git and Version Control
|
||
- Package Management
|
||
- Dependency Management
|
||
- System and Monitoring
|
||
- Terminal Management
|
||
- Clipboard
|
||
- Network
|
||
- Pager and Logging
|
||
- AI and Developer Tools
|
||
- Media and Utilities
|
||
- Miscellaneous
|
||
6. Dependency Catalog
|
||
7. Customization
|
||
8. Components Reference
|
||
- C1 \[em] Command Shadows
|
||
- C2 \[em] Startup Side-Effects
|
||
- C3 \[em] Key and Environment Overrides
|
||
- C4 \[em] Terminal and Tool Integration
|
||
- C5 \[em] Logging and Capture
|
||
- C6 \[em] Greeting and First-Run UI
|
||
9. Fisher Plugins
|
||
10. Installation
|
||
11. Personalization
|
||
12. Troubleshooting
|
||
13. Viewing This Manual
|
||
14. Testing
|
||
15. Contributing
|
||
16. Attribution
|
||
17. License
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
* * * * *
|
||
.SH 1. CONFIGURATION VARIABLES
|
||
.PP
|
||
These variables are exported from \f[V]config.fish\f[R] on every
|
||
interactive session.
|
||
Override them in \f[V]local.fish\f[R] (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]completions/tailscale.fish\f[R], autoloaded on the first
|
||
\f[V]tailscale<TAB>\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 \f[V]npm\f[R] 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 (\f[V]fish_vi_key_bindings\f[R]).
|
||
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] twice anywhere on the
|
||
command line to open an fzf picker and replace the
|
||
\[at]\[at] with the selection. The \[at]\[at] must be typed as its
|
||
own token: \[dq]cat \[at]\[at]\[dq] triggers it, but \[dq]cat\[at]\[at]\[dq] does
|
||
not.
|
||
|
||
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]
|
||
Abbreviation Description
|
||
───────────────────────────────────────────────────────────────────
|
||
n nvim
|
||
nv nvim
|
||
neovim nvim
|
||
cdnv cd \[ti]/.config/nvim
|
||
cdnvn cd \[ti]/.config/nvim; nvim
|
||
k kate
|
||
e edit
|
||
se sudoedit
|
||
\f[R]
|
||
.fi
|
||
.SS 4.2 Navigation and Listing
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Abbreviation Description
|
||
───────────────────────────────────────────────────────────────────
|
||
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)
|
||
\f[R]
|
||
.fi
|
||
.SS 4.3 Git
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Abbreviation Description
|
||
───────────────────────────────────────────────────────────────────
|
||
lg lazygit
|
||
g git
|
||
gitig generate .gitignore
|
||
git-ignore 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]
|
||
Abbreviation Description
|
||
───────────────────────────────────────────────────────────────────
|
||
editt Open new tab with nvim (terminal-aware)
|
||
:q Close current pane/window
|
||
:Q Close current tab
|
||
: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
|
||
: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 \[ti]/.local/share/chezmoi
|
||
:tgcm New tab at \[ti]/.config/chezmoi
|
||
:tgp New tab at \[ti]/projects
|
||
:tgr New tab at / (root)
|
||
:wgk New OS window at \[ti]/.config/kitty
|
||
:wgn New OS window at \[ti]/.config/nvim
|
||
:wgf New OS window at \[ti]/.config/fish
|
||
:wgh New OS window at \[ti]
|
||
:wgzd New OS window at \[ti]/.local/share/chezmoi
|
||
:wgcz New OS window at \[ti]/.config/chezmoi
|
||
:wgp New OS window at \[ti]/projects
|
||
:wgr New OS window at / (root)
|
||
:wvgk Split bottom at \[ti]/.config/kitty
|
||
:wvgn Split bottom at \[ti]/.config/nvim
|
||
:wvgf Split bottom at \[ti]/.config/fish
|
||
:wvgh Split bottom at \[ti]
|
||
:wvgcz Split bottom at \[ti]/.local/share/chezmoi
|
||
:wvgcm Split bottom at \[ti]/.config/chezmoi
|
||
:wvgp Split bottom at \[ti]/projects
|
||
:wvgr Split bottom at / (root)
|
||
:whgk Split right at \[ti]/.config/kitty
|
||
:whgn Split right at \[ti]/.config/nvim
|
||
:whgf Split right at \[ti]/.config/fish
|
||
:whgh Split right at \[ti]
|
||
:whgcz Split right at \[ti]/.local/share/chezmoi
|
||
:whgcm Split right at \[ti]/.config/chezmoi
|
||
:whgp Split right at \[ti]/projects
|
||
:whgr Split right at / (root)
|
||
:cdk cd \[ti]/.config/kitty
|
||
:cdkn cd \[ti]/.config/kitty; nvim
|
||
:cdn cd \[ti]/.config/nvim
|
||
:cdnn cd \[ti]/.config/nvim; nvim
|
||
:cdf cd \[ti]/.config/fish
|
||
:cdfn cd \[ti]/.config/fish; nvim
|
||
:cdh cd \[ti]
|
||
:cdhn cd \[ti]; nvim
|
||
:cdcz cd \[ti]/.local/share/chezmoi
|
||
:cdczn cd \[ti]/.local/share/chezmoi; nvim
|
||
:cdcm cd \[ti]/.config/chezmoi
|
||
:cdcmn cd \[ti]/.config/chezmoi; nvim
|
||
:cdp cd \[ti]/projects/...
|
||
:cdpn cd \[ti]/projects; nvim
|
||
:cdw cd \[ti]/.config/wezterm
|
||
:cdwn cd \[ti]/.config/wezterm; nvim
|
||
:sw spwin (spawn new OS window)
|
||
\f[R]
|
||
.fi
|
||
.SS 4.5 Chezmoi
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Abbreviation Description
|
||
───────────────────────────────────────────────────────────────────
|
||
cm chezmoi
|
||
cmcd chezmoi cd
|
||
czcd chezmoi cd
|
||
cdcm chezmoi cd
|
||
cdcz chezmoi cd
|
||
cme chezmoi edit
|
||
cze chezmoi edit
|
||
cmad chezmoi add
|
||
czad chezmoi add
|
||
cmap chezmoi apply
|
||
czap chezmoi apply
|
||
cmrm chezmoi forget
|
||
cmf chezmoi forget
|
||
czrm chezmoi forget
|
||
czf chezmoi forget
|
||
cmi chezmoi init
|
||
czi chezmoi init
|
||
\f[R]
|
||
.fi
|
||
.SS 4.6 Docker
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Abbreviation Description
|
||
───────────────────────────────────────────────────────────────────
|
||
dcl docker context use default
|
||
lzd ld (lazydocker)
|
||
dcls docker context ls
|
||
\f[R]
|
||
.fi
|
||
.SS 4.7 Systemctl
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Abbreviation Description
|
||
───────────────────────────────────────────────────────────────────
|
||
sc systemctl
|
||
ssc sudo systemctl
|
||
scu systemctl --user
|
||
st systemctl status
|
||
scs systemctl start
|
||
scr systemctl restart
|
||
ssct sudo systemctl status
|
||
sscs sudo systemctl start
|
||
sscr sudo systemctl restart
|
||
\f[R]
|
||
.fi
|
||
.SS 4.8 AI Assistants
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Abbreviation Description
|
||
───────────────────────────────────────────────────────────────────
|
||
v antigravity-ide
|
||
s wezterm ssh (WezTerm only)
|
||
ag agy
|
||
ag. agy .
|
||
\f[R]
|
||
.fi
|
||
.SS 4.9 History Expansion
|
||
.PP
|
||
Bash-style history expansions trigger on Space or Enter.
|
||
Some are implemented as abbreviations (e.g.\ \f[V]!*\f[R]), while others
|
||
(\f[V]!!\f[R], \f[V]!$\f[R], \f[V]!.\f[R]) are implemented as
|
||
keybindings, but they all serve the same purpose.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Abbreviation Description
|
||
───────────────────────────────────────────────────────────────────
|
||
!\[ha] Expand to the first argument of the previous command
|
||
!* Expand to all arguments of the previous command
|
||
\[ha]old\[ha]new\[ha] Interactive typo substitution (replace \[aq]old\[aq] with \[aq]new\[aq] in previous command)
|
||
!string Expand to the most recent command starting with \[aq]string\[aq]
|
||
!?string? Expand to the most recent command containing \[aq]string\[aq]
|
||
!-n Expand to the nth-previous command
|
||
!! Expand to the previous command
|
||
!$ Expand to the last argument of the previous command
|
||
!. Expand .. to ../.. and so on
|
||
\f[R]
|
||
.fi
|
||
.SS 4.10 Miscellaneous
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Abbreviation Description
|
||
───────────────────────────────────────────────────────────────────
|
||
sudu sudo -s
|
||
kt kitty (Kitty only)
|
||
c cat
|
||
/exit exit
|
||
speedtest-fast fast-cli
|
||
bl bd list
|
||
bs bd sync
|
||
bC bd create --title
|
||
bsh bd show
|
||
lb lazybeads
|
||
open-repo repo-open
|
||
url-open open-url
|
||
\f[R]
|
||
.fi
|
||
.SS 4.11 Shell Aliases
|
||
.PP
|
||
These aliases are defined in \f[V]conf.d/tricks.fish\f[R] via alias
|
||
(which creates Fish functions).
|
||
They are active in all interactive sessions.
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Abbreviation Description
|
||
───────────────────────────────────────────────────────────────────
|
||
\&.. cd ..
|
||
\&... cd ../..
|
||
\&.... cd ../../..
|
||
\&..... cd ../../../..
|
||
\&...... cd ../../../../..
|
||
dir dir --color=auto
|
||
vdir vdir --color=auto
|
||
grep grep --color=auto
|
||
fgrep fgrep --color=auto
|
||
egrep egrep --color=auto
|
||
cp cp -i
|
||
mv mv -i
|
||
tarnow tar -acf
|
||
untar tar -zxvf
|
||
tb nc termbin.com 9999
|
||
jctl journalctl -p 3 -xb
|
||
\f[R]
|
||
.fi
|
||
.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
|
||
|
||
Exit Status:
|
||
Exit status of eza, lsd, or ls, whichever ran
|
||
|
||
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
|
||
|
||
Exit Status:
|
||
Exit status of eza, lsd, or ls, whichever ran
|
||
|
||
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
|
||
|
||
Exit Status:
|
||
Exit status of eza, lsd, or ls, whichever ran
|
||
|
||
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
|
||
|
||
Exit Status:
|
||
Exit status of eza, lsd, or ls, whichever ran
|
||
|
||
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
|
||
|
||
Exit Status:
|
||
Exit status of eza, lsd, or ls, whichever ran
|
||
|
||
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
|
||
|
||
Exit Status:
|
||
Exit status of eza, lsd, or ls, whichever ran
|
||
|
||
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
|
||
|
||
Exit Status:
|
||
Exit status of eza, lsd, or ls, whichever ran
|
||
|
||
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 mv
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Synopsis: mv [args...]
|
||
|
||
Wraps mv to automatically collapse nested directories of the same name.
|
||
When extracting archives results in redundant structures (e.g.,
|
||
themes/themes/), calling mv themes/themes themes will gracefully
|
||
move the inner contents up one level and remove the empty outer shell.
|
||
|
||
Opinionated component (C1): when disabled via __fish_config_op_aliases,
|
||
behaves exactly like bare command mv.
|
||
|
||
Arguments:
|
||
args... Arguments forwarded to standard mv
|
||
|
||
Exit Status:
|
||
0 Operation succeeded
|
||
>0 Standard mv failure, or failed to collapse directory
|
||
|
||
Example:
|
||
mv \[ti]/.config/btop/themes/themes \[ti]/.config/btop/themes
|
||
\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.
|
||
|
||
Exit Status:
|
||
0 Command selected and inserted, or fzf was cancelled
|
||
1 Disabled by __fish_config_op_integrations
|
||
|
||
Example:
|
||
hist
|
||
\f[R]
|
||
.fi
|
||
.SS mkrep
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Synopsis: mkrep [--cd | --no-cd] [--mkdir | --no-mkdir] [--git | --no-git]
|
||
[-c | --clean | --no-clean] [--strict] [-v | --verbose]
|
||
[-s | --silent] [--template <path>] [--branch <name>]
|
||
[--remote <url>] [--new-remote [<cmd>]] [--server <type>]
|
||
[--check-existing] [--name <name>] [-h | --help] <dir>
|
||
|
||
Creates a directory, cds into it, and git-inits it -- mkcd plus a git
|
||
repo in one step. All three actions are on by default and each has a
|
||
--no-* flag to skip it, plus a same-named flag to force it back on. If
|
||
both a flag and its --no- counterpart are given, --no- wins.
|
||
|
||
--clean removes an existing target directory before recreating it,
|
||
for a guaranteed-fresh start; --strict instead refuses to proceed if
|
||
the directory already exists. The two compose: --clean runs first, so
|
||
--clean --strict together is not a contradiction -- strict sees an
|
||
empty slot because clean just emptied it.
|
||
|
||
--remote links an already-existing remote (git remote add origin
|
||
<url>) -- it does not create anything. --new-remote creates one first
|
||
by running a shell command template in the new repo directory, then
|
||
nothing further is needed since the template itself does the linking
|
||
(e.g. gh repo create {name} --source=. --remote=origin --push).
|
||
Three placeholders are substituted in a template: {name} (--name, or
|
||
the target directory\[aq]s basename), {user} ($USER), and {server} (the
|
||
resolved server base URL, gitea/gitlab only). Pass a command after
|
||
--new-remote to use it for this call only; with no value it falls
|
||
back to $MKREP_REMOTE_CMD. --remote and --new-remote are mutually
|
||
exclusive, and either requires --git.
|
||
|
||
--server <type> (gitea, gitlab, or github) picks a host without an
|
||
explicit --remote/--new-remote: resolve its base URL from
|
||
$GITEA_URL/$GITEA_HOST (gitea) or $GITLAB_URL/$GITLAB_HOST (gitlab),
|
||
preferring the _URL form when both are set. _URL is used as-is and
|
||
must include its scheme (https://git.example.com); _HOST is bare
|
||
(git.example.com) and gets https:// prepended. Then run
|
||
$MKREP_REMOTE_CMD or that type\[aq]s built-in default template. With no
|
||
--server, --remote, or --new-remote, $GIT_SERVER picks the type the
|
||
same way (invalid values are rejected the same as an invalid
|
||
--server) -- $GITEA_URL/$GITEA_HOST/$GITLAB_URL/$GITLAB_HOST only ever
|
||
supply the base URL, never the type on their own, so setting one for
|
||
an unrelated tool (an API token helper, say) can\[aq]t turn a plain mkrep
|
||
call into a remote-creating one. This auto-detect path is silent (no
|
||
error) under --no-git; --server itself still requires --git, and
|
||
--server together with --remote or --new-remote is an error. Either
|
||
way, before creating anything mkrep checks whether
|
||
<user>/<name> already exists on that host: if so, it links to the
|
||
existing repo instead of creating one; if not, it creates the repo
|
||
and reports the new remote\[aq]s URL. --check-existing runs just that
|
||
check and reports the result without creating or linking anything; it
|
||
requires a resolved server and is mutually exclusive with --remote
|
||
and --new-remote.
|
||
|
||
Arguments:
|
||
<dir> Directory to create and enter
|
||
--cd, --no-cd Change into <dir> (default: --cd)
|
||
--mkdir, --no-mkdir
|
||
Create <dir>, including missing parents (default: --mkdir)
|
||
--git, --no-git Run git init in <dir> (default: --git)
|
||
-c, --clean Remove <dir> first if it already exists
|
||
--no-clean Leave an existing <dir> alone (default)
|
||
--strict Fail if <dir> already exists (checked after --clean)
|
||
-v, --verbose Print each step as it runs
|
||
-s, --silent Suppress all output; overrides --verbose
|
||
--template <path>
|
||
Passed through as git init --template=<path>
|
||
--branch <name> Passed through as git init -b <name>
|
||
--remote <url> Link an existing remote: git remote add origin <url>
|
||
--new-remote [<cmd>]
|
||
Create + link a remote by running <cmd> (or
|
||
$MKREP_REMOTE_CMD) in the new repo directory
|
||
--server <type> Auto-create/link a remote on gitea, gitlab, or github
|
||
--check-existing Report whether the repo exists on the resolved
|
||
server; creates or links nothing
|
||
--name <name> {name} substitution for --new-remote/--server
|
||
(default: <dir>\[aq]s basename)
|
||
-h, --help Show this help message
|
||
|
||
Exit Status:
|
||
0 All requested steps completed
|
||
1 Bad arguments, or a step (mkdir, cd, git init, remote) failed
|
||
|
||
Example:
|
||
mkrep \[ti]/projects/my-new-repo
|
||
mkrep --clean --strict \[ti]/projects/scratch
|
||
mkrep --remote git\[at]git.example.com:me/foo.git \[ti]/projects/foo
|
||
set -Ux MKREP_REMOTE_CMD \[aq]gh repo create {name} --private --source=. --remote=origin --push\[aq]
|
||
mkrep --new-remote \[ti]/projects/foo
|
||
set -gx GITEA_URL https://git.example.com
|
||
set -gx GIT_SERVER gitea
|
||
mkrep \[ti]/projects/foo
|
||
mkrep --server gitlab --check-existing \[ti]/projects/foo
|
||
|
||
Starting points for $MKREP_REMOTE_CMD, one per host CLI -- each assumes
|
||
that tool is already installed and authenticated, creates a private
|
||
repo under the caller\[aq]s own account, and pushes it if there is
|
||
already a commit to push (mkrep itself only runs git init, so a
|
||
freshly created repo has none yet -- pushing an unborn HEAD is a
|
||
guaranteed error regardless of the remote, so the push is skipped
|
||
rather than attempted). These are also mkrep\[aq]s built-in defaults for
|
||
--server/$GIT_SERVER when $MKREP_REMOTE_CMD is unset. gh supports a
|
||
one-shot --source/--remote/--push; glab and tea\[aq]s create commands do
|
||
not, so they are chained with the git commands that do the linking:
|
||
GitHub (gh): gh repo create {name} --private --source=. --remote=origin --push
|
||
GitLab (glab): glab repo create {name} --private --skipGitInit && git remote add origin {server}/{user}/{name}.git && if git rev-parse --verify -q HEAD >/dev/null 2>&1; git push -u origin HEAD; end
|
||
Gitea (tea): tea repos create --name {name} --private && git remote add origin {server}/{user}/{name}.git && if git rev-parse --verify -q HEAD >/dev/null 2>&1; git push -u origin HEAD; end
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\f[B]Dependencies:\f[R] \f[V]_fish_mkdir_p\f[R],
|
||
\f[V]__fish_palette\f[R], \f[V]_mkrep_say\f[R],
|
||
\f[V]_mkrep_verbose\f[R], \f[V]_mkrep_default_remote_cmd\f[R],
|
||
\f[V]_mkrep_remote_url\f[R], \f[V]_mkrep_repo_exists\f[R], \f[V]git\f[R]
|
||
.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.
|
||
|
||
Exit Status:
|
||
0 No orphans found, or orphans removed successfully
|
||
Nonzero sudo pacman -Rns failed
|
||
|
||
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.
|
||
|
||
Exit Status:
|
||
Exit status of fish-deps status
|
||
|
||
Example:
|
||
check_fish_deps
|
||
\f[R]
|
||
.fi
|
||
.SS fish-deps
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Synopsis: fish-deps [status|install|update|sync] [--optional] [--terminals] [--all]
|
||
|
||
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 five tiers:
|
||
|
||
Required fish, fzf
|
||
Recommended cargo, starship, uv, zoxide, direnv, paru, yay,
|
||
eza, lsd, bat, ov, ripgrep, trash, python3
|
||
Optional btop, dust, duf, prettyping, go, lazygit,
|
||
lazydocker, docker, yt-dlp, screen \[em] single-purpose
|
||
wrapper conveniences that only matter if you
|
||
already use that tool; skipped by install/sync
|
||
unless --optional (or --all) is passed
|
||
Terminal Emulators kitty, wezterm \[em] only matter if one of them is
|
||
your actual terminal; skipped by install/sync
|
||
unless --terminals (or --all) is passed
|
||
Integrations wakatime, tailscale
|
||
|
||
Arguments:
|
||
status Report installed/missing deps (default)
|
||
install Install missing deps interactively
|
||
update Update all installed deps
|
||
sync Install missing deps, then update all
|
||
--optional With install/sync: also offer Optional-tier deps
|
||
--terminals With install/sync: also offer Terminal-Emulator-tier deps
|
||
--all With install/sync: shorthand for --optional --terminals
|
||
|
||
Exit Status:
|
||
0 Subcommand completed
|
||
1 Unknown subcommand
|
||
|
||
Example:
|
||
fish-deps sync
|
||
fish-deps
|
||
fish-deps install
|
||
fish-deps install --optional
|
||
fish-deps install --terminals
|
||
fish-deps install --all
|
||
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.
|
||
|
||
Exit Status:
|
||
0 fzf installed or updated successfully
|
||
Nonzero git or the fzf install script failed
|
||
|
||
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.
|
||
|
||
Exit Status:
|
||
0 Always (individual step failures are not propagated)
|
||
|
||
Example:
|
||
limine-edit
|
||
\f[R]
|
||
.fi
|
||
.SS lock
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Synopsis: lock
|
||
|
||
Locks the current desktop session using loginctl lock-session.
|
||
|
||
Exit Status:
|
||
Exit status of 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.
|
||
|
||
Exit Status:
|
||
Exit status of lsof
|
||
|
||
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.
|
||
|
||
Exit Status:
|
||
Exit status of 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).
|
||
|
||
Exit Status:
|
||
0 Always
|
||
|
||
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 docker
|
||
and starship are both installed and C3 overrides are enabled, also shows
|
||
the active Docker context (if non-default).
|
||
|
||
Exit Status:
|
||
0 Always
|
||
|
||
Example:
|
||
# Rendered automatically by fish; not called directly.
|
||
\f[R]
|
||
.fi
|
||
.SS jobrunner
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Synopsis: jobrunner [-t <tool>] [<subcommand>] [<name>] [<command>...]
|
||
jr [-t <tool>] [<subcommand>] [<name>] [<command>...]
|
||
|
||
Runs, lists, inspects, re-attaches to, and terminates named background
|
||
jobs using tmux or GNU screen as the process engine. Unlike bkg and
|
||
detach, which discard output, a jobrunner job keeps a live terminal you
|
||
can return to later \[em] it survives closing the shell, and attach
|
||
restores it in any subsequent session.
|
||
Run and manage named background jobs. Jobs are detached from the shell
|
||
and backed by tmux (preferred) or GNU screen.
|
||
|
||
If the job name is omitted when starting a new job (e.g. jobrunner sleep 1),
|
||
a memorable, random name (like sleepy-badger) will be generated.
|
||
|
||
Exit Status:
|
||
0 Command succeeded, or no jobs are running
|
||
1 Invalid arguments, or the named job does not exist
|
||
127 neither tmux nor screen is installed
|
||
|
||
Notes:
|
||
Detach from an attached job with Ctrl-A then D; the job keeps running.
|
||
Commands are executed directly rather than through a shell, so pipes and
|
||
redirections must be wrapped explicitly, e.g.
|
||
jobrunner run sync fish -c \[aq]a | b\[aq].
|
||
|
||
Example:
|
||
jobrunner run -n build make -j8
|
||
jobrunner sleep 1000
|
||
jobrunner -t screen run -n backup rsync -a ./data remote:/backup/
|
||
jobrunner list
|
||
jobrunner logs build
|
||
jobrunner build
|
||
jobrunner kill build
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\f[B]Dependencies:\f[R] \f[V]tmux\f[R], \f[V]screen\f[R],
|
||
\f[V]__jobrunner_sessions\f[R]
|
||
.PP
|
||
\f[B]Used by:\f[R] \f[V]jr\f[R]
|
||
.SS jr
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Synopsis: jr [<subcommand>] [<name>] [<command>...]
|
||
|
||
Shorthand for jobrunner. Accepts the same subcommands, flags, and
|
||
shorthands, and inherits its completions.
|
||
|
||
Arguments:
|
||
See jobrunner --help for the full argument reference.
|
||
|
||
Exit Status:
|
||
Same as jobrunner.
|
||
|
||
Example:
|
||
jr run build make -j8
|
||
jr list
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\f[B]Dependencies:\f[R] \f[V]jobrunner\f[R]
|
||
.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.
|
||
|
||
Exit Status:
|
||
0 Always
|
||
|
||
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.
|
||
|
||
Exit Status:
|
||
0 Always (network failures print \[dq]Not detected\[dq] instead of failing)
|
||
|
||
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.
|
||
|
||
Exit Status:
|
||
Exit status of curl
|
||
|
||
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
|
||
|
||
Exit Status:
|
||
Exit status of qrencode, or curl if qrencode is unavailable
|
||
|
||
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
|
||
exit 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. At the end
|
||
of every invocation any uncommitted changes inside the sub-repo are
|
||
auto-committed so agent-made edits are captured automatically. Fully
|
||
idempotent: a second run produces no output and no new commits.
|
||
|
||
The commit is local only. Nothing here fetches or pushes: the wrappers
|
||
call this synchronously before starting an agent, and a network round
|
||
trip there blocks the launch until an unreachable remote times out and
|
||
can prompt for credentials with nobody watching. A sub-repo that has an
|
||
upstream is pulled by hand, on the user\[aq]s own schedule.
|
||
|
||
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, the AGENTS/ commit was
|
||
rejected, or an unresolved rebase blocked it)
|
||
|
||
Example:
|
||
agents-init
|
||
agents-init --agents
|
||
agents-init --plugins
|
||
agents-init --quiet
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\f[B]Dependencies:\f[R] \f[V]_agents_repo_install_tools\f[R],
|
||
\f[V]_agents_repo_sync\f[R], \f[V]_agents_init_ensure_gitignore\f[R]
|
||
.PP
|
||
\f[B]Used by:\f[R] \f[V]agy\f[R], \f[V]claude\f[R]
|
||
.SS agents-vault
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Synopsis: agents-vault [--link] [--push] [--restore] [--status]
|
||
[--adopt=SLUG] [--remote=URL]
|
||
[-v | --verbose] [-q | --quiet] [-s | --silent]
|
||
[-h | --help]
|
||
|
||
Tracks curated agent memory in a host-scoped git repository so it
|
||
survives losing a machine. Complements agents-init, which scaffolds the
|
||
per-project AGENTS/ repo: that holds the shareable agent specification,
|
||
while this holds the personal memory an agent accumulates.
|
||
|
||
Memory does not live in any project tree. Claude keeps it under
|
||
\[ti]/.claude/projects/<mangled-path>/memory/ and agy keeps its knowledge
|
||
store under \[ti]/.gemini/antigravity-cli/, both outside every repository.
|
||
|
||
Entries are keyed by normalized git remote URL rather than by path, so
|
||
the key survives a machine change or a directory rename. The live
|
||
memory directory becomes a symlink into the vault, which makes backup
|
||
and restore the same operation: on a new machine, clone the vault once
|
||
and the first agents-vault run in any project relinks its memory
|
||
automatically. No manifest and no batch restore step are involved.
|
||
|
||
Only curated memory is tracked. Session transcripts are excluded (tens
|
||
of megabytes per project, growing per session). Paths are allowlisted,
|
||
never denylisted, so nothing new upstream adds can leak in. The
|
||
allowlist runs all the way down, not just at the top: inside agy\[aq]s
|
||
knowledge store only *.md and *.json files are copied, so a credential
|
||
file or a conversation database appearing there is left behind by the
|
||
same rule rather than by being known about in advance. Symlinks found
|
||
inside the store are neither followed nor copied, so the allowlist
|
||
bounds whose files it collects and not merely what kind.
|
||
|
||
Global state that belongs to no project is tracked as well. Claude\[aq]s
|
||
global memory directory (\[ti]/.claude/memory) is symlinked into the vault
|
||
exactly like per-project memory, and is only linked when one side or
|
||
the other already holds something, since that path does not exist by
|
||
default. agy\[aq]s knowledge store and settings.json are copied rather
|
||
than symlinked: agy partitions by conversation UUID rather than by
|
||
workspace, so it has no per-project slice, and its store sits beside
|
||
SQLite databases whose WAL sidecars must never be live-tracked inside
|
||
a git worktree. A failed copy is reported but is not fatal, because an
|
||
incomplete backup still leaves the agent working.
|
||
|
||
Because the slug is derived from the remote, gaining, losing, or
|
||
rewriting a project\[aq]s origin changes it. Each run detects this by
|
||
reading the previous slug straight off the live memory symlink\[aq]s
|
||
target (no guessing) and migrates that entry to the new slug before
|
||
relinking, so memory accumulated under the old key is never orphaned.
|
||
If both the old and new entries already hold content the migration is
|
||
ambiguous and is refused; resolve it with --adopt=SLUG. An entry that
|
||
is already at the new key but holds no memory -- the shape a fresh
|
||
clone always produces, since git cannot track an empty directory -- is
|
||
moved aside, not deleted, and its origin log is folded into the
|
||
migrated entry, so a clone\[aq]s provenance survives the rename. The
|
||
rename is atomic: a failure at any point leaves the vault exactly as
|
||
it was and reports it.
|
||
|
||
Run with no flags, the command scaffolds the vault, syncs global state,
|
||
links the current project, and commits. The other modes are exclusive
|
||
and each returns as soon as it is done:
|
||
|
||
--status is a report and mutates nothing at all. It is answered before
|
||
the vault is even scaffolded, so asking what the vault looks like never
|
||
creates it, never copies agy state into it, and never claims
|
||
\[ti]/.claude/memory. A missing vault is reported rather than built.
|
||
|
||
--restore walks every vault entry and relinks the live memory directory
|
||
of each one whose recorded origin path still exists, naming the rest so
|
||
they can be rebound by hand. It is a convenience: the ordinary per-
|
||
project run restores a cloned vault\[aq]s memory on its own.
|
||
|
||
--adopt=SLUG rebinds the current project\[aq]s entry to SLUG, which is how
|
||
a machine-specific local-* key or an ambiguous migration is resolved.
|
||
SLUG must match [a-z0-9._-]+ and be neither \[dq].\[dq] nor \[dq]..\[dq] -- the charset
|
||
the slug formula itself emits -- since it is interpolated into a vault
|
||
path and handed to git mv. The rename and the relink are atomic: if the
|
||
live memory directory cannot be repinned onto the new entry the rename
|
||
is rolled back, so an ordinary run still finds the original entry.
|
||
|
||
--remote=URL points the vault at a remote; --push commits, pulls, and
|
||
then pushes there. The pull happens only on this path. Committing needs
|
||
no remote at all, and both wrappers run this command synchronously
|
||
before starting an agent, so a fetch on the ordinary run would block
|
||
every launch for as long as an unreachable remote takes to time out --
|
||
and would take the local commit down with it, leaving an offline
|
||
machine with no backup at all.
|
||
|
||
Arguments:
|
||
--link Scaffold the vault and link this project\[aq]s memory; skip
|
||
the final commit
|
||
--push Commit, pull, then push to the vault remote
|
||
--restore Walk the vault, relink what is possible, report the rest
|
||
--status Show entries, link health, remote state, and orphans
|
||
--adopt=SLUG Bind the current project to an existing vault entry
|
||
--remote=URL Set the vault remote
|
||
-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
|
||
-h, --help Show this help message and exit
|
||
|
||
Exit Status:
|
||
0 Completed successfully
|
||
1 Fatal error (vault unavailable, git failure, ambiguous migration,
|
||
invalid --adopt slug, nothing committed, or a push that did not
|
||
reach the remote)
|
||
|
||
Returns:
|
||
--status prints its report on stdout: the vault path, the remote and
|
||
how far ahead of it the vault is, a warning for an unresolved rebase,
|
||
then one line per entry reading \[dq]linked\[dq] or \[dq]orphan\[dq], the slug, and the
|
||
file count. Every other mode prints only verbosity-gated progress
|
||
lines, and nothing at all when there was nothing to do.
|
||
|
||
Notes:
|
||
Set __fish_agent_vault_dir to relocate the vault. Set
|
||
__fish_agent_vault_autopush to 1 to also push on wrapper launch; it
|
||
defaults to off because that push is synchronous and so delays every
|
||
launch. With it on, the pull and the push are each capped at 20
|
||
seconds, since git has no connect timeout of its own and an
|
||
unreachable remote otherwise blocks for minutes. An explicit --push
|
||
is left uncapped: it is watched, and it must report what a real
|
||
transfer really did. The cap is timeout(1); on a system that somehow
|
||
lacks it, autopush says so on stderr and does not push at all, since
|
||
an unbounded network call in front of a launch is the one outcome the
|
||
cap exists to prevent. --push still works there.
|
||
|
||
Over ssh the cap is delivered by setting GIT_SSH_COMMAND, which would
|
||
silently outrank the user\[aq]s own configuration -- so it is not set at
|
||
all when GIT_SSH_COMMAND is already exported or git\[aq]s core.sshCommand
|
||
is configured. A vault remote reachable only through a particular
|
||
identity file or ssh wrapper therefore keeps it, uncapped, rather than
|
||
failing to authenticate for the sake of a timeout.
|
||
|
||
--adopt rebinds an entry; it does not pin its name. The slug is
|
||
re-derived from the project on every run, so the next ordinary run
|
||
migrates the adopted entry straight back to the canonical key, carrying
|
||
the memory and the live link with it. That is the point rather than a
|
||
wart: adopting is how a mismatched or ambiguous binding is repaired, not
|
||
how an entry is given a permanent name of its own.
|
||
|
||
An entry\[aq]s origin file records the project path once, when the entry is
|
||
created, and is never refreshed. A project that later moves on disk
|
||
therefore keeps a stale path there and --restore degrades to reporting
|
||
it as unplaceable rather than relinking the wrong directory. Rebind
|
||
such an entry from the project itself with --adopt=SLUG.
|
||
|
||
The agy knowledge copy is merge-only. Files are copied into the vault
|
||
but are never removed from it, so a fact deleted upstream from agy\[aq]s
|
||
knowledge store persists in the vault indefinitely, and a restore or a
|
||
fresh clone brings it back. Prune such an entry from the vault by hand
|
||
if it must really be gone.
|
||
|
||
Three further variables exist only so the test suite can run against
|
||
throwaway directories instead of the real home, and are not meant for
|
||
everyday use. __fish_agent_vault_claude_root overrides Claude\[aq]s
|
||
per-project directory (\[ti]/.claude/projects), which is where the
|
||
per-project memory directories live. __fish_agent_vault_claude_home
|
||
overrides Claude\[aq]s home directory (\[ti]/.claude), whose memory
|
||
subdirectory holds the global memory. Those two name different paths
|
||
and setting one has no effect on the other.
|
||
__fish_agent_vault_agy_root overrides agy\[aq]s state directory
|
||
(\[ti]/.gemini/antigravity-cli), which is only ever read from.
|
||
|
||
The last two are not optional niceties. Without them, a test run on a
|
||
machine that has a real global memory directory would move it into a
|
||
throwaway directory and leave a dangling symlink behind, which is
|
||
strictly worse than having had no backup at all.
|
||
|
||
Example:
|
||
agents-vault
|
||
agents-vault --status
|
||
agents-vault --remote=https://git.rootiest.dev/rootiest/agent-vault.git
|
||
agents-vault --push
|
||
agents-vault --adopt=git.rootiest.dev-rootiest-fish-config
|
||
agents-vault --restore
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\f[B]Dependencies:\f[R] \f[V]_agents_vault_dir\f[R],
|
||
\f[V]_agents_repo_slug\f[R], \f[V]_agents_repo_local_slug\f[R],
|
||
\f[V]_agents_repo_ensure_symlink\f[R], \f[V]_agents_repo_sync\f[R],
|
||
\f[V]_agents_repo_install_tools\f[R], \f[V]git\f[R], \f[V]hostname\f[R]
|
||
.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.
|
||
|
||
Also syncs the host-scoped agent memory vault (agents-vault). agy has
|
||
no session-end hook, so its memory is captured on the next launch
|
||
rather than at session end.
|
||
|
||
Arguments are forwarded verbatim to the real agy binary, except for
|
||
-r/--resume which use different syntax in agy than claude: bare
|
||
-r/--resume (no session id following) translate to -c/--continue
|
||
(resume most-recent session); -r/--resume given a session id (via
|
||
=id or a following bare word) translate to --conversation(=id)
|
||
(open that specific session).
|
||
|
||
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/--resume
|
||
translate to -c/--continue or --conversation, see DESCRIPTION)
|
||
|
||
Exit Status:
|
||
Exit status of the underlying agy binary
|
||
|
||
Example:
|
||
agy
|
||
agy --resume
|
||
agy --resume=5fffb251-2cd6-4cfe-8dac-b5e913a86db6
|
||
agy -i \[dq]initial prompt\[dq]
|
||
agy models
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\f[B]Dependencies:\f[R] \f[V]agents-init\f[R], \f[V]agents-vault\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.
|
||
|
||
Also syncs the host-scoped agent memory vault (agents-vault), which
|
||
tracks curated memory living outside the project tree. The vault
|
||
commits on launch but does not push; pushing happens from the Claude
|
||
Code SessionEnd hook or an explicit agents-vault --push.
|
||
|
||
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], \f[V]agents-vault\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.
|
||
|
||
Exit Status:
|
||
Exit status of the claude invocation
|
||
|
||
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.
|
||
|
||
Exit Status:
|
||
Exit status of the claude invocation
|
||
|
||
Example:
|
||
claude-pr
|
||
\f[R]
|
||
.fi
|
||
.SS docker
|
||
.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,
|
||
and a bare invocation with no subcommand, are passed through to the real
|
||
docker binary.
|
||
|
||
Arguments:
|
||
subcommand Docker subcommand (ps is redirected to dops)
|
||
args... Arguments forwarded to docker or dops
|
||
|
||
Exit Status:
|
||
Exit status of dops (for ps), or of the real docker binary otherwise
|
||
|
||
Example:
|
||
docker ps
|
||
docker
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\f[B]Dependencies:\f[R] \f[V]dops\f[R]
|
||
.PP
|
||
\f[B]Used by:\f[R] \f[V]dops\f[R]
|
||
.SS dops
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Synopsis: dops [args...]
|
||
|
||
Enhanced container listing: runs docker ps with a clean custom table
|
||
(Names, Image, Status, Ports) instead of docker\[aq]s noisier default
|
||
columns. Extra arguments (e.g. -a) are forwarded to docker ps.
|
||
|
||
Arguments:
|
||
args... Arguments forwarded to docker ps
|
||
|
||
Exit Status:
|
||
Exit status of docker ps
|
||
|
||
Example:
|
||
dops
|
||
dops -a
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\f[B]Dependencies:\f[R] \f[V]docker\f[R]
|
||
.PP
|
||
\f[B]Used by:\f[R] \f[V]docker\f[R]
|
||
.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 qc --help 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 play-media
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Synopsis: play-media [-p|--player <cmd>]
|
||
play-media --help
|
||
|
||
Opens an fzf picker (with thumbnail/metadata preview via
|
||
_fzf_preview_media) listing audio and video files under the current
|
||
directory, and plays the selection(s) in the best available media
|
||
player. Supports multi-select (Tab) to queue several files at once.
|
||
|
||
Player resolution order:
|
||
1. -p/--player <cmd> (explicit override, validated as a command)
|
||
2. $play_media_player (explicit override, validated as a command)
|
||
3. xdg-mime default handler for the first selected file\[aq]s mimetype
|
||
4. First known player binary found in a built-in list (mpv, vlc)
|
||
|
||
The player is launched backgrounded and detached, mirroring open-url,
|
||
so the shell is never blocked.
|
||
|
||
Arguments:
|
||
-p, --player <cmd> Force a specific player command
|
||
-h, --help Print usage and exit
|
||
|
||
Exit Status:
|
||
0 Player launched (or the picker was cancelled)
|
||
1 No media files found, invalid --player/$play_media_player, or no
|
||
player found
|
||
|
||
Example:
|
||
play-media
|
||
play-media --player mpv
|
||
\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.
|
||
|
||
Exit Status:
|
||
Exit status of steam (via systemd-inhibit)
|
||
|
||
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 man -l; 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 help config [...] \[em] this function is
|
||
registered as a handler in the help wrapper so that syntax works
|
||
transparently. Direct config-help 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. On the
|
||
Universal/Session pages, Enter on a category row (C1\[en]C6) opens that
|
||
category\[aq]s sub-category drill-down page, which leads with the category\[aq]s
|
||
own toggle; Escape backs out. Value rows (Sponge, Paths) use Enter to edit
|
||
inline and ← / h to reset to the row default; committing a blank edit does
|
||
the same. 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 through pages.
|
||
|
||
/ filters the current page on label and description. On the Universal and
|
||
Session pages the filter also reaches into every category\[aq]s sub-categories,
|
||
listing hits as \[dq]Category › Sub\[dq], so a sub-category can be toggled without
|
||
drilling into its parent first.
|
||
|
||
Edits are collected while the TUI runs and applied in one batch when it
|
||
exits, via __config_settings_apply and __config_settings_set_value. The
|
||
status bar shows a pending count. This is a deliberate consequence of the
|
||
renderer being a child process: a child cannot reach into its parent shell
|
||
to set a global, so the Session page\[aq]s edits come back as a fish script the
|
||
function sources on exit, and the Universal page rides the same path for
|
||
consistency. 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. Editing Dots link re-runs __fish_user_dots_link.
|
||
|
||
The panel is drawn by scripts/config-settings-tui.py using Python\[aq]s stdlib
|
||
curses module, which owns the cell arithmetic, the alternate screen and the
|
||
redraw diffing. It resizes with the terminal and needs no width tiers.
|
||
|
||
Navigation:
|
||
↑ ↓ / k j Move cursor
|
||
← → / h l Toggle rows: OFF ← DEFAULT → ON
|
||
← / h Value rows: reset to default
|
||
Enter Category rows: open the sub-category page.
|
||
Value rows: edit inline
|
||
/ Filter, sub-categories included
|
||
Escape Back out of a sub-category page, or clear the filter
|
||
Tab / S-Tab Next / previous page
|
||
? Help overlay
|
||
q Apply pending edits and exit
|
||
|
||
Arguments:
|
||
-h, --help Print usage and exit
|
||
|
||
Exit Status:
|
||
0 Exited normally
|
||
1 Unknown flag, no TTY, or python3/curses unavailable
|
||
|
||
Example:
|
||
config-settings
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
\f[B]Dependencies:\f[R] \f[V]__fish_palette\f[R],
|
||
\f[V]__config_settings_state\f[R], \f[V]__config_settings_apply\f[R],
|
||
\f[V]__config_settings_set_value\f[R], \f[V]python3\f[R]
|
||
.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 exec fish 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.
|
||
install 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. uninstall reverses it. status
|
||
reports wiring, installed watcher version, and C5 logging state. dismiss
|
||
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.
|
||
|
||
Exit Status:
|
||
1 docker or lazydocker is not installed
|
||
|
||
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 rand_string
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Synopsis: rand_string [COMPONENTS/MODIFIERS]...
|
||
|
||
Generates a random, memorable string using a sequence of specified word
|
||
categories and formatting modifiers. Words are pulled from curated
|
||
plain-text databases bundled in data/words/.
|
||
|
||
Modifiers like --separator and --case are evaluated sequentially and
|
||
apply only to the components that follow them.
|
||
|
||
Supported Components:
|
||
<category> A bundled word list (e.g. adjective, animal, color, name, noun, verb)
|
||
digits=<N> N random digits (e.g. digits=3 -> 842)
|
||
literal=<text> A static string component (e.g. literal=TEST)
|
||
|
||
Arguments:
|
||
-s, --separator=<sep> Delimiter for subsequent words (dash, underscore, dot, none, or literal chars)
|
||
-c, --case=<casing> Casing for subsequent words (lower, upper, title)
|
||
-h, --help Show usage help
|
||
|
||
Exit Status:
|
||
0 String generated successfully
|
||
1 Unknown category or missing word list file
|
||
|
||
Notes:
|
||
Falls back to random choice if GNU shuf is missing, but shuf is
|
||
much faster for files with >1000 lines.
|
||
|
||
Example:
|
||
rand_string adjective animal
|
||
rand_string --case=title color animal --separator=dot digits=4
|
||
rand_string literal=TEST --separator=underscore verb noun
|
||
\f[R]
|
||
.fi
|
||
.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 origin remote in a
|
||
browser (via open-url). Deep-links to the current branch when it exists
|
||
on the remote, falling back to the remote\[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.
|
||
|
||
Exit Status:
|
||
0 Always
|
||
|
||
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
|
||
\f[V]fish-deps\f[R] manages these tools.
|
||
Run \f[V]fish-deps\f[R] to check status, \f[V]fish-deps install\f[R] to
|
||
install missing Required/Recommended ones, or add \f[V]--optional\f[R],
|
||
\f[V]--terminals\f[R], or \f[V]--all\f[R] to also include the Optional
|
||
and/or Terminal Emulators tiers.
|
||
.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 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 \f[V]direnv\f[R] 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 \f[V]paru\f[R]); 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]ov\f[R]
|
||
T}@T{
|
||
Modern pager (replaces \f[V]less\f[R]); also backs the \f[V]logs\f[R]
|
||
viewer.
|
||
Not a Rust crate, despite the name collision with an unrelated
|
||
\f[V]ov\f[R] crate on crates.io.
|
||
Prefers \f[V]go install github.com/noborus/ov\[at]latest\f[R] when
|
||
\f[V]go\f[R] is available (always gets the latest release, and covers
|
||
distros like Debian/Ubuntu that don\[cq]t package \f[V]ov\f[R] in their
|
||
base repos); falls back to the system PM (AUR on Arch) otherwise.
|
||
T}
|
||
T{
|
||
\f[V]ripgrep\f[R]
|
||
T}@T{
|
||
Fast line search
|
||
T}
|
||
T{
|
||
\f[V]trash\f[R]
|
||
T}@T{
|
||
Safe delete (\f[V]trash-cli\f[R]); backs the \f[V]rm\f[R] and
|
||
\f[V]scrub\f[R] wrappers.
|
||
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}
|
||
.TE
|
||
.SS Optional
|
||
.PP
|
||
Single-purpose tools that back one wrapper function (or less) and only
|
||
matter if you already use that specific tool.
|
||
Skipped by \f[V]fish-deps install\f[R]/\f[V]sync\f[R] unless you pass
|
||
\f[V]--optional\f[R].
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(35.0n) lw(35.0n).
|
||
T{
|
||
Tool
|
||
T}@T{
|
||
Description
|
||
T}
|
||
_
|
||
T{
|
||
\f[V]btop\f[R]
|
||
T}@T{
|
||
Modern resource monitor; backs the \f[V]top\f[R] wrapper (falls back to
|
||
system \f[V]top\f[R]).
|
||
T}
|
||
T{
|
||
\f[V]dust\f[R]
|
||
T}@T{
|
||
Disk usage tree (Rust); one of two backends for the \f[V]du\f[R] wrapper
|
||
(falls back to system \f[V]du\f[R]).
|
||
T}
|
||
T{
|
||
\f[V]duf\f[R]
|
||
T}@T{
|
||
Disk usage/free overview; the other backend for the \f[V]du\f[R] wrapper
|
||
(falls back to system \f[V]du\f[R]).
|
||
T}
|
||
T{
|
||
\f[V]prettyping\f[R]
|
||
T}@T{
|
||
Colorized \f[V]ping\f[R] wrapper; backs the \f[V]ping\f[R] wrapper
|
||
(falls back to system \f[V]ping\f[R]).
|
||
T}
|
||
T{
|
||
\f[V]go\f[R]
|
||
T}@T{
|
||
Go toolchain; only used to install \f[V]ov\f[R] via \f[V]go install\f[R]
|
||
(see below), which gets the latest release and doesn\[cq]t depend on
|
||
your distro packaging \f[V]ov\f[R].
|
||
Package name varies by distro (\f[V]go\f[R] on Arch/Homebrew,
|
||
\f[V]golang\f[R]/\f[V]golang-go\f[R] on Debian/Fedora) \[em] install
|
||
manually if the listed package name doesn\[cq]t resolve on your system.
|
||
T}
|
||
T{
|
||
\f[V]lazygit\f[R]
|
||
T}@T{
|
||
Terminal git UI; only referenced by the \f[V]lg\f[R] abbreviation.
|
||
T}
|
||
T{
|
||
\f[V]lazydocker\f[R]
|
||
T}@T{
|
||
Terminal docker UI; backs the \f[V]ld\f[R] wrapper.
|
||
T}
|
||
T{
|
||
\f[V]docker\f[R]
|
||
T}@T{
|
||
Container runtime; gates the Docker context indicator in the right
|
||
prompt and backs the \f[V]ld\f[R] wrapper.
|
||
Both consumers are guarded with \f[V]type -q docker\f[R] and degrade
|
||
gracefully without it.
|
||
Installing the daemon package does not enable/start the service \[em] do
|
||
that yourself if you want it running.
|
||
T}
|
||
T{
|
||
\f[V]yt-dlp\f[R]
|
||
T}@T{
|
||
Video/media downloader; backs the \f[V]yt-dlp\f[R] wrapper function.
|
||
The wrapper falls back to the system \f[V]yt-dlp\f[R] and the rest of
|
||
the config works without it.
|
||
T}
|
||
T{
|
||
\f[V]screen\f[R]
|
||
T}@T{
|
||
GNU screen; fallback backend for \f[V]jobrunner\f[R] when \f[V]tmux\f[R]
|
||
is unavailable.
|
||
T}
|
||
.TE
|
||
.SS Terminal Emulators
|
||
.PP
|
||
GPU-accelerated terminal emulators.
|
||
Only one is ever relevant to a given user \[em] the one matching
|
||
\f[V]$TERM\f[R] \[em] so neither is installed by default.
|
||
Skipped by \f[V]fish-deps install\f[R]/\f[V]sync\f[R] unless you pass
|
||
\f[V]--terminals\f[R] (or \f[V]--all\f[R]).
|
||
.PP
|
||
.TS
|
||
tab(@);
|
||
lw(35.0n) lw(35.0n).
|
||
T{
|
||
Tool
|
||
T}@T{
|
||
Description
|
||
T}
|
||
_
|
||
T{
|
||
\f[V]kitty\f[R]
|
||
T}@T{
|
||
GPU-accelerated terminal; unlocks kitty-specific abbreviations and
|
||
\f[V]--hyperlink-format=kitty\f[R] in the \f[V]rg\f[R] wrapper when
|
||
\f[V]$TERM = xterm-kitty\f[R].
|
||
T}
|
||
T{
|
||
\f[V]wezterm\f[R]
|
||
T}@T{
|
||
GPU-accelerated terminal; unlocks WezTerm-specific abbreviations when
|
||
it\[cq]s the active terminal.
|
||
T}
|
||
.TE
|
||
.SS Integrations
|
||
.PP
|
||
Opt-in third-party services that require their own account/setup.
|
||
.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 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]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{
|
||
\f[V]go install\f[R]
|
||
T}@T{
|
||
\f[V]ov\f[R] \[em] preferred over the system PM when \f[V]go\f[R] is
|
||
available; always gets the latest release
|
||
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 or \f[V]go install\f[R] path
|
||
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 \f[V]config-settings\f[R]
|
||
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 \f[V]local.fish\f[R] directly, not by
|
||
\f[V]config.fish\f[R].
|
||
.PP
|
||
\f[V]local.fish\f[R] is sourced at the end of \f[V]config.fish\f[R] on
|
||
every interactive session, so it and its companion
|
||
\f[V]secrets.fish\f[R] can override anything set earlier.
|
||
.SS Overriding Configuration Variables
|
||
.PP
|
||
Any variable set in \f[V]local.fish\f[R] 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 (\f[V]fzf\f[R] colors, theme) are stored in
|
||
\f[V]fish_variables\f[R] via \f[V]set -U\f[R].
|
||
These are machine-local and git-ignored.
|
||
Do not commit \f[V]fish_variables\f[R].
|
||
.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
|
||
\f[V]config-settings\f[R] \[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 (\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 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 Sub-categories
|
||
.PP
|
||
Each of the six categories further sub-divides into two to six
|
||
sub-categories, each with its own
|
||
\f[V]__fish_config_op_<category>_<subcategory>\f[R] variable
|
||
(e.g.\ \f[V]__fish_config_op_aliases_filesystem\f[R]).
|
||
These follow the exact same truthy/falsy/unset cascade one level deeper:
|
||
an explicit sub-category value overrides the master switch and the
|
||
parent category\[cq]s setting, and an unset sub-category inherits from
|
||
its parent category (which in turn inherits from
|
||
\f[V]__fish_config_opinionated\f[R]).
|
||
Run \f[V]config-settings\f[R] and press Enter on a category row to
|
||
browse and toggle its sub-categories interactively.
|
||
See Components Reference for the full sub-category breakdown of every
|
||
category.
|
||
.SS Agent Memory Vault
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
__fish_agent_vault_dir
|
||
|
||
Overrides the agent memory vault location. Defaults to
|
||
$XDG_DATA_HOME/agent-vault (or \[ti]/.local/share/agent-vault).
|
||
|
||
__fish_agent_vault_autopush
|
||
|
||
When set to 1, agents-vault also pushes on wrapper launch. Defaults to
|
||
off: the vault commits locally on every launch and pushes from the
|
||
Claude Code SessionEnd hook or an explicit agents-vault --push. That
|
||
push is synchronous, so with autopush on the pull and the push are
|
||
each capped at 20 seconds; an explicit --push is left uncapped.
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
NOTE: With autopush off and no SessionEnd hook installed, backups
|
||
accumulate locally and never reach the remote.
|
||
Run \f[V]agents-vault --status\f[R] to check how far ahead the vault is.
|
||
.SS Prompt and Theme
|
||
.SS Starship
|
||
.PP
|
||
The primary prompt is Starship, initialized by
|
||
\f[V]conf.d/starship.fish\f[R].
|
||
Configure it via \f[V]\[ti]/.config/starship.toml\f[R].
|
||
.PP
|
||
\f[V]conf.d/starship.fish\f[R] defines a \f[V]fish_prompt\f[R] wrapper
|
||
that only activates when \f[V]starship\f[R] is in PATH and C3 overrides
|
||
are enabled (see Opinionated Components above).
|
||
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.
|
||
It also prints a blank line before the prompt, skipped in private mode
|
||
or on a freshly cleared screen.
|
||
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
|
||
\f[V]functions/fish_prompt.fish\f[R].
|
||
No external dependencies \[em] fish builtins only.
|
||
.PP
|
||
Layout (a dim job line appears between the two rows for each running
|
||
background job):
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
┬─[user\[at]host:\[ti]/path] (main)
|
||
│ nvim notes.md
|
||
╰─>$
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Elements:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Segment Meaning
|
||
────────────────────────────────────────────────────────────────
|
||
user Yellow (Catppuccin Yellow); red if root
|
||
\[at]host Blue (local) or Teal (SSH)
|
||
\[ti]/path prompt_pwd abbreviation (Catppuccin Text)
|
||
─[N/I/R/V/O] Vi-mode indicator (Normal/Insert/Replace/Visual/Operator);
|
||
shown only when vi or hybrid key bindings are active
|
||
─[V:name] Active Python venv basename; omitted when none
|
||
(main) Current git branch in Catppuccin Pink, with ↑/↓
|
||
upstream-tracking arrows when applicable;
|
||
omitted outside repos
|
||
┬─ / ╰─> Connector lines: Catppuccin Green on success,
|
||
Red on failure
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The right prompt (\f[V]fish_right_prompt.fish\f[R]) always renders,
|
||
independently of which left prompt is active:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Segment Shown when
|
||
────────────────────────────────────────────────────────────────
|
||
✘ <code> The previous command exited non-zero (red)
|
||
<context> docker and starship are both installed, C3
|
||
overrides are enabled, and the active Docker
|
||
context is set and non-default
|
||
<timestamp> Always (dim, Catppuccin Overlay0)
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
The exit-status and Docker segments are independent \[em] for example,
|
||
right after a failing command with a non-default Docker context active:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
✘ 1 myctx Fri Jun 12 00:51:21 2026
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
A successful command with the same Docker context shows the segment too:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
myctx Fri Jun 12 00:51:21 2026
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
And without Starship (or with C3 disabled, or Docker not installed),
|
||
only the exit-status prefix and timestamp ever appear:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
✘ 1 Fri Jun 12 00:51:21 2026
|
||
\f[R]
|
||
.fi
|
||
.SS FZF
|
||
.PP
|
||
FZF is themed to Catppuccin Mocha via \f[V]FZF_DEFAULT_OPTS\f[R], set in
|
||
\f[V]conf.d/theme.fish\f[R] (opinionated; disabled by
|
||
\f[V]__fish_config_op_overrides\f[R], see Opinionated Components above).
|
||
The colors applied:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
Hex Role Catppuccin name
|
||
────────────────────────────────────────────────────────
|
||
#1E1E2E Background Base
|
||
#313244 Highlighted background Surface0
|
||
#45475A Selected background Surface1
|
||
#CDD6F4 Foreground Text
|
||
#F38BA8 Highlight / header Red
|
||
#CBA6F7 Info / prompt Mauve
|
||
#B4BEFE Marker Lavender
|
||
#F5E0DC Spinner / pointer Rosewater
|
||
#6C7086 Border Overlay0
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
To customize, override \f[V]FZF_DEFAULT_OPTS\f[R] in
|
||
\f[V]local.fish\f[R] \[em] it is sourced after
|
||
\f[V]conf.d/theme.fish\f[R] on every session, so a
|
||
\f[V]set -Ux FZF_DEFAULT_OPTS ...\f[R] there always wins.
|
||
.SS Catppuccin Mocha Syntax Highlighting
|
||
.PP
|
||
The Catppuccin Mocha theme ships with this config in themes/ and is
|
||
applied automatically on first run via \f[V]conf.d/first_run.fish\f[R]
|
||
(gated by \f[V]__fish_config_op_autoexec\f[R]; see Opinionated
|
||
Components above).
|
||
Colors are stored in \f[V]fish_variables\f[R] (universal).
|
||
Three other bundled variants are available in themes/ \[em] Latte,
|
||
Frappé, and Macchiato.
|
||
To switch:
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
fish_config theme choose \[dq]Catppuccin Latte\[dq]
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
* * * * *
|
||
.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 (rm, cp) to be safe by default
|
||
C2 Startup Side-Effects \[em] Bootstraps Fisher, generates wrappers, auto-activates venvs
|
||
C3 Overrides \[em] Overrides cd, sets Vi mode, binds <CR> to smart_enter
|
||
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
|
||
Each category further sub-divides into several sub-categories, each with
|
||
its own \f[V]__fish_config_op_<category>_<subcategory>\f[R] toggle \[en]
|
||
see that category\[cq]s page for its sub-category list.
|
||
.SS Per-function overrides: \f[V]C0\f[R]/\f[V]always\f[R]
|
||
.PP
|
||
Every guarded function or file can also carry a reserved
|
||
\f[V]always/on\f[R] or \f[V]always/off\f[R] tag in its
|
||
\f[V]# COMPONENT\f[R] header, independent of every C1-C6 category and
|
||
sub-category toggle and invisible to \f[V]config-settings\f[R].
|
||
An \f[V]always/off\f[R] tag disables that function unconditionally; an
|
||
\f[V]always/on\f[R] tag enables it unconditionally, ignoring the state
|
||
of every other tagged sub-category.
|
||
This is a per-function escape hatch for cases too granular or too
|
||
idiosyncratic to justify a taxonomy entry \[en] edit the header directly
|
||
and run \f[V]__fish_config_op_registry_rebuild\f[R] to apply the change.
|
||
.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 Sub-categories
|
||
.PP
|
||
\f[V]__fish_config_op_aliases\f[R] sub-divides into six sub-categories,
|
||
each with its own \f[V]__fish_config_op_aliases_<slug>\f[R] toggle:
|
||
.SS filesystem
|
||
.PP
|
||
\f[V]ls\f[R], \f[V]cat\f[R], \f[V]cd\f[R], \f[V]du\f[R],
|
||
\f[V]mkdir\f[R], \f[V]rm\f[R], \f[V]mv\f[R], and \f[V]cd\f[R]/zoxide
|
||
navigation \[en] the everyday filesystem-inspection and -modification
|
||
shadows.
|
||
.SS search
|
||
.PP
|
||
\f[V]rg\f[R], with its Kitty hyperlink formatting.
|
||
.SS network
|
||
.PP
|
||
\f[V]ping\f[R], \f[V]ssh\f[R], and \f[V]yt-dlp\f[R] \[en] shadows that
|
||
talk to the network.
|
||
.SS monitor
|
||
.PP
|
||
\f[V]top\f[R] -> \f[V]btop\f[R].
|
||
.SS shell-tools
|
||
.PP
|
||
\f[V]bash\f[R] (XDG bashrc + \f[V]$SHELL\f[R] reset), \f[V]less\f[R]
|
||
(\f[V]$PAGER\f[R] fallback chain), and the \f[V]help config\f[R]
|
||
interception.
|
||
.SS dev-tools
|
||
.PP
|
||
\f[V]claude\f[R] (\f[V]AGENTS.md/CLAUDE.md\f[R] auto-linking) and
|
||
\f[V]edit\f[R] (multi-editor launcher), plus \f[V]agy\f[R].
|
||
.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
|
||
\f[V]paru\f[R]/\f[V]yay\f[R] wrapper generation, no automatic venv
|
||
activation, no WakaTime reporting, no \f[V]auto-pull\f[R] (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 \f[V]config-settings\f[R] 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 \f[V]direnv\f[R] (\f[V].envrc\f[R] present),
|
||
\f[V]direnv\f[R] 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 Sub-categories
|
||
.PP
|
||
\f[V]__fish_config_op_autoexec\f[R] sub-divides into five
|
||
sub-categories, each with its own
|
||
\f[V]__fish_config_op_autoexec_<slug>\f[R] toggle:
|
||
.SS plugin-management
|
||
.PP
|
||
Fisher bootstrap on first run.
|
||
.SS pkg-wrappers
|
||
.PP
|
||
\f[V]paru\f[R]/\f[V]yay\f[R] wrapper generation.
|
||
.SS venv
|
||
.PP
|
||
Automatic Python virtualenv activation.
|
||
.SS telemetry
|
||
.PP
|
||
The WakaTime hook\[cq]s startup bootstrap.
|
||
.SS sync
|
||
.PP
|
||
Auto-pull background fast-forward, and the user-dots convenience
|
||
symlink.
|
||
.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
|
||
DO_NOT_TRACK=1 Universal telemetry opt-out for tools and AI agents
|
||
DISABLE_TELEMETRY=1 Telemetry opt-out for telemetry-aware CLIs
|
||
\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 Sub-categories
|
||
.PP
|
||
\f[V]__fish_config_op_overrides\f[R] sub-divides into four
|
||
sub-categories, each with its own
|
||
\f[V]__fish_config_op_overrides_<slug>\f[R] toggle:
|
||
.SS key-bindings
|
||
.PP
|
||
Vi mode, autopair, puffer key intercepts, bang-bang history expansion,
|
||
and \f[V]smart_exit\f[R]\[cq]s plain-exit path.
|
||
.SS environment
|
||
.PP
|
||
\f[V]$PATH\f[R], \f[V]$PAGER\f[R]/\f[V]$EDITOR\f[R]/\f[V]$GPG_TTY\f[R],
|
||
and \f[V]$CDPATH\f[R].
|
||
.SS prompt
|
||
.PP
|
||
Starship, the right prompt, Catppuccin syntax/prompt colors, and FZF
|
||
theming (\f[V]$FZF_DEFAULT_OPTS\f[R]) \[en] all driven by the same guard
|
||
as a single unit, not independently toggleable from each other.
|
||
.SS privacy
|
||
.PP
|
||
\f[V]$DO_NOT_TRACK\f[R] and \f[V]$DISABLE_TELEMETRY\f[R] environment
|
||
variables for telemetry opt-out across CLI tools, runtimes, and AI
|
||
agents.
|
||
.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 Sub-categories
|
||
.PP
|
||
\f[V]__fish_config_op_integrations\f[R] sub-divides into five
|
||
sub-categories, each with its own
|
||
\f[V]__fish_config_op_integrations_<slug>\f[R] toggle:
|
||
.SS terminal-abbrs
|
||
.PP
|
||
The Kitty/WezTerm abbreviation set.
|
||
.SS window-mgmt
|
||
.PP
|
||
\f[V]spwin\f[R], \f[V]tab\f[R], \f[V]split\f[R].
|
||
.SS notifications
|
||
.PP
|
||
\f[V]done\f[R]\[cq]s completion notifications, and the WakaTime activity
|
||
hook.
|
||
.SS history-logs
|
||
.PP
|
||
\f[V]hist\f[R], \f[V]logs\f[R].
|
||
.SS pkg-upgrade
|
||
.PP
|
||
\f[V]upgrade\f[R].
|
||
.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:
|
||
\[ti]/.terminal_history/scrollback_YYYY-MM-DD_HH-MM-SS.log
|
||
tmux pane capture Continuous pane stream via pipe-pane, saved to:
|
||
\[ti]/.terminal_history/tmux_<session>-w<win>-p<pane>_YYYY-MM-DD_HH-MM-SS.log
|
||
zellij pane capture Pane scrollback snapshot on shell exit, saved to:
|
||
\[ti]/.terminal_history/zellij_<session>-p<pane>_YYYY-MM-DD_HH-MM-SS.log
|
||
paru wrapper All paru/AUR output captured to:
|
||
\[ti]/.terminal_history/paru_YYYY-MM-DD_HH-MM-SS.log
|
||
yay wrapper All yay/AUR output captured to:
|
||
\[ti]/.terminal_history/yay_YYYY-MM-DD_HH-MM-SS.log
|
||
Kitty watcher watcher.py 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 \f[V]tmux\f[R] capture starts automatically when fish launches
|
||
inside any \f[V]tmux\f[R] pane (\f[V]$TMUX\f[R] is set).
|
||
It uses \f[V]tmux\f[R]\[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
|
||
\f[V]paru\f[R]/\f[V]yay\f[R] wrapper behaviour.
|
||
.PP
|
||
The \f[V]zellij\f[R] 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
|
||
\f[V]zellij\f[R] server write the file).
|
||
A \f[V]fish_exit\f[R] 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] \f[V]zellij\f[R] capture only fires on a clean shell
|
||
exit (typing \f[V]exit\f[R], \f[V]Ctrl-D\f[R], or a logout), because
|
||
that is when the \f[V]fish_exit\f[R] handler runs.
|
||
It does NOT capture when you close a pane or quit \f[V]zellij\f[R]
|
||
through \f[V]zellij\f[R] itself:
|
||
.IP \[bu] 2
|
||
Closing a pane signals the shell and tears the pane down concurrently,
|
||
so even if the handler runs, dump-screen may find the pane buffer
|
||
already gone.
|
||
.IP \[bu] 2
|
||
Quitting \f[V]zellij\f[R] kills the \f[V]zellij\f[R] 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 \f[V]tmux\f[R], NOT a bug.
|
||
\f[V]tmux\f[R] 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 \f[V]zellij\f[R] pane is logged, end the session with
|
||
\f[V]exit\f[R] or \f[V]Ctrl-D\f[R] rather than \f[V]zellij\f[R]\[cq]s
|
||
close-pane or quit actions.
|
||
.PP
|
||
The Kitty watcher is managed by the \f[V]kitty-logging\f[R] 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 /usr/bin/paru and
|
||
/usr/bin/yay 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.
|
||
\f[V]smart_exit\f[R] stops saving scrollback logs.
|
||
5.
|
||
Stops \f[V]tmux pipe-pane\f[R] capture in every open fish shell inside
|
||
\f[V]tmux\f[R].
|
||
.PP
|
||
Enabling \f[V]__fish_config_op_logging\f[R]: 1.
|
||
Removes the sentinel in every open shell.
|
||
2.
|
||
Regenerates \f[V]paru\f[R]/\f[V]yay\f[R] logging wrappers in
|
||
\f[V]\[ti]/.local/bin/\f[R].
|
||
3.
|
||
Kitty watcher resumes capture on the next session exit.
|
||
4.
|
||
Restarts \f[V]tmux\f[R] pipe-pane capture in every open fish shell
|
||
inside \f[V]tmux\f[R].
|
||
.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 \f[V]smart_exit\f[R] 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 Sub-categories
|
||
.PP
|
||
\f[V]__fish_config_op_logging\f[R] sub-divides into three
|
||
sub-categories, each with its own
|
||
\f[V]__fish_config_op_logging_<slug>\f[R] toggle (all still opt-in by
|
||
default, inherited from C5\[cq]s own opt-in behavior \[en] see §3 of the
|
||
design spec):
|
||
.SS terminal-capture
|
||
.PP
|
||
Kitty watcher scrollback capture, and \f[V]smart_exit\f[R]\[cq]s
|
||
logging-guard path.
|
||
.SS multiplexer-capture
|
||
.PP
|
||
\f[V]tmux\f[R] \f[V]pipe-pane\f[R] and \f[V]zellij\f[R]
|
||
\f[V]dump-screen\f[R] capture.
|
||
.SS pkg-logs
|
||
.PP
|
||
\f[V]paru\f[R]/\f[V]yay\f[R] AUR log wrappers.
|
||
.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.
|
||
.SS Sub-categories
|
||
.PP
|
||
\f[V]__fish_config_op_greeting\f[R] sub-divides into two sub-categories,
|
||
each with its own \f[V]__fish_config_op_greeting_<slug>\f[R] toggle:
|
||
.SS first-run
|
||
.PP
|
||
The first-run welcome banner.
|
||
.SS greeting-message
|
||
.PP
|
||
The per-session \f[V]fish_greeting\f[R] override.
|
||
.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 \[bu] 2
|
||
\f[V]jorgebucaran/fisher\f[R] (https://github.com/jorgebucaran/fisher)
|
||
\[em] Plugin manager itself
|
||
.IP \[bu] 2
|
||
\f[V]meaningful-ooo/sponge\f[R] (https://github.com/meaningful-ooo/sponge)
|
||
\[em] Remove failed commands from history
|
||
.SS Sponge History Filtering
|
||
.PP
|
||
Sponge removes failed commands from history and, via
|
||
\f[V]conf.d/sponge_privacy.fish\f[R], also filters privacy-sensitive
|
||
commands through three layers.
|
||
Detection is heuristic \[em] pattern- and variable-name-based \[em] so
|
||
this reduces the risk of a credential landing in persistent history; it
|
||
is not a guarantee that no secret can ever reach it, and it is not a
|
||
substitute for rotating a credential that gets typed in plaintext.
|
||
Treat it as a safety net, not a vault.
|
||
.PP
|
||
Layer 1 \[em] Static patterns (universal, persistent across sessions):
|
||
Commands matching any of these structural signatures are never recorded:
|
||
.IP \[bu] 2
|
||
\f[V]--password\f[R] / \f[V]--token\f[R] / \f[V]--passphrase\f[R] /
|
||
\f[V]--api-key\f[R] flags with values
|
||
.IP \[bu] 2
|
||
Inline env assignments: \f[V]GITHUB_TOKEN=xxx\f[R],
|
||
\f[V]MY_API_KEY=abc\f[R]
|
||
.IP \[bu] 2
|
||
Fish set with sensitive names: \f[V]set -gx GITHUB_TOKEN xxx\f[R]
|
||
.IP \[bu] 2
|
||
URLs with embedded credentials: \f[V]https://user:pass\[at]host\f[R]
|
||
.IP \[bu] 2
|
||
HTTP Authorization headers:
|
||
\f[V]curl -H \[dq]Authorization: ...\[dq]\f[R]
|
||
.IP \[bu] 2
|
||
Basic auth flags: \f[V]curl -u user:pass\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]sshpass\f[R], \f[V]docker login -p\f[R],
|
||
\f[V]openssl -passin/-passout\f[R]
|
||
.PP
|
||
Layer 2 \[em] Dynamic secret values (session globals, refreshed each
|
||
login): On the first prompt, after \f[V]secrets.fish\f[R] has loaded,
|
||
the literal values of all exported variables whose names suggest
|
||
credentials (TOKEN, PASSWORD, SECRET, \f[V]API_KEY\f[R], 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 (\f[V]sponge_filter_secrets\f[R]):
|
||
Catches credentials in variables exported after login, such as tokens
|
||
sourced from a project .env file mid-session.
|
||
.PP
|
||
A match is actively deleted from history, not stored and redacted.
|
||
Sponge queues a matched command on \f[V]fish_postexec\f[R] and purges
|
||
anything past \f[V]sponge_delay\f[R] entries on the very next
|
||
\f[V]fish_prompt\f[R], immediately forcing a \f[V]history save\f[R].
|
||
With this config\[cq]s (upstream) defaults, that means a matched command
|
||
is gone from disk within about one prompt cycle \[em] it is not left
|
||
sitting in persistent history for the rest of the session.
|
||
.PP
|
||
This timing depends on \f[V]sponge_purge_only_on_exit\f[R] staying
|
||
\f[V]false\f[R], which is sponge\[cq]s own default and is not overridden
|
||
here.
|
||
Turning it on defers all purging to the \f[V]fish_exit\f[R] event
|
||
instead of the next prompt \[em] and because \f[V]fish_exit\f[R] does
|
||
not fire on a killed or crashed session, a matched command purged only
|
||
on exit can survive indefinitely if the shell never exits cleanly.
|
||
Leave this setting off.
|
||
.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 \f[V]ACME_API\f[R] also covers \f[V]ACME_API_KEY\f[R].
|
||
(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] \f[V]sponge_delay\f[R],
|
||
\f[V]sponge_successful_exit_codes\f[R],
|
||
\f[V]sponge_purge_only_on_exit\f[R], and
|
||
\f[V]sponge_allow_previously_successful\f[R] \[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 \[bu] 2
|
||
\f[V]catppuccin/fish\f[R] (https://github.com/catppuccin/fish) →
|
||
\f[V]themes/\f[R] + \f[V]conf.d/theme.fish\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]PatrickF1/fzf.fish\f[R] (https://github.com/PatrickF1/fzf.fish) →
|
||
\f[V]functions/_fzf_*.fish\f[R] + \f[V]conf.d/fzf.fish\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]franciscolourenco/done\f[R] (https://github.com/franciscolourenco/done)
|
||
→ \f[V]conf.d/done.fish\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]jorgebucaran/autopair.fish\f[R] (https://github.com/jorgebucaran/autopair.fish)
|
||
→ \f[V]functions/_autopair_*.fish\f[R] + \f[V]conf.d/autopair.fish\f[R]
|
||
.IP \[bu] 2
|
||
\f[V]nickeb96/puffer-fish\f[R] (https://github.com/nickeb96/puffer-fish)
|
||
→ \f[V]functions/_puffer_fish_*.fish\f[R] + \f[V]conf.d/puffer.fish\f[R]
|
||
.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 \[bu] 2
|
||
\f[V]jorgebucaran/fisher\f[R] (https://github.com/jorgebucaran/fisher)
|
||
\[em] Plugin manager itself
|
||
.IP \[bu] 2
|
||
\f[V]meaningful-ooo/sponge\f[R] (https://github.com/meaningful-ooo/sponge)
|
||
\[em] Remove failed commands from history
|
||
.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
|
||
\f[V]config.fish\f[R] ends with a return sentinel guard.
|
||
Any lines appended after it by a tool\[cq]s setup command
|
||
(\f[V]starship init fish | source\f[R],
|
||
\f[V]zoxide init fish | source\f[R], etc.)
|
||
will have no effect.
|
||
All integrations are managed via \f[V]conf.d/\f[R] 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 \[bu] 2
|
||
\f[V]config-update\f[R] \[em] Fetch and apply the latest commits from
|
||
upstream
|
||
.IP \[bu] 2
|
||
\f[V]config-update --dry-run\f[R] \[em] Preview available changes
|
||
without applying them
|
||
.IP \[bu] 2
|
||
\f[V]config-update --force\f[R] \[em] Stash local changes, pull, then
|
||
restore the stash
|
||
.PP
|
||
All git output is suppressed.
|
||
Run \f[V]exec fish\f[R] 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
|
||
\f[V]config.fish\f[R] sources \f[V]local.fish\f[R] from that directory
|
||
on every interactive session.
|
||
\f[V]local.fish\f[R] is responsible for sourcing its own
|
||
\f[V]secrets.fish\f[R]:
|
||
.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
|
||
\f[V]fish_variables\f[R] (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
|
||
\f[V]local.fish\f[R] is sourced at the end of \f[V]config.fish\f[R] with
|
||
an existence check so the public config works cleanly on any machine
|
||
without the private repo.
|
||
\f[V]local.fish\f[R] in turn sources \f[V]secrets.fish\f[R] 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,
|
||
\f[V]tmux\f[R]/\f[V]zellij\f[R] 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
|
||
\f[V]fastfetch\f[R]) 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 \f[V]fish_greeting\f[R] in your
|
||
\f[V]local.fish\f[R]:
|
||
.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 \f[V]local.fish\f[R] 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 (\f[V]starship\f[R], \f[V]zoxide\f[R],
|
||
\f[V]direnv\f[R]) 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, \f[V]starship\f[R] 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 (rm, cp) to be safe by default
|
||
C2 Startup Side-Effects \[em] Bootstraps Fisher, generates wrappers, auto-activates venvs
|
||
C3 Overrides \[em] Overrides cd, sets Vi mode, binds <CR> to smart_enter
|
||
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
|
||
Each category can also have several sub-categories (e.g.
|
||
\f[V]__fish_config_op_aliases_filesystem\f[R]) that can be checked,
|
||
disabled, or reset the same way \[em]
|
||
\f[V]set -U __fish_config_op_<category>_<subcategory> off\f[R] and
|
||
\f[V]set -Ue __fish_config_op_<category>_<subcategory>\f[R] work
|
||
identically to the category-level recipes above, just one level more
|
||
granular.
|
||
See Components Reference for the full list.
|
||
.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 \f[V]docs/fish-config.1\f[R] directly via man
|
||
\f[V]-l\f[R], 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.
|
||
\f[V]fish_config\f[R] (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 14. TESTING
|
||
.IP
|
||
.nf
|
||
\f[C]
|
||
fish tests/run-tests.fish
|
||
\f[R]
|
||
.fi
|
||
.PP
|
||
Runs before every push (and gates the documentation
|
||
build (https://git.rootiest.dev/rootiest/fish-config/src/branch/main/.github/workflows/ci.yml)
|
||
in CI, so a broken config can\[cq]t get published): syntax-lints every
|
||
\f[V].fish\f[R] file, then loads the config in an isolated
|
||
\f[V]HOME\f[R]/XDG sandbox \[em] never this checkout itself, since it
|
||
doubles as a real \f[V]\[ti]/.config/fish\f[R] \[em] and runs functional
|
||
checks against foundational behavior (XDG/PATH/CDPATH setup, key
|
||
bindings, abbreviations, core functions, the opinionated-component
|
||
registry, and more).
|
||
.SH 15. CONTRIBUTING
|
||
.PP
|
||
Interested in contributing?
|
||
See
|
||
\f[V]CONTRIBUTING.md\f[R] (https://git.rootiest.dev/rootiest/fish-config/src/branch/main/CONTRIBUTING.md)
|
||
for the branching/PR workflow, commit conventions, fish coding
|
||
standards, and the docs/testing pipeline this repo follows.
|
||
.PP
|
||
\f[B]Preferred forge:\f[R]
|
||
git.rootiest.dev/rootiest/fish-config (https://git.rootiest.dev/rootiest/fish-config)
|
||
is the base repository.
|
||
github.com/rootiest/fish-config (https://github.com/rootiest/fish-config)
|
||
is a push-mirror of it \[em] identical content, but one-way and
|
||
read-only from a contributor\[cq]s perspective.
|
||
Branches, forks, and merges made on the GitHub side aren\[cq]t fed back
|
||
upstream, so they risk being silently overwritten by the next mirror
|
||
push.
|
||
Until two-way sync exists, please fork, branch, and open issues/PRs from
|
||
the Gitea repository rather than the GitHub mirror.
|
||
.SH 16. ATTRIBUTION
|
||
.PP
|
||
The core of the Zoxide
|
||
integration (https://fish.rootiest.fyi/02-path-setup/) in this
|
||
repository was originally adapted from the
|
||
icezyclon/zoxide.fish (https://github.com/icezyclon/zoxide.fish) plugin
|
||
(MIT Licensed) and has since been heavily customized for performance and
|
||
Fish 4.x compatibility.
|
||
.SH 17. LICENSE
|
||
.PP
|
||
Copyright (C) 2026 Rootiest
|
||
.PP
|
||
This project is licensed under the \f[B]GNU Affero General Public
|
||
License v3.0 or later\f[R] (AGPLv3+).
|
||
See the
|
||
LICENSE (https://git.rootiest.dev/rootiest/fish-config/src/branch/main/LICENSE)
|
||
file for the full license text.
|
||
.SH AUTHORS
|
||
Rootiest.
|