Commit Graph

10 Commits

Author SHA1 Message Date
gffranco 95645a2b91 fix(syntax): highlight code blocks with embedded language syntax
CI / cargo fmt --check (push) Successful in 1m10s
CI / cargo clippy (push) Successful in 19s
CI / cargo test (push) Successful in 28s
Release / build x86_64-unknown-linux-gnu (push) Successful in 1m1s
Release / build aarch64-unknown-linux-musl (push) Successful in 54s
Release / build aarch64-unknown-linux-gnu (push) Successful in 1m8s
Release / build x86_64-unknown-linux-musl (push) Successful in 1m13s
CI / editor keymaps (push) Successful in 1m32s
Release / gitea release (push) Successful in 23s
`{{{lang … }}}` fences were painted as one String group. Add automatic
nested-syntax highlighting (like vimwiki): scan the buffer for the languages
used, `:syntax include` each under a cluster, and define a contained region
per language so e.g. `{{{sh` blocks get shell highlighting and `{{{python`
gets Python. Bare `{{{` / `{{{class="…"` fences fall back to nuwikiPreformatted.
A small alias map maps labels like bash/shell → sh.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 22:24:27 -03:00
gffranco fa2d1b8b42 feat(keywords): add STOPPED keyword
CI / cargo fmt --check (push) Successful in 26s
CI / cargo clippy (push) Successful in 19s
CI / cargo test (push) Successful in 31s
CI / editor keymaps (push) Successful in 1m18s
Adds STOPPED alongside TODO/DONE/STARTED/FIXME/FIXED/XXX across the stack:
lexer, AST Keyword enum, HTML renderer (class="stopped"), LSP keyword_str,
and the Vim syntax red group (nuwikiKeywordAttn). Grouped with the
attention/pending keywords (red) for both export and in-editor highlighting.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 22:05:23 -03:00
gffranco d2475e136b fix(syntax): colour keywords red/green like the HTML export
CI / cargo fmt --check (push) Successful in 39s
CI / cargo clippy (push) Successful in 24s
CI / cargo test (push) Successful in 27s
CI / editor keymaps (push) Successful in 1m16s
All keywords shared one `nuwikiKeyword` group linked to `Todo`, so the editor
showed TODO, DONE and XXX in the same colour. Split into nuwikiKeywordAttn
(TODO/FIXME/XXX, red) and nuwikiKeywordDone (DONE/FIXED/STARTED, green) with
explicit colours so the distinction survives any colorscheme — matching the
export's per-keyword classes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 21:49:36 -03:00
gffranco 04cbe67882 fix(syntax): per-level heading groups so colorschemes differentiate H1-H6
The single `nuwikiHeading` group linked all six levels to `Title`.
Many popular colorschemes (codedark, gruvbox-light, etc.) define
`Title` as bold-only with no foreground colour, so every heading
rendered as bold text in the Normal colour — H1 and H3 were
visually identical.

Split into nuwikiHeading1..6 and link each to a different accent
(Title / Function / Identifier / Type / Constant / PreProc), matching
the per-level Tree-sitter mapping the Neovim semantic-token side
already uses. The patterns are mutually exclusive: each requires
whitespace immediately after the equals run, so `=` won't match `==`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 22:03:51 -03:00
gffranco cf48242542 fix(syntax): target colorscheme-stable groups for inline markup
Two undefined targets meant bold/italic rendered as plain text:

  - Neovim semantic-token defaults linked @vimwikiBold/Italic to
    markdownBold/Italic, which only exist when the markdown treesitter
    parser is loaded — never in a .wiki buffer. Use @markup.strong /
    @markup.italic / @markup.raw.inline / @markup.link instead; those
    are defined by every nvim 0.9+ colorscheme.
  - The static fallback linked nuwikiBold/Italic to Bold/Italic groups
    that exist in Neovim but not plain Vim, so on Vim the links
    resolved to nothing. Define them with explicit gui=bold/italic
    attributes so they render correctly everywhere.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 22:02:32 -03:00
gffranco 8f8c2884a9 feat(vim): conceal markup delimiters when conceallevel=2
Set conceallevel=2 and concealcursor=nc on .wiki buffers and add
contained `conceal` matches for the bold/italic/code delimiters and
wikilink brackets/targets. The static-fallback rendering now mirrors
what the Neovim semantic-token path produced: *bold* shows as bold
without the asterisks, [[target|desc]] shows just "desc", etc.

The wikilink region uses an inline `contains=` (no line continuation)
because some Vim builds (notably Homebrew Vim 9.2) raise E10 on the
leading `\\ contains=...` form even though the surrounding region
parses fine.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 22:01:55 -03:00
gffranco f1bf70d448 fix(vim): gate Neovim TS-style highlight groups + correct bin path lookup
CI / cargo fmt --check (push) Successful in 28s
CI / cargo clippy (push) Successful in 1m20s
CI / cargo test (push) Successful in 1m16s
Plain Vim spat a wall of `W18: Invalid character in group name` on
every buffer load because `syntax/vimwiki.vim` declared the
LSP-token highlight defaults with Tree-sitter-style names
(`@vimwikiHeading.level1`, `@vimwikiBold`, …). Those work on Neovim
but Vim rejects `@` and `.` in group names.

- `syntax/vimwiki.vim` now guards the `@vimwiki*` block with
  `has('nvim')`. The static regex fallback below it (which uses
  Vim-compatible `nuwiki*` group names) keeps highlighting working
  on plain Vim.

While reproducing, also noticed `autoload/nuwiki/lsp.vim`'s
`s:bin_path` reported the binary at `/home/gfranco/bin/nuwiki-ls`
(only two dirs under `$HOME`) instead of
`/home/gfranco/git-repositories/nuwiki/bin/nuwiki-ls`. Cause:
`expand('<sfile>:p')` inside a function resolves to the *calling*
script at invocation time, not this autoload file. Captured the
plugin root via `<sfile>` at script-load time into a new
`s:plugin_root` and used it in `bin_path()`.

Verified with `vim -u .vimrc index.wiki`:
- `:messages` is empty of W18 warnings.
- The "binary not found" path (when no built binary exists) now
  prints the correct repo-relative path.

Total 377 Rust tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 01:04:23 +00:00
gffranco 09b9bd98a3 fix(ftplugin): load on .wiki buffers without manual filetype override
CI / cargo fmt --check (push) Successful in 35s
CI / cargo clippy (push) Successful in 1m12s
CI / cargo test (push) Successful in 1m26s
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>
2026-05-11 22:16:57 +00:00
gffranco ee61d40872 phase 9: editor glue — plugin, LSP wiring, install, health, docs
CI / cargo fmt --check (push) Successful in 30s
CI / cargo clippy (push) Successful in 1m23s
CI / cargo test (push) Successful in 1m29s
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>
2026-05-11 00:38:09 +00:00
gffranco cf336ee839 phase 0: scaffold workspace, plugin layout, and CI
CI / cargo fmt --check (push) Successful in 46s
CI / cargo clippy (push) Successful in 1m33s
CI / cargo test (push) Successful in 53s
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>
2026-05-10 16:01:58 +00:00