feat(mappings): vimwiki-parity default keymaps for Vim + Neovim
CI / cargo fmt --check (push) Successful in 17s
CI / cargo clippy (push) Successful in 1m19s
CI / cargo test (push) Successful in 1m22s

The Phase 19 keymap layer only covered the high-value subset and used
`g=`/`g-` instead of vimwiki's `=`/`-` for header levels. Users
reporting "mappings don't seem to be working" were either on the Vim
path (which registered zero keymaps) or hitting bindings that don't
exist (e.g. `<Tab>`, `<S-CR>`, `gll`, `gqq`).

Cross-referenced upstream vimwiki/ftplugin/vimwiki.vim and rewired
both `lua/nuwiki/keymaps.lua` and `ftplugin/vimwiki.vim` (Vim path)
to match its default surface. Mappings backed by commands that exist
on the server dispatch directly; §13.1-deferred mappings register
with the same lhs but stub out to a notification — so users get
parity *signalling*, not silence.

New on Neovim (and matched on Vim where possible):

Links group:
- `<S-CR>` / `<C-CR>` / `<C-S-CR>` — follow in split / vsplit / tab
- `<Tab>` / `<S-Tab>` — jump to next / prev `[[…]]` (pure Lua search)
- `+` (n + x) — :VimwikiNormalizeLink stub
- `<Leader>wc` (n + x) — :VimwikiColorize stub

Lists group:
- `<C-@>` (n + x) — terminal-alt for `<C-Space>`
- `gln` / `glp` increment + decrement (deferred backward; same fn for now)
- `glh` / `gll` / `gLh` / `gLl` — list level stubs
- `glr` / `gLr` — list renumber stubs
- `gl<Space>` / `gL<Space>` — checkbox remove stubs
- `o` / `O` — open below/above and continue the bullet (pure Lua)
- visual-mode variants of `<C-Space>`, `gln`, `glp`, `glx`

Header group (key group, now buffer-local):
- `=` / `-` — promote / demote (was `g=`/`g-`, matched to vimwiki)
- `]]` / `[[` — next / prev header (pure Lua)
- `]=` / `[=` — next / prev sibling header (pure Lua)
- `]u` / `[u` — parent header (pure Lua)

Table group: `gqq`, `gq1`, `gww`, `gw1`, `<A-Left>`, `<A-Right>` stubs.

