Commit Graph
229 Commits
Author SHA1 Message Date
rootiest 040c98c0a7 fix(config-settings,docs): address final whole-branch review findings
Bundled fix wave for six findings from the sub-category-granularity
whole-branch review:

- config-settings: reset in_subcat on Tab/Shift-Tab so up/down keep
  routing to cur_row instead of freezing on the Sponge/Paths pages
  after a drill-down
- verify-manual: _parsed_components() now delegates to
  generate_component_registry.collect_components() instead of a
  lossy dict.update() merge, closing a taxonomy-check blind spot on
  identity collisions
- verify-manual: add test_committed_registry_matches_headers to
  catch the committed registry drifting from current # COMPONENT
  headers
- build-docs workflow: trigger on conf.d/** and config.fish edits,
  not just functions/**
- __config_settings_draw_subcat: show (Universal)/(Session) in the
  drill-down title so the persistence scope is visible before toggling
- __config_settings_draw / config-settings: mention the Enter
  sub-category drill-down in the on-screen hint and --help text
- generate_component_registry: send the "wrote ..." progress line to
  stderr so it no longer corrupts --concat's stdout output
2026-08-18 16:46:46 -04:00
rootiest 3c0bba1737 fix(config-settings): fix silent varname resolution failure and stale panel_h in sub-category drill-down
Two bugs invisible to single-frame rendering, only reachable via the
interactive event loop:

- right/l and left/h resolved the sub-category variable name with
  "$toggle_vars[(math ...)]"_(...) inside a quoted string -- fish
  cannot expand a command-substitution index there ("Invalid index
  value"), so the set never ran and varname silently kept the parent
  category variable. Every arrow-key press on a sub-category row
  toggled the parent category instead. Fixed by hoisting the category
  variable into a plain local first, the same technique the down/j
  case already used for its page index.

- __cs_dispatch_draw left panel_h fixed at 16 regardless of what it
  actually drew, but the new sub-category page is n+7 lines (9-13,
  always < 16). Every redraw/cleanup erase computed its height from
  the stale constant, erasing too many rows and corrupting whatever
  was above the panel. Fixed by having the dispatcher record the
  actual printed height into panel_h after every draw, including
  resetting it back to 16 on the value pages even when in_subcat is
  stale from a Tab away without an intervening Escape.
2026-08-18 03:22:19 -04:00
rootiest 489e3cc7de feat(config-settings): render and toggle sub-categories in the drill-down page
Adds __config_settings_draw_subcat.fish, rendering a category's own
toggle plus its sub-category rows, sized dynamically from
__config_settings_subcats instead of the fixed 6-row category layout.
Wires the real per-category row count into config-settings.fish's
up/down handling (replacing Task 17's stub) and adds the
hyphen-to-underscore sub-category variable resolution to the
left/right toggle handlers, mirroring the translation the guard
function already applies.

Two box-drawing bugs surfaced while adapting the design doc's draft to
the real static sub-category data and were fixed rather than
transcribed: the title-dashes offset was off by 5, and several real
sub-category labels/descriptions (e.g. "Notifications", 13 chars;
several descriptions past 30 chars) exceed the narrower width tiers'
fixed field widths, so both fields are now defensively truncated
before padding to keep every row exactly iw+2 wide regardless of
content length.
2026-08-18 03:11:17 -04:00
rootiest 7ad3b90503 feat(config-settings): add sub-category drill-down navigation state 2026-08-18 03:01:22 -04:00
rootiest 6b2d3bf491 refactor(config): migrate multi-category files and config.fish to named sites
Adds multi-site `# COMPONENT` headers and converts every guard call site in
conf.d/tricks.fish, conf.d/abbr.fish, functions/smart_exit.fish,
conf.d/yay-wrapper.fish, conf.d/paru-wrapper.fish, conf.d/wakatime.fish,
conf.d/first_run.fish, and config.fish (9 sites across 3 categories) to the
self-identifying `(status current-function|basename) <site>` calling
convention. Regenerates conf.d/__fish_config_op_registry.fish.
2026-08-18 02:39:47 -04:00
rootiest c3a2e35465 refactor(config): migrate C5 logging call sites to self-identifying guard 2026-08-18 02:22:31 -04:00
rootiest e02919de21 fix(config): translate hyphens to underscores in sub-category guard variable names
__fish_config_op_enabled built the sub-category override variable name by
concatenating the tag's slug verbatim, e.g. __fish_config_op_integrations_window-mgmt.
Fish variable names cannot contain hyphens, so any hyphenated sub-category
slug (14 of the 24 in the taxonomy) silently could never be overridden --
an unset such variable safely fell through via set -q, but attempting to
set it always errored with "invalid variable name", masking the defect
since no prior smoke test exercised an explicit sub-category-level toggle.
The registry tag itself (as authored in # COMPONENT headers and the
taxonomy docs) stays hyphenated; only the derived fish variable name is
translated.
2026-08-17 21:53:48 -04:00
rootiest 516b2ba26c refactor(config): migrate C4 integrations call sites to self-identifying guard 2026-08-17 21:49:45 -04:00
rootiest a981fa7f0a refactor(config): migrate C3 overrides call sites to self-identifying guard 2026-08-17 21:37:35 -04:00
rootiest 760b8e68fd refactor(config): migrate C2 autoexec call sites to self-identifying guard 2026-08-17 21:23:12 -04:00
rootiest 04fd832974 refactor(config): migrate C1 aliases call sites to self-identifying guard 2026-08-17 21:12:56 -04:00
rootiest d2e07effc1 feat(config): add manual registry-rebuild command 2026-08-17 20:46:55 -04:00
rootiest 9642cd69db feat(config): rewrite guard as self-identifying with C0 and site support 2026-08-17 20:23:49 -04:00
rootiest 7fa5ca2568 feat(config): add component registry lookup helper 2026-08-17 20:19:42 -04:00
rootiest 94a4fbe45f feat(config): add sub-category cascade evaluator 2026-08-17 20:15:29 -04:00
rootiest c17f6663db feat(deps): add Optional/Terminal Emulator tiers, fix docker prompt hang and ov install path
Reworks fish-deps' dependency classification from three tiers to five:
Required, Recommended, Optional, Terminal Emulators, and Integrations.

- Add an Optional tier for single-purpose wrapper conveniences that only
  matter if you already use that specific tool (btop, dust, duf,
  prettyping, go, lazygit, lazydocker, docker, yt-dlp, screen). Skipped by
  `fish-deps install`/`sync` by default.
- Split kitty/wezterm into their own Terminal Emulators tier, since only
  the one matching $TERM is ever relevant to a given user.
- Add --optional, --terminals, and --all flags to `install`/`sync` to
  opt back into the skipped tiers, with a summary of how many were
  skipped and which flag restores them.
- Fix `_fish_deps_status` marking missing Integrations as critical (red)
  the same as Required — only Required is red now; Recommended stays
  yellow, everything else renders as a neutral dim note.

Also fixes two bugs surfaced during dependency testing on a fresh
install:

- `fish_right_prompt` called `docker context show` on every prompt with
  no `type -q docker` guard, unlike every other optional integration in
  this config — on a system without docker this printed a visible
  "Unknown command: docker" block on every single prompt render. Added
  the missing guard, and hardened the `ld` wrapper with explicit
  docker/lazydocker presence checks.
- `ov`'s catalog entry offered `cargo install ov` as its preferred
  install method, but crates.io's `ov` is an unrelated crate, not the
  noborus/ov pager — cargo would silently install the wrong package.
  Removed the cargo path; `ov` now prefers `go install
  github.com/noborus/ov@latest` (ahead of the system PM) when go is
  available, since not all distros package `ov` in their base repos,
  and falls back to the system PM otherwise.
2026-08-14 16:42:37 -04:00
rootiest adbcd1d3c0 fix(mv): bring header and completions up to repo conventions
The EXIT STATUS block used a single space before the ">0" row's
description, which falls below the doc pipeline's 2-space column
threshold and silently degrades the rendered site page from a table
(like rm's) to a plain indented block. Pad it to match. Also strip
trailing whitespace from two DESCRIPTION lines and add --wraps='mv'
so fish inherits real mv's completions, matching the bash/top wrapper
convention.
2026-08-14 16:02:07 -04:00
rootiest 80d4f5d9fa feat(mv): wrap the mv command to facilitate moving a directory up the tree 2026-08-14 15:24:40 -04:00
rootiest 742fd7941d docs: use markdown tables for abbreviations
Generates actual markdown tables instead of indented text blocks to ensure MDX/Starlight correctly renders abbreviations.
2026-08-06 15:04:06 -04:00
rootiest cb74cd84e2 fix: change jobrunner auto-naming to adjective-animal 2026-08-02 05:47:29 -04:00
rootiest 89fdfc8e72 refactor: use -n flag for explicit jobrunner names 2026-08-02 05:45:35 -04:00
rootiest 0e9c3b4b27 feat: implement jobrunner auto-naming fallback 2026-08-02 05:41:48 -04:00
rootiest d5535a38ad feat: add verb dictionary and preserve literal string casing in rand_string 2026-08-02 05:37:06 -04:00
rootiest 01553b71fd refactor: drop __ prefix and add -h flag to rand_string 2026-08-02 05:32:33 -04:00
rootiest ffff95f3b9 feat: implement __rand_string generator and update jobrunner to use tmux 2026-08-02 05:21:29 -04:00
rootiest 674a50ea05 feat(jobrunner): add named background job manager backed by GNU screen
Adds jobrunner (short alias jr) for running, listing, inspecting,
re-attaching to, and terminating detached background tasks. Unlike bkg
and detach, which discard output, a jobrunner job keeps a live terminal
that survives closing the shell and can be restored later with attach.

Includes the __jobrunner_sessions parser shared by the function and its
completions, dynamic job-name completions, and screen in the fish-deps
catalog.
2026-08-02 04:40:07 -04:00
rootiest 5c54ede483 refactor(deps): demote zoxide to recommended tier 2026-07-28 03:09:08 -04:00
rootiest 94e4e0dfab feat(function): add a --resume flag to the agy function
The agy tool uses -c and --continue natively. It does not recognize -r
or --resume. This commit allows -r and --resume to be used by
translating them to -c and --continue respectively.
2026-07-27 21:28:40 -04:00
rootiest d2f3da4a23 docs(functions): add category metadata to undocumented functions 2026-07-27 20:04:37 -04:00
rootiest f2874bf890 feat(logging)!: make C5 session logging opt-in
Session logging is the one opinionated category that writes a persistent
record of terminal output to disk, and those logs can contain secrets.
Silent-by-default is the wrong posture for it, so C5 now defaults to off:
__fish_config_op_logging must be set to an explicit truthy value to enable
capture, and the master switch cannot enable it on its own.

Implemented as a single special case in __fish_config_op_enabled, so all
five capture components, the sentinel file, the paru/yay wrappers, the
Kitty watcher, and the config-settings TUI pick it up with no other code
changes. The existing startup sync in conf.d/logging-events.fish
reconciles the sentinel and removes the generated wrappers on the first
shell after upgrading.

BREAKING CHANGE: users relying on the previous default must now run
`set -U __fish_config_op_logging on`. Existing logs in ~/.terminal_history
are left untouched.
2026-07-27 19:17:05 -04:00
rootiest ba6146c343 docs: update documentation URL to fish.rootiest.fyi
Replaced all instances of fish-config.rootiest.fyi with the new domain fish.rootiest.fyi across the codebase.
2026-07-27 01:37:34 -04:00
rootiest e651566e14 docs(functions): split RETURNS into EXIT STATUS and stdout RETURNS
RETURNS previously conflated fish's $status exit code with genuine
stdout/printed output, e.g. rm listing "0/1" as if they were print
values rather than exit codes. Rename RETURNS to EXIT STATUS across
all 83 documented functions, and reintroduce RETURNS as a distinct
label reserved for the 15 functions that actually print to stdout.

Update build-manual.py's ENTRY_HEADS to render Exit Status before
Returns, manualtools.py's SECTIONS constant, and AGENTS.md's label
order and label-usage guidance to match. Add two verify-manual.py
regression tests: EXIT STATUS bodies must never contain stray
stdout/printed language, and Returns: must always render after
Exit Status: when both are present. Regenerate docs/fish-config.md.
2026-07-26 16:41:57 -04:00
rootiest ab030d7ec0 docs: update site title and canonical URL
Offline docs drift reminder / remind (push) Successful in 16s
Generate documentation / build-docs (push) Successful in 3m14s
Rename the Starlight site to "Rootiest Fish Config" and switch its
canonical URL from the Cloudflare Pages subdomain to
fish-config.rootiest.fyi (now aliased in Cloudflare). Updates all
references in README, config-help, open-url, and the manual, and
regenerates the concat/man-page artifacts to match.
2026-07-26 15:34:08 -04:00
rootiest 4197e7faec Merge remote-tracking branch 'origin/main' into docs-option-tables
# Conflicts:
#	docs/fish-config.md
#	docs/manual/05-functions/14-miscellaneous.md
2026-07-26 04:37:55 -04:00
rootiest daf81bf0a4 docs(functions): publish dops and fzf-update
Both carry complete headers and are user-facing, but had no # CATEGORY
so generated no entry. Surfaced by the new verify-manual.py warning,
which is exactly what it is there for.

The 8 that still warn are correct exclusions: fast is a self-described
placeholder, the rest are bundled plugin and prompt internals.
2026-07-26 04:16:31 -04:00
rootiest a65e05b661 feat(docs): generate Section 5 from function comment headers
The man-page-style comment header above each function in functions/*.fish
becomes the SSOT for that function's documentation. Writing a new function
and documenting it are now the same act.

- manualtools.parse_functions() parses every header carrying a # CATEGORY;
  absence of one is the opt-in, keeping bundled-plugin and prompt internals
  out of the manual with no exclusion list to maintain.
- build-manual.py generates entries for both --concat and --site, with
  **Dependencies:** rendered as links and a **Used by:** reverse index
  computed in one pass. Cross-category links are the navigation win.
- docs/manual/05-functions/*.md reduced to frontmatter-only stubs. Every
  intro measured zero words, so the category files were pure entry
  containers; ordering, titles, and helpKeywords routing are untouched.
- _first_sentence() unwraps the leading hard-wrapped paragraph and skips
  the whole Synopsis block, not just its label line. Site cards no longer
  truncate mid-clause or show a synopsis as their description.

Verification, per the design spec:
- test_concat_roundtrips_original scoped to sections 0-4 and 6-11. It
  guarded a format migration; this is a content migration.
- replaced by structural checks: one entry per categorised function, the
  required sections present, every category resolving to a stub with no
  stub empty, and every declared dependency resolving to a real function
  or a type -q-guarded binary.
- public functions lacking # CATEGORY warn rather than fail, so a new
  user-facing function going undocumented stays visible in CI.

24/24 checks pass. 94 entries generated from 94 parsed headers.

Also drops a stale claim from open-url's NOTES: config-help --html calls
xdg-open directly and has never called open-url.
2026-07-26 04:12:48 -04:00
rootiest 00f70e8558 docs(functions): merge remaining manual-only facts into headers
Word-level diff of every manual entry against its generated counterpart
surfaced 546 tokens present in the manual and absent from the header —
losses reconcile.py missed, because it compared description length and
these headers are longer overall thanks to ARGUMENTS/RETURNS.

Merged the substantive ones (546 -> 202 residual tokens, the remainder
being synonym drift). Notable real fixes:

- git-clean: -f/--force was missing from ARGUMENTS entirely
- pkg: per-package-manager query table
- qc: cli-role rationale, role paths, --role passthrough
- config-help: site URL, xdg-open, man page path, case-insensitivity
- agents-init: idempotency, .gitignore paths, upstream pull, wrapper callers
- smart_exit: exit-builtin wiring note, $SCROLLBACK_HISTORY_DIR

The manual's claim that claude/agy pass `agents-init --agents` is stale;
both pass `--quiet` (full setup). Header wins, manual dropped.
2026-07-26 04:02:57 -04:00
rootiest 8d6ca1797a docs(functions): merge remaining manual prose into function headers
Folds the last seven manual entries whose description exceeded their header
back into the source-of-truth comment blocks: config-settings (Sponge/Paths
page detail, list-value parsing, width tiers, navigation keys), fish-deps
(install-method priority, dependency tiers), logs (fzf keybindings, ov
viewer behavior), kitty-logging (symlink wording, C5 inert-vs-uninstalled),
config-update (exec fish reload), yt-dlp (C1 guard). Drops duplicate example
lines left by the previous merge.
2026-07-26 03:52:02 -04:00
rootiest 02c46ebea7 docs(functions): merge manual-only examples and notes into headers
Folds the examples Section 5 carried but the headers did not into each
function's `# EXAMPLE`, and moves the three lines that only looked like
examples -- the two typo-abbreviation notes and rm's /usr/bin/rm fallback --
into `# NOTES`, the label already in use.

Also corrects gi's synopsis, which omitted -l, and documents yt-dlp's
--no-embed-thumbnail in `# ARGUMENTS`.
2026-07-26 03:47:25 -04:00
rootiest 5f4306b6ca docs(functions): add man-page headers to branch, fc, gitup, sudo-toggle
These four were the only documented functions with no comment header,
carrying just a one-line description. Content is merged from their manual
entries plus what the implementations actually do (fc's vi fallback and
empty-buffer abort, sudo-toggle's credential-cache clear), so the headers
are a superset of Section 5 rather than a copy of it.
2026-07-26 03:45:03 -04:00
rootiest 4c51ef7a33 docs(functions): add # CATEGORY to documented function headers
Records each documented function's manual category in its own header, so
Section 5 can later be generated from source instead of hand-maintained
alongside it. Values reproduce the current grouping in
docs/manual/05-functions/ exactly; no documentation changes meaning here.

Four functions are skipped because they have no header at all yet
(branch, fc, gitup, sudo-toggle); they get one in the merge that follows.
2026-07-26 03:44:03 -04:00
rootiest 073dbd9b14 docs: remove hard-coded URL mention from config-update documentation 2026-07-26 01:15:45 -04:00
rootiest 16e969ee15 chore(docs): retire wiki, chunked HTML, and split-manual pipeline
docs/manual/** plus the Astro Starlight site (https://fish-config-docs.pages.dev/)
replace the Gitea wiki (docs/wiki/) and chunked offline HTML (docs/html/,
docs/html-style.html) as the published documentation surface. Retires the
now-unused docs/split-wiki.py and docs/split-manual.py generators alongside them.

- config-help --html now opens the published site root instead of resolving
  a local sitemap anchor; when a keyword was given it prints a note that deep
  links aren't available yet and to use the site's search box.
- open-url and docs/manual/05-functions/14-miscellaneous.md examples
  repointed from docs/html/index.html to the site URL.
- docs/manual/11-viewing-this-manual.md rewritten to document the four
  access paths: the website, the man page, in-terminal pager, and reading
  docs/manual/** directly. fish-config.index updated to match the new
  headings.
- README.md documentation section and Zoxide attribution link repointed at
  the site; corrected the stale "single source file" claim about
  fish-config.md.
- Regenerated docs/fish-config.md via build-manual.py --concat.
2026-07-25 23:33:26 -04:00
rootiest 29b69c7b03 refactor(kitty-logging): move watcher to scripts/ and symlink it
Relocate the Kitty scrollback watcher out of the single-purpose kitty/
directory into scripts/kitty-fish-config-watcher.py, and change the
installer to symlink it into the Kitty config directory instead of
copying it.

The symlink always tracks the canonical source, which removes the
version-staleness comparison and the copy-vs-refresh messaging. uninstall
now removes a symlink (including a dangling one) or a legacy copied file.
Existing installs migrate automatically on the next `kitty-logging install`.

Docs (README, docs/fish-config.md, wiki) updated to match.
2026-07-16 02:39:41 -04:00
rootiest 38bce499bd fix(ls): pass --hyperlink=auto to eza for consistent OSC 8 behavior 2026-07-16 01:51:08 -04:00
rootiest f3533835be feat(functions): add qc quick-chat wrapper around aichat
Defaults to the bundled 'cli' role (concise, terminal-friendly output),
installed on first use by symlinking scripts/cli-agent.md into the aichat
config dir. Inherits all aichat flags and completions via --wraps; passing
--role/-r forwards unchanged. Only defined when aichat is installed.
--help prepends a banner and rewrites aichat's own help to qc.

Docs: fish-config.md 5.12 + index keywords.
2026-07-16 01:51:00 -04:00
rootiest ec47b0671c feat(config-settings): add Dots link toggle for user-dots symlink
Extract the user-dots symlink logic into the __fish_user_dots_link helper and
add a dedicated __fish_user_dots_symlink toggle, surfaced as a 'Dots link' bool
row on the config-settings Paths page. Unlike the opinionated categories it has
no universal/session split — it acts on a literal path.

Setting it falsy (or toggling off) stops symlink generation and removes any
existing link immediately, honoured regardless of the C2 master switch.
Creation remains a C2 startup side-effect. config.fish now calls the helper.

Docs: README, fish-config.md (C2 table, Paths page, machine-local section),
and fish-config.index updated.
2026-07-04 02:34:20 -04:00
rootiest fe3eb818ba Merge pull request 'fix(help): repair 'help config' wrapper for Fish 4.x embedded help' (#68) from fix-help-config-fish4-embedded into main
Reviewed-on: #68
2026-07-04 06:13:24 +00:00
rootiest 7afb470a42 fix(help): repair 'help config' wrapper for Fish 4.x embedded help
Fish 4.x ships the native `help` function embedded in the binary
(embedded:functions/help.fish) with no on-disk file. The old
functions/help.fish tried to `source $__fish_data_dir/functions/help.fish`
to back up the native help before shadowing it — that path no longer exists,
so the first `help config ...` call errored:

    source: No such file or directory
    functions: Function 'help' does not exist

The backup cannot happen from functions/help.fish at all: an autoload shadow
of that name makes `help` resolve to our own wrapper (or nothing, mid-load),
so `functions -c help` can never capture the embedded original.

Move the wrapper to conf.d/help.fish, sourced at startup before any shadow
exists, where `functions -c help __original_help` copies the embedded native
help. Behavior is otherwise unchanged: 'help config' delegates to config-help,
all other topics fall through to __original_help, and the C1 opinionated guard
still applies. Delete the obsolete functions/help.fish.
2026-07-04 02:11:17 -04:00
rootiest 4761c48d96 feat(functions): add open-url and repo-open browser helpers
Extract the browser-detection and launch logic out of config-help into a
reusable open-url function, then build repo-open on top of it to open the
current repo's origin remote in a browser.

- open-url: resolve the best graphical browser (fish_help_browser -> BROWSER
  -> xdg-mime https handler -> known binaries -> xdg-open) and launch it
  backgrounded. Silent by default; -v/--verbose reports the browser, -s/--silent
  is accepted explicitly. Browser console chatter is discarded.
- repo-open: normalize the origin URL from HTTPS and SSH/scp forms, deep-link
  to the current branch (falling back to the remote default) and sub-directory.
  Provider layout resolved via git config browse.provider, hostname heuristic
  (github/gitlab/gitea/bitbucket, codeberg->gitea), then github default.
  -p/--print emits the URL, -r/--root ignores the sub-directory.
- config-help: replace the inlined browser block with an open-url call.
- abbr: add open-repo and url-open abbreviations that expand to the canonical
  command names on space/enter.
- docs: document both functions in the SSoT (fish-config.md + index) and add a
  repo-open row to the README doc-browsing table.
2026-07-04 02:02:28 -04:00