*nuwiki.txt*    A vimwiki-compatible plugin backed by a Rust language server.

Author:  Gabriel Fróes Franco
License: Dual MIT / Apache-2.0

==============================================================================
CONTENTS                                                    *nuwiki-contents*

  1. Introduction ............ |nuwiki-introduction|
  2. Requirements ............ |nuwiki-requirements|
  3. Installation ............ |nuwiki-installation|
  4. Configuration ........... |nuwiki-config|
  5. Commands ................ |nuwiki-commands|
  6. Keymaps ................. |nuwiki-keymaps|
  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*

nuwiki keeps vimwiki's file format, keymaps, and `:Vimwiki*` command surface
intact, but moves the heavy lifting into a Rust language server that the
editor talks to over LSP stdio. The result feels like vimwiki — same files,
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*

  * Neovim 0.11+                       (preferred path)
  * Vim 9.1+ with one of:
      - vim-lsp     (prabirshrestha/vim-lsp)
      - coc.nvim    (neoclide/coc.nvim)
  * `curl` and `tar` (only for the binary download path; not needed if
    you build from source)
  * `cargo` and a Rust toolchain (only if you opt into source builds)

==============================================================================
3. INSTALLATION                                         *nuwiki-installation*

Install via your plugin manager; the build hook downloads a pre-built
`nuwiki-ls` binary into the plugin's `bin/` directory.

lazy.nvim: >

  {
    "gffranco/nuwiki",
    build = "lua require('nuwiki').install()",
    ft    = { "vimwiki" },
    opts  = { wiki_root = "~/vimwiki" },
  }

<vim-plug: >

  Plug 'gffranco/nuwiki', { 'do': 'vim -e -s -c "source scripts/download_bin.vim" -c "q"' }

<dein.vim: >

  call dein#add('gffranco/nuwiki', {
    \ 'build': 'vim -e -s -c "source scripts/download_bin.vim" -c "q"',
    \ })

<To force a build from source (skip the download path), set: >

  let g:nuwiki_build_from_source = 1

<in Vim before re-running the build hook, or in Neovim: >

  vim.g.nuwiki_build_from_source = 1
  require('nuwiki').install()

<==============================================================================
4. CONFIGURATION                                              *nuwiki-config*

Neovim users call `setup()` (omit the block entirely to take every
default): >

  require('nuwiki').setup({
    wiki_root      = '~/vimwiki',
    file_extension = '.wiki',
    syntax         = 'vimwiki',
    log_level      = 'warn',
  })

<For multiple wikis or per-wiki tuning, use the `wikis` list: >

  require('nuwiki').setup({
    wikis = {
      {
        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' },
      },
    },
  })

<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*
`wiki_root`        ~/vimwiki
    Root directory of the single-wiki shorthand. Ignored when `wikis` is
    set (the multi-wiki list takes precedence).

                                                     *g:nuwiki_file_extension*
`file_extension`   .wiki
    File extension associated with the wiki filetype.

                                                              *g:nuwiki_syntax*
`syntax`           vimwiki
    Future-proofing; currently only `vimwiki` is supported.

                                                          *g:nuwiki_log_level*
`log_level`        warn
    `error` | `warn` | `info` | `debug`. Forwarded to the language server.

                                                       *nuwiki-config-folding*
`folding`          'lsp'
    `lsp` uses the server's `foldingRange` provider (Neovim 0.11+ wires
    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.

                                                               *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`
    Override the auto-discovered server binary path. If set and the
    file is readable, it overrides the `{plugin}/bin/nuwiki-ls` default.

==============================================================================
5. COMMANDS                                                 *nuwiki-commands*

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.

Wiki / navigation ~

                                                              *:VimwikiIndex*
:VimwikiIndex [{count}]
    Open wiki N's index page (default: 1).

                                                           *:VimwikiTabIndex*
:VimwikiTabIndex [{count}]
    Same, in a new tab.

                                                           *:VimwikiUISelect*
:VimwikiUISelect
    Pick a wiki from a list (multi-wiki only). Uses |vim.ui.select| on
    Neovim, |inputlist()| on Vim.

                                                               *:VimwikiGoto*
:VimwikiGoto {page}
    Open `{page}.wiki` by name.

                                                         *:VimwikiFollowLink*
: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
    Install (or re-install) the `nuwiki-ls` binary into the plugin's
    `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:
