docs: rewrite README + :help nuwiki for users
Both files now describe what the plugin DOES, with no references to
internal phase work or SPEC.md (which is dev-only).
README.md
* Reorganised the feature list by area (syntax, editor intelligence,
editing, diary, other) and surfaced everything actually shipped:
text objects, smart `<CR>` / `<Tab>` in insert, table alignment
markers, colspan/rowspan, transclusion attributes, diary
frequencies, list continuation, etc.
* Updated the keymaps table to include the full insert-mode bindings,
list-rewriter shortcuts (`gLh`/`gLl`, `glr`/`gLr`, `gl<Space>`),
and all five text-object pairs (was "ah/ih + planned follow-ups").
* Expanded the configuration example with the per-wiki keys (diary,
HTML export, listsyms, nested_syntaxes) and the new Vim globals
(`g:nuwiki_no_folding`, `g:nuwiki_mouse_mappings`).
* Dropped the architecture / repository-layout / phase-log sections.
Contributors who care about those still find them in the codebase.
* Removed the "two known behavior deltas" note — the gln/glp claim
is no longer accurate (both bindings ship as separate keymaps),
and the lazy-index caveat moved into the Migrating section.
doc/nuwiki.txt
* Grew from 7 sections to 14 covering installation, configuration
(top-level + per-wiki + Vim globals), commands, keymaps (by area),
text objects, insert-mode bindings, diary (with frequency formats),
tables (with alignment / span syntax), HTML export, folding, health
checks, and migrating from vimwiki.
* Every public command has a help anchor.
* Removed the §6.9 spec reference and the phase 9 caveat.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,33 +5,72 @@
|
|||||||
nuwiki replaces the original [vimwiki](https://github.com/vimwiki/vimwiki)
|
nuwiki replaces the original [vimwiki](https://github.com/vimwiki/vimwiki)
|
||||||
plugin while keeping its file format, keymaps, and `:Vimwiki*` command
|
plugin while keeping its file format, keymaps, and `:Vimwiki*` command
|
||||||
surface intact. The substantive work happens in a Rust LSP daemon — Vim
|
surface intact. The substantive work happens in a Rust LSP daemon — Vim
|
||||||
and Neovim are thin client layers that just wire up keystrokes and
|
and Neovim are thin client layers that wire up keystrokes and display
|
||||||
display results.
|
results.
|
||||||
|
|
||||||
- ✅ Full vimwiki syntax (`.wiki`) — headings, lists with checkboxes,
|
## Features
|
||||||
tables, math, code, tags, links (wiki / interwiki / diary / file /
|
|
||||||
raw URL / transclusion).
|
|
||||||
- ✅ Goto-definition, backlinks, hover, completion, workspace symbol
|
|
||||||
search, semantic highlighting — all over LSP.
|
|
||||||
- ✅ Diary (today/yesterday/tomorrow/next/prev), tags (search + link
|
|
||||||
generation), TOC generation, broken-link diagnostics, orphan finder.
|
|
||||||
- ✅ Multi-wiki with cross-wiki interwiki links (`[[wn.name:Page]]`).
|
|
||||||
- ✅ HTML export with templates, CSS, auto-export on save, RSS feed.
|
|
||||||
- ✅ Folding (LSP `foldingRange` + regex fallback), header & link
|
|
||||||
text objects, the `<CR>` two-step link-create-and-follow.
|
|
||||||
- ✅ `:Vimwiki*` command compat + `:Nuwiki*` canonical aliases.
|
|
||||||
|
|
||||||
See [`SPEC.md`](./SPEC.md) for the architecture, design decisions, and
|
### Syntax & rendering
|
||||||
the full phase log.
|
|
||||||
|
- Full vimwiki syntax (`.wiki`) — headings, lists with checkboxes,
|
||||||
|
numbered / lettered / Roman lists, tables (with `|---|`, `|:--|--:|:--:|`
|
||||||
|
alignment markers and `>` / `\/` colspan/rowspan), inline math, code
|
||||||
|
fences, tags, comments, and links (wiki, interwiki, diary, file, local,
|
||||||
|
raw URL, transclusion).
|
||||||
|
- Transclusions support attributes: `{{image.png|alt|style="border:1px"}}`.
|
||||||
|
- HTML export with templates, CSS, RSS feed, and incremental
|
||||||
|
`:VimwikiAll2HTML`.
|
||||||
|
|
||||||
|
### Editor intelligence (LSP)
|
||||||
|
|
||||||
|
- Goto-definition (follow wikilinks), backlinks, hover preview,
|
||||||
|
completion on `[[`, document outline, workspace symbol search.
|
||||||
|
- Semantic-token highlighting (no syntax-file fallback needed).
|
||||||
|
- Broken-link diagnostics and an orphan-page finder.
|
||||||
|
- Folding: server-driven `foldingRange` by default, regex fallback when
|
||||||
|
the server isn't ready.
|
||||||
|
|
||||||
|
### Editing
|
||||||
|
|
||||||
|
- Insert-mode smart `<CR>`: continues list markers (`-`, `*`, `1.`,
|
||||||
|
`a)`, `i)`, …) and checkboxes; breaks out of an empty bullet; inserts
|
||||||
|
a fresh row when inside a `|…|` table.
|
||||||
|
- Insert-mode `<Tab>` / `<S-Tab>` jumps between table cells, adding a
|
||||||
|
new row past the last column.
|
||||||
|
- `<C-D>` / `<C-T>` indent/dedent the current list item; `<C-L><C-J>`
|
||||||
|
/ `<C-L><C-K>` cycle through the marker styles; `<C-L><C-M>` toggles
|
||||||
|
or adds a checkbox.
|
||||||
|
- Five text-object pairs in operator-pending + visual mode:
|
||||||
|
`ah`/`ih` (heading section), `aH`/`iH` (heading + subtree),
|
||||||
|
`al`/`il` (list item), `a\`/`i\` (table cell), `ac`/`ic` (table column).
|
||||||
|
- Two-step `<CR>` on a bare word: wraps it as `[[word]]`, second press
|
||||||
|
follows the link.
|
||||||
|
|
||||||
|
### Diary
|
||||||
|
|
||||||
|
- Daily diary out of the box (`<Leader>ww`, `<C-Down>` / `<C-Up>`).
|
||||||
|
- Configurable cadence: set `diary_frequency = 'weekly'` (or `'monthly'`
|
||||||
|
/ `'yearly'`) per wiki and the commands address `2026-W19.wiki`,
|
||||||
|
`2026-05.wiki`, `2026.wiki` instead. Navigation stays at the same
|
||||||
|
cadence as the entry under the cursor.
|
||||||
|
- Diary index page generation (`:VimwikiDiaryGenerateLinks`).
|
||||||
|
|
||||||
|
### Other
|
||||||
|
|
||||||
|
- Multi-wiki with cross-wiki `[[wn.name:Page]]` interwiki links and a
|
||||||
|
`:VimwikiUISelect` picker.
|
||||||
|
- TOC generation, tag search, tag-to-page link lists.
|
||||||
|
- `:Vimwiki*` command compat + canonical `:Nuwiki*` aliases.
|
||||||
|
- Plain Vim and Neovim both supported with feature parity (text
|
||||||
|
objects, folding, smart insert-mode bindings).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
The plugin ships a `nuwiki-ls` binary that the editor talks to over
|
The plugin ships a `nuwiki-ls` binary that the editor talks to over LSP
|
||||||
LSP stdio. The `install()` Lua helper downloads a pre-built release for
|
stdio. The `install()` helper downloads a pre-built release for your
|
||||||
your platform, falling back to `cargo build --release` if no asset
|
platform, falling back to `cargo build --release` if no asset matches.
|
||||||
matches.
|
|
||||||
|
|
||||||
### lazy.nvim
|
### lazy.nvim
|
||||||
|
|
||||||
@@ -74,31 +113,28 @@ cd ~/.vim/pack/gffranco/start/nuwiki && cargo build --release -p nuwiki-ls
|
|||||||
mkdir -p bin && ln -s target/release/nuwiki-ls bin/nuwiki-ls
|
mkdir -p bin && ln -s target/release/nuwiki-ls bin/nuwiki-ls
|
||||||
```
|
```
|
||||||
|
|
||||||
Then ensure an LSP client is loaded (Vim path prefers
|
Plain Vim users also need an LSP client —
|
||||||
[`vim-lsp`](https://github.com/prabirshrestha/vim-lsp), falls back to
|
[`vim-lsp`](https://github.com/prabirshrestha/vim-lsp) is the
|
||||||
[`coc.nvim`](https://github.com/neoclide/coc.nvim)). Neovim 0.11+ uses
|
recommended path, with [`coc.nvim`](https://github.com/neoclide/coc.nvim)
|
||||||
its built-in LSP client — no extra plugin needed.
|
as a fallback. Neovim 0.11+ uses its built-in LSP client and needs
|
||||||
|
no extra plugin.
|
||||||
|
|
||||||
### Trying it without touching your config
|
### Try it without touching your config
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./start-nvim.sh # spawns Neovim with a scratch wiki under
|
./start-nvim.sh # spawns Neovim against an isolated sample wiki
|
||||||
# $XDG_CACHE_HOME/nuwiki-dev
|
./start-vim.sh # same, for plain Vim (clones vim-lsp on first run)
|
||||||
./start-vim.sh # same, but for plain Vim — clones vim-lsp
|
|
||||||
# into the cache on first run
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Both scripts build the LSP binary, seed a sample wiki, and launch
|
Both scripts build the LSP binary, seed a scratch wiki, and launch the
|
||||||
the editor against an isolated state dir. Pass a wiki file path to
|
editor against an isolated state dir under `$XDG_CACHE_HOME/nuwiki-dev`.
|
||||||
open it directly; `NUWIKI_DEV_WIKI=/path/to/wiki` points at your
|
|
||||||
own sandbox instead.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Defaults are vimwiki-compatible. Full schema (with type annotations and
|
Defaults are vimwiki-compatible. Every key has a sensible default — the
|
||||||
defaults) lives in [`lua/nuwiki/config.lua`](./lua/nuwiki/config.lua).
|
example below shows the full surface for reference.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
require('nuwiki').setup({
|
require('nuwiki').setup({
|
||||||
@@ -108,41 +144,55 @@ require('nuwiki').setup({
|
|||||||
syntax = 'vimwiki', -- 'vimwiki' | 'markdown' (future)
|
syntax = 'vimwiki', -- 'vimwiki' | 'markdown' (future)
|
||||||
log_level = 'warn',
|
log_level = 'warn',
|
||||||
|
|
||||||
-- Or the multi-wiki form. The single-wiki keys above desugar into
|
-- Multi-wiki: each entry honours every per-wiki key vimwiki understands.
|
||||||
-- a one-entry `wikis = [...]` list, so you can pick either shape.
|
-- Pick either this OR the single-wiki shorthand above. If both are set,
|
||||||
|
-- `wikis` wins.
|
||||||
wikis = {
|
wikis = {
|
||||||
{
|
{
|
||||||
name = 'personal',
|
name = 'personal',
|
||||||
root = '~/vimwiki',
|
root = '~/vimwiki',
|
||||||
file_extension = '.wiki',
|
index = 'index', -- index page stem
|
||||||
diary_rel_path = 'diary',
|
file_extension = '.wiki',
|
||||||
diary_index = 'diary',
|
-- Diary
|
||||||
-- HTML export (Phase 17)
|
diary_rel_path = 'diary',
|
||||||
|
diary_index = 'diary',
|
||||||
|
diary_frequency = 'daily', -- 'daily' | 'weekly' | 'monthly' | 'yearly'
|
||||||
|
diary_sort = 'desc', -- 'desc' | 'asc'
|
||||||
|
diary_header = 'Diary',
|
||||||
|
-- HTML export
|
||||||
html_path = '~/vimwiki/_html',
|
html_path = '~/vimwiki/_html',
|
||||||
template_path = '~/vimwiki/_templates',
|
template_path = '~/vimwiki/_templates',
|
||||||
template_default = 'default',
|
template_default = 'default',
|
||||||
template_ext = '.tpl',
|
template_ext = '.tpl',
|
||||||
css_name = 'style.css',
|
css_name = 'style.css',
|
||||||
auto_export = false, -- export on save
|
auto_export = false, -- export on save
|
||||||
exclude_files = {}, -- glob patterns
|
auto_toc = false, -- auto-refresh TOC on save
|
||||||
|
exclude_files = {}, -- glob patterns
|
||||||
|
-- Checkbox progression characters: " .oOX" by default.
|
||||||
|
listsyms = ' .oOX',
|
||||||
|
listsyms_propagate = true,
|
||||||
|
-- Inline highlighting: 6 heading levels by default.
|
||||||
|
maxhi = 1,
|
||||||
|
-- Embed other syntaxes inside `{{{lang …}}}` fences.
|
||||||
|
nested_syntaxes = {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
-- Keymap groups — flip subgroups off independently. Defaults all on.
|
-- Keymap groups. Flip subgroups off independently. Defaults all on.
|
||||||
mappings = {
|
mappings = {
|
||||||
enabled = true,
|
enabled = true,
|
||||||
wiki_prefix = true, -- <Leader>w*
|
wiki_prefix = true, -- <Leader>w*
|
||||||
links = true, -- <CR>, <S-CR>, <Tab>, <BS>, +, …
|
links = true, -- <CR>, <S-CR>, <Tab>, <BS>, +, …
|
||||||
lists = true, -- <C-Space>, gln/glp/glx, gl<Space>, o/O
|
lists = true, -- <C-Space>, gln/glp/glx, gl<Space>, o/O, …
|
||||||
headers = true, -- =, -, ]], [[, ]=, [=, ]u, [u
|
headers = true, -- =, -, ]], [[, ]=, [=, ]u, [u
|
||||||
table_editing = true, -- gqq, gq1, gww, gw1, <A-Left>, <A-Right>
|
table_editing = true, -- gqq, <A-Left>, <A-Right>, <Tab> in insert mode
|
||||||
diary = true, -- <C-Down>, <C-Up>
|
diary = true, -- <C-Down>, <C-Up>
|
||||||
html_export = true, -- <Leader>wh, <Leader>whh
|
html_export = true, -- <Leader>wh, <Leader>whh
|
||||||
text_objects = true, -- ah, ih
|
text_objects = true, -- ah, ih, aH, iH, al, il, a\, i\, ac, ic
|
||||||
|
mouse = false, -- <2-LeftMouse>, <RightMouse>, … (opt-in)
|
||||||
},
|
},
|
||||||
|
|
||||||
-- Folding strategy: 'lsp' (server-driven foldingRange — default on
|
-- 'lsp' (server-driven foldingRange, default) | 'expr' (regex) | 'off'.
|
||||||
-- Neovim 0.11+), 'expr' (pure regex), or 'off'.
|
|
||||||
folding = 'lsp',
|
folding = 'lsp',
|
||||||
|
|
||||||
-- Broken-link diagnostic severity: 'off' | 'hint' | 'warn' | 'error'.
|
-- Broken-link diagnostic severity: 'off' | 'hint' | 'warn' | 'error'.
|
||||||
@@ -152,14 +202,16 @@ require('nuwiki').setup({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
Vim users without Lua should set the equivalent globals before sourcing
|
Vim users without Lua set the equivalent globals before loading the
|
||||||
the plugin:
|
plugin:
|
||||||
|
|
||||||
```vim
|
```vim
|
||||||
let g:nuwiki_wiki_root = '~/vimwiki'
|
let g:nuwiki_wiki_root = '~/vimwiki'
|
||||||
let g:nuwiki_file_extension = '.wiki'
|
let g:nuwiki_file_extension = '.wiki'
|
||||||
let g:nuwiki_log_level = 'warn'
|
let g:nuwiki_log_level = 'warn'
|
||||||
let g:nuwiki_no_default_mappings = 0 " set to 1 to skip the keymap layer
|
let g:nuwiki_no_default_mappings = 0 " set to 1 to skip the keymap layer
|
||||||
|
let g:nuwiki_no_folding = 0 " set to 1 to skip foldexpr setup
|
||||||
|
let g:nuwiki_mouse_mappings = 0 " set to 1 to enable mouse maps
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -170,89 +222,122 @@ let g:nuwiki_no_default_mappings = 0 " set to 1 to skip the keymap layer
|
|||||||
|
|
||||||
Both `:Vimwiki*` (migration compat) and `:Nuwiki*` (canonical native)
|
Both `:Vimwiki*` (migration compat) and `:Nuwiki*` (canonical native)
|
||||||
are registered as buffer-local commands on every `.wiki` buffer.
|
are registered as buffer-local commands on every `.wiki` buffer.
|
||||||
Selected highlights — see `:Vimwiki<Tab>` for the full list.
|
Selected highlights — type `:Vimwiki<Tab>` for the full list.
|
||||||
|
|
||||||
| Command | What it does |
|
| Command | What it does |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `:VimwikiIndex [N]` | Open wiki N's `index.wiki` (default: 1) |
|
| `:VimwikiIndex [N]` | Open wiki N's index page (default: 1) |
|
||||||
|
| `:VimwikiTabIndex [N]` | Same, in a new tab |
|
||||||
| `:VimwikiUISelect` | Pick a wiki from a list (multi-wiki only) |
|
| `:VimwikiUISelect` | Pick a wiki from a list (multi-wiki only) |
|
||||||
| `:VimwikiMakeDiaryNote` | Open today's diary page |
|
| `:VimwikiGoto {page}` | Open `{page}.wiki` by name |
|
||||||
| `:VimwikiDiaryNextDay` / `:VimwikiDiaryPrevDay` | Chronological diary nav |
|
| `:VimwikiMakeDiaryNote` | Open today's diary entry (or this week / month / year, depending on `diary_frequency`) |
|
||||||
| `:VimwikiTOC` | Generate / refresh table of contents on the current page |
|
| `:VimwikiMakeYesterdayDiaryNote` / `:VimwikiMakeTomorrowDiaryNote` | Step the diary back / forward by one period |
|
||||||
| `:VimwikiGenerateLinks` | Flat list of every page in the wiki |
|
| `:VimwikiDiaryIndex` | Open the diary index page |
|
||||||
|
| `:VimwikiDiaryGenerateLinks` | Rebuild the diary index from current entries |
|
||||||
|
| `:VimwikiDiaryNextDay` / `:VimwikiDiaryPrevDay` | Chronological diary nav (same cadence as the current entry) |
|
||||||
|
| `:VimwikiTOC` | Generate / refresh the table of contents on the current page |
|
||||||
|
| `:VimwikiGenerateLinks` | Insert a flat list of every page in the wiki |
|
||||||
| `:VimwikiCheckLinks` | Send broken links to the quickfix list |
|
| `:VimwikiCheckLinks` | Send broken links to the quickfix list |
|
||||||
| `:VimwikiSearchTags {tag}` | Quickfix of all occurrences of `:tag:` |
|
| `:VimwikiSearchTags {tag}` | Quickfix listing every occurrence of `:tag:` |
|
||||||
| `:VimwikiGenerateTagLinks [tag]` | Insert a section linking all pages with `<tag>` |
|
| `:VimwikiGenerateTagLinks [tag]` | Insert a section linking every page that has `<tag>` |
|
||||||
| `:VimwikiRebuildTags` | Force a full workspace re-index |
|
| `:VimwikiRebuildTags` | Force a full workspace re-index |
|
||||||
| `:VimwikiRenameFile` | Rename current page; rewrites incoming links |
|
| `:VimwikiRenameFile` | Rename the current page, rewriting incoming links |
|
||||||
| `:VimwikiDeleteFile` | Delete current page (server-side `DeleteFile`) |
|
| `:VimwikiDeleteFile` | Delete the current page |
|
||||||
| `:Vimwiki2HTML` | Render current page to HTML |
|
| `:Vimwiki2HTML` | Render the current page to HTML |
|
||||||
| `:Vimwiki2HTMLBrowse` | Render + open in default browser |
|
| `:Vimwiki2HTMLBrowse` | Render the current page and open it in the default browser |
|
||||||
| `:VimwikiAll2HTML[!]` | Export the whole wiki (`!` forces, otherwise incremental) |
|
| `:VimwikiAll2HTML[!]` | Export the whole wiki (`!` forces; otherwise incremental) |
|
||||||
| `:VimwikiRss` | Write `rss.xml` of diary entries |
|
| `:VimwikiRss` | Write `rss.xml` for diary entries |
|
||||||
| `:VimwikiFollowLink` | Follow link under cursor (`<CR>`) |
|
| `:VimwikiFollowLink` | Follow the link under the cursor |
|
||||||
| `:VimwikiBacklinks` | Show references to current page |
|
| `:VimwikiBacklinks` | Show all references to the current page |
|
||||||
|
| `:VimwikiNextLink` / `:VimwikiPrevLink` | Jump to the next / previous wikilink on the page |
|
||||||
|
| `:VimwikiBaddLink` | Add the target of the link under the cursor to the buffer list |
|
||||||
|
|
||||||
### Default keymaps
|
### Default keymaps
|
||||||
|
|
||||||
All buffer-local. Disable any group via `mappings.<group> = false` in
|
All buffer-local. Disable any group via `mappings.<group> = false` in
|
||||||
Neovim, or `let g:nuwiki_no_default_mappings = 1` in Vim.
|
Neovim, or `let g:nuwiki_no_default_mappings = 1` in Vim.
|
||||||
|
|
||||||
**Links**
|
**Links** (normal mode)
|
||||||
|
|
||||||
| Key | Action |
|
| Key | Action |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `<CR>` | Smart follow: inside `[[…]]` → jump; on a bare word → wrap as `[[word]]` (second `<CR>` follows) |
|
| `<CR>` | Smart follow — inside `[[…]]` jumps; on a bare word wraps as `[[word]]` (second `<CR>` follows) |
|
||||||
| `<S-CR>` | Follow in horizontal split |
|
| `<S-CR>` | Follow in horizontal split |
|
||||||
| `<C-CR>` | Follow in vertical split |
|
| `<C-CR>` | Follow in vertical split |
|
||||||
| `<C-S-CR>` | Follow in new tab |
|
| `<C-S-CR>` | Follow in a new tab |
|
||||||
| `<BS>` | Jump back (`<C-o>`) |
|
| `<BS>` | Jump back (`<C-o>`) |
|
||||||
| `<Tab>` / `<S-Tab>` | Next / previous wikilink on or after the cursor |
|
| `<Tab>` / `<S-Tab>` | Next / previous wikilink on or after the cursor |
|
||||||
|
| `+` | Wrap word / visual selection as a wikilink (no follow) |
|
||||||
|
|
||||||
**Lists**
|
**Lists** (normal mode)
|
||||||
|
|
||||||
| Key | Action |
|
| Key | Action |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `<C-Space>` / `<C-@>` / `<Nul>` | Toggle checkbox (terminal byte aliases) |
|
| `<C-Space>` / `<C-@>` / `<Nul>` | Toggle the checkbox under the cursor (the three aliases cover terminal byte differences) |
|
||||||
| `gln` / `glp` | Cycle checkbox state (forward / backward) |
|
| `gln` / `glp` | Cycle the checkbox state forward / backward |
|
||||||
| `glx` | Toggle the rejected marker `[-]` |
|
| `glx` | Toggle the rejected marker `[-]` |
|
||||||
| `gnt` | Jump to the next unfinished task |
|
| `gnt` | Jump to the next unfinished task |
|
||||||
| `o` / `O` | Open a new line and continue the list marker (and checkbox if any) |
|
| `glh` / `gll` | Dedent / indent the current list item |
|
||||||
|
| `gLh` / `gLl` | Dedent / indent including the item's sublist |
|
||||||
|
| `glr` | Renumber the current ordered list |
|
||||||
|
| `gLr` | Renumber every ordered list in the buffer |
|
||||||
|
| `gl<Space>` | Remove every completed item from the current list |
|
||||||
|
| `gL<Space>` | Remove every completed item in the buffer |
|
||||||
|
| `o` / `O` | Open a new line and continue the list marker (preserves any checkbox) |
|
||||||
|
|
||||||
|
**Lists** (insert mode)
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|---|---|
|
||||||
|
| `<CR>` | Continue the list with the same marker (preserves checkbox), or break out on an empty bullet |
|
||||||
|
| `<C-D>` / `<C-T>` | Dedent / indent the current item |
|
||||||
|
| `<C-L><C-J>` / `<C-L><C-K>` | Cycle the marker style (`-` → `*` → `#` → `1.` → `1)` → `a)` → `A)` → `i)` → `I)`) |
|
||||||
|
| `<C-L><C-M>` | Toggle / add a checkbox on the current item |
|
||||||
|
|
||||||
**Headers**
|
**Headers**
|
||||||
|
|
||||||
| Key | Action |
|
| Key | Action |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `=` / `-` | Add / remove a heading level |
|
| `=` / `-` | Increase / decrease the heading level |
|
||||||
| `]]` / `[[` | Next / previous heading |
|
| `]]` / `[[` | Next / previous heading (any level) |
|
||||||
| `]=` / `[=` | Next / previous sibling heading |
|
| `]=` / `[=` | Next / previous sibling heading |
|
||||||
| `]u` / `[u` | Jump to parent heading |
|
| `]u` / `[u` | Jump to the parent heading |
|
||||||
|
|
||||||
**Wiki / diary / export**
|
**Tables**
|
||||||
|
|
||||||
| Key | Action |
|
| Key | Action |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `<Leader>ww` | Today's diary |
|
| `gqq` / `gq1` / `gww` / `gw1` | Align the table under the cursor |
|
||||||
| `<Leader>ws` | Pick a wiki (`vim.ui.select` / `inputlist`) |
|
| `<A-Left>` / `<A-Right>` | Move the column under the cursor left / right |
|
||||||
| `<Leader>wi` | Diary index |
|
| `<Tab>` / `<S-Tab>` (insert) | Jump to the next / previous cell; `<Tab>` past the last cell inserts a fresh row |
|
||||||
|
| `<CR>` (insert) | Insert a fresh empty row below the current one |
|
||||||
|
|
||||||
|
**Wiki / diary / export** (normal mode)
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|---|---|
|
||||||
|
| `<Leader>ww` | Open today's diary |
|
||||||
|
| `<Leader>ws` | Pick a wiki |
|
||||||
|
| `<Leader>wi` | Open the diary index |
|
||||||
| `<Leader>w<Leader>w` / `<Leader>w<Leader>y` / `<Leader>w<Leader>t` | Today / yesterday / tomorrow |
|
| `<Leader>w<Leader>w` / `<Leader>w<Leader>y` / `<Leader>w<Leader>t` | Today / yesterday / tomorrow |
|
||||||
| `<Leader>w<Leader>i` | Rebuild diary index page |
|
| `<Leader>w<Leader>i` | Rebuild the diary index page |
|
||||||
| `<Leader>wn` / `<Leader>wd` / `<Leader>wr` | Goto / delete / rename page |
|
| `<Leader>wn` / `<Leader>wd` / `<Leader>wr` | Goto / delete / rename page |
|
||||||
| `<Leader>wh` / `<Leader>whh` | Export current page → HTML / open in browser |
|
| `<Leader>wh` / `<Leader>whh` | Export the current page to HTML / open in browser |
|
||||||
| `<Leader>wha` | Export every page |
|
| `<Leader>wha` | Export every page |
|
||||||
|
| `<Leader>wc` | Wrap word (or visual selection) in a colour span |
|
||||||
| `<C-Down>` / `<C-Up>` | Next / previous diary entry |
|
| `<C-Down>` / `<C-Up>` | Next / previous diary entry |
|
||||||
|
|
||||||
**Text objects**
|
**Text objects** (operator-pending + visual)
|
||||||
|
|
||||||
| Key | Selection |
|
| Object | Selection |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `ah` / `ih` | A heading (with / without the heading line itself) |
|
| `ah` / `ih` | The heading's section (`ih` excludes the heading line) |
|
||||||
|
| `aH` / `iH` | The heading's section plus every subheading underneath |
|
||||||
|
| `al` / `il` | The list item under the cursor (`il` excludes the marker / checkbox) |
|
||||||
|
| `a\` / `i\` | The table cell under the cursor (`i\` excludes the surrounding `\|`) |
|
||||||
|
| `ac` / `ic` | The table column under the cursor (`ic` excludes the header separator row) |
|
||||||
|
|
||||||
Additional text objects (`aH`, `iH`, `a\`, `i\`, `ac`, `ic`, `al`,
|
### Health check (Neovim)
|
||||||
`il`) are planned follow-ups now that the table/list rewriter
|
|
||||||
commands they depend on have shipped.
|
|
||||||
|
|
||||||
### Health check
|
|
||||||
|
|
||||||
```vim
|
```vim
|
||||||
:checkhealth nuwiki
|
:checkhealth nuwiki
|
||||||
@@ -265,96 +350,17 @@ whether the configured HTML output directory is writable.
|
|||||||
### Migrating from vimwiki
|
### Migrating from vimwiki
|
||||||
|
|
||||||
The file extension, syntax, command names, and default keymaps all
|
The file extension, syntax, command names, and default keymaps all
|
||||||
match vimwiki. Drop the original `vimwiki` plugin from your config,
|
match vimwiki. To migrate:
|
||||||
install nuwiki, and point `wiki_root` at the same directory. Existing
|
|
||||||
pages, diary entries, tags, and templates Just Work.
|
|
||||||
|
|
||||||
Two known behavior deltas vs. upstream vimwiki:
|
1. Drop the original `vimwiki` plugin from your config.
|
||||||
|
2. Install nuwiki.
|
||||||
|
3. Point `wiki_root` (or each `wikis[i].root`) at your existing
|
||||||
|
directory.
|
||||||
|
|
||||||
- nuwiki's index is built lazily on workspace scan; the very first
|
Existing pages, diary entries, tags, and templates work without
|
||||||
`:VimwikiCheckLinks` after launch may be empty until the background
|
modification. The first workspace scan after launch may show an empty
|
||||||
task completes. Subsequent runs are instant.
|
`:VimwikiCheckLinks` result until the background index completes;
|
||||||
- `gln` and `glp` both call `nuwiki.list.cycleCheckbox`, which is
|
subsequent runs are instant.
|
||||||
forward-only at present. A reverse cycle lands once the v1.1 list
|
|
||||||
rewriters do.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Repository layout
|
|
||||||
|
|
||||||
```
|
|
||||||
nuwiki/
|
|
||||||
├── Cargo.toml workspace root
|
|
||||||
├── crates/
|
|
||||||
│ ├── nuwiki-core/ parser, AST, renderer (editor-independent)
|
|
||||||
│ ├── nuwiki-lsp/ LSP protocol bridge
|
|
||||||
│ └── nuwiki-ls/ stdio LSP binary entry point
|
|
||||||
├── plugin/ universal Vim/Neovim entry point
|
|
||||||
├── lua/nuwiki/ Neovim Lua glue
|
|
||||||
├── autoload/nuwiki/ Vim VimL glue
|
|
||||||
├── ftdetect/ filetype detection for .wiki
|
|
||||||
├── ftplugin/vimwiki.vim per-buffer settings + commands + keymaps
|
|
||||||
├── syntax/vimwiki.vim static fallback highlighting
|
|
||||||
├── doc/ `:h nuwiki`
|
|
||||||
├── scripts/ test harness + build helpers
|
|
||||||
└── .gitea/workflows/ CI / release pipelines
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
### Build + test
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cargo build --workspace
|
|
||||||
cargo test --workspace # 381 Rust tests
|
|
||||||
./scripts/test-keymaps.sh # 19 Neovim keymap cases (LSP-driven)
|
|
||||||
./scripts/test-keymaps-vim.sh # 12 Vim keymap cases (pure-VimL)
|
|
||||||
```
|
|
||||||
|
|
||||||
CI runs all four on every push (`.gitea/workflows/ci.yaml`). MSRV: Rust
|
|
||||||
1.83.
|
|
||||||
|
|
||||||
### Trying changes against a real wiki
|
|
||||||
|
|
||||||
```sh
|
|
||||||
./start-nvim.sh # isolated state under
|
|
||||||
./start-vim.sh # $XDG_CACHE_HOME/nuwiki-dev
|
|
||||||
```
|
|
||||||
|
|
||||||
Both regenerate their minimal config on every launch and seed a
|
|
||||||
scratch wiki with sample pages, links, checkboxes, and tags.
|
|
||||||
|
|
||||||
### Implementation status
|
|
||||||
|
|
||||||
#### v1.0 — foundation
|
|
||||||
|
|
||||||
| Phase | Name | Status |
|
|
||||||
|---|---|---|
|
|
||||||
| 0 | Scaffolding | ✅ done |
|
|
||||||
| 1 | Core AST | ✅ done |
|
|
||||||
| 2 | Syntax Plugin Interface | ✅ done |
|
|
||||||
| 3 | Vimwiki Lexer | ✅ done |
|
|
||||||
| 4 | Vimwiki Parser | ✅ done |
|
|
||||||
| 5 | Renderer | ✅ done |
|
|
||||||
| 6 | LSP Foundation | ✅ done |
|
|
||||||
| 7 | Semantic Tokens | ✅ done |
|
|
||||||
| 8 | Navigation | ✅ done |
|
|
||||||
| 9 | Editor Glue | ✅ done |
|
|
||||||
| 10 | CI/CD release pipeline | ✅ done |
|
|
||||||
|
|
||||||
#### v1.1 — full vimwiki replacement
|
|
||||||
|
|
||||||
| Phase | Name | Status |
|
|
||||||
|---|---|---|
|
|
||||||
| 11 | Plumbing prerequisites | ✅ done |
|
|
||||||
| 12 | Tags | ✅ done |
|
|
||||||
| 13 | Workspace edits + executeCommand | ✅ done |
|
|
||||||
| 14 | List & table edit commands | ✅ done |
|
|
||||||
| 15 | Link health + TOC/index generation | ✅ done |
|
|
||||||
| 16 | Diary | ✅ done |
|
|
||||||
| 17 | HTML export commands | ✅ done |
|
|
||||||
| 18 | Multi-wiki | ✅ done |
|
|
||||||
| 19 | Editor glue v2 (`:Vimwiki*` compat, keymaps, text objects, folding) | ✅ done |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+537
-63
@@ -1,4 +1,4 @@
|
|||||||
*nuwiki.txt* LSP-backed vimwiki support for Vim and Neovim.
|
*nuwiki.txt* A vimwiki-compatible plugin backed by a Rust language server.
|
||||||
|
|
||||||
Author: Gabriel Fróes Franco
|
Author: Gabriel Fróes Franco
|
||||||
License: Dual MIT / Apache-2.0
|
License: Dual MIT / Apache-2.0
|
||||||
@@ -10,17 +10,42 @@ CONTENTS *nuwiki-contents*
|
|||||||
2. Requirements ............ |nuwiki-requirements|
|
2. Requirements ............ |nuwiki-requirements|
|
||||||
3. Installation ............ |nuwiki-installation|
|
3. Installation ............ |nuwiki-installation|
|
||||||
4. Configuration ........... |nuwiki-config|
|
4. Configuration ........... |nuwiki-config|
|
||||||
5. Health check ............ |nuwiki-health|
|
5. Commands ................ |nuwiki-commands|
|
||||||
6. LSP features ............ |nuwiki-features|
|
6. Keymaps ................. |nuwiki-keymaps|
|
||||||
7. Commands ................ |nuwiki-commands|
|
7. Text objects ............ |nuwiki-text-objects|
|
||||||
|
8. Insert-mode bindings .... |nuwiki-insert-mode|
|
||||||
|
9. Diary ................... |nuwiki-diary|
|
||||||
|
10. Tables ................... |nuwiki-tables|
|
||||||
|
11. HTML export .............. |nuwiki-html|
|
||||||
|
12. Folding .................. |nuwiki-folding|
|
||||||
|
13. Health check ............. |nuwiki-health|
|
||||||
|
14. Migrating from vimwiki ... |nuwiki-migrating|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
1. INTRODUCTION *nuwiki-introduction*
|
1. INTRODUCTION *nuwiki-introduction*
|
||||||
|
|
||||||
nuwiki brings full vimwiki syntax support to Vim and Neovim via a Rust-
|
nuwiki keeps vimwiki's file format, keymaps, and `:Vimwiki*` command surface
|
||||||
based language server (|nuwiki-ls|). It is architecturally distinct from
|
intact, but moves the heavy lifting into a Rust language server that the
|
||||||
vimwiki itself — installable through any standard plugin manager, with the
|
editor talks to over LSP stdio. The result feels like vimwiki — same files,
|
||||||
heavy lifting done in a single binary that speaks LSP over stdio.
|
same shortcuts — with goto-definition, backlinks, completion, semantic
|
||||||
|
highlighting, broken-link diagnostics, and incremental HTML export.
|
||||||
|
|
||||||
|
Highlights:
|
||||||
|
|
||||||
|
* Full vimwiki syntax — headings, lists, checkboxes, tables (with
|
||||||
|
alignment / colspan / rowspan), inline math, code, tags, every link
|
||||||
|
kind (wiki, interwiki, diary, file, local, raw URL, transclusion with
|
||||||
|
attributes).
|
||||||
|
* LSP intelligence — goto-definition, backlinks, hover, completion on
|
||||||
|
`[[`, document outline, workspace symbol search, broken-link
|
||||||
|
diagnostics, orphan-page finder.
|
||||||
|
* Editing helpers — smart `<CR>` continues lists / tables, `<Tab>`
|
||||||
|
cycles between table cells, five text-object pairs, list-marker
|
||||||
|
cycling.
|
||||||
|
* Diary at four cadences — daily, weekly, monthly, or yearly.
|
||||||
|
* Multi-wiki with `[[wn.name:Page]]` interwiki links.
|
||||||
|
* HTML export with templates, CSS, RSS, and on-save export.
|
||||||
|
* Plain Vim and Neovim both supported with feature parity.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
2. REQUIREMENTS *nuwiki-requirements*
|
2. REQUIREMENTS *nuwiki-requirements*
|
||||||
@@ -29,15 +54,15 @@ heavy lifting done in a single binary that speaks LSP over stdio.
|
|||||||
* Vim 9.1+ with one of:
|
* Vim 9.1+ with one of:
|
||||||
- vim-lsp (prabirshrestha/vim-lsp)
|
- vim-lsp (prabirshrestha/vim-lsp)
|
||||||
- coc.nvim (neoclide/coc.nvim)
|
- coc.nvim (neoclide/coc.nvim)
|
||||||
* `curl` and `tar` (only for binary download; not needed if you build
|
* `curl` and `tar` (only for the binary download path; not needed if
|
||||||
from source)
|
you build from source)
|
||||||
* `cargo` and a Rust toolchain (only if you opt into source builds)
|
* `cargo` and a Rust toolchain (only if you opt into source builds)
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
3. INSTALLATION *nuwiki-installation*
|
3. INSTALLATION *nuwiki-installation*
|
||||||
|
|
||||||
Install via your plugin manager of choice; the build hook will download
|
Install via your plugin manager; the build hook downloads a pre-built
|
||||||
the pre-built `nuwiki-ls` binary into the plugin's `bin/` directory.
|
`nuwiki-ls` binary into the plugin's `bin/` directory.
|
||||||
|
|
||||||
lazy.nvim: >
|
lazy.nvim: >
|
||||||
|
|
||||||
@@ -45,7 +70,7 @@ lazy.nvim: >
|
|||||||
"gffranco/nuwiki",
|
"gffranco/nuwiki",
|
||||||
build = "lua require('nuwiki').install()",
|
build = "lua require('nuwiki').install()",
|
||||||
ft = { "vimwiki" },
|
ft = { "vimwiki" },
|
||||||
opts = {},
|
opts = { wiki_root = "~/vimwiki" },
|
||||||
}
|
}
|
||||||
|
|
||||||
<vim-plug: >
|
<vim-plug: >
|
||||||
@@ -58,7 +83,7 @@ lazy.nvim: >
|
|||||||
\ 'build': 'vim -e -s -c "source scripts/download_bin.vim" -c "q"',
|
\ 'build': 'vim -e -s -c "source scripts/download_bin.vim" -c "q"',
|
||||||
\ })
|
\ })
|
||||||
|
|
||||||
<To force a build from source (no download), set: >
|
<To force a build from source (skip the download path), set: >
|
||||||
|
|
||||||
let g:nuwiki_build_from_source = 1
|
let g:nuwiki_build_from_source = 1
|
||||||
|
|
||||||
@@ -70,7 +95,8 @@ lazy.nvim: >
|
|||||||
<==============================================================================
|
<==============================================================================
|
||||||
4. CONFIGURATION *nuwiki-config*
|
4. CONFIGURATION *nuwiki-config*
|
||||||
|
|
||||||
Neovim (`require('nuwiki').setup{}`): >
|
Neovim users call `setup()` (omit the block entirely to take every
|
||||||
|
default): >
|
||||||
|
|
||||||
require('nuwiki').setup({
|
require('nuwiki').setup({
|
||||||
wiki_root = '~/vimwiki',
|
wiki_root = '~/vimwiki',
|
||||||
@@ -79,85 +105,533 @@ Neovim (`require('nuwiki').setup{}`): >
|
|||||||
log_level = 'warn',
|
log_level = 'warn',
|
||||||
})
|
})
|
||||||
|
|
||||||
<Vim sets the equivalent globals before plugin load: >
|
<For multiple wikis or per-wiki tuning, use the `wikis` list: >
|
||||||
|
|
||||||
let g:nuwiki_wiki_root = '~/vimwiki'
|
require('nuwiki').setup({
|
||||||
let g:nuwiki_file_extension = '.wiki'
|
wikis = {
|
||||||
let g:nuwiki_syntax = 'vimwiki'
|
{
|
||||||
let g:nuwiki_log_level = 'warn'
|
name = 'personal',
|
||||||
|
root = '~/vimwiki',
|
||||||
|
index = 'index',
|
||||||
|
file_extension = '.wiki',
|
||||||
|
diary_rel_path = 'diary',
|
||||||
|
diary_frequency = 'daily', -- daily | weekly | monthly | yearly
|
||||||
|
diary_sort = 'desc',
|
||||||
|
html_path = '~/vimwiki/_html',
|
||||||
|
template_path = '~/vimwiki/_templates',
|
||||||
|
template_default = 'default',
|
||||||
|
css_name = 'style.css',
|
||||||
|
auto_export = false,
|
||||||
|
nested_syntaxes = { python = 'python' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
<Options:
|
<Vim users without Lua set the equivalent globals before loading the
|
||||||
|
plugin: >
|
||||||
|
|
||||||
|
let g:nuwiki_wiki_root = '~/vimwiki'
|
||||||
|
let g:nuwiki_file_extension = '.wiki'
|
||||||
|
let g:nuwiki_log_level = 'warn'
|
||||||
|
|
||||||
|
<Top-level options ~
|
||||||
|
|
||||||
*g:nuwiki_wiki_root*
|
*g:nuwiki_wiki_root*
|
||||||
`wiki_root` ~/vimwiki
|
`wiki_root` ~/vimwiki
|
||||||
Root directory of the wiki. Used as a fallback `root_dir` when no
|
Root directory of the single-wiki shorthand. Ignored when `wikis` is
|
||||||
`.git` / `.nuwiki` marker is found near the buffer.
|
set (the multi-wiki list takes precedence).
|
||||||
|
|
||||||
*g:nuwiki_file_extension*
|
*g:nuwiki_file_extension*
|
||||||
`file_extension` .wiki
|
`file_extension` .wiki
|
||||||
File extension associated with the wiki filetype. Note that
|
File extension associated with the wiki filetype.
|
||||||
`ftdetect/nuwiki.vim` hardcodes `.wiki`; users with a custom
|
|
||||||
extension should add their own ftdetect autocmd.
|
|
||||||
|
|
||||||
*g:nuwiki_syntax*
|
*g:nuwiki_syntax*
|
||||||
`syntax` vimwiki
|
`syntax` vimwiki
|
||||||
Future-proofing for additional syntaxes (e.g. `markdown`). Phase 9
|
Future-proofing; currently only `vimwiki` is supported.
|
||||||
only ships the vimwiki plugin.
|
|
||||||
|
|
||||||
*g:nuwiki_log_level*
|
*g:nuwiki_log_level*
|
||||||
`log_level` warn
|
`log_level` warn
|
||||||
`error` | `warn` | `info` | `debug`. Forwarded to the language server.
|
`error` | `warn` | `info` | `debug`. Forwarded to the language server.
|
||||||
|
|
||||||
*g:nuwiki_build_from_source*
|
*nuwiki-config-folding*
|
||||||
`g:nuwiki_build_from_source` 0
|
`folding` 'lsp'
|
||||||
When 1, the install step always builds from source (cargo) and skips
|
`lsp` uses the server's `foldingRange` provider (Neovim 0.11+ wires
|
||||||
the release-asset download path.
|
it automatically). `expr` falls back to a regex `foldexpr`. `off`
|
||||||
|
disables folding setup entirely. See |nuwiki-folding| for details.
|
||||||
|
Vim users see the regex fallback when |g:nuwiki_no_folding| is not
|
||||||
|
set.
|
||||||
|
|
||||||
*g:nuwiki_binary_path*
|
*nuwiki-mappings*
|
||||||
|
`mappings` (all on except `mouse`)
|
||||||
|
Per-buffer keymap groups. Each subgroup can be flipped off
|
||||||
|
independently to suppress that group of keymaps. Subgroups:
|
||||||
|
`enabled`, `wiki_prefix`, `links`, `lists`, `headers`,
|
||||||
|
`table_editing`, `diary`, `html_export`, `text_objects`, `mouse`.
|
||||||
|
|
||||||
|
`diagnostic.link_severity` `'warn'`
|
||||||
|
Severity of broken-link diagnostics: `off`, `hint`, `warn`, `error`.
|
||||||
|
|
||||||
|
Per-wiki options ~
|
||||||
|
|
||||||
|
Every option in this list lives on a `wikis[i] = {...}` entry. Defaults
|
||||||
|
match upstream vimwiki.
|
||||||
|
|
||||||
|
`name` String — display name in `:VimwikiUISelect`.
|
||||||
|
`root` String — absolute or `~`-relative path.
|
||||||
|
`index` `'index'` — stem of the wiki's index page.
|
||||||
|
`file_extension` `'.wiki'`
|
||||||
|
`diary_rel_path` `'diary'`
|
||||||
|
`diary_index` `'diary'` — stem of the diary index page.
|
||||||
|
`diary_frequency` `'daily'` | `'weekly'` | `'monthly'` | `'yearly'`
|
||||||
|
`diary_caption_level` `1`
|
||||||
|
`diary_sort` `'desc'` | `'asc'`
|
||||||
|
`diary_header` `'Diary'`
|
||||||
|
`html_path` Path for `:Vimwiki2HTML` output.
|
||||||
|
`template_path` Path holding `<name>.tpl` templates.
|
||||||
|
`template_default` `'default'`
|
||||||
|
`template_ext` `'.tpl'`
|
||||||
|
`css_name` `'style.css'`
|
||||||
|
`auto_export` `false` — export to HTML on save.
|
||||||
|
`auto_toc` `false` — refresh TOC on save.
|
||||||
|
`exclude_files` List of glob patterns excluded from export.
|
||||||
|
`listsyms` `' .oOX'` — checkbox progression characters.
|
||||||
|
`listsyms_propagate` `true`
|
||||||
|
`maxhi` `1` — inline heading-level highlighting count.
|
||||||
|
`nested_syntaxes` `{}` — embed other syntaxes inside
|
||||||
|
`{{{lang …}}}` fenced blocks.
|
||||||
|
`links_space_char` `' '`
|
||||||
|
|
||||||
|
Vim-specific globals ~
|
||||||
|
|
||||||
|
*g:nuwiki_no_default_mappings*
|
||||||
|
`g:nuwiki_no_default_mappings` 0
|
||||||
|
When 1, the Vim path skips every buffer-local keymap. Equivalent to
|
||||||
|
`mappings.enabled = false` in Neovim.
|
||||||
|
|
||||||
|
*g:nuwiki_no_folding*
|
||||||
|
`g:nuwiki_no_folding` 0
|
||||||
|
When 1, the Vim path skips `foldexpr` / `foldmethod` setup.
|
||||||
|
|
||||||
|
*g:nuwiki_mouse_mappings*
|
||||||
|
`g:nuwiki_mouse_mappings` 0
|
||||||
|
When 1, the Vim path registers mouse keymaps (double-click follows,
|
||||||
|
middle-click `:badd`s the link target, etc.). Mirrors
|
||||||
|
`mappings.mouse = true` in Neovim.
|
||||||
|
|
||||||
|
*g:nuwiki_build_from_source*
|
||||||
|
`g:nuwiki_build_from_source` 0
|
||||||
|
When 1, the install step always builds the server with `cargo` and
|
||||||
|
skips the release-asset download.
|
||||||
|
|
||||||
|
*g:nuwiki_binary_path*
|
||||||
`g:nuwiki_binary_path`
|
`g:nuwiki_binary_path`
|
||||||
Override the auto-discovered server path. If set and the file is
|
Override the auto-discovered server binary path. If set and the
|
||||||
readable, `autoload/nuwiki/lsp.vim` uses it instead of the
|
file is readable, it overrides the `{plugin}/bin/nuwiki-ls` default.
|
||||||
`{plugin}/bin/nuwiki-ls` default.
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
5. HEALTH CHECK *nuwiki-health*
|
5. COMMANDS *nuwiki-commands*
|
||||||
|
|
||||||
Neovim users can run: >
|
Every command listed below is registered buffer-local on `.wiki` files
|
||||||
|
under both names: the `:Vimwiki*` form (for migration from vimwiki) and
|
||||||
|
the canonical `:Nuwiki*` alias. Only the `:Vimwiki*` form is shown.
|
||||||
|
|
||||||
:checkhealth nuwiki
|
Wiki / navigation ~
|
||||||
|
|
||||||
<This reports whether the binary exists, responds to `--version`, whether
|
*:VimwikiIndex*
|
||||||
`wiki_root` exists, whether `.wiki` filetype detection is wired up, and
|
:VimwikiIndex [{count}]
|
||||||
whether an LSP client is currently attached.
|
Open wiki N's index page (default: 1).
|
||||||
|
|
||||||
==============================================================================
|
*:VimwikiTabIndex*
|
||||||
6. LSP FEATURES *nuwiki-features*
|
:VimwikiTabIndex [{count}]
|
||||||
|
Same, in a new tab.
|
||||||
|
|
||||||
The language server provides every method listed in SPEC §6.9:
|
*:VimwikiUISelect*
|
||||||
|
:VimwikiUISelect
|
||||||
|
Pick a wiki from a list (multi-wiki only). Uses |vim.ui.select| on
|
||||||
|
Neovim, |inputlist()| on Vim.
|
||||||
|
|
||||||
* Syntax highlighting via semantic tokens
|
*:VimwikiGoto*
|
||||||
`textDocument/semanticTokens/full` + `/range`
|
:VimwikiGoto {page}
|
||||||
* Document outline
|
Open `{page}.wiki` by name.
|
||||||
`textDocument/documentSymbol`
|
|
||||||
* Diagnostics (parse errors)
|
|
||||||
`textDocument/publishDiagnostics`
|
|
||||||
* Go-to-definition (follow wikilinks)
|
|
||||||
`textDocument/definition`
|
|
||||||
* Backlinks
|
|
||||||
`textDocument/references`
|
|
||||||
* Hover preview (page title + outline)
|
|
||||||
`textDocument/hover`
|
|
||||||
* Completion on `[[`
|
|
||||||
`textDocument/completion`
|
|
||||||
* Workspace symbol search
|
|
||||||
`workspace/symbol`
|
|
||||||
|
|
||||||
==============================================================================
|
*:VimwikiFollowLink*
|
||||||
7. COMMANDS *nuwiki-commands*
|
:VimwikiFollowLink
|
||||||
|
Follow the link under the cursor.
|
||||||
|
|
||||||
|
*:VimwikiBacklinks*
|
||||||
|
:VimwikiBacklinks
|
||||||
|
Show all references to the current page.
|
||||||
|
|
||||||
|
*:VimwikiNextLink*
|
||||||
|
:VimwikiNextLink
|
||||||
|
*:VimwikiPrevLink*
|
||||||
|
:VimwikiPrevLink
|
||||||
|
Jump to the next / previous wikilink on the page.
|
||||||
|
|
||||||
|
*:VimwikiBaddLink*
|
||||||
|
:VimwikiBaddLink
|
||||||
|
Add the target of the link under the cursor to the buffer list.
|
||||||
|
|
||||||
|
*:VimwikiRenameFile*
|
||||||
|
:VimwikiRenameFile
|
||||||
|
Prompt for a new name; rename the current page and rewrite every
|
||||||
|
inbound link.
|
||||||
|
|
||||||
|
*:VimwikiDeleteFile*
|
||||||
|
:VimwikiDeleteFile
|
||||||
|
Delete the current page and its on-disk file.
|
||||||
|
|
||||||
|
Diary ~
|
||||||
|
|
||||||
|
*:VimwikiMakeDiaryNote*
|
||||||
|
:VimwikiMakeDiaryNote
|
||||||
|
Open today's diary entry. With `diary_frequency = 'weekly'` (or
|
||||||
|
`'monthly'` / `'yearly'`) this addresses this week's / this month's
|
||||||
|
/ this year's entry instead. The file stems follow:
|
||||||
|
|
||||||
|
daily YYYY-MM-DD 2026-05-12.wiki
|
||||||
|
weekly YYYY-Www 2026-W19.wiki (ISO 8601 week)
|
||||||
|
monthly YYYY-MM 2026-05.wiki
|
||||||
|
yearly YYYY 2026.wiki
|
||||||
|
|
||||||
|
*:VimwikiMakeYesterdayDiaryNote*
|
||||||
|
:VimwikiMakeYesterdayDiaryNote
|
||||||
|
*:VimwikiMakeTomorrowDiaryNote*
|
||||||
|
:VimwikiMakeTomorrowDiaryNote
|
||||||
|
Step the diary back / forward by one period at the configured
|
||||||
|
cadence.
|
||||||
|
|
||||||
|
*:VimwikiDiaryIndex*
|
||||||
|
:VimwikiDiaryIndex
|
||||||
|
Open the diary index page.
|
||||||
|
|
||||||
|
*:VimwikiDiaryGenerateLinks*
|
||||||
|
:VimwikiDiaryGenerateLinks
|
||||||
|
Rebuild the diary index page from the entries currently on disk.
|
||||||
|
|
||||||
|
*:VimwikiDiaryNextDay*
|
||||||
|
:VimwikiDiaryNextDay
|
||||||
|
*:VimwikiDiaryPrevDay*
|
||||||
|
:VimwikiDiaryPrevDay
|
||||||
|
Walk to the next / previous indexed diary entry at the same cadence
|
||||||
|
as the current one.
|
||||||
|
|
||||||
|
Page generation ~
|
||||||
|
|
||||||
|
*:VimwikiTOC*
|
||||||
|
:VimwikiTOC
|
||||||
|
Generate or refresh the table of contents on the current page.
|
||||||
|
|
||||||
|
*:VimwikiGenerateLinks*
|
||||||
|
:VimwikiGenerateLinks
|
||||||
|
Insert a flat list of every page in the wiki under the cursor.
|
||||||
|
|
||||||
|
*:VimwikiCheckLinks*
|
||||||
|
:VimwikiCheckLinks
|
||||||
|
Send every broken link in the workspace to the |quickfix| list.
|
||||||
|
|
||||||
|
Tags ~
|
||||||
|
|
||||||
|
*:VimwikiSearchTags*
|
||||||
|
:VimwikiSearchTags {tag}
|
||||||
|
Quickfix listing every `:tag:` occurrence.
|
||||||
|
|
||||||
|
*:VimwikiGenerateTagLinks*
|
||||||
|
:VimwikiGenerateTagLinks [tag]
|
||||||
|
Insert a section linking every page that has `<tag>`. With no
|
||||||
|
argument, generates a section per tag found in the workspace.
|
||||||
|
|
||||||
|
*:VimwikiRebuildTags*
|
||||||
|
:VimwikiRebuildTags
|
||||||
|
Force a full workspace re-index.
|
||||||
|
|
||||||
|
HTML export ~
|
||||||
|
|
||||||
|
*:Vimwiki2HTML*
|
||||||
|
:Vimwiki2HTML
|
||||||
|
Render the current page to HTML.
|
||||||
|
|
||||||
|
*:Vimwiki2HTMLBrowse*
|
||||||
|
:Vimwiki2HTMLBrowse
|
||||||
|
Render the current page and open it in the default browser.
|
||||||
|
|
||||||
|
*:VimwikiAll2HTML*
|
||||||
|
:VimwikiAll2HTML[!]
|
||||||
|
Export every page in the wiki. `!` forces a full rebuild; otherwise
|
||||||
|
only out-of-date pages are re-rendered.
|
||||||
|
|
||||||
|
*:VimwikiRss*
|
||||||
|
:VimwikiRss
|
||||||
|
Write `rss.xml` summarising recent diary entries.
|
||||||
|
|
||||||
|
Other ~
|
||||||
|
|
||||||
*:NuwikiInstall*
|
*:NuwikiInstall*
|
||||||
:NuwikiInstall
|
:NuwikiInstall
|
||||||
Install (or re-install) the `nuwiki-ls` binary into the plugin's
|
Install (or re-install) the `nuwiki-ls` binary into the plugin's
|
||||||
`bin/` directory. Equivalent to running the build hook by hand.
|
`bin/` directory. Equivalent to running the build hook by hand.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
6. KEYMAPS *nuwiki-keymaps*
|
||||||
|
|
||||||
|
Every keymap is buffer-local. Disable a group via `mappings.<group> =
|
||||||
|
false` in Neovim, or `let g:nuwiki_no_default_mappings = 1` in Vim.
|
||||||
|
|
||||||
|
Links (normal mode) ~
|
||||||
|
|
||||||
|
<CR> Smart follow — inside `[[…]]` jumps; on a bare word
|
||||||
|
wraps as `[[word]]` (second <CR> follows the link).
|
||||||
|
<S-CR> Follow in a horizontal split.
|
||||||
|
<C-CR> Follow in a vertical split.
|
||||||
|
<C-S-CR> Follow in a new tab.
|
||||||
|
<BS> Jump back (`<C-o>`).
|
||||||
|
<Tab> Next wikilink on or after the cursor.
|
||||||
|
<S-Tab> Previous wikilink.
|
||||||
|
+ Wrap word (or visual selection) as `[[word]]`. No follow.
|
||||||
|
|
||||||
|
Lists (normal mode) ~
|
||||||
|
|
||||||
|
<C-Space> Toggle the checkbox under the cursor. Also bound to <C-@>
|
||||||
|
and <Nul> to cover terminal byte differences.
|
||||||
|
gln Cycle the checkbox state forward.
|
||||||
|
glp Cycle the checkbox state backward.
|
||||||
|
glx Toggle the rejected marker `[-]`.
|
||||||
|
gnt Jump to the next unfinished task.
|
||||||
|
glh Dedent the current list item.
|
||||||
|
gll Indent the current list item.
|
||||||
|
gLh Dedent the item including its sublist.
|
||||||
|
gLl Indent the item including its sublist.
|
||||||
|
glr Renumber the current ordered list.
|
||||||
|
gLr Renumber every ordered list in the buffer.
|
||||||
|
gl<Space> Remove every completed item from the current list.
|
||||||
|
gL<Space> Remove every completed item in the buffer.
|
||||||
|
o Open a new line and continue the list marker (preserves
|
||||||
|
any checkbox).
|
||||||
|
O Same, opening above the current line.
|
||||||
|
|
||||||
|
Headers ~
|
||||||
|
|
||||||
|
= Increase the heading level under the cursor.
|
||||||
|
- Decrease the heading level.
|
||||||
|
]] Next heading (any level).
|
||||||
|
[[ Previous heading.
|
||||||
|
]= Next sibling heading.
|
||||||
|
[= Previous sibling heading.
|
||||||
|
]u Jump to the parent heading.
|
||||||
|
[u Same — alternate binding.
|
||||||
|
|
||||||
|
Tables (normal mode) ~
|
||||||
|
|
||||||
|
gqq Align the table under the cursor. Also `gq1`, `gww`, `gw1`.
|
||||||
|
<A-Left> Move the column under the cursor left.
|
||||||
|
<A-Right> Move the column under the cursor right.
|
||||||
|
|
||||||
|
Wiki / diary / export ~
|
||||||
|
|
||||||
|
<Leader>ww Open today's diary.
|
||||||
|
<Leader>ws Pick a wiki.
|
||||||
|
<Leader>wi Open the diary index.
|
||||||
|
<Leader>w<Leader>w Today.
|
||||||
|
<Leader>w<Leader>y Yesterday.
|
||||||
|
<Leader>w<Leader>t Tomorrow.
|
||||||
|
<Leader>w<Leader>i Rebuild the diary index page.
|
||||||
|
<Leader>wn Goto page (prompts for name).
|
||||||
|
<Leader>wd Delete the current page.
|
||||||
|
<Leader>wr Rename the current page.
|
||||||
|
<Leader>wh Export the current page to HTML.
|
||||||
|
<Leader>whh Export and open in the browser.
|
||||||
|
<Leader>wha Export every page.
|
||||||
|
<Leader>wc Wrap word / selection in a colour span.
|
||||||
|
<C-Down> Next diary entry.
|
||||||
|
<C-Up> Previous diary entry.
|
||||||
|
|
||||||
|
Mouse (opt-in via |g:nuwiki_mouse_mappings|) ~
|
||||||
|
|
||||||
|
<2-LeftMouse> Follow the link clicked.
|
||||||
|
<S-2-LeftMouse> Follow in a horizontal split.
|
||||||
|
<C-2-LeftMouse> Follow in a vertical split.
|
||||||
|
<MiddleMouse> Add the link target to the buffer list.
|
||||||
|
<RightMouse> Jump back (`<C-o>`).
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
7. TEXT OBJECTS *nuwiki-text-objects*
|
||||||
|
|
||||||
|
Operator-pending + visual. Disable via `mappings.text_objects = false`.
|
||||||
|
|
||||||
|
ah A heading section — the heading line and everything up to
|
||||||
|
the next heading at any level.
|
||||||
|
ih Same, but excluding the heading line itself.
|
||||||
|
aH A heading section plus every subheading underneath — stops
|
||||||
|
at the next heading of same-or-shallower level.
|
||||||
|
iH Same, but excluding the heading line.
|
||||||
|
al The list item under the cursor.
|
||||||
|
il Same, but excluding the marker / checkbox prefix.
|
||||||
|
a\ The table cell under the cursor (includes the trailing `|`).
|
||||||
|
i\ Same, content only — no surrounding `|`s or padding.
|
||||||
|
ac The table column under the cursor (includes the header
|
||||||
|
separator row).
|
||||||
|
ic Same, content cells only.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
8. INSERT-MODE BINDINGS *nuwiki-insert-mode*
|
||||||
|
|
||||||
|
Smart return ~
|
||||||
|
|
||||||
|
`<CR>` is bound to a smart helper that does the right thing depending
|
||||||
|
on context:
|
||||||
|
|
||||||
|
* On a list item with content — continue the list with the same marker
|
||||||
|
on a new line. Preserves a leading checkbox if present.
|
||||||
|
* On an empty list item (marker only) — clear the marker and break
|
||||||
|
out of the list with a plain newline.
|
||||||
|
* Inside a `|…|` table row — insert a fresh empty row below with the
|
||||||
|
same column count; cursor lands inside the first cell.
|
||||||
|
* Otherwise — plain `<CR>`.
|
||||||
|
|
||||||
|
Table cell navigation ~
|
||||||
|
|
||||||
|
<Tab> Jump to the next cell. Past the last cell, insert a fresh
|
||||||
|
row below and land in its first cell.
|
||||||
|
<S-Tab> Jump to the previous cell.
|
||||||
|
|
||||||
|
Outside a table row both pass through to their default insert-mode
|
||||||
|
behaviour (literal tab / shift-tab).
|
||||||
|
|
||||||
|
List editing ~
|
||||||
|
|
||||||
|
<C-D> Dedent the current list item.
|
||||||
|
<C-T> Indent the current list item.
|
||||||
|
<C-L><C-J> Cycle the marker forward through the canonical run:
|
||||||
|
`-` → `*` → `#` → `1.` → `1)` → `a)` → `A)` → `i)` → `I)`
|
||||||
|
<C-L><C-K> Cycle the marker backward.
|
||||||
|
<C-L><C-M> Toggle the checkbox on the current item, or insert
|
||||||
|
`[ ]` after the marker when there isn't one.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
9. DIARY *nuwiki-diary*
|
||||||
|
|
||||||
|
The diary holds dated entries under `<wiki_root>/<diary_rel_path>/` —
|
||||||
|
`diary/` by default.
|
||||||
|
|
||||||
|
Frequencies ~
|
||||||
|
|
||||||
|
The `diary_frequency` per-wiki option controls the cadence:
|
||||||
|
|
||||||
|
daily YYYY-MM-DD e.g. `2026-05-12.wiki` (default)
|
||||||
|
weekly YYYY-Www ISO 8601 week, e.g. `2026-W19.wiki`
|
||||||
|
monthly YYYY-MM e.g. `2026-05.wiki`
|
||||||
|
yearly YYYY e.g. `2026.wiki`
|
||||||
|
|
||||||
|
`:VimwikiMakeDiaryNote` opens the entry for the current period at the
|
||||||
|
configured cadence; the yesterday / tomorrow commands step back and
|
||||||
|
forward by one period. `<C-Down>` / `<C-Up>` walk between indexed
|
||||||
|
entries of the same flavour as the one under the cursor — so on a
|
||||||
|
weekly page, navigation stays weekly.
|
||||||
|
|
||||||
|
Index ~
|
||||||
|
|
||||||
|
`:VimwikiDiaryGenerateLinks` rebuilds the diary index page (`diary.wiki`
|
||||||
|
by default) with a chronological list of every entry on disk, grouped
|
||||||
|
by year / month. The page name is set by `diary_index`; the heading is
|
||||||
|
set by `diary_header`.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
10. TABLES *nuwiki-tables*
|
||||||
|
|
||||||
|
Tables use vimwiki's pipe syntax: >
|
||||||
|
|
||||||
|
| Name | Score |
|
||||||
|
|-------|-------|
|
||||||
|
| Alice | 97 |
|
||||||
|
| Bob | 72 |
|
||||||
|
|
||||||
|
<Alignment markers on the header separator row follow Markdown
|
||||||
|
conventions:
|
||||||
|
|
||||||
|
`|:---|` left-align
|
||||||
|
`|---:|` right-align
|
||||||
|
`|:---:|` centre-align
|
||||||
|
|
||||||
|
A cell containing just `>` merges with the cell to its left (colspan);
|
||||||
|
a cell containing just `\/` merges with the cell directly above
|
||||||
|
(rowspan). The HTML renderer emits proper `colspan="N"` / `rowspan="N"`
|
||||||
|
attributes plus `style="text-align: …;"` per cell when alignment is
|
||||||
|
specified.
|
||||||
|
|
||||||
|
See |nuwiki-keymaps| for the table-editing shortcuts (alignment,
|
||||||
|
column moves, cell navigation, new-row insertion).
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
11. HTML EXPORT *nuwiki-html*
|
||||||
|
|
||||||
|
`:Vimwiki2HTML` renders the current page; `:Vimwiki2HTMLBrowse` opens
|
||||||
|
the result in the default browser; `:VimwikiAll2HTML` exports every
|
||||||
|
page (incremental by default; `!` forces a full rebuild).
|
||||||
|
|
||||||
|
Per-wiki knobs:
|
||||||
|
|
||||||
|
`html_path` Output directory (created if missing).
|
||||||
|
`template_path` Where to find `<name>.tpl` files.
|
||||||
|
`template_default` Default template name (without extension).
|
||||||
|
`template_ext` Template file extension (default `.tpl`).
|
||||||
|
`css_name` CSS file copied into `html_path`.
|
||||||
|
`auto_export` When `true`, exports on every save.
|
||||||
|
`exclude_files` Glob patterns excluded from export.
|
||||||
|
|
||||||
|
Templates may include `{title}`, `{rootpath}`, `{content}`, `{css}`,
|
||||||
|
`{date}` placeholders. RSS for the diary is written by `:VimwikiRss`.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
12. FOLDING *nuwiki-folding*
|
||||||
|
|
||||||
|
Folds follow the heading outline: each `= H1 =` opens a level-1 fold,
|
||||||
|
each `== H2 ==` opens a level-2 fold, etc. Folds close at the next
|
||||||
|
heading of same-or-shallower level.
|
||||||
|
|
||||||
|
Neovim picks between two providers based on the `folding` setup option:
|
||||||
|
|
||||||
|
`'lsp'` Server-driven `foldingRange` (Neovim 0.11+ wires it
|
||||||
|
automatically; the editor falls back to the regex variant
|
||||||
|
if the server isn't yet attached).
|
||||||
|
`'expr'` Regex `foldexpr` over `getline()` — no server roundtrip.
|
||||||
|
`'off'` No folding setup.
|
||||||
|
|
||||||
|
Vim users get the regex variant via `nuwiki#folding#expr()` unless
|
||||||
|
|g:nuwiki_no_folding| is set.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
13. HEALTH CHECK *nuwiki-health*
|
||||||
|
|
||||||
|
*:checkhealth-nuwiki*
|
||||||
|
Neovim users can run: >
|
||||||
|
|
||||||
|
:checkhealth nuwiki
|
||||||
|
|
||||||
|
<This reports:
|
||||||
|
|
||||||
|
* Whether the binary exists and responds to `--version`.
|
||||||
|
* Whether `wiki_root` exists.
|
||||||
|
* Whether the `.wiki` filetype is registered (`vimwiki`).
|
||||||
|
* Whether an LSP client is currently attached.
|
||||||
|
* Which `executeCommand` handlers the server advertised.
|
||||||
|
|
||||||
|
Vim users without `:checkhealth` can run `:LspStatus` (vim-lsp) or
|
||||||
|
`:CocCommand workspace.showOutput` (coc.nvim).
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
14. MIGRATING FROM VIMWIKI *nuwiki-migrating*
|
||||||
|
|
||||||
|
The file extension, syntax, command names, and default keymaps all
|
||||||
|
match vimwiki. To migrate:
|
||||||
|
|
||||||
|
1. Drop the original `vimwiki` plugin from your config.
|
||||||
|
2. Install nuwiki.
|
||||||
|
3. Point `wiki_root` (or each `wikis[i].root`) at your existing
|
||||||
|
directory.
|
||||||
|
|
||||||
|
Existing pages, diary entries, tags, and templates work without
|
||||||
|
modification. The first workspace scan after launch may show an empty
|
||||||
|
`:VimwikiCheckLinks` result until the background index completes;
|
||||||
|
subsequent runs are instant.
|
||||||
|
|
||||||
vim:tw=78:ts=8:ft=help:norl:
|
vim:tw=78:ts=8:ft=help:norl:
|
||||||
|
|||||||
Reference in New Issue
Block a user