From 2af129f081ec22c0f5cda4d69df9029cbfb4d5c1 Mon Sep 17 00:00:00 2001 From: rootiest Date: Sat, 6 Jun 2026 03:50:40 -0400 Subject: [PATCH] fix(config_help): index-based section lookup with normalized fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace fragile pattern/jump-target approach with a two-stage lookup: 1. fish-config.index maps keyword aliases to exact heading text so "keybindings" resolves to "# 3. KEY BINDINGS" without guessing. 2. Normalized scan fallback strips non-alphanumeric chars from both keyword and headings for unknown terms. Line numbers are resolved at runtime via grep -F so the index never goes stale from doc edits — only heading renames require updates. Also fix --section-delimiter: ov matches against logical (ANSI-stripped) text, so "^#" is correct for bat-colored output; the previous ANSI regex never matched, leaving the sections sidebar empty. --- docs/fish-config.index | 176 +++++++++++++++++++++++++++++++++++++ functions/config_help.fish | 73 +++++++++------ 2 files changed, 224 insertions(+), 25 deletions(-) create mode 100644 docs/fish-config.index diff --git a/docs/fish-config.index b/docs/fish-config.index new file mode 100644 index 0000000..b26b879 --- /dev/null +++ b/docs/fish-config.index @@ -0,0 +1,176 @@ +# Fish Config Help Index +# Format: keyword=exact heading text as it appears in fish-config.md +# Multiple keywords may map to the same heading. +# Update this file whenever headings are added, removed, or renamed. +# config_help uses this for fast exact lookups; unknown keywords fall back +# to a normalized heading scan automatically. + +# ── Top-level ───────────────────────────────────────────────── +name=# NAME +synopsis=# SYNOPSIS +description=# DESCRIPTION +toc=# TABLE OF CONTENTS +contents=# TABLE OF CONTENTS + +# ── Section 1: Configuration Variables ─────────────────────── +variables=# 1. CONFIGURATION VARIABLES +config=# 1. CONFIGURATION VARIABLES +xdg=## Environment Directories (XDG) +toolhomes=## Tool Homes (XDG-compliant) +editor=## Editor and Pager +pager=## Editor and Pager +scrollback=## Scrollback History + +# ── Section 2: PATH ─────────────────────────────────────────── +path=# 2. PATH SETUP + +# ── Section 3: Key Bindings ─────────────────────────────────── +keybindings=# 3. KEY BINDINGS +bindings=# 3. KEY BINDINGS +key-bindings=# 3. KEY BINDINGS +keys=# 3. KEY BINDINGS +fzf-bindings=## FZF Bindings (from fzf --fish integration) +fzf=## FZF Bindings (from fzf --fish integration) + +# ── Section 4: Abbreviations ────────────────────────────────── +abbreviations=# 4. ABBREVIATIONS +abbr=# 4. ABBREVIATIONS +abbrs=# 4. ABBREVIATIONS +editors-abbr=## 4.1 Editors +nav=## 4.2 Navigation and Listing +navigation=## 4.2 Navigation and Listing +listing=## 4.2 Navigation and Listing +git-abbr=## 4.3 Git +terminal=## 4.4 Terminal Windows, Tabs, and Panes +panes=## 4.4 Terminal Windows, Tabs, and Panes +windows=## 4.4 Terminal Windows, Tabs, and Panes +tabs=## 4.4 Terminal Windows, Tabs, and Panes +chezmoi=## 4.5 Chezmoi +docker=## 4.6 Docker +systemctl=## 4.7 Systemctl +systemd=## 4.7 Systemctl +ai-abbr=## 4.8 AI Assistants +history=## 4.9 History Expansion +misc-abbr=## 4.10 Miscellaneous + +# ── Section 5: Functions ────────────────────────────────────── +functions=# 5. FUNCTIONS REFERENCE +files=## 5.1 File and Directory +cat=### cat +copy=### copy +du=### du +dusize=### dusize +ls=### ls +lsr=### lsr +lss=### lss +lstree=### lstree +lt=### lt +ltr=### ltr +lx=### lx +mkdir=### mkdir +mkcd=### mkcd +poke=### poke +rm=### rm +scrub=### scrub +nav-fns=## 5.2 Navigation +cdi=### cdi +clone=### clone +clonet=### clonet +editors=## 5.3 Editors and Viewers +edit=### edit +fc=### fc +less=### less +rawfish=### rawfish +view=### view +git=## 5.4 Git and Version Control +branch=### branch +gi=### gi +gitignore=### gi +git-clean=### git-clean +gitup=### gitup +gitui=### gitui +hist=### hist +pkg=### pkg +package=### pkg +package-manager=## 5.5 Package Management +packages=## 5.5 Package Management +search=### search +upgrade=### upgrade +cleanup=### cleanup +parur=### parur +deps=## 5.6 Dependency Management +fish-deps=### fish-deps +check-deps=### check_fish_deps +system=## 5.7 System and Monitoring +top=### top +swapstat=### swapstat +sbver=### sbver +ports=### ports +screensleep=### screensleep +lock=### lock +sudo-toggle=### sudo-toggle +limine=### limine-edit +terminal-mgmt=## 5.8 Terminal Management +tab=### tab +split=### split +spwin=### spwin +detach=### detach +bkg=### bkg +ssh=### ssh +clipboard=## 5.9 Clipboard +copy-fn=### y +paste=### paste +network=## 5.10 Network +gip=### gip +ping=### ping +qr=### qr +logging=## 5.11 Pager and Logging +logs=### logs +smart-exit=### smart_exit +ai=## 5.12 AI and Developer Tools +antigravity=### antigravity +claude=### claude-resume +claude-docs=### claude-docs +claude-pr=### claude-pr +code-resume=### code-resume +superpowers=### superpowers +media=## 5.13 Media and Utilities +dng2avif=### dng2avif +spark=### spark +miscfns=## 5.14 Miscellaneous +bash=### bash +cheat=### cheat +dockup=### dockup +joplin=### joplin +replay=### replay +tmux=### tmux-clean +wake-lock=### wake-lock +zellij=### zellij + +# ── Section 6: Dependency Catalog ──────────────────────────── +catalog=# 6. DEPENDENCY CATALOG +deps-catalog=# 6. DEPENDENCY CATALOG +required=## Required +integrations=## Integrations +recommended=## Recommended +install-methods=## Install Methods + +# ── Section 7: Customization ────────────────────────────────── +customization=# 7. CUSTOMIZATION +customize=# 7. CUSTOMIZATION +local=## Machine-local Configuration +secrets=## Secrets and API Keys +overrides=## Overriding Configuration Variables +universal=## Fish Universal Variables + +# ── Section 8: Fisher Plugins ───────────────────────────────── +plugins=# 8. FISHER PLUGINS +fisher=# 8. FISHER PLUGINS + +# ── Section 9: Viewing This Manual ─────────────────────────── +viewing=# 9. VIEWING THIS MANUAL +manual=# 9. VIEWING THIS MANUAL +ov=## With ov (recommended) +man-page=## As a man page (if compiled) +manpage=## As a man page (if compiled) +jump=## Jumping to a section diff --git a/functions/config_help.fish b/functions/config_help.fish index ff90028..dfbcde8 100644 --- a/functions/config_help.fish +++ b/functions/config_help.fish @@ -8,7 +8,8 @@ # Opens the offline fish shell configuration manual in the best available # pager. Falls back through ov -> bat -> man -> less -> cat. # If a section keyword is provided, the pager opens at the first heading -# that matches the keyword (case-insensitive). +# that matches the keyword. Lookup order: docs/fish-config.index (exact +# keyword aliases), then a normalized heading scan as fallback. # # ARGUMENTS # section Optional keyword to jump to a matching section heading @@ -24,6 +25,7 @@ # config_help fish-deps 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" set -l man_file "$__fish_config_dir/docs/fish-config.1" if not test -f "$doc_file" @@ -33,26 +35,48 @@ function config_help --description 'Open the offline fish shell configuration ma return 1 end - # ── Resolve section start line ─────────────────────────────── - # Normalize both sides: strip non-alphanumeric chars and lowercase. - # This lets "keybindings" match "KEY BINDINGS", "fish-deps" match - # "fish-deps", etc. without requiring exact punctuation or case. + # ── Resolve section ────────────────────────────────────────── + # 1. Look up keyword in fish-config.index (keyword → exact heading text). + # 2. Fall back to normalized scan of heading lines if not in index. + # 3. Resolve start_line via grep -F on the heading text (immune to line + # number drift — only breaks if the heading itself is renamed). set -l start_line 1 + set -l found_text "" if test -n "$argv[1]" set -l norm_kw (string lower -- $argv[1] | string replace -ra '[^a-z0-9]' '') - set -l found "" - for entry in (grep -n "^#" "$doc_file") - set -l parts (string split -m 1 ':' -- $entry) - set -l lnum $parts[1] - set -l text $parts[2] - set -l norm_text (string lower -- $text | string replace -ra '[^a-z0-9]' '') - if string match -q "*$norm_kw*" $norm_text - set found $lnum - break + + # ── Index lookup ───────────────────────────────────────── + if test -f "$idx_file" + while read -l idxline + string match -qr '^[[:space:]]*(#|$)' -- $idxline; and continue + set -l kv (string split -m 1 '=' -- $idxline) + test (count $kv) -lt 2; and continue + set -l k (string lower -- $kv[1] | string replace -ra '[^a-z0-9]' '') + if test "$k" = "$norm_kw" + set found_text $kv[2] + break + end + end < "$idx_file" + end + + # ── Normalized scan fallback ───────────────────────────── + if test -z "$found_text" + for entry in (grep -n "^#" "$doc_file") + set -l parts (string split -m 1 ':' -- $entry) + set -l text $parts[2] + set -l norm_text (string lower -- $text | string replace -ra '[^a-z0-9]' '') + if string match -q "*$norm_kw*" $norm_text + set found_text $text + break + end end end - if test -n "$found" - set start_line $found + + if test -n "$found_text" + set -l lnum (grep -Fn "$found_text" "$doc_file" | cut -d: -f1 | head -1) + if test -n "$lnum" + set start_line $lnum + end else set_color yellow echo "note: no section matching '$argv[1]' — opening at top" >&2 @@ -61,17 +85,16 @@ function config_help --description 'Open the offline fish shell configuration ma end # ── Viewer fallback chain ──────────────────────────────────── - # bat colors the output; ov matches headers via an ANSI-aware regex. - # bat emits: ESC[m# ... so delimiter ^(\x1b\[[0-9;]*m)+# matches - # any 8/24-bit color sequence before a '#', theme-agnostic. + # ov matches section-delimiter against logical (displayed) text, so "^#" + # works on bat-colored output — no ANSI regex needed. # Section nav: Space (next), ^ (previous), Alt+u (section list sidebar). - # psub creates a seekable temp file so --jump-target works on bat output. + # --pattern uses the exact heading text for a precise one-line match. if type -q ov; and type -q bat set -l ov_args \ - --section-delimiter "^(\x1b\[[0-9;]*m)+#" \ + --section-delimiter "^#" \ --section-header - if test $start_line -gt 1 - set -a ov_args --jump-target $start_line + if test -n "$found_text" + set -a ov_args --pattern (string escape --style=regex -- $found_text) end ov $ov_args (bat --color=always --style=plain --language=markdown "$doc_file" | psub) @@ -80,8 +103,8 @@ function config_help --description 'Open the offline fish shell configuration ma set -l ov_args \ --section-delimiter "^#" \ --section-header - if test $start_line -gt 1 - set -a ov_args --jump-target $start_line + if test -n "$found_text" + set -a ov_args --pattern (string escape --style=regex -- $found_text) end ov $ov_args "$doc_file"