ee0309b3c2a35d2691f840b99e86d07ea1dc0eda
14 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ee0309b3c2 |
parity(1): vimwiki per-wiki config keys, table colspan/rowspan,
named link commands, mouse maps
Parity audit Cluster 1 — small wins.
WikiConfig (server) extended with 14 vimwiki globals:
- `index` (`g:vimwiki_index`), wired into `:VimwikiIndex` so users
with a custom index page stem (e.g. `home`) get the right file.
- `diary_frequency`, `diary_start_week_day`, `diary_caption_level`,
`diary_sort`, `diary_header` — diary keys (weekly/monthly/yearly
semantics land in Cluster 4; the keys parse now so config
migration doesn't need to wait).
- `maxhi`, `listsyms`, `listsyms_propagate`, `list_margin`,
`links_space_char`, `nested_syntaxes`, `auto_toc` — list +
highlight knobs the renderer/handlers can consult.
All keys threaded through `RawWiki` → `WikiConfig::from(RawWiki)`,
defaults centralised in `wiki_defaults()` so `empty()`, `from_root()`,
the legacy single-wiki path, and the `RawWiki` impl stay in sync.
Lua front-door (`lua/nuwiki/config.lua`) now documents the multi-wiki
`wikis = {…}` shape with every accepted per-wiki key — users who
prefer Lua tables no longer have to round-trip through
`init_options` raw JSON.
HTML renderer (`crates/nuwiki-core/src/render/html.rs`):
- New `table_spans()` pre-pass resolves vimwiki's `>` (col_span) and
`\\/` (row_span) continuation markers into proper HTML
`colspan="N"` / `rowspan="N"` attributes on the lead cell. Continuation
cells emit nothing, matching what browsers expect.
- The old behaviour (emitting `class="col-span"` / `class="row-span"`
as visual markers) is gone — replaced with real merging so the
rendered HTML matches the source semantics.
Named ex-commands:
- `:VimwikiNextLink` / `:VimwikiPrevLink` — were keymapped only
(`<Tab>`/`<S-Tab>`); now have explicit `:` commands in both editor
paths, dispatching to new `nuwiki.commands.link_next` / `link_prev`
pure-Vim/Lua helpers.
- `:VimwikiBaddLink` — adds the link target's file to the buffer
list without switching focus. Goes through
`textDocument/definition` and runs `:badd <fname>` on the resolved
URI.
Mouse maps (opt-in via `mappings.mouse = true` in Lua or
`g:nuwiki_mouse_mappings = 1` in Vim):
- `<2-LeftMouse>` follows, `<S-2-LeftMouse>` / `<C-2-LeftMouse>`
follow in split/vsplit, `<MiddleMouse>` adds to buflist,
`<RightMouse>` goes back. Mirrors upstream vimwiki's defaults.
Tests: 7 new in `parity_cluster_1.rs` covering the per-wiki config
defaults + raw JSON parse, the legacy-single-wiki path, colspan
folding into a lead cell with no leftover class markers, rowspan
across rows, no-attrs when the table has no spans, and a sanity
paragraph render. Total 421 Rust tests pass; clippy clean; both
keymap harnesses still green (20 nvim + 12 vim).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
de8b8fa30d |
feat(13.1): colorize + color_dic → ColorNode renderer
Closes the last pending §13.1 entries: - **`nuwiki.colorize`** (client-side, Lua + VimL) — wraps the word at cursor (or the visual selection on Neovim) in an inline `<span style="color:%c">…</span>` template. Matches vimwiki's default `color_tag_template`. Bound to `<Leader>wc` in both normal and visual mode on both editor paths; the previous "deferred" stub is gone. - **`color_dic` → renderer** — `HtmlConfig` gains a `color_dic: HashMap<String, String>` field reading the same key out of `initializationOptions` / `didChangeConfiguration`. The HTML export path threads it into `HtmlRenderer::with_colors`; `ColorNode` now picks `style="color:<value>"` when the colour name is in the dict, falling back to the existing `class="color-<name>"` when it isn't. SPEC §13.1 is fully checked off — the table moved from "deferred sketch" to a per-command status table marking all 11 commands done, plus a note on the `color_dic` follow-up landing alongside. README's "Phase 14 list & table edit commands" row now reads ✅ without the deferred-subset caveat, and the §13.1-blocked text-objects note in the keymaps section is rephrased as "planned follow-ups". Tests: 4 new in `phase17_colorize.rs` covering the renderer fallback when the dict is empty, the inline-style emission for a listed name, the fallback path for an unlisted name in a populated dict, and the `initializationOptions` JSON shape. Total 414 Rust tests pass; clippy clean; keymap harness still 20/20. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
4245424d2f |
feat(13.1-B): table rewriters — insert, align, moveColumn
Closes the table-rewriter cluster from SPEC §13.1. Server-side (ops module): - `render_blank_table(cols, rows)` — pure templating: header row, separator `|--|--|--|`, then `rows` empty data rows. Wired through `table_insert` which dispatches a `TextEdit` at the cursor. - `table_align_edit` — locates the `TableNode` containing the cursor line, computes max width per column across every row, re-emits the table with each cell space-padded to its column's width. The parser drops `|---|---|` separator rows but sets `TableNode.has_header`; the renderer re-inserts a padded separator after the header so the result still parses. - `table_move_column_edit` — column-under-cursor swap with the left or right neighbour (`dir = "left" | "right"`). Cursor column is computed by counting pipe separators before the cursor's byte offset on the row's line. Column widths swap alongside the data so the post-swap table stays aligned. No-ops cleanly when the swap would fall off either edge. Editor glue: - `lua/nuwiki/commands.lua` / `autoload/nuwiki/commands.vim` — the three "not yet implemented" stubs are replaced with real LSP dispatchers. `table_insert` accepts optional `cols`/`rows` arguments (defaults: 3×2). - Default keymaps `gqq` / `gq1` / `gww` / `gw1` now call `table_align`; `<A-Left>` / `<A-Right>` call `table_move_column_left` / `_right`. No more "deferred" notifications on the table keys. Tests: 8 new in `cluster_b_table_rewriters.rs` — blank-table shape (3×2 + 1×1), column-width alignment with separator-row repad, swap- right shape, swap-left clamp at column 0, no-table-found fallbacks, COMMANDS list completeness. Total 410 Rust tests pass; clippy clean; Neovim keymap harness still 20/20. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
9d34c8baa2 |
feat(13.1-A): list rewriters — removeDone, renumber, changeSymbol/Level
Closes the four-command list-rewriter cluster from SPEC §13.1. Server-side (commands.rs ops module): - `parse_symbol` / `render_marker` — round-trip between `:VimwikiListChangeSymbol` arg shapes (`-`, `1.`, `a)`, `i)`, `Dash`, `Numeric`, …) and the rendered marker text. `render_marker` knows how to spell `a/b/…/z/aa` and `i/ii/iv/v/…/MMM` for the alphabetic + roman variants. - `remove_done_edit` — walks every list (recursively through blockquotes and sublists), emits delete TextEdits for items whose checkbox is `Done` or `Rejected`. Item span gets extended through the trailing newline so we don't leave behind empty lines. Accepts an optional `position` to scope the operation to the item under cursor + its descendants. - `renumber_edit` — finds the list containing the cursor line (or every list when `whole_file: true`), re-sequences numeric markers in-place. Unordered lists are left alone. - `change_symbol_edit` — rewrites the leading marker on a single item, or every item in a list when `whole_list: true`. Uses `render_marker` so ordered variants get the right index. - `change_level_edit` — re-indents the marker line (or every line of the item subtree when `whole_subtree: true`) by ±2 spaces per level. Dedent clamps at column 0. - `find_list_at_line` + `find_marker_span` — pure helpers reused by the three above. Editor glue: - `lua/nuwiki/commands.lua` / `autoload/nuwiki/commands.vim` — removed all four "not yet implemented" stubs and wired them to the real LSP commands. Lua also exposes `list_change_lvl(direction)` for the `:VimwikiListChangeLvl decrease|increase` compat entry. - Keymaps for `glh` / `gll` / `gLh` / `gLl` (list level single + subtree), `glr` / `gLr` (renumber list + whole-file), `gl<Space>` / `gL<Space>` (remove done items) now hit the real commands instead of printing a "deferred" notification. Tests: 16 new in `cluster_a_list_rewriters.rs` covering symbol parsing, marker rendering (alpha + roman + numeric), removeDone shape, scoped removeDone, no-match cases, renumber sequencing, whole-file walk, changeSymbol single + whole-list, changeLevel single + subtree + clamp, and COMMANDS list completeness. Total 402 Rust tests pass; clippy clean; keymap harness still at 20/20. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
cebc806ce3 |
feat(13.1-C): link helpers — pasteWikilink, pasteUrl, normalize
Closing out §13.1's smallest cluster. Three commands move from "not yet implemented" stubs to real behaviour: - `nuwiki.link.pasteWikilink` (server, executeCommand) — derives the current page name from the source URI + wiki root, returns a `WorkspaceEdit` inserting `[[<page>]]` at the requested cursor position. - `nuwiki.link.pasteUrl` (server) — same lookup, but the inserted text is the page's relative HTML output URL (`<page>.html`, including subdir segments) so the snippet survives when the export root moves. - `nuwiki.link.normalize` (client) — wraps the word at cursor as `[[word]]` without following. Reuses the `wrap_cword_as_wikilink` helper that already powers the `<CR>` two-step. Pure-VimL on the Vim path; pure-Lua on the Neovim path. No LSP round-trip. Keymaps: - `+` (normal + visual) now actually calls `normalize_link` on both editor paths instead of stubbing with a "deferred" notification. Tests: - 5 new Rust unit tests in `cluster_c_link_helpers.rs` covering command-list presence + the page-name derivation for root and subdirectory pages + the URL / wikilink shape strings. - Neovim keymap harness gains a `links.normalize_via_+` case (20 passing now, up from 19). Vim harness inherits the same command-presence check via its existing smoke tests. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
347e2f02f7 |
fix(follow-link): create missing page + wrap word on <CR>
Two missing pieces in the previous "follow creates page" fix:
1. **`wiki_root` never reached the server.** The Lua glue (and the
Vim autoload glue) was sending the config under `settings` — that
field is for `workspace/didChangeConfiguration` notifications, not
for `initialize`. The server's `Config::from_init_params` reads
`initialization_options`, so `wiki_root` arrived as `None`, the
`Wiki` aggregate was empty, and `wiki_for_uri` returned `None` →
`resolve_target_uri` bailed before reaching my synthesise path,
leaving `<CR>` with "No Location Found".
Both glues now send the same payload under both keys:
- `lua/nuwiki/lsp.lua` → adds `init_options = init_options()`
alongside the existing `settings = …`.
- `autoload/nuwiki/lsp.vim` → adds `initialization_options` to
the `lsp#register_server` call.
The server keeps reading from `initializationOptions` at startup
*and* honouring `didChangeConfiguration` later (Phase 11 plumbing).
2. **No-wiki fallback in the server.** Even with the glue fix above,
users who launch nuwiki on an ad-hoc `.wiki` file outside any
workspace folder would still get an empty `wikis` list. The
`LinkKind::Wiki` arm now falls back to a new
`synthesise_page_uri_next_to(source_uri, path)` which builds the
future page next to the current file. `<CR>` on `[[NewPage]]`
opens `./NewPage.wiki`, save creates it.
3. **`<CR>` on a plain word now wraps + follows.** Mirrors vimwiki's
`:VimwikiFollowLink`: when the cursor isn't already inside
`[[…]]`, the new `nuwiki.commands.follow_link_or_create` /
`nuwiki#commands#follow_link_or_create` first wraps the word
under cursor as `[[word]]`, places the cursor inside the link,
then dispatches `vim.lsp.buf.definition()` /
`:LspDefinition`. Both editor paths now bind `<CR>` /
`<S-CR>` / `<C-CR>` / `<C-S-CR>` to this smart variant.
Verified end-to-end:
- `[[NewPage]]` with the rebuilt binary: definition returns
`file:///tmp/wiki/NewPage.wiki` as a Location, so the editor
opens an empty buffer for it.
- A bare `MyPage` word becomes `[[MyPage]]` in the buffer before
the follow request fires.
Total 381 tests still pass; fmt + clippy clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
9d86218b13 |
fix(keymap): C-Space toggle fires across all terminal byte spellings
User reported Ctrl+Space didn't toggle list items. Three things contributed: 1. **Terminal byte ambiguity.** Different terminals encode Ctrl+Space differently — GUI / kitty protocol sends `<C-Space>`, xterm and most legacy terms send NUL which Vim sees as `<C-@>` (or, in some Neovim builds, `<Nul>` in keymap.lhs). The previous keymap registered only `<C-Space>` + `<C-@>`. Added the `<Nul>` alias too (both Lua and VimL paths) so the binding fires regardless of what byte the user's terminal produces. 2. **Deprecated `vim.lsp.util.make_position_params`.** Neovim 0.12 requires `position_encoding` explicitly. The old no-arg call now prints a deprecation warning, and in stricter setups returns nil — which made the command's `arguments` malformed and the `executeCommand` request silently fail. `position_params()` now pulls `offset_encoding` from the resolved client and passes both args, with a `pcall`-guarded fallback to the no-arg form for Neovim < 0.10. 3. **Deprecated `client.request(...)` dot-call.** Same Neovim 0.12 change — `Client:request()` is the method form. Use the colon call now; both arities are preserved for back-compat. Verified end-to-end: feeding all three of `<C-Space>` / `<C-@>` / `<Nul>` via `nvim_feedkeys` toggles the checkbox; `:messages` no longer carries the deprecation warnings. 381 tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
d58a34a2d7 |
feat(vim): close keymap gap with Neovim (47 → 63 maps)
The previous commit registered the parity surface on Neovim but only ported ~75% to plain Vim. Filling the remaining 16: autoload/nuwiki/commands.vim — new functions: - `wiki_ui_select` — Vim has no `vim.ui.select`, so route through `inputlist()` after fetching the wiki list via the LSP. - `open_below_with_bullet` / `open_above_with_bullet` — port of the Lua `o` / `O` continuation that preserves the list marker (and a `[ ]` checkbox when present) on the new line. - `next_header` / `prev_header` / `next_sibling_header` / `prev_sibling_header` / `parent_header` — port of the Lua heading jumper. Pure VimL, no LSP round-trip. ftplugin/vimwiki.vim (Vim path) new mappings: - `<Leader>ws` → `wiki_ui_select` - `]=` / `[=` → next / prev sibling header - `]u` / `[u` → parent header - `o` / `O` → bullet continuation - `gl<Space>` / `gL<Space>` → :VimwikiRemove*CB stubs - `gq1` / `gw1` → :VimwikiTableAlignQ1/W1 stubs - x-mode variants for `+`, `<Leader>wc`, `gln`, `glp`, `glx` Replaced the regex-based `]]` / `[[` (which just searched `^\s*=\+\s`) with calls into the new heading nav so they skip non-heading `=` runs and respect heading levels. Verified end-to-end: `silent map <buffer>` reports 63 maps on Vim, matching Neovim's 63. All 377 Rust tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
9e6faa5554 |
feat(mappings): vimwiki-parity default keymaps for Vim + Neovim
The Phase 19 keymap layer only covered the high-value subset and used `g=`/`g-` instead of vimwiki's `=`/`-` for header levels. Users reporting "mappings don't seem to be working" were either on the Vim path (which registered zero keymaps) or hitting bindings that don't exist (e.g. `<Tab>`, `<S-CR>`, `gll`, `gqq`). Cross-referenced upstream vimwiki/ftplugin/vimwiki.vim and rewired both `lua/nuwiki/keymaps.lua` and `ftplugin/vimwiki.vim` (Vim path) to match its default surface. Mappings backed by commands that exist on the server dispatch directly; §13.1-deferred mappings register with the same lhs but stub out to a notification — so users get parity *signalling*, not silence. New on Neovim (and matched on Vim where possible): Links group: - `<S-CR>` / `<C-CR>` / `<C-S-CR>` — follow in split / vsplit / tab - `<Tab>` / `<S-Tab>` — jump to next / prev `[[…]]` (pure Lua search) - `+` (n + x) — :VimwikiNormalizeLink stub - `<Leader>wc` (n + x) — :VimwikiColorize stub Lists group: - `<C-@>` (n + x) — terminal-alt for `<C-Space>` - `gln` / `glp` increment + decrement (deferred backward; same fn for now) - `glh` / `gll` / `gLh` / `gLl` — list level stubs - `glr` / `gLr` — list renumber stubs - `gl<Space>` / `gL<Space>` — checkbox remove stubs - `o` / `O` — open below/above and continue the bullet (pure Lua) - visual-mode variants of `<C-Space>`, `gln`, `glp`, `glx` Header group (key group, now buffer-local): - `=` / `-` — promote / demote (was `g=`/`g-`, matched to vimwiki) - `]]` / `[[` — next / prev header (pure Lua) - `]=` / `[=` — next / prev sibling header (pure Lua) - `]u` / `[u` — parent header (pure Lua) Table group: `gqq`, `gq1`, `gww`, `gw1`, `<A-Left>`, `<A-Right>` stubs. Wiki prefix: `<Leader>w<Leader>m` (vimwiki's tomorrow), `<Leader>w<Leader>i` (rebuild diary index). Config schema (`config.options.mappings`) updates to vimwiki's group names — `links` / `lists` / `headers` / `table_editing` / `diary` / `html_export` / `text_objects` / `wiki_prefix`. Old names (`list_editing` / `header_nav`) are retired; rename only — keeps the opt-out shape intact. Vim path: same set ported to buffer-local VimL maps. `g:nuwiki_no_default_mappings` opts out the whole layer for users who prefer their own bindings. Lua side uses the Neovim 0.11+ `vim.keymap.set` API; both call straight into the same `nuwiki#commands#…` autoload (Vim) / `nuwiki.commands` (Lua) layer that drives the LSP. Total 377 tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
04df170791 |
feat(vim): :Vimwiki* / :Nuwiki* commands for plain Vim via vim-lsp
The Phase 19 ftplugin only registered the command surface on Neovim
and finished early for plain Vim, leaving `start-vim.sh` users with
only commentstring + suffixesadd — exactly the "no commands" report.
`autoload/nuwiki/commands.vim` now ships the Vim-side dispatch:
- `s:exec` sends `workspace/executeCommand` through vim-lsp's
`lsp#send_request`. Optional callback for commands that return data.
- `s:open_uri_from` reads `{ uri }` out of the LSP response and runs
`:edit` (or `:tabedit` for the tab variants).
- `s:results_to_qf` lifts `checkLinks` / `findOrphans` / `tags.search`
arrays into the quickfix list and opens `:copen` — same UX as the
Neovim path.
- `s:open_browser` fires `open` / `xdg-open` after `export.browse`.
- §13.1 deferred commands stub out with a "not yet implemented"
notification so users get the same signal as on Neovim.
`ftplugin/vimwiki.vim` defines the same `:Vimwiki*` / `:Nuwiki*`
command set on the plain-Vim path, each delegating to its
`nuwiki#commands#…` autoload counterpart. `:VimwikiFollowLink` /
`:VimwikiBacklinks` map straight to vim-lsp's `:LspDefinition` /
`:LspReferences`. coc.nvim users can still use `:CocCommand` directly
and ignore the aliases entirely.
Verified with `vim -e -s -u .vimrc index.wiki`:
filetype=vimwiki, did_ftplugin=1,
:VimwikiTOC, :NuwikiIndex, :VimwikiToggleListItem all defined.
Total 377 tests still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
09b9bd98a3 |
fix(ftplugin): load on .wiki buffers without manual filetype override
Three reasons the plugin wasn't activating on `nvim --clean -u init.lua
foo.wiki`:
1. **File-name mismatch.** Vim's filetype-plugin runtime looks for
`ftplugin/<filetype>.vim` matching the *filetype name*. Our
filetype is `vimwiki` (per `ftdetect`) but the file was named
`ftplugin/nuwiki.vim` — so `:runtime! ftplugin/vimwiki.vim` from
the built-in FileType autocmd never found it, and none of the
`:Vimwiki*` / `:Nuwiki*` commands got defined. Same wart on the
syntax side. Renamed:
- `ftplugin/nuwiki.vim` → `ftplugin/vimwiki.vim`
- `syntax/nuwiki.vim` → `syntax/vimwiki.vim`
2. **`setfiletype` deferred to Neovim's bundled rule.** Neovim ships
a default `*.wiki → mediawiki` rule via `vim.filetype.add`, and
`:setfiletype vimwiki` is a no-op once a filetype has been set.
- `ftdetect/nuwiki.vim` now uses `set filetype=vimwiki` (force).
- `lua/nuwiki/init.lua`'s `setup()` also calls
`vim.filetype.add({ extension = { wiki = 'vimwiki', ... } })`
so the modern table-based detection picks us before the
bundled rule fires. Honours `config.options.file_extension`
so a user with a custom extension gets covered automatically.
3. **`foldmethod`/`foldexpr` are window-local options.**
`ftplugin.lua` was setting them with `nvim_set_option_value({ buf
= bufnr })`, which threw `'buf' cannot be passed for window-local
option 'foldmethod'` and aborted the rest of the per-buffer
attach. Switched to `vim.opt_local.*` (window-aware), applied on
the current window when the ftplugin fires, and re-applied via a
`BufWinEnter` autocmd so `:split` / `:vsplit` keep the fold mode.
Verified end-to-end with:
nvim --clean -u init.lua sample.wiki
→ filetype = vimwiki
→ :VimwikiTOC, :NuwikiIndex, … all defined
→ foldmethod = expr, foldexpr = v:lua.vim.lsp.foldexpr()
→ ftdetect, plugin, ftplugin, syntax all in :scriptnames
Total 377 tests still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
63e5b6d514 |
phase 19: editor glue v2
Server-side:
- New `folding.rs` module with `folding_ranges(ast, total_lines)`.
Emits one fold per top-level heading (start → line before the
next same-or-higher-level heading, or EOF) plus one per top-level
list block. Nested headings fold inside their parent thanks to the
level-aware end-line computation; sublists fold implicitly via
their parent item's source span. `FoldingRangeKind::Region` is set
on every fold so collapsing UIs render them as section folds.
- `Backend::folding_range` handler wires the module into
`textDocument/foldingRange`; `ServerCapabilities.folding_range_provider`
advertises it.
- `folding::line_count` exposed for the handler and tests; treats a
trailing newline as a virtual empty line (the line LSP positions
use for EOF).
Editor glue (Neovim primary, Vim minimal):
- `lua/nuwiki/commands.lua` — async `workspace/executeCommand`
wrappers for every server command shipped through Phase 18. The
open-* family handles `{ uri }` responses by opening the file
(with `tab` / `split` variants). `check_links` and `find_orphans`
hand results to `setqflist` + `:copen` for quickfix-style review.
§13.1-deferred commands (`list.changeSymbol`, table rewriters,
`link.pasteWikilink/pasteUrl`, `colorize`) stub out with
`vim.notify` so users get a clear "not yet implemented" signal
instead of an LSP "unknown command" error.
- `lua/nuwiki/keymaps.lua` — buffer-local default mappings. Subgroups
(`list_editing`, `header_nav`, `diary`, `html_export`,
`text_objects`) flip independently via the new
`mappings.<group>` config. Heading promote/demote uses `g=`/`g-`
to avoid clobbering Vim's built-in `=`/`-` operators.
- `lua/nuwiki/textobjects.lua` — `ah`/`ih` (around/inside heading)
using a buffer scan for the heading-block boundary. The four
remaining text objects from SPEC §12.10 wait until §13.1 lands
the table/list rewriters they share infrastructure with.
- `lua/nuwiki/folding.lua` — pure regex `foldexpr` + `foldtext`
fallback for clients without `foldingRange`. Same heading-block
model as the server.
- `lua/nuwiki/ftplugin.lua` — single per-buffer attach entry point.
`folding = 'lsp'` (default) uses Neovim 0.11+'s `vim.lsp.foldexpr`,
falling back to the regex on older versions; `'expr'` forces the
fallback; `'off'` skips folding setup.
- `lua/nuwiki/config.lua` — extends defaults with `mappings = {...}`
(P10 keymap layer) and `folding` (P14 resolved).
- `ftplugin/nuwiki.vim` — declares every `:Vimwiki*` / `:Nuwiki*`
command from SPEC §12.10 by inlining `lua require(...).fn()`
bodies (no script-local function indirection so commands stay
callable after re-source). Plain-Vim users get only the buffer
options; they're expected to drive the LSP via vim-lsp / coc's
built-in commands.
Health check (§12.10 additions):
- `:checkhealth nuwiki` now reports the count of `executeCommand`
entries the server advertises, whether `foldingRange` capability
was negotiated, and whether the configured HTML output directory
exists + is writable. Default keymap subgroup status is also
surfaced.
Tests: 8 new in `phase19_folding.rs` covering empty docs, single
heading → EOF, sibling headings each getting their own fold,
nested heading bounded by parent, top-level list folds, single-line
heading non-fold, fold-kind classification, and `line_count`
semantics. Total 377 tests pass; fmt + clippy clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
ee61d40872 |
phase 9: editor glue — plugin, LSP wiring, install, health, docs
P5 + P6 resolved (SPEC §11): Neovim 0.11+ and Vim 9.1+.
Universal Vim entry:
- plugin/nuwiki.vim dispatches Vim vs Neovim. Neovim path waits for
the user's `require('nuwiki').setup()` call; Vim path starts the
LSP client on `FileType vimwiki` and exposes `:NuwikiInstall`.
- ftdetect/nuwiki.vim associates `*.wiki` with the `vimwiki` filetype.
- ftplugin/nuwiki.vim sets commentstring + comments + formatoptions +
suffixesadd + iskeyword, with a clean `b:undo_ftplugin`.
- syntax/nuwiki.vim ships default `@vimwiki*` highlight links for the
semantic-token legend (with `level1..6` + `centered` modifiers),
plus a minimal regex fallback so static highlighting works before
the LSP attaches.
Lua glue (Neovim 0.11+):
- init.lua exposes setup() / install() / health() — wiring only per
SPEC §6.2.
- config.lua holds the §7.5 schema (wiki_root / file_extension /
syntax / log_level) and a tbl_deep_extend apply().
- lsp.lua registers via `vim.lsp.config{} + vim.lsp.enable` on 0.11+;
falls back to a FileType autocmd calling `vim.lsp.start` on older
builds. Root dir walks up for `.git` / `.nuwiki`, then uses
wiki_root.
- install.lua does target-triple detection (Linux gnu/musl x x86_64/
aarch64, macOS arm/x86, Windows), curl+tar download from the
release URL, cp/chmod into bin/, with a cargo fallback. Honours
`g:nuwiki_build_from_source`.
- health.lua implements `:checkhealth nuwiki` per §7.6.
VimL glue (Vim 9.1+):
- autoload/nuwiki/lsp.vim follows §7.4 preference order:
vim-lsp (calls `lsp#register_server`) → coc.nvim (prints the
coc-settings.json snippet) → error.
- scripts/download_bin.vim mirrors the Lua installer for Dein /
vim-plug build hooks — same target triples, same download →
fallback → cargo build chain.
Help: doc/nuwiki.txt with tags for install (lazy.nvim / vim-plug /
Dein), config options, health, LSP feature list, `:NuwikiInstall`.
Rust workspace unchanged this phase; 172 tests still green locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
cf336ee839 |
phase 0: scaffold workspace, plugin layout, and CI
Lay down the empty repo skeleton defined in SPEC.md §5 so subsequent phases have somewhere to land: - Cargo workspace (resolver v2, edition 2021, MSRV 1.83) with nuwiki-core, nuwiki-lsp, nuwiki-ls — dep direction matches §6.2. - Vim/Neovim plugin directory layout (plugin, lua, autoload, ftdetect, ftplugin, syntax, doc, scripts) with header-only stubs. - .gitea/workflows/ci.yaml running fmt, clippy -D warnings, and tests pinned to Rust 1.83. - README, dual MIT/Apache-2.0 license texts, .gitignore. Verified: cargo check / fmt --check / clippy / test all clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |