feat(help): render code spans in the pager instead of printing backticks #121
+15
-2
@@ -243,8 +243,21 @@ Write doc-headers as plain text — no backticks. `-a/--all`,
|
||||
`__fish_config_op_aliases` and `~/.config/fish/config.fish` are typed
|
||||
bare, because the header is also read as-is by `config-help` and by
|
||||
anyone opening the file. `docs/codespans.py` adds the inline code spans
|
||||
the docs site wants when it renders, so the SSOT never carries them; see
|
||||
`docs/site/README.md` for which shapes it recognises.
|
||||
when it renders, so the SSOT never carries them; see
|
||||
`docs/site/README.md` for which shapes it recognises. That pass runs for
|
||||
every output — the site, the man page and `config-help` — so a token is
|
||||
typeset the same way wherever it is read.
|
||||
|
||||
Two rules apply to backticks you write under `docs/manual/` as well:
|
||||
|
||||
- **Never inside an indented block.** A four-space block is verbatim in
|
||||
every renderer, so a backtick there is a literal character on the page
|
||||
rather than markup.
|
||||
- **Never wrapped across a line break.** Markdown accepts a span split
|
||||
over two lines, but `config-help` pairs backticks one line at a time
|
||||
and would show the halves literally. Reflow the sentence instead.
|
||||
|
||||
`docs/verify-manual.py` enforces both.
|
||||
|
||||
## Testing
|
||||
|
||||
|
||||
+20
-6
@@ -95,6 +95,16 @@ def build_concat(root: Path) -> str:
|
||||
with no frontmatter fences and no Astro-visible frontmatter key. When
|
||||
present, its contents are re-emitted byte-for-byte as the leading
|
||||
`---`-fenced block, ahead of every heading.
|
||||
|
||||
Bodies go through `codespans` here so a token is typeset the same way
|
||||
in every output: `tmux` and `local.fish` are wrapped on the site by
|
||||
that pass, and without it the man page marked only what the SSOT
|
||||
happened to backtick by hand. Section 5 is unaffected -- its entries
|
||||
arrive as indented verbatim blocks, which `codespans` leaves alone and
|
||||
pandoc already sets in a monospace font.
|
||||
|
||||
Only bodies are passed: the pandoc metadata block above is not prose
|
||||
and must survive byte-for-byte.
|
||||
"""
|
||||
entries = build_entries(mt.parse_functions(FUNCTIONS))
|
||||
chunks: list[str] = []
|
||||
@@ -117,6 +127,7 @@ def build_concat(root: Path) -> str:
|
||||
body = re.sub(r"<LinkButton.*?</LinkButton>\n*", "", body, flags=re.DOTALL)
|
||||
body = re.sub(r"<CardGrid.*?</CardGrid>\n*", "", body, flags=re.DOTALL)
|
||||
body = re.sub(r"\[([^\]]+)\]\(/[^)]+\)", r"\1", body)
|
||||
body = codespans.add_code_spans(body, _code_vocabulary())
|
||||
chunks.append(mt.shift_headings(body, depth))
|
||||
return "\n\n".join(chunks) + "\n"
|
||||
|
||||
@@ -495,12 +506,15 @@ def _code_vocabulary() -> codespans.Vocabulary:
|
||||
def prettify(body: str, entry_name: str | None = None) -> str:
|
||||
"""Rewrite a body's indented code blocks and labeled asides for the website.
|
||||
|
||||
Site-only: the man page and `config-help` keep reading the untouched
|
||||
SSOT, where the indented form and the `LABEL:` text are exactly what
|
||||
pandoc/`config-help` want. The same applies to the inline code spans
|
||||
added last: `-a/--all` and `__fish_config_op_aliases` are authored bare
|
||||
so the `functions/*.fish` headers stay readable as plain text, and the
|
||||
backticks the site wants are put on here rather than in the SSOT.
|
||||
The block and aside rewrites are site-only: the man page and
|
||||
`config-help` keep reading the untouched SSOT, where the indented form
|
||||
and the `LABEL:` text are exactly what pandoc/`config-help` want.
|
||||
|
||||
The inline code spans added last are not site-only. `-a/--all` and
|
||||
`__fish_config_op_aliases` are authored bare so the `functions/*.fish`
|
||||
headers stay readable as plain text, and the backticks every output
|
||||
wants are put on here rather than in the SSOT -- `build_concat()` runs
|
||||
the same pass for the man page and `config-help`.
|
||||
"""
|
||||
out: list[str] = []
|
||||
block: list[str] = []
|
||||
|
||||
+16
-4
@@ -18,8 +18,9 @@ touched, so the man page and `config-help` keep the plain-text form.
|
||||
Everything here is conservative by construction: leaving a token alone is
|
||||
always safe and wrapping the wrong one is not, so every rule bails out the
|
||||
moment it is unsure. The regions that must never be rewritten -- fenced
|
||||
blocks, existing code spans, link targets, URLs, JSX attributes,
|
||||
`<FileTree>` bodies, headings -- are recognised first and passed through.
|
||||
blocks, indented code blocks, existing code spans, link targets, URLs, JSX
|
||||
attributes, `<FileTree>` bodies, headings -- are recognised first and
|
||||
passed through.
|
||||
"""
|
||||
|
||||
import functools
|
||||
@@ -359,6 +360,14 @@ FILE_TREE_OPEN = "<FileTree"
|
||||
FILE_TREE_CLOSE = "</FileTree>"
|
||||
CELL_SPLIT_RE = re.compile(r"(?<!\\)\|")
|
||||
|
||||
# A four-space indent is this manual's code block. The site never sees one
|
||||
# -- prettify() has already turned it into a fence by the time this module
|
||||
# runs -- but build_concat() keeps the indented form, because that is what
|
||||
# pandoc and `config-help` want, and its contents are code that must not be
|
||||
# rewritten: the table of contents alone would otherwise have `ov`, `bat`,
|
||||
# `less` and `cat` wrapped inside a code block.
|
||||
INDENTED_CODE = " "
|
||||
|
||||
|
||||
def _skip_line(line: str) -> bool:
|
||||
"""True for a line that must be passed through untouched.
|
||||
@@ -488,8 +497,9 @@ def add_code_spans(text: str, vocab: Vocabulary = EMPTY_VOCABULARY) -> str:
|
||||
"""Wrap code-shaped tokens in `text` in inline code spans.
|
||||
|
||||
`text` is a rendered page body (no frontmatter). Fenced blocks,
|
||||
`<FileTree>` bodies, headings, component markup, existing code spans,
|
||||
link targets and URLs are left exactly as they are.
|
||||
indented code blocks, `<FileTree>` bodies, headings, component markup,
|
||||
existing code spans, link targets and URLs are left exactly as they
|
||||
are.
|
||||
"""
|
||||
scanner = _scanner(vocab)
|
||||
atom_re = _atom_re(vocab)
|
||||
@@ -510,6 +520,8 @@ def add_code_spans(text: str, vocab: Vocabulary = EMPTY_VOCABULARY) -> str:
|
||||
if FILE_TREE_CLOSE in line:
|
||||
in_tree = False
|
||||
continue
|
||||
if line.startswith(INDENTED_CODE):
|
||||
continue
|
||||
eligible[i] = not _skip_line(line)
|
||||
|
||||
# Command columns are a property of a whole table, so the contiguous
|
||||
|
||||
+111
-111
@@ -32,10 +32,10 @@ A production-grade Fish shell configuration targeting Fish 4.x. It provides:
|
||||
- Drop-in replacements for common Unix tools (`ls`, `cat`, `rm`, `du`, `ping`, `less`)
|
||||
- Deep Kitty and WezTerm terminal integration: tab/window/pane management from
|
||||
the command line
|
||||
- Optional session logging: terminal scrollback, tmux/zellij panes, and
|
||||
paru/yay output captured to `~/.terminal_history` (off by default; see C5 Logging)
|
||||
- Optional session logging: terminal scrollback, `tmux`/`zellij` panes, and
|
||||
`paru`/`yay` output captured to `~/.terminal_history` (off by default; see C5 Logging)
|
||||
- Automatic Python virtualenv activation on directory change
|
||||
- Cross-platform package management via pkg and fish-deps
|
||||
- Cross-platform package management via pkg and `fish-deps`
|
||||
- AI scaffolding helpers for Claude Code and Antigravity
|
||||
- Catppuccin Mocha color theme throughout
|
||||
|
||||
@@ -133,8 +133,8 @@ The configuration uses a structured file tree:
|
||||
|
||||
# 1. CONFIGURATION VARIABLES
|
||||
|
||||
These variables are exported from config.fish on every interactive session.
|
||||
Override them in local.fish (see Section 10, Personalization).
|
||||
These variables are exported from `config.fish` on every interactive session.
|
||||
Override them in `local.fish` (see Section 10, Personalization).
|
||||
|
||||
## Environment Directories (XDG)
|
||||
|
||||
@@ -290,7 +290,7 @@ Directories prepended to PATH in this order (first wins):
|
||||
| `~/scripts` | Personal shell scripts |
|
||||
| `~/bin` | Cargo binaries (appended — lowest priority) |
|
||||
| `$BUN_INSTALL/bin` | Bun runtime and global packages |
|
||||
| `$NPM_CONFIG_PREFIX/bin` | Global npm packages |
|
||||
| `$NPM_CONFIG_PREFIX/bin` | Global `npm` packages |
|
||||
| `~/.lmstudio/bin` | LM Studio CLI |
|
||||
| `~/.resend/bin` | Resend CLI |
|
||||
| `~/.fzf/bin` | `fzf` binary (git-installed) |
|
||||
@@ -306,7 +306,7 @@ TIP: This standard PATH setup is gated behind the opinionated component override
|
||||
|
||||
# 3. KEY BINDINGS
|
||||
|
||||
The shell uses Vi key bindings (fish_vi_key_bindings). All custom bindings
|
||||
The shell uses Vi key bindings (`fish_vi_key_bindings`). All custom bindings
|
||||
are active in Insert, Normal, and Visual modes unless noted.
|
||||
|
||||
Binding Action
|
||||
@@ -561,7 +561,7 @@ as keybindings, but they all serve the same purpose.
|
||||
|
||||
## 4.11 Shell Aliases
|
||||
|
||||
These aliases are defined in conf.d/tricks.fish via alias (which creates Fish
|
||||
These aliases are defined in `conf.d/tricks.fish` via alias (which creates Fish
|
||||
functions). They are active in all interactive sessions.
|
||||
|
||||
Abbreviation Description
|
||||
@@ -800,7 +800,7 @@ functions). They are active in all interactive sessions.
|
||||
|
||||
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
|
||||
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,
|
||||
@@ -1327,10 +1327,10 @@ functions). They are active in all interactive sessions.
|
||||
Optional btop, dust, duf, prettyping, go, lazygit,
|
||||
lazydocker, docker, yt-dlp, screen — single-purpose
|
||||
wrapper conveniences that only matter if you
|
||||
already use that tool; skipped by `install`/`sync`
|
||||
already use that tool; skipped by install/sync
|
||||
unless --optional (or --all) is passed
|
||||
Terminal Emulators kitty, wezterm — only matter if one of them is
|
||||
your actual terminal; skipped by `install`/`sync`
|
||||
your actual terminal; skipped by install/sync
|
||||
unless --terminals (or --all) is passed
|
||||
Integrations wakatime, tailscale
|
||||
|
||||
@@ -1565,13 +1565,13 @@ functions). They are active in all interactive sessions.
|
||||
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 — it survives closing the shell, and `attach`
|
||||
can return to later — 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.
|
||||
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
|
||||
@@ -1582,7 +1582,7 @@ functions). They are active in all interactive sessions.
|
||||
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 'a | b'`.
|
||||
jobrunner run sync fish -c 'a | b'.
|
||||
|
||||
Example:
|
||||
jobrunner run -n build make -j8
|
||||
@@ -1893,7 +1893,7 @@ functions). They are active in all interactive sessions.
|
||||
|
||||
Notes:
|
||||
The exit builtin is wired to smart_exit for interactive sessions. Typing
|
||||
`exit` or Ctrl+D behaves identically to calling smart_exit directly.
|
||||
exit or Ctrl+D behaves identically to calling smart_exit directly.
|
||||
|
||||
Example:
|
||||
smart_exit
|
||||
@@ -2122,7 +2122,7 @@ functions). They are active in all interactive sessions.
|
||||
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
|
||||
function is only defined when aichat is installed. Run qc --help for
|
||||
aichat's full flag reference with the command name rewritten to qc.
|
||||
|
||||
Arguments:
|
||||
@@ -2350,7 +2350,7 @@ functions). They are active in all interactive sessions.
|
||||
in the default browser via xdg-open — deep links to a section aren't
|
||||
supported there, so if a keyword is given a note points you to the site'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
|
||||
(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.
|
||||
|
||||
@@ -2369,9 +2369,9 @@ functions). They are active in all interactive sessions.
|
||||
Otherwise, the manual is shown via the resolved pager (not captured stdout).
|
||||
|
||||
Notes:
|
||||
The preferred invocation is `help config [...]` — this function is
|
||||
The preferred invocation is help config [...] — this function is
|
||||
registered as a handler in the help wrapper so that syntax works
|
||||
transparently. Direct `config-help` calls are also valid.
|
||||
transparently. Direct config-help calls are also valid.
|
||||
|
||||
Example:
|
||||
config-help
|
||||
@@ -2476,7 +2476,7 @@ functions). They are active in all interactive sessions.
|
||||
Pulls the latest fish shell configuration from the upstream repository
|
||||
into ~/.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.
|
||||
short summary of changed files; run exec fish to reload the shell.
|
||||
|
||||
Arguments:
|
||||
-h, --help Show this help message and exit
|
||||
@@ -2570,11 +2570,11 @@ functions). They are active in all interactive sessions.
|
||||
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
|
||||
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`
|
||||
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
|
||||
@@ -2654,9 +2654,9 @@ functions). They are active in all interactive sessions.
|
||||
|
||||
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/`.
|
||||
plain-text databases bundled in data/words/.
|
||||
|
||||
Modifiers like `--separator` and `--case` are evaluated sequentially and
|
||||
Modifiers like --separator and --case are evaluated sequentially and
|
||||
apply only to the components that follow them.
|
||||
|
||||
Supported Components:
|
||||
@@ -2674,7 +2674,7 @@ functions). They are active in all interactive sessions.
|
||||
1 Unknown category or missing word list file
|
||||
|
||||
Notes:
|
||||
Falls back to `random choice` if GNU `shuf` is missing, but `shuf` is
|
||||
Falls back to random choice if GNU shuf is missing, but shuf is
|
||||
much faster for files with >1000 lines.
|
||||
|
||||
Example:
|
||||
@@ -2706,7 +2706,7 @@ functions). They are active in all interactive sessions.
|
||||
Synopsis: repo-open [-p|--print] [-r|--root]
|
||||
repo-open --help
|
||||
|
||||
Opens the web page for the current repository's `origin` remote in a
|
||||
Opens the web page for the current repository's origin remote in a
|
||||
browser (via open-url). Deep-links to the current branch when it exists
|
||||
on the remote, falling back to the remote's default branch (main/master)
|
||||
otherwise, and to the current sub-directory when invoked below the repo
|
||||
@@ -2778,7 +2778,7 @@ functions). They are active in all interactive sessions.
|
||||
|
||||
# 6. DEPENDENCY CATALOG
|
||||
|
||||
fish-deps manages these tools. Run `fish-deps` to check status,
|
||||
`fish-deps` manages these tools. Run `fish-deps` to check status,
|
||||
`fish-deps install` to install missing Required/Recommended ones, or add
|
||||
`--optional`, `--terminals`, or `--all` to also include the Optional and/or
|
||||
Terminal Emulators tiers.
|
||||
@@ -2797,9 +2797,9 @@ Terminal Emulators tiers.
|
||||
| `cargo` | Rust toolchain (via rustup); used by `fish-deps` to install Rust-based tools and to build fish from source. All paths are gated on `type -q cargo` and degrade gracefully. |
|
||||
| `starship` | Cross-shell prompt; loaded via `type -q starship` guard. Without it the Catppuccin nim-style fallback prompt activates. |
|
||||
| `uv` | Python package and project manager (Astral); used by the fish-from-source build path in `fish-deps`. All consumers degrade gracefully without it. |
|
||||
| `direnv` | Per-directory environment loading; integration is fully guarded with `type -q direnv`. Without it the direnv hook is simply not loaded and auto-venv activates normally. |
|
||||
| `direnv` | Per-directory environment loading; integration is fully guarded with `type -q direnv`. Without it the `direnv` hook is simply not loaded and auto-venv activates normally. |
|
||||
| `paru` | AUR helper (Arch only; preferred); guarded throughout — non-Arch systems silently skip AUR-specific paths. |
|
||||
| `yay` | AUR helper (Arch only; fallback to paru); same guards apply. |
|
||||
| `yay` | AUR helper (Arch only; fallback to `paru`); same guards apply. |
|
||||
| `eza` | Modern `ls` replacement |
|
||||
| `zoxide` | Smart cd with frecency |
|
||||
| `lsd` | `ls` replacement (fallback to `eza`) |
|
||||
@@ -2820,7 +2820,7 @@ matter if you already use that specific tool. Skipped by
|
||||
| `btop` | Modern resource monitor; backs the `top` wrapper (falls back to system `top`). |
|
||||
| `dust` | Disk usage tree (Rust); one of two backends for the `du` wrapper (falls back to system `du`). |
|
||||
| `duf` | Disk usage/free overview; the other backend for the `du` wrapper (falls back to system `du`). |
|
||||
| `prettyping` | Colorized ping wrapper; backs the `ping` wrapper (falls back to system `ping`). |
|
||||
| `prettyping` | Colorized `ping` wrapper; backs the `ping` wrapper (falls back to system `ping`). |
|
||||
| `go` | Go toolchain; only used to install `ov` via `go install` (see below), which gets the latest release and doesn't depend on your distro packaging `ov`. Package name varies by distro (`go` on Arch/Homebrew, `golang`/`golang-go` on Debian/Fedora) — install manually if the listed package name doesn't resolve on your system. |
|
||||
| `lazygit` | Terminal git UI; only referenced by the `lg` abbreviation. |
|
||||
| `lazydocker` | Terminal docker UI; backs the `ld` wrapper. |
|
||||
@@ -2886,7 +2886,7 @@ 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
|
||||
"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.
|
||||
|
||||
@@ -2896,16 +2896,16 @@ real file or directory at that path.
|
||||
$__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.
|
||||
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
|
||||
`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.
|
||||
Any variable set in `local.fish` after the main config loads takes effect.
|
||||
Example: to increase the scrollback history limit:
|
||||
|
||||
# in local.fish
|
||||
@@ -2914,9 +2914,9 @@ Example: to increase the scrollback history limit:
|
||||
|
||||
## Fish Universal Variables
|
||||
|
||||
Some settings (fzf colors, theme) are stored in fish_variables via
|
||||
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.
|
||||
`fish_variables`.
|
||||
|
||||
|
||||
## Opinionated Components (Minimal Mode)
|
||||
@@ -2994,13 +2994,13 @@ Examples:
|
||||
# (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
|
||||
`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.
|
||||
- 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
|
||||
@@ -3011,7 +3011,7 @@ 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
|
||||
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 for the
|
||||
full sub-category breakdown of every category.
|
||||
@@ -3021,11 +3021,11 @@ full sub-category breakdown of every category.
|
||||
|
||||
### Starship
|
||||
|
||||
The primary prompt is Starship, initialized by conf.d/starship.fish.
|
||||
Configure it via ~/.config/starship.toml.
|
||||
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
|
||||
`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
|
||||
@@ -3037,7 +3037,7 @@ 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
|
||||
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
|
||||
@@ -3063,7 +3063,7 @@ Elements:
|
||||
┬─ / ╰─> Connector lines: Catppuccin Green on success,
|
||||
Red on failure
|
||||
|
||||
The right prompt (fish_right_prompt.fish) always renders, independently of
|
||||
The right prompt (`fish_right_prompt.fish`) always renders, independently of
|
||||
which left prompt is active:
|
||||
|
||||
Segment Shown when
|
||||
@@ -3090,8 +3090,8 @@ the exit-status prefix and timestamp ever appear:
|
||||
|
||||
### FZF
|
||||
|
||||
FZF is themed to Catppuccin Mocha via FZF_DEFAULT_OPTS, set in
|
||||
conf.d/theme.fish (opinionated; disabled by `__fish_config_op_overrides`,
|
||||
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
|
||||
@@ -3106,8 +3106,8 @@ see Opinionated Components above). The colors applied:
|
||||
#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 ...`
|
||||
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
|
||||
@@ -3115,7 +3115,7 @@ there always wins.
|
||||
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
|
||||
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"
|
||||
@@ -3130,9 +3130,9 @@ category variable.
|
||||
|
||||
Category Description
|
||||
──────────────────────────────────────────────────────────────────────────
|
||||
C1 Command Shadows — Wraps destructive commands (`rm`, `cp`) to be safe by default
|
||||
C1 Command Shadows — Wraps destructive commands (rm, cp) to be safe by default
|
||||
C2 Startup Side-Effects — Bootstraps Fisher, generates wrappers, auto-activates venvs
|
||||
C3 Overrides — Overrides `cd`, sets Vi mode, binds `<CR>` to `smart_enter`
|
||||
C3 Overrides — Overrides cd, sets Vi mode, binds <CR> to smart_enter
|
||||
C4 Integrations — Kitty/Wezterm integrations, starship hooks, fzf theme
|
||||
C5 Logging and Capture — Session logs, command duration
|
||||
C6 Greeting & First-Run UI — Custom startup banner
|
||||
@@ -3212,7 +3212,7 @@ and the `help config` interception.
|
||||
|
||||
### dev-tools
|
||||
|
||||
`claude` (AGENTS.md/CLAUDE.md auto-linking) and `edit` (multi-editor
|
||||
`claude` (`AGENTS.md/CLAUDE.md` auto-linking) and `edit` (multi-editor
|
||||
launcher), plus `agy`.
|
||||
|
||||
## C2 — Startup Side-Effects
|
||||
@@ -3233,20 +3233,20 @@ These run automatically without any user action. Disabling
|
||||
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
|
||||
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
|
||||
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 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
|
||||
`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
|
||||
@@ -3401,59 +3401,59 @@ CAUTION: This configuration is capable of silently recording terminal output and
|
||||
Component What it captures
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
Scrollback capture Terminal session output saved to:
|
||||
`~/.terminal_history/scrollback_YYYY-MM-DD_HH-MM-SS.log`
|
||||
~/.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`
|
||||
~/.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`
|
||||
~/.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`
|
||||
~/.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
|
||||
~/.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
|
||||
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.
|
||||
`SCROLLBACK_HISTORY_MAX_FILES`, matching the `paru`/`yay` wrapper behaviour.
|
||||
|
||||
The zellij capture works differently: Zellij has no live output-streaming
|
||||
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` 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:
|
||||
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
|
||||
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
|
||||
- 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
|
||||
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
|
||||
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
|
||||
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
|
||||
@@ -3476,22 +3476,22 @@ 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.
|
||||
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.
|
||||
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/`.
|
||||
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.
|
||||
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
|
||||
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.
|
||||
|
||||
@@ -3508,7 +3508,7 @@ Kitty watcher scrollback capture, and `smart_exit`'s logging-guard path.
|
||||
|
||||
### multiplexer-capture
|
||||
|
||||
tmux `pipe-pane` and zellij `dump-screen` capture.
|
||||
`tmux` `pipe-pane` and `zellij` `dump-screen` capture.
|
||||
|
||||
### pkg-logs
|
||||
|
||||
@@ -3566,7 +3566,7 @@ commit them. Fisher installs and updates them automatically.
|
||||
|
||||
## Sponge History Filtering
|
||||
|
||||
Sponge removes failed commands from history and, via conf.d/sponge_privacy.fish,
|
||||
Sponge removes failed commands from history and, via `conf.d/sponge_privacy.fish`,
|
||||
also filters privacy-sensitive commands through three layers. Detection is
|
||||
heuristic — pattern- and variable-name-based — so this reduces the risk of a
|
||||
credential landing in persistent history; it is not a guarantee that no
|
||||
@@ -3586,14 +3586,14 @@ Commands matching any of these structural signatures are never recorded:
|
||||
- `sshpass`, `docker login -p`, `openssl -passin/-passout`
|
||||
|
||||
Layer 2 — Dynamic secret values (session globals, refreshed each login):
|
||||
On the first prompt, after secrets.fish has loaded, the literal values of
|
||||
On the first prompt, after `secrets.fish` has loaded, the literal values of
|
||||
all exported variables whose names suggest credentials (TOKEN, PASSWORD,
|
||||
SECRET, API_KEY, etc.) are collected, regex-escaped, and added as a
|
||||
SECRET, `API_KEY`, etc.) are collected, regex-escaped, and added as a
|
||||
session-scoped overlay. Because globals shadow universals in Fish, the
|
||||
combined list is what sponge sees. Rotating a token takes effect on the
|
||||
next login automatically.
|
||||
|
||||
Layer 3 — Per-command filter (sponge_filter_secrets):
|
||||
Layer 3 — Per-command filter (`sponge_filter_secrets`):
|
||||
Catches credentials in variables exported after login, such as tokens
|
||||
sourced from a project .env file mid-session.
|
||||
|
||||
@@ -3621,12 +3621,12 @@ their values), add name tokens — via `config-settings` → Sponge, or directly
|
||||
set -U -a __fish_sponge_extra_sensitive ACME_API VAULT_PW
|
||||
|
||||
Tokens are folded into the Layer 2 name match case-insensitively as substrings,
|
||||
so ACME_API also covers ACME_API_KEY. (The match uses `--entire` to return the
|
||||
so `ACME_API` also covers `ACME_API_KEY`. (The match uses `--entire` to return the
|
||||
full variable name, so partial-name tokens dereference the right value.)
|
||||
|
||||
The `config-settings` Sponge page also surfaces sponge's own tuning variables —
|
||||
sponge_delay, sponge_successful_exit_codes, sponge_purge_only_on_exit, and
|
||||
sponge_allow_previously_successful — so they can be changed without typing
|
||||
`sponge_delay`, `sponge_successful_exit_codes`, `sponge_purge_only_on_exit`, and
|
||||
`sponge_allow_previously_successful` — so they can be changed without typing
|
||||
variable names.
|
||||
|
||||
## Bundled Plugin Functionality
|
||||
@@ -3654,8 +3654,8 @@ The `fish_plugins` file at the config root:
|
||||
- [`jorgebucaran/fisher`](https://github.com/jorgebucaran/fisher) — Plugin manager itself
|
||||
- [`meaningful-ooo/sponge`](https://github.com/meaningful-ooo/sponge) — Remove failed commands from history
|
||||
|
||||
To update all Fisher-managed plugins, run `fisher update` or `fish-deps
|
||||
update` which calls it as its first step.
|
||||
To update all Fisher-managed plugins, run `fisher update` or
|
||||
`fish-deps update` which calls it as its first step.
|
||||
|
||||
---
|
||||
|
||||
@@ -3705,14 +3705,14 @@ Or use the interactive TUI — run `config-settings` and navigate to the
|
||||
"Dots Path" row (last row). Press Enter to type a new path, or ← / h to
|
||||
reset to the default.
|
||||
|
||||
config.fish sources local.fish from that directory on every interactive
|
||||
session. local.fish is responsible for sourcing its own secrets.fish:
|
||||
`config.fish` sources `local.fish` from that directory on every interactive
|
||||
session. `local.fish` is responsible for sourcing its own `secrets.fish`:
|
||||
|
||||
$__fish_user_dots_path/
|
||||
├── secrets.fish API keys, tokens, passwords, personal identifiers
|
||||
└── local.fish Machine-specific paths, env vars, and sourcing secrets
|
||||
|
||||
fish_variables (auto-managed by fish) is excluded from this repo via
|
||||
`fish_variables` (auto-managed by fish) is excluded from this repo via
|
||||
.gitignore. Do not commit it.
|
||||
|
||||
## secrets.fish
|
||||
@@ -3749,9 +3749,9 @@ wrong on any other system.
|
||||
abbr -a dcr 'docker context use my-remote-server'
|
||||
abbr -a dcw 'docker context use work-server'
|
||||
|
||||
local.fish is sourced at the end of config.fish with an existence check so
|
||||
`local.fish` is sourced at the end of `config.fish` with an existence check so
|
||||
the public config works cleanly on any machine without the private repo.
|
||||
local.fish in turn sources secrets.fish when it exists.
|
||||
`local.fish` in turn sources `secrets.fish` when it exists.
|
||||
|
||||
---
|
||||
|
||||
@@ -3823,7 +3823,7 @@ For other systems or building from source, see https://fishshell.com.
|
||||
## Enable or Disable Session Logging
|
||||
|
||||
Session logging is opt-in: it is off until you turn it on. To enable all
|
||||
logging and capture (scrollback, tmux/zellij pane logs, AUR helper wrappers,
|
||||
logging and capture (scrollback, `tmux`/`zellij` pane logs, AUR helper wrappers,
|
||||
Kitty watcher):
|
||||
|
||||
set -U __fish_config_op_logging on
|
||||
@@ -3843,12 +3843,12 @@ See C5 — Logging and Capture for the full component breakdown.
|
||||
|
||||
## Change or Disable the Greeting
|
||||
|
||||
This config suppresses the distro greeting (e.g. CachyOS fastfetch) by
|
||||
This config suppresses the distro greeting (e.g. CachyOS `fastfetch`) by
|
||||
default. To let the distro greeting through:
|
||||
|
||||
set -U __fish_config_op_greeting off
|
||||
|
||||
To set a custom greeting, define fish_greeting in your local.fish:
|
||||
To set a custom greeting, define `fish_greeting` in your `local.fish`:
|
||||
|
||||
# in $__fish_user_dots_path/local.fish
|
||||
function fish_greeting
|
||||
@@ -3868,7 +3868,7 @@ Machine-specific config goes in `$__fish_user_dots_path/local.fish` (defaults
|
||||
to `~/.config/.user-dots/fish/local.fish`). Secrets go in `secrets.fish` in
|
||||
the same directory.
|
||||
|
||||
If local.fish is not loading, verify the path:
|
||||
If `local.fish` is not loading, verify the path:
|
||||
|
||||
echo $__fish_user_dots_path
|
||||
test -f "$__fish_user_dots_path/local.fish"; and echo exists; or echo missing
|
||||
@@ -3900,7 +3900,7 @@ Fix: create a dedicated `conf.d/` file instead of appending to `config.fish`:
|
||||
# ~/.config/fish/conf.d/mytool.fish
|
||||
mytool init fish | source
|
||||
|
||||
All existing integrations (starship, zoxide, direnv) already have `conf.d/`
|
||||
All existing integrations (`starship`, `zoxide`, `direnv`) already have `conf.d/`
|
||||
files. See Return Sentinel for background.
|
||||
|
||||
## Missing Dependencies
|
||||
@@ -3937,7 +3937,7 @@ override it in `local.fish` (See Personalization):
|
||||
fish_default_key_bindings
|
||||
|
||||
This restores Emacs-style bindings without disabling the rest of C3
|
||||
(bang-bang, autopair, starship prompt, pager settings, etc.).
|
||||
(bang-bang, autopair, `starship` prompt, pager settings, etc.).
|
||||
|
||||
To disable the entire C3 category (Vi mode and all other key/environment
|
||||
overrides):
|
||||
@@ -3953,9 +3953,9 @@ This configuration groups its opinionated behaviors into six categories (C1–C6
|
||||
|
||||
Category Description
|
||||
──────────────────────────────────────────────────────────────────────────
|
||||
C1 Command Shadows — Wraps destructive commands (`rm`, `cp`) to be safe by default
|
||||
C1 Command Shadows — Wraps destructive commands (rm, cp) to be safe by default
|
||||
C2 Startup Side-Effects — Bootstraps Fisher, generates wrappers, auto-activates venvs
|
||||
C3 Overrides — Overrides `cd`, sets Vi mode, binds `<CR>` to `smart_enter`
|
||||
C3 Overrides — Overrides cd, sets Vi mode, binds <CR> to smart_enter
|
||||
C4 Integrations — Kitty/Wezterm integrations, starship hooks, fzf theme
|
||||
C5 Logging and Capture — Session logs, command duration
|
||||
C6 Greeting & First-Run UI — Custom startup banner
|
||||
@@ -4012,7 +4012,7 @@ its search box to jump straight to what you need.
|
||||
help config --man
|
||||
help config pkg --man
|
||||
|
||||
Opens the compiled docs/fish-config.1 directly via man -l, bypassing
|
||||
Opens the compiled `docs/fish-config.1` directly via man `-l`, bypassing
|
||||
the pager fallback chain. If a section keyword is given, the pager opens
|
||||
at the nearest matching heading. The symlink is created once on first
|
||||
run (like an install step) and MANPATH is set each session, enabling
|
||||
@@ -4020,7 +4020,7 @@ the standard invocation:
|
||||
|
||||
man fish-config
|
||||
|
||||
NOTE: fish-config (hyphen) is this config's man page. fish_config
|
||||
NOTE: fish-config (hyphen) is this config's man page. `fish_config`
|
||||
(underscore) is fish's built-in browser-based configuration tool —
|
||||
a completely separate command. Do not mix them up.
|
||||
|
||||
|
||||
@@ -18,16 +18,16 @@ CAUTION: This configuration is capable of silently recording terminal output and
|
||||
Component What it captures
|
||||
───────────────────────────────────────────────────────────────────────────
|
||||
Scrollback capture Terminal session output saved to:
|
||||
`~/.terminal_history/scrollback_YYYY-MM-DD_HH-MM-SS.log`
|
||||
~/.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`
|
||||
~/.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`
|
||||
~/.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`
|
||||
~/.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
|
||||
~/.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/`)
|
||||
@@ -58,7 +58,7 @@ 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
|
||||
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.
|
||||
@@ -93,7 +93,7 @@ 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.
|
||||
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.
|
||||
|
||||
@@ -12,9 +12,9 @@ category variable.
|
||||
|
||||
Category Description
|
||||
──────────────────────────────────────────────────────────────────────────
|
||||
C1 [Command Shadows](/08-components-reference/01-c1-command-shadows/) — Wraps destructive commands (`rm`, `cp`) to be safe by default
|
||||
C1 [Command Shadows](/08-components-reference/01-c1-command-shadows/) — Wraps destructive commands (rm, cp) to be safe by default
|
||||
C2 [Startup Side-Effects](/08-components-reference/02-c2-startup-side-effects/) — Bootstraps Fisher, generates wrappers, auto-activates venvs
|
||||
C3 [Overrides](/08-components-reference/03-c3-key-and-environment-overrides/) — Overrides `cd`, sets Vi mode, binds `<CR>` to `smart_enter`
|
||||
C3 [Overrides](/08-components-reference/03-c3-key-and-environment-overrides/) — Overrides cd, sets Vi mode, binds <CR> to smart_enter
|
||||
C4 [Integrations](/08-components-reference/04-c4-terminal-and-tool-integration/) — Kitty/Wezterm integrations, starship hooks, fzf theme
|
||||
C5 [Logging and Capture](/08-components-reference/05-c5-logging-and-capture/) — Session logs, command duration
|
||||
C6 [Greeting & First-Run UI](/08-components-reference/06-c6-greeting-and-first-run-ui/) — Custom startup banner
|
||||
|
||||
@@ -120,7 +120,7 @@ The `fish_plugins` file at the config root:
|
||||
- [`jorgebucaran/fisher`](https://github.com/jorgebucaran/fisher) — Plugin manager itself
|
||||
- [`meaningful-ooo/sponge`](https://github.com/meaningful-ooo/sponge) — Remove failed commands from history
|
||||
|
||||
To update all Fisher-managed plugins, run `fisher update` or `fish-deps
|
||||
update` which calls it as its first step.
|
||||
To update all Fisher-managed plugins, run `fisher update` or
|
||||
`fish-deps update` which calls it as its first step.
|
||||
|
||||
---
|
||||
|
||||
@@ -208,9 +208,9 @@ This configuration groups its opinionated behaviors into six categories (C1–C6
|
||||
|
||||
Category Description
|
||||
──────────────────────────────────────────────────────────────────────────
|
||||
C1 [Command Shadows](/08-components-reference/01-c1-command-shadows/) — Wraps destructive commands (`rm`, `cp`) to be safe by default
|
||||
C1 [Command Shadows](/08-components-reference/01-c1-command-shadows/) — Wraps destructive commands (rm, cp) to be safe by default
|
||||
C2 [Startup Side-Effects](/08-components-reference/02-c2-startup-side-effects/) — Bootstraps Fisher, generates wrappers, auto-activates venvs
|
||||
C3 [Overrides](/08-components-reference/03-c3-key-and-environment-overrides/) — Overrides `cd`, sets Vi mode, binds `<CR>` to `smart_enter`
|
||||
C3 [Overrides](/08-components-reference/03-c3-key-and-environment-overrides/) — Overrides cd, sets Vi mode, binds <CR> to smart_enter
|
||||
C4 [Integrations](/08-components-reference/04-c4-terminal-and-tool-integration/) — Kitty/Wezterm integrations, starship hooks, fzf theme
|
||||
C5 [Logging and Capture](/08-components-reference/05-c5-logging-and-capture/) — Session logs, command duration
|
||||
C6 [Greeting & First-Run UI](/08-components-reference/06-c6-greeting-and-first-run-ui/) — Custom startup banner
|
||||
|
||||
+15
-6
@@ -25,8 +25,13 @@ first if you've touched a header or a manual page.
|
||||
Function headers are read as plain text (by `config-help`, by `funcsave`,
|
||||
by anyone opening the `.fish` file), so they're authored without backticks
|
||||
— `-a/--all`, not `` `-a`/`--all` ``. `docs/codespans.py` puts the
|
||||
backticks on at render time, as the last step of `prettify()`, so only the
|
||||
site sees them.
|
||||
backticks on at render time, as the last step of `prettify()`.
|
||||
|
||||
`build_concat()` runs the same pass, so the man page and `config-help`
|
||||
mark code the way the site does rather than only where the SSOT happened
|
||||
to backtick something by hand. `config-help` then renders those spans
|
||||
bold and drops the delimiters, since a terminal pager would otherwise
|
||||
show them as literal punctuation.
|
||||
|
||||
It recognises flags, `$vars`, `SCREAMING_SNAKE` env vars, snake_case
|
||||
identifiers (`__fish_config_op_aliases`, `fish_greeting`), paths and
|
||||
@@ -41,10 +46,14 @@ Names that also read as English (`find`, `top`, `screen`) are listed in
|
||||
where position already proves they're a command. Add to that list rather
|
||||
than removing a rule if a wrap ever reads wrong.
|
||||
|
||||
Fenced blocks, existing code spans, headings, link targets, URLs,
|
||||
component markup, and `<FileTree>` bodies are never touched. Leaving a
|
||||
token alone is always the safe outcome, so every rule bails out when it
|
||||
isn't sure.
|
||||
Fenced blocks, indented blocks, existing code spans, headings, link
|
||||
targets, URLs, component markup, and `<FileTree>` bodies are never
|
||||
touched. Leaving a token alone is always the safe outcome, so every rule
|
||||
bails out when it isn't sure.
|
||||
|
||||
Indented blocks matter only to the concat — `prettify()` has already
|
||||
fenced them by the time the site is rendered — but there they are the
|
||||
table of contents and every section 5 entry, which must stay verbatim.
|
||||
|
||||
## llms.txt
|
||||
|
||||
|
||||
+70
-4
@@ -1401,13 +1401,79 @@ def test_codespans_vocabulary_comes_from_the_deps_catalog():
|
||||
assert "find" in vocab.full, "…but it still counts as a command-line opener"
|
||||
|
||||
|
||||
def test_codespans_is_site_only():
|
||||
"""The concat (man page, config-help) keeps the plain-text form."""
|
||||
def test_codespans_leaves_indented_code_blocks_alone():
|
||||
"""A four-space block is code, whatever it happens to contain.
|
||||
|
||||
The concat keeps the indented form pandoc wants, so unlike the site
|
||||
this pass meets real indented blocks -- the table of contents among
|
||||
them, which is nothing but a list of command names.
|
||||
"""
|
||||
body = "\n".join(
|
||||
[
|
||||
"Pick a viewer:",
|
||||
"",
|
||||
" 1. ov + bat section navigation",
|
||||
" 2. less plain text with --jump",
|
||||
"",
|
||||
"Then run config-help.",
|
||||
]
|
||||
)
|
||||
got = _spans(body).split("\n")
|
||||
assert got[2] == " 1. ov + bat section navigation", got[2]
|
||||
assert got[3] == " 2. less plain text with --jump", got[3]
|
||||
assert got[5] == "Then run `config-help`.", "prose after the block was skipped"
|
||||
|
||||
|
||||
def test_codespans_reach_the_man_page_pipeline():
|
||||
"""Prose is marked identically wherever it is rendered.
|
||||
|
||||
`build_concat` runs the same pass `build_site` does, so a token the
|
||||
site typesets as code is typeset as code in the man page and
|
||||
`config-help` too, instead of only where the SSOT hand-wrote a
|
||||
backtick.
|
||||
"""
|
||||
import build_manual
|
||||
|
||||
manual = Path(__file__).parent / "manual"
|
||||
text = build_manual.build_concat(manual)
|
||||
assert "`local.fish`" in text, "prose code spans never reached the concat"
|
||||
assert "`tmux`" in text, "a vocabulary command was not wrapped in the concat"
|
||||
|
||||
|
||||
def test_concat_code_spans_never_straddle_a_line():
|
||||
"""`config-help` pairs backticks one line at a time.
|
||||
|
||||
Its `string replace` filters run per line, so a span split across a
|
||||
line break -- ``run `fish-deps\\nupdate` `` -- leaves an unpaired
|
||||
backtick the pager then shows literally. Markdown is happy to wrap
|
||||
one, so nothing else catches this.
|
||||
"""
|
||||
import build_manual
|
||||
|
||||
text = build_manual.build_concat(Path(__file__).parent / "manual")
|
||||
assert "-r/--resume" in text, "sanity: the bare flag-pair form is what's authored"
|
||||
assert "`-r`/`--resume`" not in text, "code spans leaked into the man-page pipeline"
|
||||
odd = [
|
||||
(n, line)
|
||||
for n, line in enumerate(text.split("\n"), 1)
|
||||
if line.count("`") % 2
|
||||
]
|
||||
assert not odd, f"unpaired backtick, span wraps a line: {odd[:3]}"
|
||||
|
||||
|
||||
def test_concat_section_five_stays_verbatim():
|
||||
"""Section 5's entries are indented blocks, not prose.
|
||||
|
||||
They are generated from the `functions/*.fish` headers and pandoc sets
|
||||
them verbatim, so a backtick there would be a literal character on the
|
||||
page rather than markup.
|
||||
"""
|
||||
import build_manual
|
||||
|
||||
text = build_manual.build_concat(Path(__file__).parent / "manual")
|
||||
body = text.split("\n# 5. ", 1)[1].split("\n# 6. ", 1)[0]
|
||||
offenders = [
|
||||
line for line in body.split("\n") if line.startswith(" ") and "`" in line
|
||||
]
|
||||
assert not offenders, f"backticks inside verbatim entries: {offenders[:3]}"
|
||||
|
||||
|
||||
TESTS = [v for k, v in sorted(globals().items()) if k.startswith("test_")]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Returns the current value of a named variable in the specified scope by
|
||||
# parsing `set --show` output. Outputs "on", "off", or "DEFAULT" (when
|
||||
# parsing set --show output. Outputs "on", "off", or "DEFAULT" (when
|
||||
# the variable is not set in that scope). Scope "session" maps to "global"
|
||||
# in fish's internal terminology.
|
||||
#
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
# DESCRIPTION
|
||||
# Reads a single keypress directly from the controlling terminal in raw
|
||||
# mode and echoes a normalized token naming the key. Bypasses fish's
|
||||
# `read` builtin, whose interactive line editor swallows Tab and arrow
|
||||
# keys (and prints a `read> ` prompt) — none of which is usable for a TUI.
|
||||
# read builtin, whose interactive line editor swallows Tab and arrow
|
||||
# keys (and prints a "read> " prompt) — none of which is usable for a TUI.
|
||||
#
|
||||
# The terminal is put into raw, no-echo mode with a 0.1s inter-byte timer
|
||||
# (`stty raw -echo min 1 time 1`) so a multi-byte escape sequence (e.g.
|
||||
# (stty raw -echo min 1 time 1) so a multi-byte escape sequence (e.g.
|
||||
# an arrow key, ESC [ A) is captured in one read while a lone key returns
|
||||
# promptly. Original terminal settings are always restored before return.
|
||||
#
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
# Looks up "<identity>:<site>" (site defaults to the empty/unnamed site)
|
||||
# in the generated component registry. No registry entry (unclassified,
|
||||
# or a doc header with no # COMPONENT section) resolves to enabled --
|
||||
# the same fail-open default as an explicit `always/on` tag, so
|
||||
# the same fail-open default as an explicit always/on tag, so
|
||||
# user-authored and third-party functions that never call this guard in
|
||||
# the first place are unaffected, and one that somehow does is never
|
||||
# silently broken by a missing header. A found `always/off` tag
|
||||
# disables unconditionally; a found `always/on` tag enables
|
||||
# silently broken by a missing header. A found always/off tag
|
||||
# disables unconditionally; a found always/on tag enables
|
||||
# unconditionally, short-circuiting before any other tagged
|
||||
# sub-category is evaluated. Otherwise every tagged sub-category must
|
||||
# pass the cascade (AND semantics).
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# __fish_user_dots_link
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Manages the git-ignored `user-dots` convenience symlink in the fish config
|
||||
# Manages the git-ignored user-dots convenience symlink in the fish config
|
||||
# directory ($__fish_config_dir/user-dots), pointing it at the resolved
|
||||
# $__fish_user_dots_path so the private overlay can be browsed from
|
||||
# ~/.config/fish/.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# __jobrunner_sessions [<tool>]
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Parses `tmux list-sessions` or `screen -ls` into machine-readable rows,
|
||||
# Parses tmux list-sessions or screen -ls into machine-readable rows,
|
||||
# one per active session: name, PID, state, and start time separated by tabs.
|
||||
# Shared by jobrunner and its completions so both agree on what a session is
|
||||
# named. Prints nothing when no sessions exist.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Succeeds (returns 0) when the top-level kitty.conf contains an active
|
||||
# (non-commented) `watcher` directive — whether the fish-config managed one or
|
||||
# (non-commented) watcher directive — whether the fish-config managed one or
|
||||
# a user's own. Used to suppress the setup reminder and to inform status.
|
||||
#
|
||||
# EXIT STATUS
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Appends any patterns not already covered by the project's .gitignore.
|
||||
# Uses `git check-ignore` for accurate rule matching (catches wildcards
|
||||
# Uses git check-ignore for accurate rule matching (catches wildcards
|
||||
# and parent-dir globs). Falls back to a plain string search when the
|
||||
# root is not a git repository. Leading `/` is stripped from each pattern
|
||||
# root is not a git repository. Leading / is stripped from each pattern
|
||||
# before the path-based check so root-anchored patterns (e.g. /AGENTS.md)
|
||||
# are matched correctly.
|
||||
#
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# DESCRIPTION
|
||||
# Copies the canonical version-bump script and git hook shims from
|
||||
# fish-config's scripts/agents-tools/ into <agents_dir>/.agents-tools/,
|
||||
# refreshing them when the shipped `agents-tools-version:` marker is newer
|
||||
# refreshing them when the shipped agents-tools-version: marker is newer
|
||||
# than the installed copy. Files are made executable. Idempotent: prints
|
||||
# nothing when the installed tooling is already current, or a short summary
|
||||
# line when it installed or updated the tooling.
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
# conveniences (e.g. backs one wrapper
|
||||
# function) that only matter if you already
|
||||
# use that specific tool. Skipped by
|
||||
# `fish-deps install`/`sync` unless
|
||||
# `--optional` (or `--all`) is passed.
|
||||
# fish-deps install/sync unless
|
||||
# --optional (or --all) is passed.
|
||||
# term Terminal Emulators — GPU-accelerated terminal emulators
|
||||
# (kitty, wezterm) that only matter if one
|
||||
# of them is your actual terminal. Skipped
|
||||
# by `fish-deps install`/`sync` unless
|
||||
# `--terminals` (or `--all`) is passed.
|
||||
# by fish-deps install/sync unless
|
||||
# --terminals (or --all) is passed.
|
||||
# int Integrations — opt-in third-party services requiring
|
||||
# their own account/setup (wakatime,
|
||||
# tailscale).
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# by a desktop file manager (Dolphin, Nautilus, GNOME Videos, ...) in the
|
||||
# freedesktop thumbnail cache and renders it via _fzf_preview_image if
|
||||
# found. Otherwise falls back to ffprobe-formatted metadata (duration,
|
||||
# codec, resolution, tags) when ffprobe is installed, or plain `file`
|
||||
# codec, resolution, tags) when ffprobe is installed, or plain file
|
||||
# output as a last resort. Neither the thumbnail cache lookup nor ffprobe
|
||||
# are tracked in fish-deps: both are best-effort, matching how the
|
||||
# image-preview tool chain (kitten/chafa/viu/timg) is already handled.
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
# modification time, so the most recently written logs are kept — actively
|
||||
# appended logs (e.g. a tmux pipe-pane stream) survive.
|
||||
#
|
||||
# Uses `command ls`/`command rm` to bypass the C1 shadows: the bare `ls` is
|
||||
# Uses command ls/command rm to bypass the C1 shadows: the bare ls is
|
||||
# the eza wrapper, which injects OSC-8 hyperlink escapes into paths, and the
|
||||
# bare `rm` is the trash wrapper. The glob is expanded via `set` first so a
|
||||
# bare rm is the trash wrapper. The glob is expanded via set first so a
|
||||
# no-match (empty dir / first run) yields an empty list instead of a hard
|
||||
# "No matches for wildcard" error.
|
||||
#
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# Captures the current Zellij pane's scrollback to a timestamped log in
|
||||
# SCROLLBACK_HISTORY_DIR (default ~/.terminal_history). Zellij has no live
|
||||
# output-streaming facility like tmux's pipe-pane, so this performs a one-shot
|
||||
# `zellij action dump-screen --full` — intended to run on shell exit. Old
|
||||
# zellij action dump-screen --full — intended to run on shell exit. Old
|
||||
# zellij_*.log files are pruned via _prune_terminal_logs to stay within
|
||||
# SCROLLBACK_HISTORY_MAX_FILES.
|
||||
#
|
||||
|
||||
+36
-10
@@ -22,7 +22,7 @@
|
||||
# in the default browser via xdg-open — deep links to a section aren't
|
||||
# supported there, so if a keyword is given a note points you to the site'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
|
||||
# (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.
|
||||
#
|
||||
@@ -52,9 +52,9 @@
|
||||
# config-help pkg --man
|
||||
#
|
||||
# NOTES
|
||||
# The preferred invocation is `help config [...]` — this function is
|
||||
# The preferred invocation is help config [...] — this function is
|
||||
# registered as a handler in the help wrapper so that syntax works
|
||||
# transparently. Direct `config-help` calls are also valid.
|
||||
# transparently. Direct config-help calls are also valid.
|
||||
function config-help --description 'Open the offline fish shell configuration manual'
|
||||
set -l doc_file "$__fish_config_dir/docs/fish-config.md"
|
||||
set -l idx_file "$__fish_config_dir/docs/fish-config.index"
|
||||
@@ -247,6 +247,22 @@ function config-help --description 'Open the offline fish shell configuration ma
|
||||
set -l nav_hint \
|
||||
" \033[2mNAVIGATION: [ Space=next section ^=prev Alt+u=sections /=search q=quit ]\033[0m"
|
||||
|
||||
# ── Inline code spans ────────────────────────────────────────
|
||||
# The document carries backticks for pandoc and the docs site, but
|
||||
# nothing in this chain consumes them: bat dims the delimiters and
|
||||
# leaves the content the same colour as the surrounding prose, so
|
||||
# they arrive as literal punctuation. Render each span bold instead.
|
||||
#
|
||||
# Two forms are matched. After bat, every backtick carries its own
|
||||
# SGR sequence, and a fence survives because it puts three of them
|
||||
# inside one sequence. On raw Markdown a fence survives because it
|
||||
# offers no non-backtick content to capture. Both substitutions are
|
||||
# line-preserving, so the tail-slice below still lands on the
|
||||
# requested section.
|
||||
set -l span_ansi '\e\[[0-9;]*m`\e\[0m(.*?)\e\[[0-9;]*m`\e\[0m'
|
||||
set -l span_raw '`([^`]+)`'
|
||||
set -l span_bold (printf '\e[1m$1\e[0m')
|
||||
|
||||
# ── Viewer fallback chain ────────────────────────────────────
|
||||
# When jumping to a section, slice the file from start_line so ov
|
||||
# opens with that section at the top without needing --pattern.
|
||||
@@ -261,12 +277,14 @@ function config-help --description 'Open the offline fish shell configuration ma
|
||||
begin
|
||||
printf "$nav_hint\n"
|
||||
bat --color=always --style=plain --language=markdown "$doc_file" \
|
||||
| tail -n +$start_line
|
||||
| tail -n +$start_line \
|
||||
| string replace -ra $span_ansi $span_bold
|
||||
end | ov $ov_args
|
||||
else
|
||||
begin
|
||||
printf "$nav_hint\n"
|
||||
bat --color=always --style=plain --language=markdown "$doc_file"
|
||||
bat --color=always --style=plain --language=markdown "$doc_file" \
|
||||
| string replace -ra $span_ansi $span_bold
|
||||
end | ov $ov_args
|
||||
end
|
||||
|
||||
@@ -279,12 +297,13 @@ function config-help --description 'Open the offline fish shell configuration ma
|
||||
if test $start_line -gt 1
|
||||
begin
|
||||
printf "$nav_hint\n"
|
||||
tail -n +$start_line "$doc_file"
|
||||
tail -n +$start_line "$doc_file" \
|
||||
| string replace -ra $span_raw $span_bold
|
||||
end | ov $ov_args
|
||||
else
|
||||
begin
|
||||
printf "$nav_hint\n"
|
||||
cat "$doc_file"
|
||||
string replace -ra $span_raw $span_bold <"$doc_file"
|
||||
end | ov $ov_args
|
||||
end
|
||||
|
||||
@@ -295,16 +314,23 @@ function config-help --description 'Open the offline fish shell configuration ma
|
||||
echo "note: bat pager — use / to search for your section" >&2
|
||||
set_color normal
|
||||
end
|
||||
bat --language=markdown --paging=always "$doc_file"
|
||||
# bat owns the pager here, so the spans are flattened on the way
|
||||
# in rather than styled on the way out — bat would escape any
|
||||
# SGR sequence handed to it as input.
|
||||
string replace -ra $span_raw '$1' <"$doc_file" \
|
||||
| bat --language=markdown --paging=always
|
||||
|
||||
# Pre-compiled man page (generated by CI after merge).
|
||||
# pandoc consumed the backticks when it built this, so there is
|
||||
# nothing to strip.
|
||||
else if test -f "$man_file"
|
||||
man -l "$man_file"
|
||||
|
||||
else if type -q less
|
||||
less +"$start_line" "$doc_file"
|
||||
string replace -ra $span_raw $span_bold <"$doc_file" \
|
||||
| less -R +"$start_line"
|
||||
|
||||
else
|
||||
cat "$doc_file"
|
||||
string replace -ra $span_raw $span_bold <"$doc_file"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# Pulls the latest fish shell configuration from the upstream repository
|
||||
# into ~/.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.
|
||||
# short summary of changed files; run exec fish to reload the shell.
|
||||
#
|
||||
# ARGUMENTS
|
||||
# -h, --help Show this help message and exit
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
# Optional btop, dust, duf, prettyping, go, lazygit,
|
||||
# lazydocker, docker, yt-dlp, screen — single-purpose
|
||||
# wrapper conveniences that only matter if you
|
||||
# already use that tool; skipped by `install`/`sync`
|
||||
# already use that tool; skipped by install/sync
|
||||
# unless --optional (or --all) is passed
|
||||
# Terminal Emulators kitty, wezterm — only matter if one of them is
|
||||
# your actual terminal; skipped by `install`/`sync`
|
||||
# your actual terminal; skipped by install/sync
|
||||
# unless --terminals (or --all) is passed
|
||||
# Integrations wakatime, tailscale
|
||||
#
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
# 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 — it survives closing the shell, and `attach`
|
||||
# can return to later — 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.
|
||||
# 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.
|
||||
#
|
||||
# SUBCOMMANDS
|
||||
# run, -r, --run [-n <name>] <cmd> Start a new background job
|
||||
@@ -49,7 +49,7 @@
|
||||
# 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 'a | b'`.
|
||||
# jobrunner run sync fish -c 'a | b'.
|
||||
function jobrunner --description 'Manage detached background jobs with tmux or GNU screen'
|
||||
set -l c_head (set_color --bold cyan)
|
||||
set -l c_cmd (set_color --bold)
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Manages the fish-config Kitty scrollback watcher that powers C5 logging.
|
||||
# `install` symlinks the canonical watcher into the Kitty config dir (so it
|
||||
# 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`
|
||||
# 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
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
# DESCRIPTION
|
||||
# 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
|
||||
# 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,
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
# 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
|
||||
# function is only defined when aichat is installed. Run qc --help for
|
||||
# aichat's full flag reference with the command name rewritten to qc.
|
||||
#
|
||||
# ARGUMENTS
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
# DESCRIPTION
|
||||
# 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/`.
|
||||
# plain-text databases bundled in data/words/.
|
||||
#
|
||||
# Modifiers like `--separator` and `--case` are evaluated sequentially and
|
||||
# Modifiers like --separator and --case are evaluated sequentially and
|
||||
# apply only to the components that follow them.
|
||||
#
|
||||
# Supported Components:
|
||||
@@ -35,7 +35,7 @@
|
||||
# rand_string literal=TEST --separator=underscore verb noun
|
||||
#
|
||||
# NOTES
|
||||
# Falls back to `random choice` if GNU `shuf` is missing, but `shuf` is
|
||||
# Falls back to random choice if GNU shuf is missing, but shuf is
|
||||
# much faster for files with >1000 lines.
|
||||
function rand_string --description 'Generate random, memorable strings from curated word databases'
|
||||
set -l c_head (set_color --bold cyan)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# repo-open --help
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Opens the web page for the current repository's `origin` remote in a
|
||||
# Opens the web page for the current repository's origin remote in a
|
||||
# browser (via open-url). Deep-links to the current branch when it exists
|
||||
# on the remote, falling back to the remote's default branch (main/master)
|
||||
# otherwise, and to the current sub-directory when invoked below the repo
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#
|
||||
# NOTES
|
||||
# The exit builtin is wired to smart_exit for interactive sessions. Typing
|
||||
# `exit` or Ctrl+D behaves identically to calling smart_exit directly.
|
||||
# exit or Ctrl+D behaves identically to calling smart_exit directly.
|
||||
function smart_exit --description 'Capture colorized scrollback before exiting, with pruning and safe overrides'
|
||||
# Opinionated guard (C3): exit plainly when overrides are disabled.
|
||||
# This composes with Task #4's __fish_config_enable_logging, which will
|
||||
|
||||
Reference in New Issue
Block a user