Resolves the 18 findings from the parallel codebase review, tracked in
development/vimwiki-gap.md.
Correctness / perf:
- Wiki.config -> Arc<WikiConfig> so cloning a Wiki is a refcount bump (R5)
- WorkspaceIndex::remove is no longer O(n^2): a per-source contributions
map limits the scan to buckets the source actually wrote into (R6)
- render_color now expands color_tag_template (__STYLE__/__CONTENT__),
consuming the previously-dead field; ColorNode documented as an
extension point; 3 renderer tests added (R3/R4)
- wiki_root_for returns empty/nil on no-match instead of falling back to
the first wiki (R2); auto_header honours links_space_char (R7)
Cleanup / dedup:
- Remove dead #[allow(dead_code)] stubs + uncalled pub helpers, narrow
imports (R10/R11)
- Dedup span_of_inline x3 -> InlineNode::span() (R12)
- diary_step single read lock; page_captions single pass (R13)
- Lua auto_header loop -> wiki_list(); detect_current_symbol cleanup
(R14/R18)
Client / docs:
- :VimwikiNormalizeLink Vim cmds -> <q-args> (R17); ftplugin header fix
(R16); vars.vim multi-wiki limitation documented (R15)
- Document 19 config options in README.md + doc/nuwiki.txt; fix
list_margin/shiftwidth doc and stale comments (R1/R9)
- R8 investigated, confirmed not a real bug (documented)
Verified: Neovim harness 307, Vim harness 301/18/21, Rust suite 568, all
0 failed; clippy clean; fresh parallel-agent audit found no regressions.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the Lexer/Parser/SyntaxPlugin traits and the SyntaxRegistry per
SPEC.md §6.3.
- `Lexer<Token>` and `Parser<Token>` are typed building blocks: each
syntax owns its own token alphabet (vimwiki today, markdown later).
- `TokenStream<T>` is a `Vec<T>` newtype so the eager-vs-lazy choice
(§6.6) can flip later without breaking callers.
- `SyntaxPlugin` is type-erased: it exposes id / display_name /
file_extensions / parse(text) so the registry can hold heterogeneous
plugins behind a single trait object. Implementations chain their
Lexer + Parser inside parse().
- `SyntaxPlugin: Send + Sync` so the LSP server can stash plugins in
an Arc and share them across handler tasks.
- `SyntaxRegistry` stores `Arc<dyn SyntaxPlugin>`, supports lookup by
id and by file extension, iteration in registration order.
Tests cover TokenStream round-trip, full lex→parse chain through a
mock plugin, registry lookup hits and misses, and a compile-time
assert_send_sync::<SyntaxRegistry>().
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>