feat(docs): GitHub mirror icon, README-sourced doc sections, auto-generated TOC #129
@@ -146,9 +146,12 @@ Contributing to the docs? There are two sources, split by content type:
|
|||||||
above each function in `functions/*.fish`. Edit the function; the entry
|
above each function in `functions/*.fish`. Edit the function; the entry
|
||||||
and its site page are generated from the header.
|
and its site page are generated from the header.
|
||||||
- **Everything else** lives under `docs/manual/**`.
|
- **Everything else** lives under `docs/manual/**`.
|
||||||
|
- **Testing, Contributing, Attribution, and License** are pulled straight
|
||||||
|
from this README (the sections below) rather than authored twice — edit
|
||||||
|
them here and the manual, man page, and site all pick up the change.
|
||||||
|
|
||||||
Never edit the generated `docs/fish-config.md` — it's rebuilt from both
|
Never edit the generated `docs/fish-config.md` — it's rebuilt from all
|
||||||
sources and any hand-edits are discarded.
|
three sources and any hand-edits are discarded.
|
||||||
|
|
||||||
To browse the docs from the terminal:
|
To browse the docs from the terminal:
|
||||||
|
|
||||||
@@ -348,6 +351,14 @@ Interested in contributing? See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the
|
|||||||
branching/PR workflow, commit conventions, fish coding standards, and the
|
branching/PR workflow, commit conventions, fish coding standards, and the
|
||||||
docs/testing pipeline this repo follows.
|
docs/testing pipeline this repo follows.
|
||||||
|
|
||||||
|
**Preferred forge:** [git.rootiest.dev/rootiest/fish-config](https://git.rootiest.dev/rootiest/fish-config)
|
||||||
|
is the base repository. [github.com/rootiest/fish-config](https://github.com/rootiest/fish-config)
|
||||||
|
is a push-mirror of it — identical content, but one-way and read-only from a
|
||||||
|
contributor's perspective. Branches, forks, and merges made on the GitHub
|
||||||
|
side aren't fed back upstream, so they risk being silently overwritten by
|
||||||
|
the next mirror push. Until two-way sync exists, please fork, branch, and
|
||||||
|
open issues/PRs from the Gitea repository rather than the GitHub mirror.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Attribution
|
## Attribution
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ DOCS = Path(__file__).parent
|
|||||||
MANUAL = DOCS / "manual"
|
MANUAL = DOCS / "manual"
|
||||||
FUNCTIONS = DOCS.parent / "functions"
|
FUNCTIONS = DOCS.parent / "functions"
|
||||||
COMPLETIONS = DOCS.parent / "completions"
|
COMPLETIONS = DOCS.parent / "completions"
|
||||||
|
README = DOCS.parent / "README.md"
|
||||||
|
REPO_BLOB_BASE = "https://git.rootiest.dev/rootiest/fish-config/src/branch/main/"
|
||||||
SLUG_DIR = "reference"
|
SLUG_DIR = "reference"
|
||||||
|
|
||||||
# File-tree branches whose real directory contents get listed inline on the
|
# File-tree branches whose real directory contents get listed inline on the
|
||||||
@@ -84,6 +86,100 @@ def _with_abbreviations(body: str, abbrs: dict[str, list[dict]]) -> str:
|
|||||||
return body
|
return body
|
||||||
|
|
||||||
|
|
||||||
|
TOC_PLACEHOLDER = "<!-- GENERATED: toc -->"
|
||||||
|
TOC_SKIP_STEMS = {"index"}
|
||||||
|
|
||||||
|
|
||||||
|
def _build_toc(root: Path) -> str:
|
||||||
|
"""Render the section list for docs/manual/00-table-of-contents.md.
|
||||||
|
|
||||||
|
Walks the same tree `build_concat` does, so it can never drift from the
|
||||||
|
man page's actual section order. `index.md` and the `00-*` front-matter
|
||||||
|
pages (Name, Synopsis, this page) sit before section 1 and are excluded,
|
||||||
|
same as any `man: false` page (currently only 404).
|
||||||
|
"""
|
||||||
|
lines: list[str] = []
|
||||||
|
n = 0
|
||||||
|
for path, depth in mt.walk(root):
|
||||||
|
rel = path.relative_to(root)
|
||||||
|
# len(rel.parts) == 1 means a root-level file, not a directory's own
|
||||||
|
# index page (e.g. 04-abbreviations/index.md), which must keep its
|
||||||
|
# own numbered line even though its stem is also "index".
|
||||||
|
if depth == 0 and len(rel.parts) == 1 and (rel.stem in TOC_SKIP_STEMS or rel.stem.startswith("00-")):
|
||||||
|
continue
|
||||||
|
fm, _ = mt.parse(path)
|
||||||
|
if not fm.get("man", True):
|
||||||
|
continue
|
||||||
|
title = fm.get("title", path.stem)
|
||||||
|
if depth == 0:
|
||||||
|
n += 1
|
||||||
|
lines.append(f" {n}. {title}")
|
||||||
|
else:
|
||||||
|
lines.append(f" - {title}")
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def _with_toc(body: str, root: Path) -> str:
|
||||||
|
"""Inject the `<!-- GENERATED: toc -->` placeholder with the built section list."""
|
||||||
|
return body.replace(TOC_PLACEHOLDER, _build_toc(root)) if TOC_PLACEHOLDER in body else body
|
||||||
|
|
||||||
|
|
||||||
|
README_LINK_RE = re.compile(r"\]\((?!https?://|#|mailto:)([^)]+)\)")
|
||||||
|
README_FENCE_RE = re.compile(r"```[^\n]*\n(.*?)```\n?", re.DOTALL)
|
||||||
|
README_PLACEHOLDER_RE = re.compile(r"<!-- README: (.+?) -->")
|
||||||
|
|
||||||
|
|
||||||
|
def _rewrite_repo_links(text: str) -> str:
|
||||||
|
"""Point a README-relative link (`CONTRIBUTING.md`, `LICENSE`) at its file on Gitea."""
|
||||||
|
return README_LINK_RE.sub(lambda m: f"]({REPO_BLOB_BASE}{m.group(1)})", text)
|
||||||
|
|
||||||
|
|
||||||
|
def _defence(text: str) -> str:
|
||||||
|
"""Rewind a README fenced code block into the manual's indented-block form.
|
||||||
|
|
||||||
|
`docs/manual` bodies are authored man-page style (4-space indent), never
|
||||||
|
fenced: `codespans`/pandoc pair backticks per line, and a fence line's
|
||||||
|
triple backtick throws that count off. README.md is ordinary markdown
|
||||||
|
and fences its examples, so an injected section is converted back.
|
||||||
|
"""
|
||||||
|
def repl(m: re.Match) -> str:
|
||||||
|
block = m.group(1).rstrip("\n")
|
||||||
|
return "\n".join(" " + line for line in block.split("\n")) + "\n"
|
||||||
|
|
||||||
|
return README_FENCE_RE.sub(repl, text)
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=1)
|
||||||
|
def _readme_sections() -> dict[str, str]:
|
||||||
|
"""Split README.md into {H2 heading: body}, links rewritten to point at the repo.
|
||||||
|
|
||||||
|
Lets a manual stub pull one README section in verbatim via a
|
||||||
|
`<!-- README: <Heading> -->` placeholder, so the README stays the single
|
||||||
|
source of truth for sections that describe the repo itself rather than
|
||||||
|
the shell config (Testing, Contributing, Attribution, License).
|
||||||
|
"""
|
||||||
|
sections: dict[str, str] = {}
|
||||||
|
heading: str | None = None
|
||||||
|
lines: list[str] = []
|
||||||
|
for line in README.read_text().split("\n") + ["## "]:
|
||||||
|
if line.startswith("## "):
|
||||||
|
if heading is not None:
|
||||||
|
body = "\n".join(lines).strip()
|
||||||
|
if body.endswith("---"):
|
||||||
|
body = body[:-3].rstrip()
|
||||||
|
sections[heading] = _defence(_rewrite_repo_links(body))
|
||||||
|
heading = line[3:].strip()
|
||||||
|
lines = []
|
||||||
|
else:
|
||||||
|
lines.append(line)
|
||||||
|
return sections
|
||||||
|
|
||||||
|
|
||||||
|
def _with_readme(body: str) -> str:
|
||||||
|
"""Inject `<!-- README: Heading -->` placeholders with that README section's body."""
|
||||||
|
return README_PLACEHOLDER_RE.sub(lambda m: _readme_sections().get(m.group(1), ""), body)
|
||||||
|
|
||||||
|
|
||||||
def build_concat(root: Path) -> str:
|
def build_concat(root: Path) -> str:
|
||||||
"""Concatenate the manual into one ordered markdown document.
|
"""Concatenate the manual into one ordered markdown document.
|
||||||
|
|
||||||
@@ -123,6 +219,8 @@ def build_concat(root: Path) -> str:
|
|||||||
elif "04-abbreviations" in path.parts:
|
elif "04-abbreviations" in path.parts:
|
||||||
abbrs = mt.parse_abbreviations(DOCS.parent / "conf.d")
|
abbrs = mt.parse_abbreviations(DOCS.parent / "conf.d")
|
||||||
body = _with_abbreviations(body, abbrs)
|
body = _with_abbreviations(body, abbrs)
|
||||||
|
body = _with_readme(body)
|
||||||
|
body = _with_toc(body, root)
|
||||||
if body:
|
if body:
|
||||||
body = re.sub(r"<LinkButton.*?</LinkButton>\n*", "", body, flags=re.DOTALL)
|
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"<CardGrid.*?</CardGrid>\n*", "", body, flags=re.DOTALL)
|
||||||
@@ -749,6 +847,7 @@ def build_site(root: Path, out: Path) -> list[dict]:
|
|||||||
if "04-abbreviations" in path.parts:
|
if "04-abbreviations" in path.parts:
|
||||||
abbrs = mt.parse_abbreviations(DOCS.parent / "conf.d")
|
abbrs = mt.parse_abbreviations(DOCS.parent / "conf.d")
|
||||||
body = _with_abbreviations(body, abbrs)
|
body = _with_abbreviations(body, abbrs)
|
||||||
|
body = _with_readme(body)
|
||||||
target.parent.mkdir(parents=True, exist_ok=True)
|
target.parent.mkdir(parents=True, exist_ok=True)
|
||||||
body = _inject_subheading_cards(body)
|
body = _inject_subheading_cards(body)
|
||||||
_write_prettified(target, _page_fm(fm), prettify(body))
|
_write_prettified(target, _page_fm(fm), prettify(body))
|
||||||
|
|||||||
@@ -403,4 +403,23 @@ site=## The documentation website
|
|||||||
source=## Reading the source directly
|
source=## Reading the source directly
|
||||||
raw-source=## Reading the source directly
|
raw-source=## Reading the source directly
|
||||||
|
|
||||||
|
# ── Section 14: Testing ───────────────────────────────────────
|
||||||
|
testing=# 14. TESTING
|
||||||
|
tests=# 14. TESTING
|
||||||
|
|
||||||
|
# ── Section 15: Contributing ──────────────────────────────────
|
||||||
|
contributing=# 15. CONTRIBUTING
|
||||||
|
contribute=# 15. CONTRIBUTING
|
||||||
|
forge=# 15. CONTRIBUTING
|
||||||
|
|
||||||
|
# ── Section 16: Attribution ───────────────────────────────────
|
||||||
|
attribution=# 16. ATTRIBUTION
|
||||||
|
credits=# 16. ATTRIBUTION
|
||||||
|
|
||||||
|
# ── Section 17: License ───────────────────────────────────────
|
||||||
|
license=# 17. LICENSE
|
||||||
|
licensing=# 17. LICENSE
|
||||||
|
agpl=# 17. LICENSE
|
||||||
|
copyright=# 17. LICENSE
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+72
-39
@@ -86,48 +86,50 @@ The configuration uses a structured file tree:
|
|||||||
2. PATH Setup
|
2. PATH Setup
|
||||||
3. Key Bindings
|
3. Key Bindings
|
||||||
4. Abbreviations
|
4. Abbreviations
|
||||||
4.1 Editors
|
- Editors
|
||||||
4.2 Navigation and Listing
|
- Navigation and Listing
|
||||||
4.3 Git
|
- Git
|
||||||
4.4 Terminal Windows, Tabs, and Panes
|
- Terminal Windows, Tabs, and Panes
|
||||||
4.5 Chezmoi
|
- Chezmoi
|
||||||
4.6 Docker
|
- Docker
|
||||||
4.7 Systemctl
|
- Systemctl
|
||||||
4.8 AI Assistants
|
- AI Assistants
|
||||||
4.9 History Expansion
|
- History Expansion
|
||||||
4.10 Miscellaneous
|
- Miscellaneous
|
||||||
4.11 Shell Aliases
|
- Shell Aliases
|
||||||
5. Functions Reference
|
5. Functions Reference
|
||||||
5.1 File and Directory
|
- File and Directory
|
||||||
5.2 Navigation
|
- Navigation
|
||||||
5.3 Editors and Viewers
|
- Editors and Viewers
|
||||||
5.4 Git and Version Control
|
- Git and Version Control
|
||||||
5.5 Package Management
|
- Package Management
|
||||||
5.6 Dependency Management
|
- Dependency Management
|
||||||
5.7 System and Monitoring
|
- System and Monitoring
|
||||||
5.8 Terminal Management
|
- Terminal Management
|
||||||
5.9 Clipboard
|
- Clipboard
|
||||||
5.10 Network
|
- Network
|
||||||
5.11 Pager and Logging
|
- Pager and Logging
|
||||||
5.12 AI and Developer Tools
|
- AI and Developer Tools
|
||||||
5.13 Media and Utilities
|
- Media and Utilities
|
||||||
5.14 Miscellaneous
|
- Miscellaneous
|
||||||
6. Dependency Catalog
|
6. Dependency Catalog
|
||||||
7. Customization
|
7. Customization
|
||||||
8. Fisher Plugins
|
8. Components Reference
|
||||||
9. Installation
|
- C1 — Command Shadows
|
||||||
10. Personalization
|
- C2 — Startup Side-Effects
|
||||||
11. Troubleshooting
|
- C3 — Key and Environment Overrides
|
||||||
11.1 Uninstalling and Reverting to Backup
|
- C4 — Terminal and Tool Integration
|
||||||
11.2 Fish Version Requirement
|
- C5 — Logging and Capture
|
||||||
11.3 Enable or Disable Session Logging
|
- C6 — Greeting and First-Run UI
|
||||||
11.4 Change or Disable the Greeting
|
9. Fisher Plugins
|
||||||
11.5 Secrets and Machine-Local Configuration
|
10. Installation
|
||||||
11.6 Tool Init Does Nothing (Return Sentinel)
|
11. Personalization
|
||||||
11.7 Missing Dependencies
|
12. Troubleshooting
|
||||||
11.8 Vi Mode Keybindings
|
13. Viewing This Manual
|
||||||
11.9 What's with the C1-C6 stuff?
|
14. Testing
|
||||||
12. Viewing This Manual
|
15. Contributing
|
||||||
|
16. Attribution
|
||||||
|
17. License
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -4309,3 +4311,34 @@ to correct its documentation, open the function itself:
|
|||||||
|
|
||||||
The files under `docs/manual/05-functions/` carry only the category
|
The files under `docs/manual/05-functions/` carry only the category
|
||||||
titles, ordering, and search keywords.
|
titles, ordering, and search keywords.
|
||||||
|
|
||||||
|
# 14. TESTING
|
||||||
|
|
||||||
|
fish tests/run-tests.fish
|
||||||
|
|
||||||
|
Runs before every push (and gates the [documentation build](https://git.rootiest.dev/rootiest/fish-config/src/branch/main/.github/workflows/ci.yml) in CI, so a broken config can't get published): syntax-lints every `.fish` file, then loads the config in an isolated `HOME`/XDG sandbox — never this checkout itself, since it doubles as a real `~/.config/fish` — and runs functional checks against foundational behavior (XDG/PATH/CDPATH setup, key bindings, abbreviations, core functions, the opinionated-component registry, and more).
|
||||||
|
|
||||||
|
# 15. CONTRIBUTING
|
||||||
|
|
||||||
|
Interested in contributing? See [`CONTRIBUTING.md`](https://git.rootiest.dev/rootiest/fish-config/src/branch/main/CONTRIBUTING.md) for the
|
||||||
|
branching/PR workflow, commit conventions, fish coding standards, and the
|
||||||
|
docs/testing pipeline this repo follows.
|
||||||
|
|
||||||
|
**Preferred forge:** [git.rootiest.dev/rootiest/fish-config](https://git.rootiest.dev/rootiest/fish-config)
|
||||||
|
is the base repository. [github.com/rootiest/fish-config](https://github.com/rootiest/fish-config)
|
||||||
|
is a push-mirror of it — identical content, but one-way and read-only from a
|
||||||
|
contributor's perspective. Branches, forks, and merges made on the GitHub
|
||||||
|
side aren't fed back upstream, so they risk being silently overwritten by
|
||||||
|
the next mirror push. Until two-way sync exists, please fork, branch, and
|
||||||
|
open issues/PRs from the Gitea repository rather than the GitHub mirror.
|
||||||
|
|
||||||
|
# 16. ATTRIBUTION
|
||||||
|
|
||||||
|
The core of the [Zoxide integration](https://fish.rootiest.fyi/02-path-setup/) in this repository was originally adapted from the [icezyclon/zoxide.fish](https://github.com/icezyclon/zoxide.fish) plugin (MIT Licensed) and has since been heavily customized for performance and Fish 4.x compatibility.
|
||||||
|
|
||||||
|
# 17. LICENSE
|
||||||
|
|
||||||
|
Copyright (C) 2026 Rootiest
|
||||||
|
|
||||||
|
This project is licensed under the **GNU Affero General Public License v3.0 or later** (AGPLv3+).
|
||||||
|
See the [LICENSE](https://git.rootiest.dev/rootiest/fish-config/src/branch/main/LICENSE) file for the full license text.
|
||||||
|
|||||||
@@ -7,51 +7,6 @@ sidebar:
|
|||||||
order: 4
|
order: 4
|
||||||
---
|
---
|
||||||
|
|
||||||
1. Configuration Variables
|
<!-- GENERATED: toc -->
|
||||||
2. PATH Setup
|
|
||||||
3. Key Bindings
|
|
||||||
4. Abbreviations
|
|
||||||
4.1 Editors
|
|
||||||
4.2 Navigation and Listing
|
|
||||||
4.3 Git
|
|
||||||
4.4 Terminal Windows, Tabs, and Panes
|
|
||||||
4.5 Chezmoi
|
|
||||||
4.6 Docker
|
|
||||||
4.7 Systemctl
|
|
||||||
4.8 AI Assistants
|
|
||||||
4.9 History Expansion
|
|
||||||
4.10 Miscellaneous
|
|
||||||
4.11 Shell Aliases
|
|
||||||
5. Functions Reference
|
|
||||||
5.1 File and Directory
|
|
||||||
5.2 Navigation
|
|
||||||
5.3 Editors and Viewers
|
|
||||||
5.4 Git and Version Control
|
|
||||||
5.5 Package Management
|
|
||||||
5.6 Dependency Management
|
|
||||||
5.7 System and Monitoring
|
|
||||||
5.8 Terminal Management
|
|
||||||
5.9 Clipboard
|
|
||||||
5.10 Network
|
|
||||||
5.11 Pager and Logging
|
|
||||||
5.12 AI and Developer Tools
|
|
||||||
5.13 Media and Utilities
|
|
||||||
5.14 Miscellaneous
|
|
||||||
6. Dependency Catalog
|
|
||||||
7. Customization
|
|
||||||
8. Fisher Plugins
|
|
||||||
9. Installation
|
|
||||||
10. Personalization
|
|
||||||
11. Troubleshooting
|
|
||||||
11.1 Uninstalling and Reverting to Backup
|
|
||||||
11.2 Fish Version Requirement
|
|
||||||
11.3 Enable or Disable Session Logging
|
|
||||||
11.4 Change or Disable the Greeting
|
|
||||||
11.5 Secrets and Machine-Local Configuration
|
|
||||||
11.6 Tool Init Does Nothing (Return Sentinel)
|
|
||||||
11.7 Missing Dependencies
|
|
||||||
11.8 Vi Mode Keybindings
|
|
||||||
11.9 What's with the C1-C6 stuff?
|
|
||||||
12. Viewing This Manual
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
title: Testing
|
||||||
|
manTitle: 14. TESTING
|
||||||
|
sidebar:
|
||||||
|
order: 18
|
||||||
|
helpKeywords:
|
||||||
|
- testing
|
||||||
|
- tests
|
||||||
|
- test-suite
|
||||||
|
- run-tests
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- README: Testing -->
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
title: Contributing
|
||||||
|
manTitle: 15. CONTRIBUTING
|
||||||
|
sidebar:
|
||||||
|
order: 19
|
||||||
|
helpKeywords:
|
||||||
|
- contributing
|
||||||
|
- contribute
|
||||||
|
- pull-request
|
||||||
|
- fork
|
||||||
|
- issues
|
||||||
|
- forge
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- README: Contributing -->
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
title: Attribution
|
||||||
|
manTitle: 16. ATTRIBUTION
|
||||||
|
sidebar:
|
||||||
|
order: 20
|
||||||
|
helpKeywords:
|
||||||
|
- attribution
|
||||||
|
- credits
|
||||||
|
- zoxide
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- README: Attribution -->
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
title: License
|
||||||
|
manTitle: 17. LICENSE
|
||||||
|
sidebar:
|
||||||
|
order: 21
|
||||||
|
helpKeywords:
|
||||||
|
- license
|
||||||
|
- licensing
|
||||||
|
- agpl
|
||||||
|
- copyright
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- README: License -->
|
||||||
@@ -28,6 +28,11 @@ export default defineConfig({
|
|||||||
label: 'Gitea',
|
label: 'Gitea',
|
||||||
href: 'https://git.rootiest.dev/rootiest/fish-config',
|
href: 'https://git.rootiest.dev/rootiest/fish-config',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
icon: 'github',
|
||||||
|
label: 'GitHub',
|
||||||
|
href: 'https://github.com/rootiest/fish-config',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
components: {
|
components: {
|
||||||
SocialIcons: './src/components/starlight/SocialIcons.astro',
|
SocialIcons: './src/components/starlight/SocialIcons.astro',
|
||||||
|
|||||||
Reference in New Issue
Block a user