docs: restructure customization and components reference into nested directories

This commit is contained in:
2026-07-27 20:49:40 -04:00
parent d91c0c8deb
commit dd28fc784b
23 changed files with 634 additions and 603 deletions
+45 -45
View File
@@ -229,42 +229,42 @@ minimal=## Opinionated Components (Minimal Mode)
minimal-mode=## Opinionated Components (Minimal Mode) minimal-mode=## Opinionated Components (Minimal Mode)
opt-out=## Opinionated Components (Minimal Mode) opt-out=## Opinionated Components (Minimal Mode)
toggles=## Opinionated Components (Minimal Mode) toggles=## Opinionated Components (Minimal Mode)
component-reference=### Component Reference component-reference=# 8. COMPONENTS REFERENCE
components=### Component Reference components=# 8. COMPONENTS REFERENCE
c1=#### C1 — Command Shadows c1=## C1 — Command Shadows
command-shadows=#### C1 — Command Shadows command-shadows=## C1 — Command Shadows
aliases-detail=#### C1 — Command Shadows aliases-detail=## C1 — Command Shadows
c2=#### C2 — Startup Side-Effects c2=## C2 — Startup Side-Effects
autoexec=#### C2 — Startup Side-Effects autoexec=## C2 — Startup Side-Effects
startup=#### C2 — Startup Side-Effects startup=## C2 — Startup Side-Effects
c3=#### C3 — Key and Environment Overrides c3=## C3 — Key and Environment Overrides
overrides-detail=#### C3 — Key and Environment Overrides overrides-detail=## C3 — Key and Environment Overrides
bang-bang=#### C3 — Key and Environment Overrides bang-bang=## C3 — Key and Environment Overrides
c4=#### C4 — Terminal and Tool Integration c4=## C4 — Terminal and Tool Integration
integrations-detail=#### C4 — Terminal and Tool Integration integrations-detail=## C4 — Terminal and Tool Integration
c5=#### C5 — Logging and Capture c5=## C5 — Logging and Capture
logging-detail=#### C5 — Logging and Capture logging-detail=## C5 — Logging and Capture
logging-sentinel=#### C5 — Logging and Capture logging-sentinel=## C5 — Logging and Capture
zellij=#### C5 — Logging and Capture zellij=## C5 — Logging and Capture
zellij-logging=#### C5 — Logging and Capture zellij-logging=## C5 — Logging and Capture
tmux-logging=#### C5 — Logging and Capture tmux-logging=## C5 — Logging and Capture
pipe-pane=#### C5 — Logging and Capture pipe-pane=## C5 — Logging and Capture
dump-screen=#### C5 — Logging and Capture dump-screen=## C5 — Logging and Capture
c6=#### C6 — Greeting and First-Run UI c6=## C6 — Greeting and First-Run UI
greeting=#### C6 — Greeting and First-Run UI greeting=## C6 — Greeting and First-Run UI
# ── Prompt and Theme ────────────────────────────────────────── # ── Prompt and Theme ──────────────────────────────────────────
prompt-theme=## Prompt and Theme prompt-theme=## Prompt and Theme
starship=### Starship starship=#### Starship
fallback-prompt=### Catppuccin Fallback Prompt fallback-prompt=#### Catppuccin Fallback Prompt
catppuccin-prompt=### Catppuccin Fallback Prompt catppuccin-prompt=#### Catppuccin Fallback Prompt
nim-prompt=### Catppuccin Fallback Prompt nim-prompt=#### Catppuccin Fallback Prompt
fzf-theme=### FZF fzf-theme=#### FZF
catppuccin-theme=### Catppuccin Mocha Syntax Highlighting catppuccin-theme=#### Catppuccin Mocha Syntax Highlighting
# ── Section 8: Fisher Plugins ───────────────────────────────── # ── Section 9: Fisher Plugins ─────────────────────────────────
plugins=# 8. FISHER PLUGINS plugins=# 9. FISHER PLUGINS
fisher=# 8. FISHER PLUGINS fisher=# 9. FISHER PLUGINS
fisher-managed=## Fisher-Managed Plugins fisher-managed=## Fisher-Managed Plugins
sponge=## Fisher-Managed Plugins sponge=## Fisher-Managed Plugins
sponge-filtering=## Sponge History Filtering sponge-filtering=## Sponge History Filtering
@@ -276,22 +276,22 @@ sponge-settings=### config-settings
bundled-plugins=## Bundled Plugin Functionality bundled-plugins=## Bundled Plugin Functionality
fish-plugins-manifest=## fish_plugins Manifest fish-plugins-manifest=## fish_plugins Manifest
# ── Section 9: Installation ──────────────────────────────────── # ── Section 10: Installation ────────────────────────────────────
installation=# 9. INSTALLATION installation=# 10. INSTALLATION
install=# 9. INSTALLATION install=# 10. INSTALLATION
sentinel=## Return Sentinel sentinel=## Return Sentinel
updating=## Updating updating=## Updating
# ── Section 10: Personalization ─────────────────────────────── # ── Section 11: Personalization ───────────────────────────────
personalization=# 10. PERSONALIZATION personalization=# 11. PERSONALIZATION
personalize=# 10. PERSONALIZATION personalize=# 11. PERSONALIZATION
secrets-file=## secrets.fish secrets-file=## secrets.fish
local-config=## local.fish local-config=## local.fish
# ── Section 11: Troubleshooting ────────────────────────────── # ── Section 12: Troubleshooting ──────────────────────────────
troubleshooting=# 11. TROUBLESHOOTING troubleshooting=# 12. TROUBLESHOOTING
troubleshoot=# 11. TROUBLESHOOTING troubleshoot=# 12. TROUBLESHOOTING
faq=# 11. TROUBLESHOOTING faq=# 12. TROUBLESHOOTING
uninstall=## Uninstalling and Reverting to Backup uninstall=## Uninstalling and Reverting to Backup
revert=## Uninstalling and Reverting to Backup revert=## Uninstalling and Reverting to Backup
fish-version=## Fish Version Requirement fish-version=## Fish Version Requirement
@@ -310,9 +310,9 @@ vi-trouble=## Vi Mode Keybindings
emacs-mode=## Vi Mode Keybindings emacs-mode=## Vi Mode Keybindings
minimal-trouble=## What's with the C1-C6 stuff? minimal-trouble=## What's with the C1-C6 stuff?
# ── Section 12: Viewing This Manual ────────────────────────── # ── Section 13: Viewing This Manual ──────────────────────────
viewing=# 12. VIEWING THIS MANUAL viewing=# 13. VIEWING THIS MANUAL
manual=# 12. VIEWING THIS MANUAL manual=# 13. VIEWING THIS MANUAL
ov=## In the terminal ov=## In the terminal
man-page=## As a man page man-page=## As a man page
manpage=## As a man page manpage=## As a man page
+77 -77
View File
@@ -2768,13 +2768,78 @@ NOTE:
- Disabled integration commands (spwin, tab, split, hist, logs, upgrade) print an error naming the variable that disabled them. - Disabled integration commands (spwin, tab, split, hist, logs, upgrade) print an error naming the variable that disabled them.
- On CachyOS, the distro fish config's own aliases, history override, and bang-bang bindings are stripped per category as well. - On CachyOS, the distro fish config's own aliases, history override, and bang-bang bindings are stripped per category as well.
### Component Reference ## Prompt and Theme
#### Starship
The primary prompt is Starship, initialized by conf.d/starship.fish.
Configure it via ~/.config/starship.toml.
conf.d/starship.fish defines a fish_prompt wrapper that only activates when
starship is in PATH. It emits OSC 133;A (prompt start) immediately before
Starship renders and OSC 133;B (input start) immediately after, placing both
markers on the prompt line itself. This allows ov to use them as sticky
section headers when browsing scrollback logs. Without Starship, fish's
built-in prompt handles these markers automatically.
#### Catppuccin Fallback Prompt
When Starship is absent or C3 overrides are disabled, a built-in nim-style
two-line prompt activates from functions/fish_prompt.fish. No external
dependencies — fish builtins only.
Layout:
┬─[user@host:~/path] (main)
╰─>$
Elements:
user Yellow (Catppuccin Yellow); red if root
@host Blue (local) or Teal (SSH)
~/path prompt_pwd abbreviation (Catppuccin Text)
(main) Current git branch in Catppuccin Pink; omitted outside repos
─[V:name] Active Python venv basename; omitted when none
─[N/I/R/V] Vi-mode indicator when vi bindings are active
┬─ / ╰─> Connector lines: Catppuccin Green on success, Red on failure
The right prompt (fish_right_prompt.fish) always renders, regardless of C3
state. On failure it shows a red ✘ and the exit code; on success it shows
only the dim timestamp. When starship is installed and C3 is enabled, the
active Docker context is also shown (if non-default):
✘ 1 󰡨 myctx Fri Jun 12 00:51:21 2026 ← failed, starship+C3 active
✘ 1 Fri Jun 12 00:51:21 2026 ← failed, fallback prompt
Fri Jun 12 00:51:21 2026 ← success (no ✘)
#### FZF
FZF is themed to Catppuccin Mocha via FZF_DEFAULT_OPTS set in
integrations/fzf.fish. The colors applied:
Background: #1E1E2E (base) #313244 (surface0)
Foreground: #CDD6F4 (text)
Highlights: #F38BA8 (red) #CBA6F7 (mauve) #B4BEFE (lavender)
To customize, override FZF_DEFAULT_OPTS in local.fish.
#### Catppuccin Mocha Syntax Highlighting
The Catppuccin Mocha theme ships with this config in themes/ and is applied
on first run via `conf.d/first_run.fish`. Colors are stored in fish_variables
(universal). To switch variants, install a different theme from themes/:
fish_config theme save "Catppuccin Latte"
---
# 8. COMPONENTS REFERENCE
The following tables detail every component in each category. Use this The following tables detail every component in each category. Use this
reference to understand exactly which behaviors change when you toggle a reference to understand exactly which behaviors change when you toggle a
category variable. category variable.
#### C1 — Command Shadows ## C1 — Command Shadows
Disabling __fish_config_op_aliases restores standard system behavior for Disabling __fish_config_op_aliases restores standard system behavior for
all of these commands. all of these commands.
@@ -2805,7 +2870,7 @@ all of these commands.
When C1 is disabled, `rm` uses bare `command rm` with no wrapper — files When C1 is disabled, `rm` uses bare `command rm` with no wrapper — files
are permanently deleted, not trashed. There is no intermediate safety net. are permanently deleted, not trashed. There is no intermediate safety net.
#### C2 — Startup Side-Effects ## C2 — Startup Side-Effects
These run automatically without any user action. Disabling These run automatically without any user action. Disabling
__fish_config_op_autoexec prevents all of them. __fish_config_op_autoexec prevents all of them.
@@ -2848,7 +2913,7 @@ branches, or repos without a remote. The handler fires once per repo entry
(not on every sub-directory cd). The registry is machine-local at (not on every sub-directory cd). The registry is machine-local at
`$__fish_user_dots_path/auto-pull.list` (defaults to `~/.config/.user-dots/fish/auto-pull.list`) and is never committed. `$__fish_user_dots_path/auto-pull.list` (defaults to `~/.config/.user-dots/fish/auto-pull.list`) and is never committed.
#### C3 — Key and Environment Overrides ## C3 — Key and Environment Overrides
These change fundamental shell behavior: how keys work, which pager opens, These change fundamental shell behavior: how keys work, which pager opens,
and what the prompt looks like. Disabling __fish_config_op_overrides removes and what the prompt looks like. Disabling __fish_config_op_overrides removes
@@ -2880,7 +2945,7 @@ When C3 is disabled, `exit` falls back to `builtin exit` with no scrollback
capture, no Kitty IPC, and no file I/O on exit. The scrollback capture block capture, no Kitty IPC, and no file I/O on exit. The scrollback capture block
is independently controlled by C5 (see below). is independently controlled by C5 (see below).
#### C4 — Terminal and Tool Integration ## C4 — Terminal and Tool Integration
These features couple the shell to specific external tools. Disabling These features couple the shell to specific external tools. Disabling
__fish_config_op_integrations disables all of them. __fish_config_op_integrations disables all of them.
@@ -2902,7 +2967,7 @@ Disabled integration commands (spwin, tab, split, hist, logs, upgrade) print
a colored error to stderr naming the variable that disabled them rather than a colored error to stderr naming the variable that disabled them rather than
silently failing. silently failing.
#### C5 — Logging and Capture ## C5 — Logging and Capture
Five components capture shell output to disk. Unlike every other category, Five components capture shell output to disk. Unlike every other category,
C5 is opt-in: it stays off until __fish_config_op_logging is set to an C5 is opt-in: it stays off until __fish_config_op_logging is set to an
@@ -3012,7 +3077,7 @@ Note: C3 and C5 compose independently. C3 controls whether the smart_exit
wrapper is active at all; C5 controls only the scrollback-capture block 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. inside it. With C3 disabled, exit is plain builtin exit regardless of C5.
#### C6 — Greeting and First-Run UI ## C6 — Greeting and First-Run UI
Component What it shows Component What it shows
─────────────────────────────────────────────────────────────────────────── ───────────────────────────────────────────────────────────────────────────
@@ -3025,72 +3090,7 @@ When C6 is disabled, no greeting is printed by this config. Any greeting
set by the distro or other configs runs normally — this config simply does set by the distro or other configs runs normally — this config simply does
not override it. not override it.
## Prompt and Theme # 9. FISHER PLUGINS
### Starship
The primary prompt is Starship, initialized by conf.d/starship.fish.
Configure it via ~/.config/starship.toml.
conf.d/starship.fish defines a fish_prompt wrapper that only activates when
starship is in PATH. It emits OSC 133;A (prompt start) immediately before
Starship renders and OSC 133;B (input start) immediately after, placing both
markers on the prompt line itself. This allows ov to use them as sticky
section headers when browsing scrollback logs. Without Starship, fish's
built-in prompt handles these markers automatically.
### Catppuccin Fallback Prompt
When Starship is absent or C3 overrides are disabled, a built-in nim-style
two-line prompt activates from functions/fish_prompt.fish. No external
dependencies — fish builtins only.
Layout:
┬─[user@host:~/path] (main)
╰─>$
Elements:
user Yellow (Catppuccin Yellow); red if root
@host Blue (local) or Teal (SSH)
~/path prompt_pwd abbreviation (Catppuccin Text)
(main) Current git branch in Catppuccin Pink; omitted outside repos
─[V:name] Active Python venv basename; omitted when none
─[N/I/R/V] Vi-mode indicator when vi bindings are active
┬─ / ╰─> Connector lines: Catppuccin Green on success, Red on failure
The right prompt (fish_right_prompt.fish) always renders, regardless of C3
state. On failure it shows a red ✘ and the exit code; on success it shows
only the dim timestamp. When starship is installed and C3 is enabled, the
active Docker context is also shown (if non-default):
✘ 1 󰡨 myctx Fri Jun 12 00:51:21 2026 ← failed, starship+C3 active
✘ 1 Fri Jun 12 00:51:21 2026 ← failed, fallback prompt
Fri Jun 12 00:51:21 2026 ← success (no ✘)
### FZF
FZF is themed to Catppuccin Mocha via FZF_DEFAULT_OPTS set in
integrations/fzf.fish. The colors applied:
Background: #1E1E2E (base) #313244 (surface0)
Foreground: #CDD6F4 (text)
Highlights: #F38BA8 (red) #CBA6F7 (mauve) #B4BEFE (lavender)
To customize, override FZF_DEFAULT_OPTS in local.fish.
### Catppuccin Mocha Syntax Highlighting
The Catppuccin Mocha theme ships with this config in themes/ and is applied
on first run via `conf.d/first_run.fish`. Colors are stored in fish_variables
(universal). To switch variants, install a different theme from themes/:
fish_config theme save "Catppuccin Latte"
---
# 8. FISHER PLUGINS
Fisher is bootstrapped automatically on the **first interactive session** via Fisher is bootstrapped automatically on the **first interactive session** via
`conf.d/first_run.fish`. This also applies the Catppuccin Mocha theme and `conf.d/first_run.fish`. This also applies the Catppuccin Mocha theme and
@@ -3190,7 +3190,7 @@ update` which calls it as its first step.
--- ---
# 9. INSTALLATION # 10. INSTALLATION
This configuration is managed as a git repository. To deploy on a new machine: This configuration is managed as a git repository. To deploy on a new machine:
@@ -3224,7 +3224,7 @@ All git output is suppressed. Run exec fish after a successful update to reload.
--- ---
# 10. PERSONALIZATION # 11. PERSONALIZATION
Sensitive credentials and machine-specific settings are kept out of version Sensitive credentials and machine-specific settings are kept out of version
control in a private directory. The path defaults to control in a private directory. The path defaults to
@@ -3286,7 +3286,7 @@ local.fish in turn sources secrets.fish when it exists.
--- ---
# 11. TROUBLESHOOTING # 12. TROUBLESHOOTING
This section covers common issues, their solutions, and how to safely revert changes or uninstall the configuration entirely. This section covers common issues, their solutions, and how to safely revert changes or uninstall the configuration entirely.
@@ -3517,7 +3517,7 @@ For an interactive alternative to setting these variables by hand, run `config-s
--- ---
# 12. VIEWING THIS MANUAL # 13. VIEWING THIS MANUAL
There are four ways to read this manual. There are four ways to read this manual.
-463
View File
@@ -1,463 +0,0 @@
---
title: Customization
manTitle: 7. CUSTOMIZATION
sidebar:
order: 11
helpKeywords:
- customization
- customize
---
This section explains how to adapt the configuration to your specific workflow, including local machine overrides and opinionated component toggles.
## Machine-local Configuration
Place machine-specific settings that should not be committed to git in:
$__fish_user_dots_path/local.fish
`__fish_user_dots_path` defaults to `~/.config/.user-dots/fish`. Set a
custom location with:
set -U __fish_user_dots_path /path/to/your/dots/fish
Typical uses: additional PATH entries, local aliases, hostname-specific env
vars, work-specific tool configs.
For convenience, a git-ignored `user-dots` symlink in the fish config
directory tracks `$__fish_user_dots_path` so the overlay can be browsed from
`~/.config/fish/`. It is created if missing and repointed if the path changes.
Opt out by setting `__fish_user_dots_symlink` to a falsy value, or toggling
"Dots link" off on the config-settings Paths page — this stops generation and
removes any existing link. It only ever manages a symlink and never clobbers a
real file or directory at that path.
## Secrets and API Keys
$__fish_user_dots_path/secrets.fish
Store API tokens, GPG keys, private credentials here. This file is never
committed. It is sourced by local.fish directly, not by config.fish.
`local.fish` is sourced at the end of config.fish on every interactive
session, so it and its companion secrets.fish can override anything set
earlier.
## Overriding Configuration Variables
Any variable set in local.fish after the main config loads takes effect.
Example: to increase the scrollback history limit:
# in local.fish
set -gx SCROLLBACK_HISTORY_MAX_FILES 200
## Fish Universal Variables
Some settings (fzf colors, theme) are stored in fish_variables via
`set -U`. These are machine-local and git-ignored. Do not commit
fish_variables.
## Opinionated Components (Minimal Mode)
Every opinionated piece of this config is active by default but can be
switched off through six category opt-out variables, each evaluated via
__fish_variable_check. Set a variable to any falsy value (0, false, no,
off, n) to disable its category; erase it or set a truthy value (1, true,
yes, on, y) to re-enable. Unset means enabled — except for C5 logging, which
is opt-in (see below).
An explicit per-category truthy value takes precedence over the master
switch: setting __fish_config_opinionated=0 disables all unset categories,
but a category with an explicit truthy value remains enabled regardless.
C5 (logging) is the one exception to "unset means enabled". 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.
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 — 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
Examples:
# 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 — 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)
For an interactive alternative to setting these variables by hand, run
config-settings — a full-screen TUI that flips any category (including C5
logging) on or off, per session or universally. See its entry in Section 5.
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 `command rm` — files are deleted permanently, not trashed.
- Disabled integration commands (spwin, tab, split, hist, logs, upgrade) print an error naming the variable that disabled them.
- On CachyOS, the distro fish config's own aliases, history override, and bang-bang bindings are stripped per category as well.
### Component Reference
The following tables detail every component in each category. Use this
reference to understand exactly which behaviors change when you toggle a
category variable.
#### C1 — Command Shadows
Disabling __fish_config_op_aliases restores standard system behavior for
all of these commands.
Command / Alias Active behavior Disabled fallback
───────────────────────────────────────────────────────────────────────────
ls eza -l -a --icons --hyperlink system ls
cat bat syntax-highlighted; dirs → ls /usr/bin/cat
cd zoxide frecency-based navigation fish builtin cd
rm moves files to trash (recoverable) command rm (permanent)
less $PAGER → ov → less → more → cat system less
du duf (disk overview) or dust (dir tree) system du
top btop resource monitor system top
ping prettyping --nolegend animation system ping
ssh kitten ssh in Kitty terminal system ssh
rg rg --hyperlink-format=kitty system rg
mkdir verbose path-tree display on creation mkdir -p silently
bash XDG bashrc + $SHELL reset on exit system bash
history timestamps prepended to every entry fish builtin history
cp / mv forced -i confirmation prompt cp / mv unmodified
wget forced --continue (resume downloads) system wget
grep/fgrep/egrep forced --color=auto system grep variants
dir / vdir forced --color=auto system dir / vdir
help config intercepts "help config" → config-help fish builtin help
claude auto-links AGENTS.md as CLAUDE.md before launch command claude
edit multi-editor launcher (GUI/term + fallbacks) $EDITOR/nvim/nano/vi
When C1 is disabled, `rm` uses bare `command rm` with no wrapper — files
are permanently deleted, not trashed. There is no intermediate safety net.
#### C2 — Startup Side-Effects
These run automatically without any user action. Disabling
__fish_config_op_autoexec prevents all of them.
Component Trigger What it does
───────────────────────────────────────────────────────────────────────────
Fisher bootstrap First shell only Downloads and installs fisher
Fisher update After bootstrap Installs all fish_plugins entries
Catppuccin Mocha theme First shell only Applies theme via fish_config
paru wrapper Every startup Writes ~/.local/bin/paru wrapper
yay wrapper Every startup Writes ~/.local/bin/yay wrapper
Python venv activation On every cd Sources .venv/bin/activate.fish
WakaTime command hook On every command Reports to WakaTime API
Auto-pull fast-forward On entering a repo Background ff-only git pull
user-dots symlink Every startup Links $__fish_config_dir/user-dots
to $__fish_user_dots_path
When C2 is disabled: no Fisher install, no theme application, no paru/yay
wrapper generation, no automatic venv activation, no WakaTime reporting,
no auto-pull (the PWD handler is never registered), and the user-dots
convenience symlink is not created. The symlink is git-ignored and only ever
managed as a symlink — a real file or directory at that path is left untouched.
The symlink has its own opt-out independent of C2: set __fish_user_dots_symlink
to a falsy value (or toggle "Dots link" off on the config-settings Paths page)
to stop generating it and remove any existing link — honoured even when C2 is
enabled. Managed by the __fish_user_dots_link helper.
The first-run completion marker (__fish_config_first_run_complete) is still
set so the init does not re-run on subsequent shells.
Python venv activation fires on every directory change. If a directory uses
direnv (.envrc present), direnv takes priority and auto-venv is skipped for
that directory.
Auto-pull fast-forwards opted-in repositories in the background when you cd
into them. The fish-config repo is always covered; other repos are added with
the `auto-pull` command (see its entry in the functions reference). It only
ever fast-forwards a clean repo whose branch has an upstream — never rebases,
merges, or overwrites work — so it is a no-op on dirty trees, divergent
branches, or repos without a remote. The handler fires once per repo entry
(not on every sub-directory cd). The registry is machine-local at
`$__fish_user_dots_path/auto-pull.list` (defaults to `~/.config/.user-dots/fish/auto-pull.list`) and is never committed.
#### C3 — Key and Environment Overrides
These change fundamental shell behavior: how keys work, which pager opens,
and what the prompt looks like. Disabling __fish_config_op_overrides removes
all of them.
Override What it replaces or sets
───────────────────────────────────────────────────────────────────────────
Vi mode fish_vi_key_bindings replaces default Emacs mode
XDG variables Sets global XDG Base Directory variables
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
MANPAGER=bat pipeline man pages rendered with syntax highlighting
CDPATH=. ~/projects ~ bare dir names resolve against ~/projects and ~
Bang-bang system ! and $ keys expand history; !^, !*, !-N, !?str?,
^old^new abbreviations; six expand_bang_* helpers
Autopair ( [ { " ' auto-close to (), [], {}, "", ''
Puffer key intercepts . ! $ * keys intercepted for smart expansion
Starship prompt fish_prompt replaced by Starship + OSC 133 markers
Catppuccin colors 30+ fish_color_* variables set to Mocha palette
FZF_DEFAULT_OPTS FZF themed to Catppuccin Mocha colors
Right prompt fish_right_prompt: exit code (on failure) + dim timestamp; always rendered; Docker context added when starship+C3 active
The bang-bang system spans key_bindings.fish, abbr.fish, puffer.fish, and
six expand_bang_*.fish functions. All are gated together — disabling C3
removes the entire bang-expansion system at once.
When C3 is disabled, `exit` falls back to `builtin exit` with no scrollback
capture, no Kitty IPC, and no file I/O on exit. The scrollback capture block
is independently controlled by C5 (see below).
#### C4 — Terminal and Tool Integration
These features couple the shell to specific external tools. Disabling
__fish_config_op_integrations disables all of them.
Component Requires
───────────────────────────────────────────────────────────────────────────
~60 Kitty/WezTerm abbrs Active Kitty or WezTerm session
(:w, :wv, :wh, :t, etc.)
Done desktop notifications Graphical desktop with a notification daemon
spwin Kitty or WezTerm
tab Kitty, WezTerm, or Konsole
split Kitty or WezTerm
hist fzf + wl-copy (Wayland clipboard)
logs fzf + ov; reads from ~/.terminal_history/
upgrade paru or yay (Arch Linux only)
WakaTime hook wakatime CLI and a configured API key
Disabled integration commands (spwin, tab, split, hist, logs, upgrade) print
a colored error to stderr naming the variable that disabled them rather than
silently failing.
#### C5 — Logging and Capture
Five components capture shell output to disk. Unlike every other category,
C5 is opt-in: it stays off until __fish_config_op_logging 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.
# 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:
~/.terminal_history/scrollback_YYYY-MM-DD_HH-MM-SS.log
tmux pane capture Continuous pane stream via pipe-pane, saved to:
~/.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:
~/.terminal_history/zellij_<session>-p<pane>_YYYY-MM-DD_HH-MM-SS.log
paru wrapper All paru/AUR output captured to:
~/.terminal_history/paru_YYYY-MM-DD_HH-MM-SS.log
yay wrapper All yay/AUR output captured to:
~/.terminal_history/yay_YYYY-MM-DD_HH-MM-SS.log
Kitty watcher watcher.py captures scrollback when Kitty closes
NOTE: **Turning off logging does not delete any existing logs.**
They remain in `$SCROLLBACK_HISTORY_DIR` (defaults to: `~/.terminal_history/`)
until you remove them manually.
The tmux capture starts automatically when fish launches inside any tmux
pane ($TMUX is set). It uses tmux's native pipe-pane to stream all pane
output directly to disk without an intermediate process. Each fish shell
session gets its own log file; a new log is created on each shell start
(including exec fish and new splits). Before each new log, the oldest
tmux_*.log files are pruned (by modification time) to keep the total within
SCROLLBACK_HISTORY_MAX_FILES, matching the paru/yay wrapper behaviour.
The zellij capture works differently: Zellij has no live output-streaming
facility like pipe-pane, so the log is taken as a one-shot snapshot when the
shell exits, via `zellij action dump-screen --full --ansi` (the --ansi flag
preserves color). The dump is captured on the fish process's stdout and
written to the log file by fish itself (not via `--path`, which would make the
zellij server write the file). A fish_exit handler (registered whenever
$ZELLIJ is set) writes the pane's full scrollback and then prunes old
zellij_*.log files the same way. Because the capture happens at exit, toggling
__fish_config_op_logging takes effect on the next exit with no restart or
sentinel coordination needed — the C5 guard is re-checked when the handler
fires.
LIMITATION — zellij capture only fires on a clean shell exit (typing `exit`,
Ctrl-D, or a logout), because that is when the fish_exit handler runs. It does
NOT capture when you close a pane or quit zellij through zellij itself:
- Closing a pane signals the shell and tears the pane down concurrently, so
even if the handler runs, `dump-screen` may find the pane buffer already
gone.
- Quitting zellij kills the zellij server, and `dump-screen` needs a live
server to read from — there is nothing left to snapshot.
This is a structural difference from tmux, NOT a bug. tmux streams pane output
to disk continuously via pipe-pane, so whatever was printed is already saved
no matter how the pane dies. Zellij can only snapshot, and the only reliable
snapshot point from the shell is a clean exit. To guarantee a zellij pane is
logged, end the session with `exit` or Ctrl-D rather than zellij's close-pane
or quit actions.
The Kitty watcher is managed by the kitty-logging command: it symlinks the
watcher (fish-config-watcher.py) into the Kitty config directory and wires it
into kitty.conf via a managed block. Inside Kitty, a non-blocking
per-session reminder points first-time users at `kitty-logging install` until
they install or run `kitty-logging dismiss`; 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 .logging_disabled
sentinel.
Logging coordination via sentinel file
C5 uses a sentinel file to synchronize state between the shell and
out-of-process components (the Kitty watcher and all running shells):
~/.config/fish/.logging_disabled
Because C5 is off by default, the sentinel is present on a fresh install —
the startup sync in conf.d/logging-events.fish reconciles it on every shell
start, so it appears without any action on your part.
Disabling __fish_config_op_logging (or leaving it unset):
1. Creates the sentinel immediately in every open shell.
2. Removes ~/.local/bin/paru and ~/.local/bin/yay logging wrappers;
bare /usr/bin/paru and /usr/bin/yay are used instead.
3. Kitty's watcher.py reads the sentinel on each save attempt and
skips capture — no Kitty restart required.
4. smart_exit stops saving scrollback logs.
5. Stops tmux pipe-pane capture in every open fish shell inside tmux.
Enabling __fish_config_op_logging:
1. Removes the sentinel in every open shell.
2. Regenerates paru/yay logging wrappers in ~/.local/bin/.
3. Kitty watcher resumes capture on the next session exit.
4. Restarts tmux pipe-pane capture in every open fish shell inside tmux.
Changes propagate to all running shells through an event handler that fires
whenever __fish_config_op_logging changes — no shell restart needed.
Note: C3 and C5 compose independently. C3 controls whether the smart_exit
wrapper is active at all; C5 controls only the scrollback-capture block
inside it. With C3 disabled, exit is plain builtin exit regardless of C5.
#### C6 — Greeting and First-Run UI
Component What it shows
───────────────────────────────────────────────────────────────────────────
First-run welcome banner One-time message on first interactive session
fish_greeting override Empty function defined late in config.fish to
suppress distro greetings (e.g. CachyOS sets
fish_greeting to fastfetch by default)
When C6 is disabled, no greeting is printed by this config. Any greeting
set by the distro or other configs runs normally — this config simply does
not override it.
## Prompt and Theme
### Starship
The primary prompt is Starship, initialized by conf.d/starship.fish.
Configure it via ~/.config/starship.toml.
conf.d/starship.fish defines a fish_prompt wrapper that only activates when
starship is in PATH. It emits OSC 133;A (prompt start) immediately before
Starship renders and OSC 133;B (input start) immediately after, placing both
markers on the prompt line itself. This allows ov to use them as sticky
section headers when browsing scrollback logs. Without Starship, fish's
built-in prompt handles these markers automatically.
### Catppuccin Fallback Prompt
When Starship is absent or C3 overrides are disabled, a built-in nim-style
two-line prompt activates from functions/fish_prompt.fish. No external
dependencies — fish builtins only.
Layout:
┬─[user@host:~/path] (main)
╰─>$
Elements:
user Yellow (Catppuccin Yellow); red if root
@host Blue (local) or Teal (SSH)
~/path prompt_pwd abbreviation (Catppuccin Text)
(main) Current git branch in Catppuccin Pink; omitted outside repos
─[V:name] Active Python venv basename; omitted when none
─[N/I/R/V] Vi-mode indicator when vi bindings are active
┬─ / ╰─> Connector lines: Catppuccin Green on success, Red on failure
The right prompt (fish_right_prompt.fish) always renders, regardless of C3
state. On failure it shows a red ✘ and the exit code; on success it shows
only the dim timestamp. When starship is installed and C3 is enabled, the
active Docker context is also shown (if non-default):
✘ 1 󰡨 myctx Fri Jun 12 00:51:21 2026 ← failed, starship+C3 active
✘ 1 Fri Jun 12 00:51:21 2026 ← failed, fallback prompt
Fri Jun 12 00:51:21 2026 ← success (no ✘)
### FZF
FZF is themed to Catppuccin Mocha via FZF_DEFAULT_OPTS set in
integrations/fzf.fish. The colors applied:
Background: #1E1E2E (base) #313244 (surface0)
Foreground: #CDD6F4 (text)
Highlights: #F38BA8 (red) #CBA6F7 (mauve) #B4BEFE (lavender)
To customize, override FZF_DEFAULT_OPTS in local.fish.
### Catppuccin Mocha Syntax Highlighting
The Catppuccin Mocha theme ships with this config in themes/ and is applied
on first run via `conf.d/first_run.fish`. Colors are stored in fish_variables
(universal). To switch variants, install a different theme from themes/:
fish_config theme save "Catppuccin Latte"
---
@@ -0,0 +1,24 @@
---
title: Machine-local Configuration
---
Place machine-specific settings that should not be committed to git in:
$__fish_user_dots_path/local.fish
`__fish_user_dots_path` defaults to `~/.config/.user-dots/fish`. Set a
custom location with:
set -U __fish_user_dots_path /path/to/your/dots/fish
Typical uses: additional PATH entries, local aliases, hostname-specific env
vars, work-specific tool configs.
For convenience, a git-ignored `user-dots` symlink in the fish config
directory tracks `$__fish_user_dots_path` so the overlay can be browsed from
`~/.config/fish/`. It is created if missing and repointed if the path changes.
Opt out by setting `__fish_user_dots_symlink` to a falsy value, or toggling
"Dots link" off on the config-settings Paths page — this stops generation and
removes any existing link. It only ever manages a symlink and never clobbers a
real file or directory at that path.
@@ -0,0 +1,13 @@
---
title: Secrets and API Keys
---
$__fish_user_dots_path/secrets.fish
Store API tokens, GPG keys, private credentials here. This file is never
committed. It is sourced by local.fish directly, not by config.fish.
`local.fish` is sourced at the end of config.fish on every interactive
session, so it and its companion secrets.fish can override anything set
earlier.
@@ -0,0 +1,10 @@
---
title: Overriding Configuration Variables
---
Any variable set in local.fish after the main config loads takes effect.
Example: to increase the scrollback history limit:
# in local.fish
set -gx SCROLLBACK_HISTORY_MAX_FILES 200
@@ -0,0 +1,8 @@
---
title: Fish Universal Variables
---
Some settings (fzf colors, theme) are stored in fish_variables via
`set -U`. These are machine-local and git-ignored. Do not commit
fish_variables.
@@ -0,0 +1,86 @@
---
title: Opinionated Components (Minimal Mode)
---
Every opinionated piece of this config is active by default but can be
switched off through six category opt-out variables, each evaluated via
__fish_variable_check. Set a variable to any falsy value (0, false, no,
off, n) to disable its category; erase it or set a truthy value (1, true,
yes, on, y) to re-enable. Unset means enabled — except for C5 logging, which
is opt-in (see below).
An explicit per-category truthy value takes precedence over the master
switch: setting __fish_config_opinionated=0 disables all unset categories,
but a category with an explicit truthy value remains enabled regardless.
C5 (logging) is the one exception to "unset means enabled". 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.
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 — 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
Examples:
# 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 — 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)
For an interactive alternative to setting these variables by hand, run
config-settings — a full-screen TUI that flips any category (including C5
logging) on or off, per session or universally. See its entry in Section 5.
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 `command rm` — files are deleted permanently, not trashed.
- Disabled integration commands (spwin, tab, split, hist, logs, upgrade) print an error naming the variable that disabled them.
- On CachyOS, the distro fish config's own aliases, history override, and bang-bang bindings are stripped per category as well.
@@ -0,0 +1,66 @@
---
title: Prompt and Theme
---
### Starship
The primary prompt is Starship, initialized by conf.d/starship.fish.
Configure it via ~/.config/starship.toml.
conf.d/starship.fish defines a fish_prompt wrapper that only activates when
starship is in PATH. It emits OSC 133;A (prompt start) immediately before
Starship renders and OSC 133;B (input start) immediately after, placing both
markers on the prompt line itself. This allows ov to use them as sticky
section headers when browsing scrollback logs. Without Starship, fish's
built-in prompt handles these markers automatically.
### Catppuccin Fallback Prompt
When Starship is absent or C3 overrides are disabled, a built-in nim-style
two-line prompt activates from functions/fish_prompt.fish. No external
dependencies — fish builtins only.
Layout:
┬─[user@host:~/path] (main)
╰─>$
Elements:
user Yellow (Catppuccin Yellow); red if root
@host Blue (local) or Teal (SSH)
~/path prompt_pwd abbreviation (Catppuccin Text)
(main) Current git branch in Catppuccin Pink; omitted outside repos
─[V:name] Active Python venv basename; omitted when none
─[N/I/R/V] Vi-mode indicator when vi bindings are active
┬─ / ╰─> Connector lines: Catppuccin Green on success, Red on failure
The right prompt (fish_right_prompt.fish) always renders, regardless of C3
state. On failure it shows a red ✘ and the exit code; on success it shows
only the dim timestamp. When starship is installed and C3 is enabled, the
active Docker context is also shown (if non-default):
✘ 1 󰡨 myctx Fri Jun 12 00:51:21 2026 ← failed, starship+C3 active
✘ 1 Fri Jun 12 00:51:21 2026 ← failed, fallback prompt
Fri Jun 12 00:51:21 2026 ← success (no ✘)
### FZF
FZF is themed to Catppuccin Mocha via FZF_DEFAULT_OPTS set in
integrations/fzf.fish. The colors applied:
Background: #1E1E2E (base) #313244 (surface0)
Foreground: #CDD6F4 (text)
Highlights: #F38BA8 (red) #CBA6F7 (mauve) #B4BEFE (lavender)
To customize, override FZF_DEFAULT_OPTS in local.fish.
### Catppuccin Mocha Syntax Highlighting
The Catppuccin Mocha theme ships with this config in themes/ and is applied
on first run via `conf.d/first_run.fish`. Colors are stored in fish_variables
(universal). To switch variants, install a different theme from themes/:
fish_config theme save "Catppuccin Latte"
---
+11
View File
@@ -0,0 +1,11 @@
---
title: Customization
manTitle: 7. CUSTOMIZATION
sidebar:
order: 11
helpKeywords:
- customization
- customize
---
This section explains how to adapt the configuration to your specific workflow, including local machine overrides and opinionated component toggles.
@@ -0,0 +1,33 @@
---
title: C1 — Command Shadows
---
Disabling __fish_config_op_aliases restores standard system behavior for
all of these commands.
Command / Alias Active behavior Disabled fallback
───────────────────────────────────────────────────────────────────────────
ls eza -l -a --icons --hyperlink system ls
cat bat syntax-highlighted; dirs → ls /usr/bin/cat
cd zoxide frecency-based navigation fish builtin cd
rm moves files to trash (recoverable) command rm (permanent)
less $PAGER → ov → less → more → cat system less
du duf (disk overview) or dust (dir tree) system du
top btop resource monitor system top
ping prettyping --nolegend animation system ping
ssh kitten ssh in Kitty terminal system ssh
rg rg --hyperlink-format=kitty system rg
mkdir verbose path-tree display on creation mkdir -p silently
bash XDG bashrc + $SHELL reset on exit system bash
history timestamps prepended to every entry fish builtin history
cp / mv forced -i confirmation prompt cp / mv unmodified
wget forced --continue (resume downloads) system wget
grep/fgrep/egrep forced --color=auto system grep variants
dir / vdir forced --color=auto system dir / vdir
help config intercepts "help config" → config-help fish builtin help
claude auto-links AGENTS.md as CLAUDE.md before launch command claude
edit multi-editor launcher (GUI/term + fallbacks) $EDITOR/nvim/nano/vi
When C1 is disabled, `rm` uses bare `command rm` with no wrapper — files
are permanently deleted, not trashed. There is no intermediate safety net.
@@ -0,0 +1,45 @@
---
title: C2 — Startup Side-Effects
---
These run automatically without any user action. Disabling
__fish_config_op_autoexec prevents all of them.
Component Trigger What it does
───────────────────────────────────────────────────────────────────────────
Fisher bootstrap First shell only Downloads and installs fisher
Fisher update After bootstrap Installs all fish_plugins entries
Catppuccin Mocha theme First shell only Applies theme via fish_config
paru wrapper Every startup Writes ~/.local/bin/paru wrapper
yay wrapper Every startup Writes ~/.local/bin/yay wrapper
Python venv activation On every cd Sources .venv/bin/activate.fish
WakaTime command hook On every command Reports to WakaTime API
Auto-pull fast-forward On entering a repo Background ff-only git pull
user-dots symlink Every startup Links $__fish_config_dir/user-dots
to $__fish_user_dots_path
When C2 is disabled: no Fisher install, no theme application, no paru/yay
wrapper generation, no automatic venv activation, no WakaTime reporting,
no auto-pull (the PWD handler is never registered), and the user-dots
convenience symlink is not created. The symlink is git-ignored and only ever
managed as a symlink — a real file or directory at that path is left untouched.
The symlink has its own opt-out independent of C2: set __fish_user_dots_symlink
to a falsy value (or toggle "Dots link" off on the config-settings Paths page)
to stop generating it and remove any existing link — honoured even when C2 is
enabled. Managed by the __fish_user_dots_link helper.
The first-run completion marker (__fish_config_first_run_complete) is still
set so the init does not re-run on subsequent shells.
Python venv activation fires on every directory change. If a directory uses
direnv (.envrc present), direnv takes priority and auto-venv is skipped for
that directory.
Auto-pull fast-forwards opted-in repositories in the background when you cd
into them. The fish-config repo is always covered; other repos are added with
the `auto-pull` command (see its entry in the functions reference). It only
ever fast-forwards a clean repo whose branch has an upstream — never rebases,
merges, or overwrites work — so it is a no-op on dirty trees, divergent
branches, or repos without a remote. The handler fires once per repo entry
(not on every sub-directory cd). The registry is machine-local at
`$__fish_user_dots_path/auto-pull.list` (defaults to `~/.config/.user-dots/fish/auto-pull.list`) and is never committed.
@@ -0,0 +1,35 @@
---
title: C3 — Key and Environment Overrides
---
These change fundamental shell behavior: how keys work, which pager opens,
and what the prompt looks like. Disabling __fish_config_op_overrides removes
all of them.
Override What it replaces or sets
───────────────────────────────────────────────────────────────────────────
Vi mode fish_vi_key_bindings replaces default Emacs mode
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=. ~/projects ~ bare dir names resolve against ~/projects and ~
Bang-bang system ! and $ keys expand history; !^, !*, !-N, !?str?,
^old^new abbreviations; six expand_bang_* helpers
Autopair ( [ { " ' auto-close to (), [], {}, "", ''
Puffer key intercepts . ! $ * keys intercepted for smart expansion
Starship prompt fish_prompt replaced by Starship + OSC 133 markers
Catppuccin colors 30+ fish_color_* variables set to Mocha palette
FZF_DEFAULT_OPTS FZF themed to Catppuccin Mocha colors
Right prompt fish_right_prompt: exit code (on failure) + dim timestamp; always rendered; Docker context added when starship+C3 active
The bang-bang system spans key_bindings.fish, abbr.fish, puffer.fish, and
six expand_bang_*.fish functions. All are gated together — disabling C3
removes the entire bang-expansion system at once.
When C3 is disabled, `exit` falls back to `builtin exit` with no scrollback
capture, no Kitty IPC, and no file I/O on exit. The scrollback capture block
is independently controlled by C5 (see below).
@@ -0,0 +1,24 @@
---
title: C4 — Terminal and Tool Integration
---
These features couple the shell to specific external tools. Disabling
__fish_config_op_integrations disables all of them.
Component Requires
───────────────────────────────────────────────────────────────────────────
~60 Kitty/WezTerm abbrs Active Kitty or WezTerm session
(:w, :wv, :wh, :t, etc.)
Done desktop notifications Graphical desktop with a notification daemon
spwin Kitty or WezTerm
tab Kitty, WezTerm, or Konsole
split Kitty or WezTerm
hist fzf + wl-copy (Wayland clipboard)
logs fzf + ov; reads from ~/.terminal_history/
upgrade paru or yay (Arch Linux only)
WakaTime hook wakatime CLI and a configured API key
Disabled integration commands (spwin, tab, split, hist, logs, upgrade) print
a colored error to stderr naming the variable that disabled them rather than
silently failing.
@@ -0,0 +1,112 @@
---
title: C5 — Logging and Capture
---
Five components capture shell output to disk. Unlike every other category,
C5 is opt-in: it stays off until __fish_config_op_logging 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.
# 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:
~/.terminal_history/scrollback_YYYY-MM-DD_HH-MM-SS.log
tmux pane capture Continuous pane stream via pipe-pane, saved to:
~/.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:
~/.terminal_history/zellij_<session>-p<pane>_YYYY-MM-DD_HH-MM-SS.log
paru wrapper All paru/AUR output captured to:
~/.terminal_history/paru_YYYY-MM-DD_HH-MM-SS.log
yay wrapper All yay/AUR output captured to:
~/.terminal_history/yay_YYYY-MM-DD_HH-MM-SS.log
Kitty watcher watcher.py captures scrollback when Kitty closes
NOTE: **Turning off logging does not delete any existing logs.**
They remain in `$SCROLLBACK_HISTORY_DIR` (defaults to: `~/.terminal_history/`)
until you remove them manually.
The tmux capture starts automatically when fish launches inside any tmux
pane ($TMUX is set). It uses tmux's native pipe-pane to stream all pane
output directly to disk without an intermediate process. Each fish shell
session gets its own log file; a new log is created on each shell start
(including exec fish and new splits). Before each new log, the oldest
tmux_*.log files are pruned (by modification time) to keep the total within
SCROLLBACK_HISTORY_MAX_FILES, matching the paru/yay wrapper behaviour.
The zellij capture works differently: Zellij has no live output-streaming
facility like pipe-pane, so the log is taken as a one-shot snapshot when the
shell exits, via `zellij action dump-screen --full --ansi` (the --ansi flag
preserves color). The dump is captured on the fish process's stdout and
written to the log file by fish itself (not via `--path`, which would make the
zellij server write the file). A fish_exit handler (registered whenever
$ZELLIJ is set) writes the pane's full scrollback and then prunes old
zellij_*.log files the same way. Because the capture happens at exit, toggling
__fish_config_op_logging takes effect on the next exit with no restart or
sentinel coordination needed — the C5 guard is re-checked when the handler
fires.
LIMITATION — zellij capture only fires on a clean shell exit (typing `exit`,
Ctrl-D, or a logout), because that is when the fish_exit handler runs. It does
NOT capture when you close a pane or quit zellij through zellij itself:
- Closing a pane signals the shell and tears the pane down concurrently, so
even if the handler runs, `dump-screen` may find the pane buffer already
gone.
- Quitting zellij kills the zellij server, and `dump-screen` needs a live
server to read from — there is nothing left to snapshot.
This is a structural difference from tmux, NOT a bug. tmux streams pane output
to disk continuously via pipe-pane, so whatever was printed is already saved
no matter how the pane dies. Zellij can only snapshot, and the only reliable
snapshot point from the shell is a clean exit. To guarantee a zellij pane is
logged, end the session with `exit` or Ctrl-D rather than zellij's close-pane
or quit actions.
The Kitty watcher is managed by the kitty-logging command: it symlinks the
watcher (fish-config-watcher.py) into the Kitty config directory and wires it
into kitty.conf via a managed block. Inside Kitty, a non-blocking
per-session reminder points first-time users at `kitty-logging install` until
they install or run `kitty-logging dismiss`; 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 .logging_disabled
sentinel.
Logging coordination via sentinel file
C5 uses a sentinel file to synchronize state between the shell and
out-of-process components (the Kitty watcher and all running shells):
~/.config/fish/.logging_disabled
Because C5 is off by default, the sentinel is present on a fresh install —
the startup sync in conf.d/logging-events.fish reconciles it on every shell
start, so it appears without any action on your part.
Disabling __fish_config_op_logging (or leaving it unset):
1. Creates the sentinel immediately in every open shell.
2. Removes ~/.local/bin/paru and ~/.local/bin/yay logging wrappers;
bare /usr/bin/paru and /usr/bin/yay are used instead.
3. Kitty's watcher.py reads the sentinel on each save attempt and
skips capture — no Kitty restart required.
4. smart_exit stops saving scrollback logs.
5. Stops tmux pipe-pane capture in every open fish shell inside tmux.
Enabling __fish_config_op_logging:
1. Removes the sentinel in every open shell.
2. Regenerates paru/yay logging wrappers in ~/.local/bin/.
3. Kitty watcher resumes capture on the next session exit.
4. Restarts tmux pipe-pane capture in every open fish shell inside tmux.
Changes propagate to all running shells through an event handler that fires
whenever __fish_config_op_logging changes — no shell restart needed.
Note: C3 and C5 compose independently. C3 controls whether the smart_exit
wrapper is active at all; C5 controls only the scrollback-capture block
inside it. With C3 disabled, exit is plain builtin exit regardless of C5.
@@ -0,0 +1,15 @@
---
title: C6 — Greeting and First-Run UI
---
Component What it shows
───────────────────────────────────────────────────────────────────────────
First-run welcome banner One-time message on first interactive session
fish_greeting override Empty function defined late in config.fish to
suppress distro greetings (e.g. CachyOS sets
fish_greeting to fastfetch by default)
When C6 is disabled, no greeting is printed by this config. Any greeting
set by the distro or other configs runs normally — this config simply does
not override it.
@@ -0,0 +1,12 @@
---
title: Components Reference
manTitle: 8. COMPONENTS REFERENCE
sidebar:
order: 12
helpKeywords:
- componentsreference
---
The following tables detail every component in each category. Use this
reference to understand exactly which behaviors change when you toggle a
category variable.
@@ -1,8 +1,8 @@
--- ---
title: Fisher Plugins title: Fisher Plugins
manTitle: 8. FISHER PLUGINS manTitle: 9. FISHER PLUGINS
sidebar: sidebar:
order: 12 order: 13
helpKeywords: helpKeywords:
- plugins - plugins
- fisher - fisher
@@ -1,8 +1,8 @@
--- ---
title: Installation title: Installation
manTitle: 9. INSTALLATION manTitle: 10. INSTALLATION
sidebar: sidebar:
order: 13 order: 14
helpKeywords: helpKeywords:
- installation - installation
- install - install
@@ -1,8 +1,8 @@
--- ---
title: Personalization title: Personalization
manTitle: 10. PERSONALIZATION manTitle: 11. PERSONALIZATION
sidebar: sidebar:
order: 14 order: 15
helpKeywords: helpKeywords:
- personalization - personalization
- personalize - personalize
@@ -1,8 +1,8 @@
--- ---
title: Troubleshooting title: Troubleshooting
manTitle: 11. TROUBLESHOOTING manTitle: 12. TROUBLESHOOTING
sidebar: sidebar:
order: 15 order: 16
helpKeywords: helpKeywords:
- troubleshooting - troubleshooting
- troubleshoot - troubleshoot
@@ -1,8 +1,8 @@
--- ---
title: Viewing This Manual title: Viewing This Manual
manTitle: 12. VIEWING THIS MANUAL manTitle: 13. VIEWING THIS MANUAL
sidebar: sidebar:
order: 16 order: 17
helpKeywords: helpKeywords:
- viewing - viewing
- manual - manual
+8 -8
View File
@@ -687,10 +687,10 @@ def test_as_file_tree_accepts_deeper_trees():
def test_customization_notes_render_as_aside(): def test_customization_notes_render_as_aside():
"""The real 07-customization.md NOTE paragraph converts to one intact <Aside>.""" """The real 07-customization NOTE paragraph converts to one intact <Aside>."""
import build_manual import build_manual
path = Path(__file__).parent / "manual" / "07-customization.md" path = Path(__file__).parent / "manual" / "07-customization" / "05-opinionated-components-minimal-mode.md"
_, body = mt.parse(path) _, body = mt.parse(path)
out = build_manual.prettify(body) out = build_manual.prettify(body)
assert out.count('<Aside type="note" title="Note">') >= 1, f"expected at least one Note aside:\n{out}" assert out.count('<Aside type="note" title="Note">') >= 1, f"expected at least one Note aside:\n{out}"
@@ -711,22 +711,22 @@ def test_site_promotes_pages_with_asides_or_filetrees_to_mdx():
out = Path(d) out = Path(d)
build_manual.build_site(docs / "manual", out) build_manual.build_site(docs / "manual", out)
assert (out / "10-personalization.mdx").exists(), "FileTree page was not promoted to .mdx" assert (out / "11-personalization.mdx").exists(), "FileTree page was not promoted to .mdx"
assert not (out / "10-personalization.md").exists(), "old .md sibling was left behind" assert not (out / "11-personalization.md").exists(), "old .md sibling was left behind"
assert (out / "12-viewing-this-manual.mdx").exists(), "Aside page (NOTE) was not promoted to .mdx" assert (out / "13-viewing-this-manual.mdx").exists(), "Aside page (NOTE) was not promoted to .mdx"
assert (out / "07-customization.mdx").exists(), "Aside page (rewritten NOTE) was not promoted to .mdx" assert (out / "07-customization/05-opinionated-components-minimal-mode.mdx").exists(), "Aside page (rewritten NOTE) was not promoted to .mdx"
assert (out / "02-path-setup.mdx").exists(), "Aside page (NOTE) was not promoted to .mdx" assert (out / "02-path-setup.mdx").exists(), "Aside page (NOTE) was not promoted to .mdx"
assert (out / "03-key-bindings.md").exists(), "plain page was wrongly promoted to .mdx" assert (out / "03-key-bindings.md").exists(), "plain page was wrongly promoted to .mdx"
assert not (out / "03-key-bindings.mdx").exists(), "plain page should stay .md" assert not (out / "03-key-bindings.mdx").exists(), "plain page should stay .md"
text = (out / "10-personalization.mdx").read_text() text = (out / "11-personalization.mdx").read_text()
assert "FileTree" in text.split("from '@astrojs/starlight/components';")[0] assert "FileTree" in text.split("from '@astrojs/starlight/components';")[0]
text2 = (out / "12-viewing-this-manual.mdx").read_text() text2 = (out / "13-viewing-this-manual.mdx").read_text()
assert "Aside" in text2.split("from '@astrojs/starlight/components';")[0] assert "Aside" in text2.split("from '@astrojs/starlight/components';")[0]