--section-header pins section-delimiter lines as sticky headers, which
removes them from ov's pattern search scope. --pattern "# 3. KEY BINDINGS"
therefore reports "not found" even though the line exists.
Replace --pattern with tail -n +$start_line piped before ov. The file
naturally starts at the target section so no search is needed, section
nav (Space/^) still works for all subsequent sections, and the sidebar
is populated correctly via --section-delimiter "^#".
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.
string split -f does not accept ranges like '2-'; split on the first
colon only with -m 1 to correctly separate the grep line number from
the heading text without erroring on every heading line.
The previous grep pattern required an exact substring match, so
"keybindings" failed to match the heading "KEY BINDINGS". Normalize
both the user keyword and each heading line by stripping all
non-alphanumeric characters and lowercasing before comparing, so
"keybindings" → "keybindings" matches "KEY BINDINGS" → "keybindings",
"fish-deps" matches "fish-deps", etc.
--pattern matched the first textual occurrence of the keyword anywhere
in the document. Replace with psub to make bat's output seekable, then
use --jump-target with the line number resolved by grep against heading
lines only (^#+.*keyword), so keyword jumps land on the actual section
header rather than an example or body reference.
--jump-target does not work reliably on piped stdin. Replace with
--pattern which positions ov at the first occurrence of the keyword
(works like less +/pattern) and keeps the match highlighted so the
user can press n/N to navigate further occurrences.
Also correct the section navigation keys in the offline manual:
Space = next section (not '.')
^ = previous section (not ',')
Alt+u = section list sidebar
bat emits Markdown headers as ESC[<color>m# so the raw ^# regex never
matches. Use ^(\x1b\[[0-9;]*m)+# instead — matches one or more ANSI
escape sequences before the # regardless of theme or color depth.
Restores section navigation (,/.) while keeping bat syntax highlighting.
ov does not support --syntax/--syntax-name. Use bat --color=always piped
into ov --jump-target for syntax highlighting + line positioning. Fall
back to ov alone (section nav via --section-delimiter) when bat is absent.