2026-05-10 16:01:58 +00:00
# nuwiki
2026-05-12 14:20:18 +00:00
**A vimwiki-compatible Vim/Neovim plugin backed by a Rust language server. **
2026-05-10 16:01:58 +00:00
2026-05-12 14:20:18 +00:00
nuwiki replaces the original [vimwiki ](https://github.com/vimwiki/vimwiki )
plugin while keeping its file format, keymaps, and `:Vimwiki*` command
surface intact. The substantive work happens in a Rust LSP daemon — Vim
2026-05-12 22:46:16 +00:00
and Neovim are thin client layers that wire up keystrokes and display
results.
## Features
### Syntax & rendering
- 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.
2026-05-30 23:12:14 -03:00
- Semantic-token highlighting (no syntax-file fallback needed). Code fences
tagged with a language (`{{{python … }}}` ) get that language's syntax
automatically — no `nested_syntaxes` config needed.
2026-05-12 22:46:16 +00:00
- 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).
2026-05-10 17:20:46 +00:00
2026-05-12 14:20:18 +00:00
---
## Installation
2026-05-12 22:46:16 +00:00
The plugin ships a `nuwiki-ls` binary that the editor talks to over LSP
stdio. The `install()` helper downloads a pre-built release for your
platform, falling back to `cargo build --release` if no asset matches.
2026-05-30 15:54:12 -03:00
You can run it any time with `:NuwikiInstall` (works in both Vim and
Neovim) instead of relying on a plugin-manager build hook.
### Requirements
- **Neovim 0.11+** — uses the built-in LSP client; no extra plugin.
Older releases fall back to a `vim.lsp.start` autocmd but aren't
officially supported.
- **Vim 9+** — needs a third-party LSP client:
[`vim-lsp` ](https://github.com/prabirshrestha/vim-lsp ) (recommended,
auto-registered) or [`coc.nvim` ](https://github.com/neoclide/coc.nvim )
(one-time `coc-settings.json` entry — see [Vim LSP client
setup ](#vim-lsp-client-setup )).
- **Rust toolchain (1.83+ stable)** — only needed when building the
binary from source; pre-built release downloads skip this.
2026-05-12 14:20:18 +00:00
### lazy.nvim
``` lua
{
' gffranco/nuwiki ' ,
build = " :lua require('nuwiki').install() " ,
ft = { ' vimwiki ' } ,
opts = {
wiki_root = ' ~/vimwiki ' ,
} ,
}
```
### vim-plug
``` vim
Plug 'gffranco/nuwiki' , { 'do' : 'vim -e -s -c "source scripts/download_bin.vim" -c "q"' }
```
In `init.lua` / `init.vim` :
``` lua
require ( ' nuwiki ' ) . setup ( { wiki_root = ' ~/vimwiki ' } )
```
### Dein
``` vim
call dein #add ( 'gffranco/nuwiki' , {
\ 'build' : 'vim -e -s -c "source scripts/download_bin.vim" -c "q"'
\ })
```
### Plain Vim (no plugin manager)
``` sh
git clone https://code.gfran.co/gffranco/nuwiki ~/.vim/pack/gffranco/start/nuwiki
cd ~/.vim/pack/gffranco/start/nuwiki && cargo build --release -p nuwiki-ls
2026-05-21 20:39:37 -03:00
mkdir -p bin && ln -s ../target/release/nuwiki-ls bin/nuwiki-ls
2026-05-12 14:20:18 +00:00
```
2026-05-30 15:54:12 -03:00
### Vim LSP client setup
Neovim 0.11+ registers the server through its built-in LSP client
automatically — nothing to configure. Plain Vim needs one of the
following clients on its `runtimepath` ; nuwiki picks them up in this
order when the first `.wiki` buffer loads.
**vim-lsp (recommended) ** — zero configuration. Once
[`vim-lsp` ](https://github.com/prabirshrestha/vim-lsp ) (and its
[`async.vim` ](https://github.com/prabirshrestha/async.vim ) dependency)
is installed, nuwiki calls `lsp#register_server()` for you and vim-lsp
auto-enables it. Your wiki settings (`g:nuwiki_wiki_root` ,
`g:nuwiki_wikis` , …) are forwarded as the server's initialization
options.
**coc.nvim ** — [`coc.nvim` ](https://github.com/neoclide/coc.nvim ) reads
its server list from `coc-settings.json` , which the plugin can't edit
on your behalf, so add the entry once yourself (open it with
`:CocConfig` ):
``` json
{
"languageserver" : {
"nuwiki" : {
"command" : "~/.vim/pack/gffranco/start/nuwiki/bin/nuwiki-ls" ,
"filetypes" : [ "vimwiki" ]
}
}
}
```
Point `command` at the installed binary — by default it lives in the
plugin's `bin/` directory (adjust the path for your plugin manager), or
set `g:nuwiki_binary_path` and reuse that value. With coc you can also
invoke server commands directly via `:CocCommand nuwiki.<command>`
instead of the `:Vimwiki*` / `:Nuwiki*` aliases.
2026-05-12 14:20:18 +00:00
2026-05-12 22:46:16 +00:00
### Try it without touching your config
2026-05-12 14:20:18 +00:00
``` sh
2026-05-30 18:35:40 +00:00
./development/start-nvim.sh # spawns Neovim against an isolated sample wiki
./development/start-vim.sh # same, for plain Vim (clones vim-lsp on first run)
2026-05-12 14:20:18 +00:00
```
2026-05-12 22:46:16 +00:00
Both scripts build the LSP binary, seed a scratch wiki, and launch the
editor against an isolated state dir under `$XDG_CACHE_HOME/nuwiki-dev` .
2026-05-12 14:20:18 +00:00
---
## Configuration
2026-05-12 22:46:16 +00:00
Defaults are vimwiki-compatible. Every key has a sensible default — the
example below shows the full surface for reference.
2026-05-12 14:20:18 +00:00
``` lua
require ( ' nuwiki ' ) . setup ( {
-- Single-wiki shorthand (vimwiki-compatible).
wiki_root = ' ~/vimwiki ' ,
file_extension = ' .wiki ' ,
syntax = ' vimwiki ' , -- 'vimwiki' | 'markdown' (future)
log_level = ' warn ' ,
2026-05-12 22:46:16 +00:00
-- Multi-wiki: each entry honours every per-wiki key vimwiki understands.
-- Pick either this OR the single-wiki shorthand above. If both are set,
-- `wikis` wins.
2026-05-12 14:20:18 +00:00
wikis = {
{
2026-05-12 22:46:16 +00:00
name = ' personal ' ,
root = ' ~/vimwiki ' ,
index = ' index ' , -- index page stem
file_extension = ' .wiki ' ,
-- Diary
diary_rel_path = ' diary ' ,
diary_index = ' diary ' ,
diary_frequency = ' daily ' , -- 'daily' | 'weekly' | 'monthly' | 'yearly'
diary_sort = ' desc ' , -- 'desc' | 'asc'
diary_header = ' Diary ' ,
-- HTML export
2026-05-12 14:20:18 +00:00
html_path = ' ~/vimwiki/_html ' ,
template_path = ' ~/vimwiki/_templates ' ,
template_default = ' default ' ,
template_ext = ' .tpl ' ,
css_name = ' style.css ' ,
2026-05-12 22:46:16 +00:00
auto_export = false , -- export on save
auto_toc = false , -- auto-refresh TOC on save
exclude_files = { } , -- glob patterns
-- Checkbox progression characters: " .oOX" by default.
listsyms = ' .oOX ' ,
listsyms_propagate = true ,
2026-05-12 14:20:18 +00:00
} ,
} ,
2026-05-12 22:46:16 +00:00
-- Keymap groups. Flip subgroups off independently. Defaults all on.
2026-05-12 14:20:18 +00:00
mappings = {
enabled = true ,
wiki_prefix = true , -- <Leader>w*
links = true , -- <CR>, <S-CR>, <Tab>, <BS>, +, …
2026-05-12 22:46:16 +00:00
lists = true , -- <C-Space>, gln/glp/glx, gl<Space>, o/O, …
2026-05-12 14:20:18 +00:00
headers = true , -- =, -, ]], [[, ]=, [=, ]u, [u
2026-05-12 22:46:16 +00:00
table_editing = true , -- gqq, <A-Left>, <A-Right>, <Tab> in insert mode
2026-05-12 14:20:18 +00:00
diary = true , -- <C-Down>, <C-Up>
html_export = true , -- <Leader>wh, <Leader>whh
2026-05-12 22:46:16 +00:00
text_objects = true , -- ah, ih, aH, iH, al, il, a\, i\, ac, ic
mouse = false , -- <2-LeftMouse>, <RightMouse>, … (opt-in)
2026-05-12 14:20:18 +00:00
} ,
2026-05-12 22:46:16 +00:00
-- 'lsp' (server-driven foldingRange, default) | 'expr' (regex) | 'off'.
2026-05-12 14:20:18 +00:00
folding = ' lsp ' ,
-- Broken-link diagnostic severity: 'off' | 'hint' | 'warn' | 'error'.
diagnostic = {
link_severity = ' warn ' ,
} ,
} )
```
2026-05-12 22:46:16 +00:00
Vim users without Lua set the equivalent globals before loading the
plugin:
2026-05-12 14:20:18 +00:00
``` vim
2026-05-12 22:46:16 +00:00
let g :nuwiki_wiki_root = '~/vimwiki'
let g :nuwiki_file_extension = '.wiki'
let g :nuwiki_log_level = 'warn'
2026-05-30 21:53:56 -03:00
let g :nuwiki_link_severity = 'warn' " 'off'|'hint'|'warn'|'error'
2026-05-12 22:46:16 +00:00
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
2026-05-12 14:20:18 +00:00
```
2026-05-30 19:24:08 -03:00
### Reference
#### Top-level options
| Key | Type | Default | Accepted values |
|-----|------|---------|-----------------|
| `wiki_root` | string (path) | `'~/vimwiki'` | any directory path |
| `file_extension` | string | `'.wiki'` | any extension, leading `.` |
| `syntax` | string | `'vimwiki'` | `'vimwiki'` (`'markdown'` planned) |
| `log_level` | string | `'warn'` | `'error'` \| `'warn'` \| `'info'` \| `'debug'` |
| `folding` | string | `'lsp'` | `'lsp'` \| `'expr'` \| `'off'` |
| `wikis` | list of tables | `nil` | per-wiki tables (see below); wins over the single-wiki shorthand |
| `mappings` | table | all on | keymap subgroups (see below) |
2026-05-30 21:53:56 -03:00
| `diagnostic` | table | `{ link_severity = 'warn' }` | `link_severity` : `'off'` \| `'hint'` \| `'warn'` \| `'error'` |
2026-05-30 19:24:08 -03:00
#### `mappings` subgroups
Each is a boolean. All default to `true` except `mouse` .
| Key | Default | Controls |
|-----|---------|----------|
| `enabled` | `true` | master switch for the whole keymap layer |
| `wiki_prefix` | `true` | `<Leader>w*` |
| `links` | `true` | `<CR>` , `<S-CR>` , `<Tab>` , `<BS>` , `+` , … |
| `lists` | `true` | `<C-Space>` , `gln` /`glp` /`glx` , `gl<Space>` , `o` /`O` , … |
| `headers` | `true` | `=` , `-` , `]]` , `[[` , `]=` , `[=` , `]u` , `[u` |
| `table_editing` | `true` | `gqq` , `<A-Left>` , `<A-Right>` , `<Tab>` (insert) |
| `diary` | `true` | `<C-Down>` , `<C-Up>` |
| `html_export` | `true` | `<Leader>wh` , `<Leader>whh` |
| `text_objects` | `true` | `ah` , `ih` , `aH` , `iH` , `al` , `il` , `a\` , `i\` , `ac` , `ic` |
| `mouse` | `false` | `<2-LeftMouse>` , `<RightMouse>` , … (opt-in) |
#### Per-wiki keys (`wikis[]`)
| Key | Type | Default | Accepted values |
|-----|------|---------|-----------------|
| `name` | string | — | any label |
| `root` | string (path) | — | any directory path |
| `file_extension` | string | `'.wiki'` | any extension |
| `syntax` | string | `'vimwiki'` | `'vimwiki'` |
| `index` | string | `'index'` | index page stem |
| `diary_rel_path` | string | `'diary'` | path relative to `root` |
| `diary_index` | string | `'diary'` | diary index page stem |
| `diary_frequency` | string | `'daily'` | `'daily'` \| `'weekly'` \| `'monthly'` \| `'yearly'` |
2026-05-30 23:12:14 -03:00
| `diary_caption_level` | int | `1` | `1` – `6` (level of the index caption) |
2026-05-30 19:24:08 -03:00
| `diary_sort` | string | `'desc'` | `'desc'` \| `'asc'` |
| `diary_header` | string | `'Diary'` | any heading text |
| `listsyms` | string | `' .oOX'` | checkbox progression chars |
| `listsyms_propagate` | bool | `true` | `true` \| `false` |
| `list_margin` | int | `-1` | `-1` (auto) or `≥ 0` |
| `links_space_char` | string | `' '` | char that replaces spaces in synthesised link paths |
| `auto_toc` | bool | `false` | `true` \| `false` |
#### HTML export keys (per-wiki)
| Key | Type | Default | Accepted values |
|-----|------|---------|-----------------|
| `html_path` | string (path) | `'<root>/_html'` | output directory |
| `template_path` | string (path) | `'<root>/_templates'` | template directory |
| `template_default` | string | `'default'` | template stem |
| `template_ext` | string | `'.tpl'` | template extension |
| `template_date_format` | string | `'%Y-%m-%d'` | strftime format |
| `css_name` | string | `'style.css'` | stylesheet filename |
| `auto_export` | bool | `false` | `true` \| `false` (export on save) |
| `html_filename_parameterization` | bool | `false` | `true` \| `false` |
| `exclude_files` | list | `{}` | glob patterns |
| `color_dic` | table | `{}` | `{ name = 'color', … }` |
#### Vim globals (`g:nuwiki_*`)
For users configuring without Lua.
| Global | Default | Meaning |
|--------|---------|---------|
| `g:nuwiki_wiki_root` | `'~/vimwiki'` | single-wiki root |
| `g:nuwiki_file_extension` | `'.wiki'` | wiki file extension |
| `g:nuwiki_log_level` | `'warn'` | `error` \| `warn` \| `info` \| `debug` |
2026-05-30 21:53:56 -03:00
| `g:nuwiki_link_severity` | `'warn'` | broken-link severity: `off` \| `hint` \| `warn` \| `error` |
2026-05-30 19:24:08 -03:00
| `g:nuwiki_no_default_mappings` | `0` | `1` skips the keymap layer |
| `g:nuwiki_no_folding` | `0` | `1` skips foldexpr setup |
| `g:nuwiki_mouse_mappings` | `0` | `1` enables mouse maps |
2026-05-12 14:20:18 +00:00
---
## Usage
### Commands
2026-05-30 15:54:12 -03:00
`:Nuwiki*` is the canonical native surface; every command also has a
`:Vimwiki*` counterpart for drop-in migration. Both are registered as
buffer-local commands on every `.wiki` buffer (the wiki picker is also
global so you can switch wikis before any `.wiki` file is open). Type
`:Nuwiki<Tab>` or `:Vimwiki<Tab>` to browse them; coc.nvim users can
also call the server directly with `:CocCommand nuwiki.<command>` .
Only the legacy short forms `:VWB` / `:VWS` and `:VimwikiSearch` keep a
Vimwiki-only name (shown as `—` in the Nuwiki column); every other
command is mirrored. The split / tab link-following commands exist on
the Neovim path only — plain Vim uses the `<S-CR>` / `<C-CR>` mappings
instead.
**Wiki & navigation **
| Nuwiki | Vimwiki | Action |
|---|---|---|
| `:NuwikiIndex [N]` | `:VimwikiIndex [N]` | Open wiki N's index page (default: 1) |
| `:NuwikiTabIndex [N]` | `:VimwikiTabIndex [N]` | Same, in a new tab |
| `:NuwikiUISelect` | `:VimwikiUISelect` | Pick a wiki from a list (multi-wiki) |
| `:NuwikiGoto {page}` | `:VimwikiGoto {page}` | Open `{page}.wiki` by name |
| `:NuwikiFollowLink` | `:VimwikiFollowLink` | Follow the link under the cursor |
| `:NuwikiSplitLink` / `:NuwikiVSplitLink` / `:NuwikiTabnewLink` | `:VimwikiSplitLink` / `:VimwikiVSplitLink` / `:VimwikiTabnewLink` | Follow the link in a horizontal split / vertical split / new tab (Neovim) |
| `:NuwikiGoBackLink` | `:VimwikiGoBackLink` | Jump back to where you followed the link from (Neovim) |
| `:NuwikiBacklinks` | `:VimwikiBacklinks` (`:VWB` ) | Show all references to the current page |
| `:NuwikiNextLink` / `:NuwikiPrevLink` | `:VimwikiNextLink` / `:VimwikiPrevLink` | Jump to the next / previous wikilink |
| `:NuwikiBaddLink` | `:VimwikiBaddLink` | Add the link target under the cursor to the buffer list |
2026-05-30 17:36:05 -03:00
| `:NuwikiNormalizeLink` | `:VimwikiNormalizeLink` | Wrap the word / visual selection under the cursor as a wikilink |
2026-05-30 15:54:12 -03:00
| — | `:VimwikiSearch {pat}` (`:VWS` ) | `:lvimgrep` `{pat}` across every page |
**Diary **
| Nuwiki | Vimwiki | Action |
|---|---|---|
| `:NuwikiMakeDiaryNote` (`:NuwikiDiaryToday` ) | `:VimwikiMakeDiaryNote` | Open today's entry (or this week / month / year, per `diary_frequency` ) |
2026-05-30 17:36:05 -03:00
| `:NuwikiTabMakeDiaryNote` | `:VimwikiTabMakeDiaryNote` | Open today's entry in a new tab |
2026-05-30 15:54:12 -03:00
| `:NuwikiMakeYesterdayDiaryNote` (`:NuwikiDiaryYesterday` ) | `:VimwikiMakeYesterdayDiaryNote` | Step the diary back one period |
| `:NuwikiMakeTomorrowDiaryNote` (`:NuwikiDiaryTomorrow` ) | `:VimwikiMakeTomorrowDiaryNote` | Step the diary forward one period |
| `:NuwikiDiaryIndex` | `:VimwikiDiaryIndex` | Open the diary index page |
| `:NuwikiDiaryGenerateLinks` | `:VimwikiDiaryGenerateLinks` | Rebuild the diary index from current entries |
| `:NuwikiDiaryNextDay` / `:NuwikiDiaryPrevDay` (`:NuwikiDiaryNext` / `:NuwikiDiaryPrev` ) | `:VimwikiDiaryNextDay` / `:VimwikiDiaryPrevDay` | Chronological diary nav (same cadence as the current entry) |
**Pages & files **
| Nuwiki | Vimwiki | Action |
|---|---|---|
2026-05-30 17:36:05 -03:00
| `:NuwikiRenameFile` | `:VimwikiRenameFile` (`:VimwikiRenameLink` ) | Rename the current page, rewriting incoming links |
| `:NuwikiDeleteFile` | `:VimwikiDeleteFile` (`:VimwikiDeleteLink` ) | Delete the current page |
2026-05-30 15:54:12 -03:00
**Lists, tasks & tables **
| Nuwiki | Vimwiki | Action |
|---|---|---|
| `:NuwikiNextTask` | `:VimwikiNextTask` | Jump to the next unfinished task |
| `:NuwikiToggleListItem` | `:VimwikiToggleListItem` | Toggle the checkbox under the cursor |
| `:NuwikiToggleRejected` | `:VimwikiToggleRejectedListItem` | Toggle the rejected marker `[-]` |
2026-05-30 17:36:05 -03:00
| `:NuwikiListToggle` | `:VimwikiListToggle` | Toggle a checkbox on the current item (adds `[ ]` if none) |
| `:NuwikiIncrementListItem` / `:NuwikiDecrementListItem` | `:VimwikiIncrementListItem` / `:VimwikiDecrementListItem` | Cycle the list marker to the next / previous symbol |
| `:NuwikiChangeSymbol {sym}` | `:VimwikiChangeSymbolTo {sym}` (`:VimwikiListChangeSymbolI` ) | Set the current item's marker to `{sym}` |
| `:NuwikiChangeSymbolInList {sym}` | `:VimwikiChangeSymbolInListTo {sym}` | Set every item in the list to `{sym}` |
2026-05-30 15:54:12 -03:00
| `:NuwikiRemoveDone` | `:VimwikiRemoveDone` | Remove every completed item from the current list |
2026-05-30 17:36:05 -03:00
| `:NuwikiRemoveCheckbox` | `:VimwikiRemoveSingleCB` | Strip the checkbox from the current list item |
| `:NuwikiRemoveCheckboxInList` | `:VimwikiRemoveCBInList` | Strip the checkbox from every item in the current list |
2026-05-30 15:54:12 -03:00
| `:NuwikiListChangeLvl {increase\|decrease}` | `:VimwikiListChangeLvl {increase\|decrease}` | Indent / dedent the current list item |
2026-05-30 17:36:05 -03:00
| `:NuwikiRenumberList` | `:VimwikiRenumberList` | Renumber the current ordered list |
| `:NuwikiRenumberAllLists` | `:VimwikiRenumberAllLists` | Renumber every ordered list in the buffer |
2026-05-30 15:54:12 -03:00
| `:NuwikiTable {cols} [rows]` | `:VimwikiTable {cols} [rows]` | Insert a table at the cursor |
| `:NuwikiTableMoveColumnLeft` / `:NuwikiTableMoveColumnRight` | `:VimwikiTableMoveColumnLeft` / `:VimwikiTableMoveColumnRight` | Move the current table column left / right |
2026-05-30 17:36:05 -03:00
| `:NuwikiTableAlign` | `:VimwikiTableAlignQ` / `:VimwikiTableAlignW` | Re-align the current table's columns |
2026-05-30 15:54:12 -03:00
**Contents, links & tags **
| Nuwiki | Vimwiki | Action |
|---|---|---|
| `:NuwikiTOC` | `:VimwikiTOC` | Generate / refresh the table of contents on the current page |
| `:NuwikiGenerateLinks` | `:VimwikiGenerateLinks` | Insert a flat list of every page in the wiki |
| `:NuwikiCheckLinks` | `:VimwikiCheckLinks` | Send broken links to the quickfix list |
| `:NuwikiFindOrphans` | `:VimwikiFindOrphans` | List pages with no incoming links in the quickfix list |
| `:NuwikiRebuildTags` | `:VimwikiRebuildTags` | Force a full workspace re-index |
| `:NuwikiSearchTags {tag}` | `:VimwikiSearchTags {tag}` | Quickfix listing every occurrence of `:tag:` |
2026-05-30 17:36:05 -03:00
| `:NuwikiGenerateTagLinks [tag]` | `:VimwikiGenerateTagLinks [tag]` (`:VimwikiGenerateTags` ) | Insert a section linking every page that has `<tag>` |
2026-05-30 15:54:12 -03:00
| `:NuwikiColorize {color}` | `:VimwikiColorize {color}` | Wrap the word / visual selection in a coloured `<span>` |
| `:NuwikiPasteLink` / `:NuwikiPasteUrl` | `:VimwikiPasteLink` / `:VimwikiPasteUrl` | Paste the clipboard contents as a wikilink / raw URL |
2026-05-30 17:36:05 -03:00
| `:NuwikiCatUrl` | `:VimwikiCatUrl` | Echo the `file://` URL of the current page's HTML export |
2026-05-30 15:54:12 -03:00
**HTML export **
| Nuwiki | Vimwiki | Action |
|---|---|---|
| `:Nuwiki2HTML` (`:NuwikiExport` ) | `:Vimwiki2HTML` | Render the current page to HTML |
| `:Nuwiki2HTMLBrowse` (`:NuwikiExportBrowse` ) | `:Vimwiki2HTMLBrowse` | Render the current page and open it in the default browser |
| `:NuwikiAll2HTML[!]` (`:NuwikiExportAll[!]` ) | `:VimwikiAll2HTML[!]` | Export the whole wiki (`!` forces; otherwise incremental) |
| `:NuwikiRss` | `:VimwikiRss` | Write `rss.xml` for diary entries |
2026-05-12 14:20:18 +00:00
### Default keymaps
All buffer-local. Disable any group via `mappings.<group> = false` in
Neovim, or `let g:nuwiki_no_default_mappings = 1` in Vim.
2026-05-12 22:46:16 +00:00
**Links ** (normal mode)
2026-05-12 14:20:18 +00:00
| Key | Action |
|---|---|
2026-05-12 22:46:16 +00:00
| `<CR>` | Smart follow — inside `[[…]]` jumps; on a bare word wraps as `[[word]]` (second `<CR>` follows) |
2026-05-12 14:20:18 +00:00
| `<S-CR>` | Follow in horizontal split |
| `<C-CR>` | Follow in vertical split |
2026-05-12 22:46:16 +00:00
| `<C-S-CR>` | Follow in a new tab |
2026-05-12 14:20:18 +00:00
| `<BS>` | Jump back (`<C-o>` ) |
| `<Tab>` / `<S-Tab>` | Next / previous wikilink on or after the cursor |
2026-05-12 22:46:16 +00:00
| `+` | Wrap word / visual selection as a wikilink (no follow) |
2026-05-12 14:20:18 +00:00
2026-05-12 22:46:16 +00:00
**Lists ** (normal mode)
2026-05-12 14:20:18 +00:00
| Key | Action |
|---|---|
2026-05-12 22:46:16 +00:00
| `<C-Space>` / `<C-@>` / `<Nul>` | Toggle the checkbox under the cursor (the three aliases cover terminal byte differences) |
| `gln` / `glp` | Cycle the checkbox state forward / backward |
2026-05-12 14:20:18 +00:00
| `glx` | Toggle the rejected marker `[-]` |
| `gnt` | Jump to the next unfinished task |
2026-05-12 22:46:16 +00:00
| `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 |
2026-05-12 14:20:18 +00:00
**Headers **
| Key | Action |
|---|---|
2026-05-12 22:46:16 +00:00
| `=` / `-` | Increase / decrease the heading level |
| `]]` / `[[` | Next / previous heading (any level) |
2026-05-12 14:20:18 +00:00
| `]=` / `[=` | Next / previous sibling heading |
2026-05-12 22:46:16 +00:00
| `]u` / `[u` | Jump to the parent heading |
2026-05-12 14:20:18 +00:00
2026-05-12 22:46:16 +00:00
**Tables **
2026-05-12 14:20:18 +00:00
| Key | Action |
|---|---|
2026-05-12 22:46:16 +00:00
| `gqq` / `gq1` / `gww` / `gw1` | Align the table under the cursor |
| `<A-Left>` / `<A-Right>` | Move the column under the cursor left / right |
| `<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 |
|---|---|
2026-05-30 15:54:12 -03:00
| `<Leader>ww` | Open the wiki index |
| `<Leader>wt` | Open the wiki index in a new tab |
2026-05-12 22:46:16 +00:00
| `<Leader>ws` | Pick a wiki |
| `<Leader>wi` | Open the diary index |
2026-05-30 15:54:12 -03:00
| `<Leader>w<Leader>w` / `<Leader>w<Leader>y` / `<Leader>w<Leader>t` | Diary today / yesterday / tomorrow |
| `<Leader>w<Leader>m` | Diary tomorrow (vimwiki-compat alias of `<Leader>w<Leader>t` ) |
2026-05-12 22:46:16 +00:00
| `<Leader>w<Leader>i` | Rebuild the diary index page |
2026-05-12 14:20:18 +00:00
| `<Leader>wn` / `<Leader>wd` / `<Leader>wr` | Goto / delete / rename page |
2026-05-12 22:46:16 +00:00
| `<Leader>wh` / `<Leader>whh` | Export the current page to HTML / open in browser |
2026-05-12 14:20:18 +00:00
| `<Leader>wha` | Export every page |
2026-05-12 22:46:16 +00:00
| `<Leader>wc` | Wrap word (or visual selection) in a colour span |
2026-05-12 14:20:18 +00:00
| `<C-Down>` / `<C-Up>` | Next / previous diary entry |
2026-05-30 15:54:12 -03:00
**Mouse ** (normal mode, opt-in via `mappings.mouse = true` / `let g:nuwiki_mouse_mappings = 1` )
| Key | Action |
|---|---|
| `<2-LeftMouse>` | Follow the link under the pointer |
| `<S-2-LeftMouse>` / `<C-2-LeftMouse>` | Follow in a horizontal / vertical split |
| `<MiddleMouse>` | Add the link target to the buffer list |
| `<RightMouse>` | Jump back (`<C-o>` ) |
2026-05-12 22:46:16 +00:00
**Text objects ** (operator-pending + visual)
2026-05-12 14:20:18 +00:00
2026-05-12 22:46:16 +00:00
| Object | Selection |
2026-05-12 14:20:18 +00:00
|---|---|
2026-05-12 22:46:16 +00:00
| `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) |
2026-05-12 14:20:18 +00:00
2026-05-12 22:46:16 +00:00
### Health check (Neovim)
2026-05-12 14:20:18 +00:00
``` vim
: checkhealth nuwiki
```
Reports the binary path, the LSP client status, registered
`executeCommand` entries, whether `foldingRange` was negotiated, and
whether the configured HTML output directory is writable.
### Migrating from vimwiki
The file extension, syntax, command names, and default keymaps all
2026-05-12 22:46:16 +00:00
match vimwiki. To migrate:
2026-05-12 14:20:18 +00:00
2026-05-12 22:46:16 +00:00
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.
2026-05-12 14:20:18 +00:00
2026-05-12 22:46:16 +00:00
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.
2026-05-11 14:32:22 +00:00
2026-05-12 14:20:18 +00:00
---
2026-05-10 16:01:58 +00:00
## License
Dual-licensed under either of:
- Apache License, Version 2.0 ([`LICENSE-APACHE` ](./LICENSE-APACHE ))
- MIT license ([`LICENSE-MIT` ](./LICENSE-MIT ))
at your option. Unless you explicitly state otherwise, any contribution
2026-05-12 14:20:18 +00:00
intentionally submitted for inclusion in this work shall be dual licensed
as above, without any additional terms or conditions.