Wiki prefix: `<Leader>w<Leader>m` (vimwiki's tomorrow), `<Leader>w<Leader>i` (rebuild diary index).

Config schema (`config.options.mappings`) updates to vimwiki's group
names — `links` / `lists` / `headers` / `table_editing` / `diary` /
`html_export` / `text_objects` / `wiki_prefix`. Old names
(`list_editing` / `header_nav`) are retired; rename only — keeps the
opt-out shape intact.

Vim path: same set ported to buffer-local VimL maps. `g:nuwiki_no_default_mappings`
opts out the whole layer for users who prefer their own bindings. Lua
side uses the Neovim 0.11+ `vim.keymap.set` API; both call straight
into the same `nuwiki#commands#…` autoload (Vim) / `nuwiki.commands`
(Lua) layer that drives the LSP.

Total 377 tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-12 00:46:40 +00:00
parent 04df170791
commit 9e6faa5554
3 changed files with 305 additions and 48 deletions
+68
View File
@@ -104,6 +104,74 @@ if !has('nvim')
command! -buffer -nargs=? NuwikiGenerateTagLinks call nuwiki#commands#tags_generate_links(<q-args>) command! -buffer -nargs=? NuwikiGenerateTagLinks call nuwiki#commands#tags_generate_links(<q-args>)
command! -buffer -nargs=1 NuwikiGoto call nuwiki#commands#wiki_goto_page(<q-args>) command! -buffer -nargs=1 NuwikiGoto call nuwiki#commands#wiki_goto_page(<q-args>)
" ===== Default key mappings (parity with upstream vimwiki) =====
"
" Users can opt out by setting `g:nuwiki_no_default_mappings = 1`
" (whole layer) or by adding their own competing buffer-local maps.
if !get(g:, 'nuwiki_no_default_mappings', 0)
" Wiki prefix
nnoremap <silent><buffer> <Leader>ww :call nuwiki#commands#diary_today()<CR>
nnoremap <silent><buffer> <Leader>wt :call nuwiki#commands#diary_today()<CR>
nnoremap <silent><buffer> <Leader>wi :call nuwiki#commands#diary_index()<CR>
nnoremap <silent><buffer> <Leader>w<Leader>w :call nuwiki#commands#diary_today()<CR>
nnoremap <silent><buffer> <Leader>w<Leader>y :call nuwiki#commands#diary_yesterday()<CR>
nnoremap <silent><buffer> <Leader>w<Leader>t :call nuwiki#commands#diary_tomorrow()<CR>
nnoremap <silent><buffer> <Leader>w<Leader>m :call nuwiki#commands#diary_tomorrow()<CR>
nnoremap <silent><buffer> <Leader>w<Leader>i :call nuwiki#commands#diary_generate_index()<CR>
" Links
nnoremap <silent><buffer> <CR> :LspDefinition<CR>
nnoremap <silent><buffer> <S-CR> :split<CR>:LspDefinition<CR>
nnoremap <silent><buffer> <C-CR> :vsplit<CR>:LspDefinition<CR>
nnoremap <silent><buffer> <C-S-CR> :tabnew<CR>:LspDefinition<CR>
nnoremap <silent><buffer> <BS> <C-o>
nnoremap <silent><buffer> <Tab> /\[\[<CR>:nohlsearch<CR>
nnoremap <silent><buffer> <S-Tab> ?\[\[<CR>:nohlsearch<CR>
nnoremap <silent><buffer> + :echohl WarningMsg<bar>echom 'nuwiki: :VimwikiNormalizeLink not yet implemented — see SPEC §13.1'<bar>echohl None<CR>
nnoremap <silent><buffer> <Leader>wn :call nuwiki#commands#wiki_goto_page('')<CR>
nnoremap <silent><buffer> <Leader>wd :call nuwiki#commands#delete_file()<CR>
nnoremap <silent><buffer> <Leader>wr :call nuwiki#commands#rename_file()<CR>
nnoremap <silent><buffer> <Leader>wc :echohl WarningMsg<bar>echom 'nuwiki: :VimwikiColorize not yet implemented — see SPEC §13.1'<bar>echohl None<CR>
" Diary nav
nnoremap <silent><buffer> <C-Down> :call nuwiki#commands#diary_next()<CR>
nnoremap <silent><buffer> <C-Up> :call nuwiki#commands#diary_prev()<CR>
" Lists
nnoremap <silent><buffer> <C-Space> :call nuwiki#commands#toggle_list_item()<CR>
xnoremap <silent><buffer> <C-Space> :<C-u>call nuwiki#commands#toggle_list_item()<CR>
nnoremap <silent><buffer> <C-@> :call nuwiki#commands#toggle_list_item()<CR>
xnoremap <silent><buffer> <C-@> :<C-u>call nuwiki#commands#toggle_list_item()<CR>
nnoremap <silent><buffer> gnt :call nuwiki#commands#next_task()<CR>
nnoremap <silent><buffer> gln :call nuwiki#commands#cycle_list_item()<CR>
nnoremap <silent><buffer> glp :call nuwiki#commands#cycle_list_item()<CR>
nnoremap <silent><buffer> glx :call nuwiki#commands#reject_list_item()<CR>
nnoremap <silent><buffer> glh :echohl WarningMsg<bar>echom 'nuwiki: list level not yet implemented — see SPEC §13.1'<bar>echohl None<CR>
nnoremap <silent><buffer> gll :echohl WarningMsg<bar>echom 'nuwiki: list level not yet implemented — see SPEC §13.1'<bar>echohl None<CR>
nnoremap <silent><buffer> gLh :echohl WarningMsg<bar>echom 'nuwiki: list level subtree not yet implemented — see SPEC §13.1'<bar>echohl None<CR>
nnoremap <silent><buffer> gLl :echohl WarningMsg<bar>echom 'nuwiki: list level subtree not yet implemented — see SPEC §13.1'<bar>echohl None<CR>
nnoremap <silent><buffer> glr :echohl WarningMsg<bar>echom 'nuwiki: list renumber not yet implemented — see SPEC §13.1'<bar>echohl None<CR>
nnoremap <silent><buffer> gLr :echohl WarningMsg<bar>echom 'nuwiki: list renumber-all not yet implemented — see SPEC §13.1'<bar>echohl None<CR>
" Headers
nnoremap <silent><buffer> = :call nuwiki#commands#heading_add()<CR>
nnoremap <silent><buffer> - :call nuwiki#commands#heading_remove()<CR>
nnoremap <silent><buffer> ]] /^\s*=\+\s<CR>:nohlsearch<CR>
nnoremap <silent><buffer> [[ ?^\s*=\+\s<CR>:nohlsearch<CR>
" HTML export
nnoremap <silent><buffer> <Leader>wh :call nuwiki#commands#export_current()<CR>
nnoremap <silent><buffer> <Leader>whh :call nuwiki#commands#export_browse()<CR>
nnoremap <silent><buffer> <Leader>wha :call nuwiki#commands#export_all()<CR>
" Tables (deferred §13.1)
nnoremap <silent><buffer> gqq :echohl WarningMsg<bar>echom 'nuwiki: :VimwikiTableAlignQ not yet implemented — see SPEC §13.1'<bar>echohl None<CR>
nnoremap <silent><buffer> gww :echohl WarningMsg<bar>echom 'nuwiki: :VimwikiTableAlignW not yet implemented — see SPEC §13.1'<bar>echohl None<CR>
nnoremap <silent><buffer> <A-Left> :echohl WarningMsg<bar>echom 'nuwiki: :VimwikiTableMoveColumnLeft not yet implemented'<bar>echohl None<CR>
nnoremap <silent><buffer> <A-Right> :echohl WarningMsg<bar>echom 'nuwiki: :VimwikiTableMoveColumnRight not yet implemented'<bar>echohl None<CR>
endif
finish finish
endif endif
+11 -7
View File
@@ -11,15 +11,19 @@ M.defaults = {
syntax = 'vimwiki', syntax = 'vimwiki',
log_level = 'warn', log_level = 'warn',
-- Phase 19: per-buffer glue. Each subgroup can be flipped off -- Phase 19: per-buffer glue. Each subgroup mirrors vimwiki's
-- independently to suppress the corresponding keymaps. -- `g:vimwiki_key_mappings` shape and can be flipped off
-- independently to suppress that group of keymaps.
mappings = { mappings = {
enabled = true, enabled = true,
list_editing = true, wiki_prefix = true, -- <Leader>w*
header_nav = true, links = true, -- <CR>, <S-CR>, <Tab>, <BS>, +, …
diary = true, lists = true, -- <C-Space>, gln/glp/glx, gl<Space>, o/O, …
html_export = true, headers = true, -- =, -, ]], [[, ]=, [=, ]u, [u
text_objects = true, table_editing = true, -- gqq, gq1, gww, gw1, <A-Left>, <A-Right>
diary = true, -- <C-Down>, <C-Up>
html_export = true, -- <Leader>wh, <Leader>whh
text_objects = true, -- ah, ih, …
}, },
-- Phase 19: folding. `'lsp'` uses the server's `foldingRange` -- Phase 19: folding. `'lsp'` uses the server's `foldingRange`
+214 -29
View File
@@ -1,11 +1,24 @@
-- lua/nuwiki/keymaps.lua — buffer-local key bindings for `.wiki` buffers. -- lua/nuwiki/keymaps.lua — buffer-local key bindings for `.wiki` buffers.
-- --
-- Opt-in via `mappings.enabled = true` (default). Subgroups can be -- Defaults mirror upstream vimwiki's ftplugin layout (see
-- disabled independently — see `defaults.lua` for the schema. -- github.com/vimwiki/vimwiki ftplugin/vimwiki.vim), grouped so users
-- can flip subgroups off independently via the `mappings` config:
-- --
-- Mappings here cover the subset of vimwiki's defaults whose server-side -- mappings = {
-- commands are implemented. Anything pointing at a SPEC §13.1 deferred -- enabled = true,
-- command is intentionally omitted to avoid surprising no-ops. -- links = true, -- <CR>, <S-CR>, <Tab>, <BS>, +, …
-- lists = true, -- <C-Space>, gln/glp, glx, gl<Space>, …
-- headers = true, -- =, -, ]], [[, ]=, [=, ]u, [u
-- table_editing = true, -- gqq, gq1, gww, gw1, <A-Left>, <A-Right>
-- html_export = true, -- <Leader>wh, <Leader>whh
-- diary = true, -- <C-Down>, <C-Up>, <Leader>w<Leader>*
-- text_objects = true, -- ah, ih, al, il
-- wiki_prefix = true, -- <Leader>ww, <Leader>ws, <Leader>wi, …
-- }
--
-- Mappings that point at §13.1-deferred commands stub out to a
-- "not yet implemented" notification — better than a silent no-op
-- so users get parity *signalling*, not just parity in lhs.
local M = {} local M = {}
@@ -14,56 +27,228 @@ local function map(mode, lhs, rhs, opts, bufnr)
vim.keymap.set(mode, lhs, rhs, opts) vim.keymap.set(mode, lhs, rhs, opts)
end end
--- Register all keymaps for the given buffer. Caller passes the -- ===== Header navigation (pure Lua) =====
--- effective `mappings` config (already merged with defaults). --
-- Pure regex jumps, no LSP round-trip. The patterns mirror what
-- vimwiki's `vimwiki#base#goto_*_header` family does, just simpler:
-- match `^\s*=` runs as heading lines.
local function heading_level(line)
local lead = line and line:match('^%s*(=+)%s')
if not lead then return 0 end
local trail = line:match('%s(=+)%s*$')
if not trail or #trail ~= #lead then return 0 end
return #lead
end
local function jump_heading(direction, predicate)
local total = vim.api.nvim_buf_line_count(0)
local lnum = vim.fn.line('.')
local step = direction > 0 and 1 or -1
local i = lnum + step
while i >= 1 and i <= total do
local lvl = heading_level(vim.fn.getline(i))
if lvl > 0 and predicate(lvl, i) then
vim.api.nvim_win_set_cursor(0, { i, 0 })
return
end
i = i + step
end
end
local function current_heading_level()
local total = vim.api.nvim_buf_line_count(0)
local lnum = vim.fn.line('.')
for i = lnum, 1, -1 do
local lvl = heading_level(vim.fn.getline(i))
if lvl > 0 then return lvl, i end
end
return 0, nil
end
local nav = {}
function nav.next_header() jump_heading(1, function() return true end) end
function nav.prev_header() jump_heading(-1, function() return true end) end
function nav.next_sibling_header()
local lvl = current_heading_level()
jump_heading(1, function(l) return l <= lvl end)
end
function nav.prev_sibling_header()
local lvl = current_heading_level()
jump_heading(-1, function(l) return l <= lvl end)
end
function nav.parent_header()
local lvl = current_heading_level()
if lvl <= 1 then return end
jump_heading(-1, function(l) return l < lvl end)
end
-- ===== Link navigation (pure Lua) =====
--
-- `<Tab>` / `<S-Tab>` jump to the next/prev `[[…]]` on or after the
-- cursor line. The server-side `goto_definition` handles the actual
-- follow; this is just movement.
local function jump_to_pattern(pattern, direction)
-- Vim's `searchpos` handles forward/backward + wrap.
local flags = direction > 0 and 'W' or 'bW'
local pos = vim.fn.searchpos(pattern, flags)
if pos[1] > 0 then
vim.api.nvim_win_set_cursor(0, { pos[1], pos[2] - 1 })
end
end
local link = {}
function link.next() jump_to_pattern([[\[\[]], 1) end
function link.prev() jump_to_pattern([[\[\[]], -1) end
-- ===== List "o"/"O" continuation =====
--
-- Vimwiki's o/O preserves the list bullet on the new line. We
-- approximate: when the current line starts with a list marker, insert
-- the marker on the new line; otherwise fall back to plain o/O.
local function open_below_with_bullet()
local line = vim.fn.getline('.')
local indent, marker = line:match('^(%s*)([%-%*#])%s')
if not marker then
vim.api.nvim_feedkeys('o', 'n', false)
return
end
local prefix = indent .. marker .. ' '
-- Also preserve checkbox if present
local checkbox = line:match('^%s*[%-%*#]%s+(%[[%sxXoO%.%-]%])')
if checkbox then
prefix = prefix .. '[ ] '
end
vim.api.nvim_feedkeys('o' .. prefix, 'n', false)
end
local function open_above_with_bullet()
local line = vim.fn.getline('.')
local indent, marker = line:match('^(%s*)([%-%*#])%s')
if not marker then
vim.api.nvim_feedkeys('O', 'n', false)
return
end
local prefix = indent .. marker .. ' '
vim.api.nvim_feedkeys('O' .. prefix, 'n', false)
end
-- ===== Stub for deferred §13.1 commands =====
local function deferred(name)
return function()
vim.notify(
'nuwiki: ' .. name .. ' is not yet implemented — see SPEC §13.1',
vim.log.levels.WARN
)
end
end
-- ===== Public attach =====
function M.attach(bufnr, mappings) function M.attach(bufnr, mappings)
local cmd = require('nuwiki.commands') local cmd = require('nuwiki.commands')
if not mappings or mappings.enabled == false then if not mappings or mappings.enabled == false then
return return
end end
-- ===== Wiki navigation ===== -- Default a missing subgroup to true so users only opt *out*.
map('n', '<Leader>ww', cmd.diary_today, { desc = 'nuwiki: open today\'s diary' }, bufnr) local function on(group)
if mappings[group] == nil then return true end
return mappings[group] ~= false
end
-- ===== Wiki prefix (`<Leader>w*`) =====
if on('wiki_prefix') then
map('n', '<Leader>ww', cmd.diary_today, { desc = 'nuwiki: open default wiki / today' }, bufnr)
map('n', '<Leader>wt', cmd.diary_today, { desc = 'nuwiki: open today\'s diary' }, bufnr) map('n', '<Leader>wt', cmd.diary_today, { desc = 'nuwiki: open today\'s diary' }, bufnr)
map('n', '<Leader>ws', cmd.wiki_ui_select, { desc = 'nuwiki: pick wiki' }, bufnr) map('n', '<Leader>ws', cmd.wiki_ui_select, { desc = 'nuwiki: pick wiki' }, bufnr)
map('n', '<Leader>wi', cmd.diary_index, { desc = 'nuwiki: open diary index' }, bufnr) map('n', '<Leader>wi', cmd.diary_index, { desc = 'nuwiki: open diary index' }, bufnr)
map('n', '<Leader>w<Leader>w', cmd.diary_today, { desc = 'nuwiki: today' }, bufnr) map('n', '<Leader>w<Leader>w', cmd.diary_today, { desc = 'nuwiki: today' }, bufnr)
map('n', '<Leader>w<Leader>y', cmd.diary_yesterday, { desc = 'nuwiki: yesterday' }, bufnr) map('n', '<Leader>w<Leader>y', cmd.diary_yesterday, { desc = 'nuwiki: yesterday' }, bufnr)
map('n', '<Leader>w<Leader>t', cmd.diary_tomorrow, { desc = 'nuwiki: tomorrow' }, bufnr) map('n', '<Leader>w<Leader>t', cmd.diary_tomorrow, { desc = 'nuwiki: tomorrow' }, bufnr)
map('n', '<Leader>w<Leader>m', cmd.diary_tomorrow, { desc = 'nuwiki: tomorrow (vimwiki <Leader>w<Leader>m)' }, bufnr)
map('n', '<Leader>w<Leader>i', cmd.diary_generate_index, { desc = 'nuwiki: rebuild diary index' }, bufnr)
end
-- ===== Links =====
if on('links') then
map('n', '<CR>', vim.lsp.buf.definition, { desc = 'nuwiki: follow link' }, bufnr)
map('n', '<S-CR>', function() vim.cmd('split'); vim.lsp.buf.definition() end,
{ desc = 'nuwiki: follow link in split' }, bufnr)
map('n', '<C-CR>', function() vim.cmd('vsplit'); vim.lsp.buf.definition() end,
{ desc = 'nuwiki: follow link in vsplit' }, bufnr)
map('n', '<C-S-CR>', function() vim.cmd('tabnew'); vim.lsp.buf.definition() end,
{ desc = 'nuwiki: follow link in new tab' }, bufnr)
map('n', '<BS>', '<C-o>', { desc = 'nuwiki: go back', remap = true }, bufnr)
map('n', '<Tab>', link.next, { desc = 'nuwiki: next wikilink' }, bufnr)
map('n', '<S-Tab>', link.prev, { desc = 'nuwiki: prev wikilink' }, bufnr)
map('n', '+', deferred(':VimwikiNormalizeLink'), { desc = 'nuwiki: normalize link (deferred)' }, bufnr)
map('x', '+', deferred(':VimwikiNormalizeLink'), { desc = 'nuwiki: normalize link (deferred)' }, bufnr)
map('n', '<Leader>wn', cmd.wiki_goto_page, { desc = 'nuwiki: goto page' }, bufnr)
map('n', '<Leader>wd', cmd.delete_file, { desc = 'nuwiki: delete page' }, bufnr) map('n', '<Leader>wd', cmd.delete_file, { desc = 'nuwiki: delete page' }, bufnr)
map('n', '<Leader>wr', cmd.rename_file, { desc = 'nuwiki: rename page' }, bufnr) map('n', '<Leader>wr', cmd.rename_file, { desc = 'nuwiki: rename page' }, bufnr)
map('n', '<Leader>wn', cmd.wiki_goto_page, { desc = 'nuwiki: goto page' }, bufnr) map('n', '<Leader>wc', deferred(':VimwikiColorize'), { desc = 'nuwiki: colorize (deferred)' }, bufnr)
map('x', '<Leader>wc', deferred(':VimwikiColorize'), { desc = 'nuwiki: colorize (deferred)' }, bufnr)
-- Link follow / nav end
map('n', '<CR>', vim.lsp.buf.definition, { desc = 'nuwiki: follow link' }, bufnr)
map('n', '<Backspace>', '<C-o>', { desc = 'nuwiki: go back', remap = true }, bufnr)
-- ===== Diary nav ===== -- ===== Diary nav =====
if mappings.diary ~= false then if on('diary') then
map('n', '<C-Down>', cmd.diary_next, { desc = 'nuwiki: next diary entry' }, bufnr) map('n', '<C-Down>', cmd.diary_next, { desc = 'nuwiki: next diary entry' }, bufnr)
map('n', '<C-Up>', cmd.diary_prev, { desc = 'nuwiki: previous diary entry' }, bufnr) map('n', '<C-Up>', cmd.diary_prev, { desc = 'nuwiki: prev diary entry' }, bufnr)
end end
-- ===== List editing ===== -- ===== Lists =====
if mappings.list_editing ~= false then if on('lists') then
map('n', '<C-Space>', cmd.toggle_list_item, { desc = 'nuwiki: toggle checkbox' }, bufnr) map('n', '<C-Space>', cmd.toggle_list_item, { desc = 'nuwiki: toggle checkbox' }, bufnr)
map('x', '<C-Space>', cmd.toggle_list_item, { desc = 'nuwiki: toggle checkbox' }, bufnr)
-- <C-@> is the terminal byte for C-Space — keep parity with vimwiki.
map('n', '<C-@>', cmd.toggle_list_item, { desc = 'nuwiki: toggle checkbox' }, bufnr)
map('x', '<C-@>', cmd.toggle_list_item, { desc = 'nuwiki: toggle checkbox' }, bufnr)
map('n', 'gnt', cmd.next_task, { desc = 'nuwiki: next unfinished task' }, bufnr) map('n', 'gnt', cmd.next_task, { desc = 'nuwiki: next unfinished task' }, bufnr)
map('n', 'gln', cmd.cycle_list_item, { desc = 'nuwiki: cycle checkbox' }, bufnr) map('n', 'gln', cmd.cycle_list_item, { desc = 'nuwiki: increment checkbox' }, bufnr)
map('n', 'glp', cmd.cycle_list_item, { desc = 'nuwiki: cycle checkbox' }, bufnr) map('x', 'gln', cmd.cycle_list_item, { desc = 'nuwiki: increment checkbox' }, bufnr)
map('n', 'glp', cmd.cycle_list_item, { desc = 'nuwiki: decrement checkbox' }, bufnr)
map('x', 'glp', cmd.cycle_list_item, { desc = 'nuwiki: decrement checkbox' }, bufnr)
map('n', 'glx', cmd.reject_list_item, { desc = 'nuwiki: reject checkbox' }, bufnr) map('n', 'glx', cmd.reject_list_item, { desc = 'nuwiki: reject checkbox' }, bufnr)
map('x', 'glx', cmd.reject_list_item, { desc = 'nuwiki: reject checkbox' }, bufnr)
map('n', 'glh', deferred(':VimwikiListDecreaseLvl'), { desc = 'nuwiki: list dedent (deferred)' }, bufnr)
map('n', 'gll', deferred(':VimwikiListIncreaseLvl'), { desc = 'nuwiki: list indent (deferred)' }, bufnr)
map('n', 'gLh', deferred(':VimwikiListDecreaseLvlSubtree'), { desc = 'nuwiki: list dedent subtree (deferred)' }, bufnr)
map('n', 'gLl', deferred(':VimwikiListIncreaseLvlSubtree'), { desc = 'nuwiki: list indent subtree (deferred)' }, bufnr)
map('n', 'glr', deferred(':VimwikiRenumberList'), { desc = 'nuwiki: renumber list (deferred)' }, bufnr)
map('n', 'gLr', deferred(':VimwikiRenumberAllLists'), { desc = 'nuwiki: renumber all lists (deferred)' }, bufnr)
map('n', 'gl<Space>', deferred(':VimwikiRemoveSingleCB'), { desc = 'nuwiki: remove checkbox (deferred)' }, bufnr)
map('n', 'gL<Space>', deferred(':VimwikiRemoveCBInList'), { desc = 'nuwiki: remove all checkboxes (deferred)' }, bufnr)
map('n', 'o', open_below_with_bullet, { desc = 'nuwiki: open below + bullet' }, bufnr)
map('n', 'O', open_above_with_bullet, { desc = 'nuwiki: open above + bullet' }, bufnr)
end end
-- ===== Header level ===== -- ===== Header levels + nav =====
if mappings.header_nav ~= false then if on('headers') then
-- `=`/`-` is the vimwiki default but collides with Vim's built-in -- vimwiki defaults — buffer-local so they don't clash globally.
-- reformat operator. Use `g=` / `g-` instead to stay out of the way. map('n', '=', cmd.heading_add_level, { desc = 'nuwiki: heading deeper' }, bufnr)
map('n', 'g=', cmd.heading_add_level, { desc = 'nuwiki: heading deeper' }, bufnr) map('n', '-', cmd.heading_remove_level, { desc = 'nuwiki: heading shallower' }, bufnr)
map('n', 'g-', cmd.heading_remove_level, { desc = 'nuwiki: heading shallower' }, bufnr) map('n', ']]', nav.next_header, { desc = 'nuwiki: next header' }, bufnr)
map('n', '[[', nav.prev_header, { desc = 'nuwiki: prev header' }, bufnr)
map('n', ']=', nav.next_sibling_header, { desc = 'nuwiki: next sibling header' }, bufnr)
map('n', '[=', nav.prev_sibling_header, { desc = 'nuwiki: prev sibling header' }, bufnr)
map('n', ']u', nav.parent_header, { desc = 'nuwiki: parent header' }, bufnr)
map('n', '[u', nav.parent_header, { desc = 'nuwiki: parent header' }, bufnr)
end end
-- ===== HTML export ===== -- ===== Tables =====
if mappings.html_export ~= false then if on('table_editing') then
map('n', 'gqq', deferred(':VimwikiTableAlignQ'), { desc = 'nuwiki: table align (deferred)' }, bufnr)
map('n', 'gq1', deferred(':VimwikiTableAlignQ1'), { desc = 'nuwiki: table align row1 (deferred)' }, bufnr)
map('n', 'gww', deferred(':VimwikiTableAlignW'), { desc = 'nuwiki: table align wide (deferred)' }, bufnr)
map('n', 'gw1', deferred(':VimwikiTableAlignW1'), { desc = 'nuwiki: table align row1 wide (deferred)' }, bufnr)
map('n', '<A-Left>', deferred(':VimwikiTableMoveColumnLeft'), { desc = 'nuwiki: table col left (deferred)' }, bufnr)
map('n', '<A-Right>', deferred(':VimwikiTableMoveColumnRight'), { desc = 'nuwiki: table col right (deferred)' }, bufnr)
end
-- ===== HTML =====
if on('html_export') then
map('n', '<Leader>wh', cmd.export_current, { desc = 'nuwiki: export to HTML' }, bufnr) map('n', '<Leader>wh', cmd.export_current, { desc = 'nuwiki: export to HTML' }, bufnr)
map('n', '<Leader>whh', cmd.export_browse, { desc = 'nuwiki: export + browse' }, bufnr) map('n', '<Leader>whh', cmd.export_browse, { desc = 'nuwiki: export + browse' }, bufnr)
map('n', '<Leader>wha', cmd.export_all, { desc = 'nuwiki: export all' }, bufnr) map('n', '<Leader>wha', cmd.export_all, { desc = 'nuwiki: export all' }, bufnr)