feat(config-help): add section linking for HTML and man page
- Section keyword is now extracted early and shared across all three output modes (pager, HTML, man) rather than duplicated per branch - --html with a section keyword resolves the heading to a pandoc anchor ID and looks it up in docs/html/sitemap.json; handles both sub-section fragment paths and top-level sections that are their own page - --man with a section keyword overrides MANPAGER to `less +/pattern` so the page opens at the nearest heading match - --help output updated to show [section] in USAGE and section+flag examples (help config keybindings --html, help config pkg --man) - docs/fish-config.md §5.14 synopsis, flags, and examples updated - docs/fish-config.md §11 "Viewing" sections updated for both HTML and man page to document the section+flag invocation - README table updated with section+html and section+man rows
This commit is contained in:
@@ -46,7 +46,9 @@ To browse the docs from the terminal:
|
||||
| `help config` | Open the terminal manual in the best available pager |
|
||||
| `help config <keyword>` | Jump directly to a section matching the keyword |
|
||||
| `help config --html` | Open the pre-built HTML docs in the default browser |
|
||||
| `help config <keyword> --html` | Open HTML docs at the matching section anchor |
|
||||
| `help config --man` | Open the compiled man page via `man -l` |
|
||||
| `help config <keyword> --man` | Open the man page jumping to the nearest match |
|
||||
|
||||
The pager falls back through: **ov** → **bat** → **man -l** → **less** → **cat**.
|
||||
|
||||
|
||||
+18
-9
@@ -1157,8 +1157,8 @@ Add -i (interactive confirmation) to destructive commands:
|
||||
### config-help
|
||||
|
||||
Synopsis: config-help [SECTION]
|
||||
config-help --html
|
||||
config-help --man
|
||||
config-help [SECTION] --html
|
||||
config-help [SECTION] --man
|
||||
config-help -h | --help
|
||||
|
||||
Opens the offline fish shell configuration manual. Without flags, opens
|
||||
@@ -1168,16 +1168,20 @@ Add -i (interactive confirmation) to destructive commands:
|
||||
|
||||
Flags:
|
||||
--html / -w Open docs/html/index.html in the default browser.
|
||||
If SECTION is given, opens at the matching anchor.
|
||||
Detects the browser via xdg-mime x-scheme-handler/https,
|
||||
then known binaries, then xdg-open as last resort.
|
||||
Respects $fish_help_browser and $BROWSER.
|
||||
--man / -m Open docs/fish-config.1 via man -l directly.
|
||||
If SECTION is given, jumps to the nearest match.
|
||||
--help / -h Print usage and navigation key reference.
|
||||
|
||||
config-help keybindings
|
||||
config-help pkg
|
||||
config-help --html
|
||||
config-help pkg --html
|
||||
config-help --man
|
||||
config-help pkg --man
|
||||
|
||||
Also available as: help config [SECTION] [FLAGS]
|
||||
|
||||
@@ -1603,10 +1607,12 @@ navigation.
|
||||
## As a man page
|
||||
|
||||
help config --man
|
||||
help config pkg --man
|
||||
|
||||
Opens the compiled docs/fish-config.1 directly via man -l, bypassing
|
||||
the pager fallback chain. The symlink and MANPATH are also configured
|
||||
automatically on shell start for the standard invocation:
|
||||
the pager fallback chain. If a section keyword is given, the pager opens
|
||||
at the nearest matching heading. The symlink and MANPATH are also
|
||||
configured automatically on shell start for the standard invocation:
|
||||
|
||||
man fish-config
|
||||
|
||||
@@ -1617,12 +1623,15 @@ a completely separate command. Do not mix them up.
|
||||
## In the browser (HTML)
|
||||
|
||||
help config --html
|
||||
help config pkg --html
|
||||
|
||||
Opens docs/html/index.html in the default web browser. Browser detection
|
||||
queries the system's x-scheme-handler/https MIME entry (via xdg-mime) to
|
||||
find the real browser binary, then falls back through known browser
|
||||
binaries (firefox, chromium, vivaldi, etc.), and finally xdg-open as a
|
||||
last resort. Set $fish_help_browser or $BROWSER to override.
|
||||
Opens docs/html/index.html in the default web browser. If a section
|
||||
keyword is given, the browser opens directly at the matching anchor
|
||||
(resolved via docs/html/sitemap.json). Browser detection queries the
|
||||
system's x-scheme-handler/https MIME entry (via xdg-mime) to find the
|
||||
real browser binary, then falls back through known browser binaries
|
||||
(firefox, chromium, vivaldi, etc.), and finally xdg-open as a last
|
||||
resort. Set $fish_help_browser or $BROWSER to override.
|
||||
|
||||
## As a wiki
|
||||
|
||||
|
||||
+129
-68
@@ -3,8 +3,8 @@
|
||||
|
||||
# SYNOPSIS
|
||||
# config-help [section]
|
||||
# config-help --html
|
||||
# config-help --man
|
||||
# config-help [section] --html
|
||||
# config-help [section] --man
|
||||
# config-help --help
|
||||
#
|
||||
# DESCRIPTION
|
||||
@@ -15,8 +15,9 @@
|
||||
# keyword aliases), then a normalized heading scan as fallback.
|
||||
# When opened with ov a sticky navigation hint is shown at the top of the
|
||||
# screen. Pass --html / -w to open the pre-built HTML version in the
|
||||
# default browser via xdg-open. Pass --man / -m to open the compiled
|
||||
# man page directly via man -l. Pass --help or -h for usage reference.
|
||||
# default browser, jumping to the matching section anchor when possible.
|
||||
# Pass --man / -m to open the compiled man page; if a section keyword is
|
||||
# given, the pager opens at the nearest match. Pass --help or -h for usage.
|
||||
#
|
||||
# ARGUMENTS
|
||||
# section Optional keyword to jump to a matching section heading
|
||||
@@ -34,7 +35,9 @@
|
||||
# config-help pkg
|
||||
# config-help fish-deps
|
||||
# config-help --html
|
||||
# config-help keys --html
|
||||
# config-help --man
|
||||
# config-help keys --man
|
||||
# config-help --help
|
||||
#
|
||||
# NOTES
|
||||
@@ -42,17 +45,98 @@
|
||||
# registered as a handler in the help wrapper so that syntax works
|
||||
# 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"
|
||||
set -l man_file "$__fish_config_dir/docs/fish-config.1"
|
||||
set -l html_dir "$__fish_config_dir/docs/html"
|
||||
set -l sitemap "$html_dir/sitemap.json"
|
||||
|
||||
# ── Extract section keyword (first non-flag argument) ────────
|
||||
set -l section_kw ""
|
||||
for arg in $argv
|
||||
if not string match -q -- '-*' $arg
|
||||
set section_kw $arg
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# ── Resolve section keyword → heading text ───────────────────
|
||||
# Used by --html (anchor lookup), --man (search pattern), and the
|
||||
# pager fallback chain (line number). Runs once, shared by all paths.
|
||||
set -l found_text ""
|
||||
if test -n "$section_kw"
|
||||
set -l norm_kw (string lower -- $section_kw | string replace -ra '[^a-z0-9]' '')
|
||||
|
||||
# 1. Index lookup (keyword aliases)
|
||||
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
|
||||
|
||||
# 2. Normalized heading scan fallback
|
||||
if test -z "$found_text"; and test -f "$doc_file"
|
||||
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
|
||||
end
|
||||
|
||||
# ── --html / -w ──────────────────────────────────────────────
|
||||
if contains -- --html $argv; or contains -- -w $argv
|
||||
set -l html_file "$__fish_config_dir/docs/html/index.html"
|
||||
if not test -f "$html_file"
|
||||
if not test -f "$html_dir/index.html"
|
||||
set_color red
|
||||
echo "error: HTML docs not found at $html_file" >&2
|
||||
echo "error: HTML docs not found at $html_dir/index.html" >&2
|
||||
set_color normal
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l page_url "file://$html_file"
|
||||
# Default to the index page; resolve a section fragment when possible.
|
||||
set -l html_path "index.html"
|
||||
if test -n "$found_text"; and test -f "$sitemap"
|
||||
# Convert heading text → pandoc anchor ID:
|
||||
# lowercase → strip non-alphanumeric (keep spaces and hyphens)
|
||||
# → spaces to hyphens → collapse runs → strip edge hyphens.
|
||||
set -l anchor (string lower -- $found_text \
|
||||
| string replace -ra '[^a-z0-9 -]' '' \
|
||||
| string replace -ra ' +' '-' \
|
||||
| string replace -ra '-+' '-' \
|
||||
| string trim -c '-')
|
||||
# 1. Sub-section: path stored as "filename.html#anchor"
|
||||
set -l match (grep -o "\"path\":\"[^\"]*#$anchor\"" "$sitemap" | head -1)
|
||||
if test -n "$match"
|
||||
set html_path (string replace -r '"path":"([^"]+)"' '$1' -- $match)
|
||||
else
|
||||
# 2. Top-level section: own page — "id":"anchor"..."path":"filename.html"
|
||||
set -l id_match (grep -o "\"id\":\"$anchor\"[^}]*\"path\":\"[^\"]*\"" "$sitemap" | head -1)
|
||||
if test -n "$id_match"
|
||||
set html_path (string replace -r '.*"path":"([^"]+)"' '$1' -- $id_match)
|
||||
else
|
||||
set_color yellow
|
||||
echo "note: no HTML anchor found for '$section_kw' — opening at top" >&2
|
||||
set_color normal
|
||||
end
|
||||
end
|
||||
else if test -n "$section_kw"
|
||||
set_color yellow
|
||||
echo "note: no section matching '$section_kw' — opening at top" >&2
|
||||
set_color normal
|
||||
end
|
||||
|
||||
set -l page_url "file://$html_dir/$html_path"
|
||||
|
||||
# Browser detection — mirrors fish's help.fish priority order but
|
||||
# resolves actual browser binaries before falling back to xdg-open.
|
||||
@@ -123,7 +207,6 @@ function config-help --description 'Open the offline fish shell configuration ma
|
||||
|
||||
# ── --man / -m ───────────────────────────────────────────────
|
||||
if contains -- --man $argv; or contains -- -m $argv
|
||||
set -l man_file "$__fish_config_dir/docs/fish-config.1"
|
||||
if not test -f "$man_file"
|
||||
set_color red
|
||||
echo "error: man page not found at $man_file" >&2
|
||||
@@ -136,7 +219,20 @@ function config-help --description 'Open the offline fish shell configuration ma
|
||||
set_color normal
|
||||
return 1
|
||||
end
|
||||
man -l "$man_file"
|
||||
if test -n "$found_text"
|
||||
# Strip Markdown heading markers to get the bare section name,
|
||||
# then pass it as a less search pattern. MANPAGER is overridden
|
||||
# here because the bat renderer does not support +/pattern jumps.
|
||||
set -l pattern (string replace -ra '^#+ *' '' -- $found_text | string trim)
|
||||
env MANPAGER="less +/$pattern" man -l "$man_file"
|
||||
else if test -n "$section_kw"
|
||||
set_color yellow
|
||||
echo "note: no section matching '$section_kw' — opening at top" >&2
|
||||
set_color normal
|
||||
man -l "$man_file"
|
||||
else
|
||||
man -l "$man_file"
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
@@ -151,8 +247,8 @@ function config-help --description 'Open the offline fish shell configuration ma
|
||||
echo USAGE
|
||||
set_color normal
|
||||
echo " help config "(set_color yellow)"[section]"(set_color normal)
|
||||
echo " help config "(set_color yellow)"--html"(set_color normal)
|
||||
echo " help config "(set_color yellow)"--man"(set_color normal)
|
||||
echo " help config "(set_color yellow)"[section] --html"(set_color normal)
|
||||
echo " help config "(set_color yellow)"[section] --man"(set_color normal)
|
||||
echo " help config "(set_color yellow)"--help"(set_color normal)
|
||||
echo ""
|
||||
set_color --bold brblue
|
||||
@@ -163,18 +259,22 @@ function config-help --description 'Open the offline fish shell configuration ma
|
||||
echo " falls back to a normalized (case- and punctuation-insensitive)"
|
||||
echo " scan of heading lines."
|
||||
echo " "(set_color yellow)"-w, --html"(set_color normal)" Open the offline HTML docs in the default browser."
|
||||
echo " If a section keyword is given, opens at the matching anchor."
|
||||
echo " "(set_color yellow)"-m, --man"(set_color normal)" Open the compiled man page via man -l."
|
||||
echo " If a section keyword is given, jumps to the nearest match."
|
||||
echo ""
|
||||
set_color --bold brblue
|
||||
echo EXAMPLES
|
||||
set_color normal
|
||||
echo " "(set_color green)"help config"(set_color normal)" open at top"
|
||||
echo " "(set_color green)"help config keybindings"(set_color normal)" jump to Key Bindings section"
|
||||
echo " "(set_color green)"help config pkg"(set_color normal)" jump to the pkg function entry"
|
||||
echo " "(set_color green)"help config fish-deps"(set_color normal)" jump to fish-deps"
|
||||
echo " "(set_color green)"help config abbreviations"(set_color normal)" jump to Abbreviations section"
|
||||
echo " "(set_color green)"help config --html"(set_color normal)" open HTML docs in browser"
|
||||
echo " "(set_color green)"help config --man"(set_color normal)" open compiled man page"
|
||||
echo " "(set_color green)"help config"(set_color normal)" open at top"
|
||||
echo " "(set_color green)"help config keybindings"(set_color normal)" jump to Key Bindings section"
|
||||
echo " "(set_color green)"help config pkg"(set_color normal)" jump to the pkg function entry"
|
||||
echo " "(set_color green)"help config fish-deps"(set_color normal)" jump to fish-deps"
|
||||
echo " "(set_color green)"help config abbreviations"(set_color normal)" jump to Abbreviations section"
|
||||
echo " "(set_color green)"help config --html"(set_color normal)" open HTML docs in browser"
|
||||
echo " "(set_color green)"help config keybindings --html"(set_color normal)" open HTML at Key Bindings"
|
||||
echo " "(set_color green)"help config --man"(set_color normal)" open compiled man page"
|
||||
echo " "(set_color green)"help config pkg --man"(set_color normal)" open man page at pkg section"
|
||||
echo ""
|
||||
set_color --bold brblue
|
||||
echo "NAVIGATION (ov pager)"
|
||||
@@ -199,10 +299,6 @@ function config-help --description 'Open the offline fish shell configuration ma
|
||||
return 0
|
||||
end
|
||||
|
||||
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"
|
||||
set_color red
|
||||
echo "error: documentation not found at $doc_file" >&2
|
||||
@@ -210,53 +306,18 @@ function config-help --description 'Open the offline fish shell configuration ma
|
||||
return 1
|
||||
end
|
||||
|
||||
# ── Resolve section start line ───────────────────────────────
|
||||
# 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).
|
||||
# ── Resolve section start line (for pager) ───────────────────
|
||||
# found_text is already resolved above; just need the line number.
|
||||
set -l start_line 1
|
||||
if test -n "$argv[1]"
|
||||
set -l norm_kw (string lower -- $argv[1] | string replace -ra '[^a-z0-9]' '')
|
||||
set -l found_text ""
|
||||
|
||||
# ── 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_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
|
||||
set_color normal
|
||||
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 if test -n "$section_kw"
|
||||
set_color yellow
|
||||
echo "note: no section matching '$section_kw' — opening at top" >&2
|
||||
set_color normal
|
||||
end
|
||||
|
||||
# ── Navigation hint line ─────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user