diff --git a/docs/build-manual.py b/docs/build-manual.py
index bf4dfc2..3154a20 100644
--- a/docs/build-manual.py
+++ b/docs/build-manual.py
@@ -315,7 +315,7 @@ def _as_ruled_table(para: list[str]) -> str | None:
TREE_ROOT_RE = re.compile(r"^[~$][\w./{}-]*/$")
-TREE_BRANCH_RE = re.compile(r"^[├└]──\s*(\S+)\s*(.*)$")
+TREE_BRANCH_RE = re.compile(r"^([│ \t]*)[├└]──\s*(\S+)\s*(.*)$")
def _as_file_tree(para: list[str]) -> str | None:
@@ -329,7 +329,10 @@ def _as_file_tree(para: list[str]) -> str | None:
return None
branches.append(m.groups())
out = ["", f"- {para[0].strip()}"]
- out += [f" - {name} {desc}".rstrip() for name, desc in branches]
+ for prefix, name, desc in branches:
+ depth = len(prefix.replace('\t', ' ')) // 4
+ indent = " " * (depth + 1)
+ out.append(f"{indent}- {name} {desc}".rstrip())
out.append("")
return "\n".join(out)
diff --git a/docs/fish-config.md b/docs/fish-config.md
index 053e423..7da92fe 100644
--- a/docs/fish-config.md
+++ b/docs/fish-config.md
@@ -53,41 +53,42 @@ A production-grade Fish shell configuration targeting Fish 4.x. It provides:
The configuration is split across:
- config.fish Main entry point; sets env vars and PATH
- conf.d/
- abbr.fish All abbreviations
- autopair.fish Auto-pair brackets and quotes (bundled from jorgebucaran/autopair.fish)
- cheat.fish cheat.sh tab completions
- done.fish Desktop notifications for long commands
- first_run.fish One-time init: Fisher bootstrap, theme, welcome
- key_bindings.fish Custom key bindings and Vi mode
- logging-events.fish C5 --on-variable event handlers; syncs logging state at startup
- kitty-watcher-reminder.fish C5 per-session reminder to set up the Kitty watcher
- paru-wrapper.fish Auto-generates ~/.local/bin/paru logging wrapper
- puffer.fish !! / !$ / ./ expansion (bundled from nickeb96/puffer-fish)
- tmux-logging.fish C5 starts tmux pipe-pane capture when fish runs inside tmux
- zellij-logging.fish C5 fish_exit handler dumping zellij pane scrollback on exit
- sponge_privacy.fish Sponge privacy patterns; filters credentials from history
- starship.fish fish_prompt with OSC 133 shell-integration markers
- tailscale.fish Tailscale CLI tab completions
- theme.fish Catppuccin syntax highlight colors
- tricks.fish PATH, bang-bang helpers, bat man pages, aliases
- wakatime.fish WakaTime shell hook
- yay-wrapper.fish Auto-generates ~/.local/bin/yay logging wrapper
- zoxide.fish Zoxide z/zi integration; overrides cd
- functions/ Custom functions, one per file, autoloaded
- completions/ Tab completion scripts
- integrations/
- fzf.fish FZF Catppuccin theme and key binding config
- scripts/
- clean_progress_log.py Strips paru/yay typescript animations to clean static logs
- agents-tools/ AGENTS.md version-bump script and git hooks (wired via core.hooksPath)
- docs/ Offline documentation and compiled man page
- fish-config.md Primary source manual (terminal-readable)
- fish-config.1 Compiled man page (auto-generated by CI)
- fish-config.index Section index for help config navigation
- html/ Chunked HTML docs (auto-generated by CI)
- wiki/ Markdown wiki (auto-generated by CI)
+ ~/.config/fish/
+ ├── config.fish Main entry point; sets env vars and PATH
+ ├── conf.d/
+ │ ├── abbr.fish All abbreviations
+ │ ├── autopair.fish Auto-pair brackets and quotes (bundled from jorgebucaran/autopair.fish)
+ │ ├── cheat.fish cheat.sh tab completions
+ │ ├── done.fish Desktop notifications for long commands
+ │ ├── first_run.fish One-time init: Fisher bootstrap, theme, welcome
+ │ ├── key_bindings.fish Custom key bindings and Vi mode
+ │ ├── logging-events.fish C5 --on-variable event handlers; syncs logging state at startup
+ │ ├── kitty-watcher-reminder.fish C5 per-session reminder to set up the Kitty watcher
+ │ ├── paru-wrapper.fish Auto-generates ~/.local/bin/paru logging wrapper
+ │ ├── puffer.fish !! / !$ / ./ expansion (bundled from nickeb96/puffer-fish)
+ │ ├── tmux-logging.fish C5 starts tmux pipe-pane capture when fish runs inside tmux
+ │ ├── zellij-logging.fish C5 fish_exit handler dumping zellij pane scrollback on exit
+ │ ├── sponge_privacy.fish Sponge privacy patterns; filters credentials from history
+ │ ├── starship.fish fish_prompt with OSC 133 shell-integration markers
+ │ ├── tailscale.fish Tailscale CLI tab completions
+ │ ├── theme.fish Catppuccin syntax highlight colors
+ │ ├── tricks.fish PATH, bang-bang helpers, bat man pages, aliases
+ │ ├── wakatime.fish WakaTime shell hook
+ │ ├── yay-wrapper.fish Auto-generates ~/.local/bin/yay logging wrapper
+ │ └── zoxide.fish Zoxide z/zi integration; overrides cd
+ ├── functions/ Custom functions, one per file, autoloaded
+ ├── completions/ Tab completion scripts
+ ├── integrations/
+ │ └── fzf.fish FZF Catppuccin theme and key binding config
+ ├── scripts/
+ │ ├── clean_progress_log.py Strips paru/yay typescript animations to clean static logs
+ │ └── agents-tools/ AGENTS.md version-bump script and git hooks (wired via core.hooksPath)
+ └── docs/ Offline documentation and compiled man page
+ ├── fish-config.md Primary source manual (terminal-readable)
+ ├── fish-config.1 Compiled man page (auto-generated by CI)
+ ├── fish-config.index Section index for help config navigation
+ ├── html/ Chunked HTML docs (auto-generated by CI)
+ └── wiki/ Markdown wiki (auto-generated by CI)
---
diff --git a/docs/manual/index.md b/docs/manual/index.md
index 7e19354..794c964 100644
--- a/docs/manual/index.md
+++ b/docs/manual/index.md
@@ -38,40 +38,41 @@ A production-grade Fish shell configuration targeting Fish 4.x. It provides:
The configuration is split across:
- config.fish Main entry point; sets env vars and PATH
- conf.d/
- abbr.fish All abbreviations
- autopair.fish Auto-pair brackets and quotes (bundled from jorgebucaran/autopair.fish)
- cheat.fish cheat.sh tab completions
- done.fish Desktop notifications for long commands
- first_run.fish One-time init: Fisher bootstrap, theme, welcome
- key_bindings.fish Custom key bindings and Vi mode
- logging-events.fish C5 --on-variable event handlers; syncs logging state at startup
- kitty-watcher-reminder.fish C5 per-session reminder to set up the Kitty watcher
- paru-wrapper.fish Auto-generates ~/.local/bin/paru logging wrapper
- puffer.fish !! / !$ / ./ expansion (bundled from nickeb96/puffer-fish)
- tmux-logging.fish C5 starts tmux pipe-pane capture when fish runs inside tmux
- zellij-logging.fish C5 fish_exit handler dumping zellij pane scrollback on exit
- sponge_privacy.fish Sponge privacy patterns; filters credentials from history
- starship.fish fish_prompt with OSC 133 shell-integration markers
- tailscale.fish Tailscale CLI tab completions
- theme.fish Catppuccin syntax highlight colors
- tricks.fish PATH, bang-bang helpers, bat man pages, aliases
- wakatime.fish WakaTime shell hook
- yay-wrapper.fish Auto-generates ~/.local/bin/yay logging wrapper
- zoxide.fish Zoxide z/zi integration; overrides cd
- functions/ Custom functions, one per file, autoloaded
- completions/ Tab completion scripts
- integrations/
- fzf.fish FZF Catppuccin theme and key binding config
- scripts/
- clean_progress_log.py Strips paru/yay typescript animations to clean static logs
- agents-tools/ AGENTS.md version-bump script and git hooks (wired via core.hooksPath)
- docs/ Offline documentation and compiled man page
- fish-config.md Primary source manual (terminal-readable)
- fish-config.1 Compiled man page (auto-generated by CI)
- fish-config.index Section index for help config navigation
- html/ Chunked HTML docs (auto-generated by CI)
- wiki/ Markdown wiki (auto-generated by CI)
+ ~/.config/fish/
+ ├── config.fish Main entry point; sets env vars and PATH
+ ├── conf.d/
+ │ ├── abbr.fish All abbreviations
+ │ ├── autopair.fish Auto-pair brackets and quotes (bundled from jorgebucaran/autopair.fish)
+ │ ├── cheat.fish cheat.sh tab completions
+ │ ├── done.fish Desktop notifications for long commands
+ │ ├── first_run.fish One-time init: Fisher bootstrap, theme, welcome
+ │ ├── key_bindings.fish Custom key bindings and Vi mode
+ │ ├── logging-events.fish C5 --on-variable event handlers; syncs logging state at startup
+ │ ├── kitty-watcher-reminder.fish C5 per-session reminder to set up the Kitty watcher
+ │ ├── paru-wrapper.fish Auto-generates ~/.local/bin/paru logging wrapper
+ │ ├── puffer.fish !! / !$ / ./ expansion (bundled from nickeb96/puffer-fish)
+ │ ├── tmux-logging.fish C5 starts tmux pipe-pane capture when fish runs inside tmux
+ │ ├── zellij-logging.fish C5 fish_exit handler dumping zellij pane scrollback on exit
+ │ ├── sponge_privacy.fish Sponge privacy patterns; filters credentials from history
+ │ ├── starship.fish fish_prompt with OSC 133 shell-integration markers
+ │ ├── tailscale.fish Tailscale CLI tab completions
+ │ ├── theme.fish Catppuccin syntax highlight colors
+ │ ├── tricks.fish PATH, bang-bang helpers, bat man pages, aliases
+ │ ├── wakatime.fish WakaTime shell hook
+ │ ├── yay-wrapper.fish Auto-generates ~/.local/bin/yay logging wrapper
+ │ └── zoxide.fish Zoxide z/zi integration; overrides cd
+ ├── functions/ Custom functions, one per file, autoloaded
+ ├── completions/ Tab completion scripts
+ ├── integrations/
+ │ └── fzf.fish FZF Catppuccin theme and key binding config
+ ├── scripts/
+ │ ├── clean_progress_log.py Strips paru/yay typescript animations to clean static logs
+ │ └── agents-tools/ AGENTS.md version-bump script and git hooks (wired via core.hooksPath)
+ └── docs/ Offline documentation and compiled man page
+ ├── fish-config.md Primary source manual (terminal-readable)
+ ├── fish-config.1 Compiled man page (auto-generated by CI)
+ ├── fish-config.index Section index for help config navigation
+ ├── html/ Chunked HTML docs (auto-generated by CI)
+ └── wiki/ Markdown wiki (auto-generated by CI)
---
diff --git a/docs/verify-manual.py b/docs/verify-manual.py
index 58d15c6..c235eb5 100644
--- a/docs/verify-manual.py
+++ b/docs/verify-manual.py
@@ -307,7 +307,7 @@ def test_site_build_produces_function_pages():
out = Path(d)
sidebar = build_manual.build_site(docs / "manual", out)
pages = list(out.rglob("*.md*"))
- assert (out / "index.md").exists(), "landing page missing"
+ assert (out / "index.md").exists() or (out / "index.mdx").exists(), "landing page missing"
fn_pages = [p for p in pages if "reference" in p.parts and p.name != "index.mdx"]
assert len(fn_pages) > 80, f"expected >80 function pages, got {len(fn_pages)}"
assert not (out / "00-name.md").exists(), "site:false page was published"
@@ -665,8 +665,8 @@ def test_as_file_tree_rejects_non_trees():
assert build_manual._as_file_tree(para) is None, f"{label} was wrongly treed"
-def test_as_file_tree_rejects_deeper_trees():
- """A tree with a second-level (indented) branch line is not detected — falls through to verbatim rendering."""
+def test_as_file_tree_accepts_deeper_trees():
+ """A tree with indented branch lines becomes a Starlight with nested markdown lists."""
import build_manual
para = [
@@ -675,7 +675,15 @@ def test_as_file_tree_rejects_deeper_trees():
"│ └── main.fish",
"└── README.md",
]
- assert build_manual._as_file_tree(para) is None
+ out = build_manual._as_file_tree(para)
+ assert out == (
+ "\n"
+ "- ~/proj/\n"
+ " - src/\n"
+ " - main.fish\n"
+ " - README.md\n"
+ ""
+ ), f"unexpected file tree output:\n{out}"
def test_customization_notes_render_as_aside():