Verified every claim in the Prompt and Theme section against the actual source and corrected several inaccuracies: the Starship wrapper's missing C3 gate, the fallback prompt's vi-mode states and segment order, the FZF theme's real location (conf.d/theme.fish, not integrations/fzf.fish) and color set, and the Catppuccin theme-switch example using the wrong fish_config subcommand (choose, not save). The right-prompt Docker-context example was rewritten to show that it's independent of exit status. While reformatting, found that any block build-manual.py couldn't classify as shell/table/tree fell back to plain 4-space markdown indentation, which silently renders as squashed, unreadable paragraph text on any page that also contains an <Aside> or <FileTree> — MDX has no indented-code-block syntax, unlike plain Markdown. This affected 07-customization.mdx plus four other pages. Fixed the fallback to emit a fenced ```text block instead, since fences work in both MDX and plain Markdown; this also gives every affected block Starlight's normal code-block styling instead of a bare grey slab. docs/fish-config.md is intentionally left stale here — CI regenerates and auto-commits it from docs/manual/** on push to main.
266 lines
12 KiB
Markdown
266 lines
12 KiB
Markdown
---
|
|
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.
|
|
|
|
### Sub-categories
|
|
|
|
Each of the six categories further sub-divides into two to six
|
|
sub-categories, each with its own `__fish_config_op_<category>_<subcategory>`
|
|
variable (e.g. `__fish_config_op_aliases_filesystem`). 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's
|
|
setting, and an unset sub-category inherits from its parent category (which
|
|
in turn inherits from `__fish_config_opinionated`). Run config-settings and
|
|
press Enter on a category row to browse and toggle its sub-categories
|
|
interactively. See [Components Reference](/08-components-reference/) for the
|
|
full sub-category breakdown of every category.
|
|
|
|
|
|
## 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 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'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 (a dim job line appears between the two rows for each running
|
|
background job):
|
|
|
|
┬─[user@host:~/path] (main)
|
|
│ nvim notes.md
|
|
╰─>$
|
|
|
|
Elements:
|
|
|
|
Segment Meaning
|
|
────────────────────────────────────────────────────────────────
|
|
user Yellow (Catppuccin Yellow); red if root
|
|
@host Blue (local) or Teal (SSH)
|
|
~/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
|
|
|
|
The right prompt (fish_right_prompt.fish) always renders, independently of
|
|
which left prompt is active:
|
|
|
|
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)
|
|
|
|
The exit-status and Docker segments are independent — for example, right
|
|
after a failing command with a non-default Docker context active:
|
|
|
|
✘ 1 myctx Fri Jun 12 00:51:21 2026
|
|
|
|
A successful command with the same Docker context shows the segment too:
|
|
|
|
myctx Fri Jun 12 00:51:21 2026
|
|
|
|
And without Starship (or with C3 disabled, or Docker not installed), only
|
|
the exit-status prefix and timestamp ever appear:
|
|
|
|
✘ 1 Fri Jun 12 00:51:21 2026
|
|
|
|
### FZF
|
|
|
|
FZF is themed to Catppuccin Mocha via FZF_DEFAULT_OPTS, set in
|
|
conf.d/theme.fish (opinionated; disabled by `__fish_config_op_overrides`,
|
|
see Opinionated Components above). The colors applied:
|
|
|
|
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
|
|
|
|
To customize, override FZF_DEFAULT_OPTS in local.fish — it is sourced after
|
|
conf.d/theme.fish on every session, so a `set -Ux FZF_DEFAULT_OPTS ...`
|
|
there always wins.
|
|
|
|
### Catppuccin Mocha Syntax Highlighting
|
|
|
|
The Catppuccin Mocha theme ships with this config in themes/ and is applied
|
|
automatically on first run via `conf.d/first_run.fish` (gated by
|
|
`__fish_config_op_autoexec`; see Opinionated Components above). Colors are
|
|
stored in fish_variables (universal). Three other bundled variants are
|
|
available in themes/ — Latte, Frappé, and Macchiato. To switch:
|
|
|
|
fish_config theme choose "Catppuccin Latte"
|
|
|
|
---
|