feat(parity): close the entire P3 Mappings section

Both remaining mapping gaps (client-side, both clients):

- Visual <CR>: upstream binds it to NormalizeLinkVisualCR (== visual `+`).
  Added `x <CR>` -> normalize_link(true) (wrap the selection as a wikilink)
  in both clients.

- Insert <S-CR>: upstream's multiline-list-item continuation (VimwikiReturn
  2 2 -> kbd_cr with no new marker). New smart_shift_return (both clients,
  <expr> insert mapping): on a list item returns <CR> + spaces aligning under
  the item text (marker width + 1, +4 for a `[ ] ` checkbox), no marker; off a
  list item, a plain <CR>. Mirrors smart_return's auto-indent handling.

Tests: map.visual_cr_wraps_selection + map.insert_shift_cr_multiline
(test-keymaps.lua, the latter exercising the handler directly since <S-CR>
doesn't round-trip headless feedkeys), and map.visual_cr_wraps_selection +
cr.shift_cr_multiline{,_checkbox} (test-keymaps-vim.vim). Docs (README +
doc/nuwiki.txt) and the gap doc updated. Neovim 305, Vim 299/18/21 pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-03 11:04:56 +00:00
parent 305324c6e9
commit 724712121d
9 changed files with 146 additions and 7 deletions
+25
View File
@@ -1000,6 +1000,31 @@ function M.smart_return()
return cr
end
-- Insert-mode `<S-CR>`: continue the current list item on a new line WITHOUT a
-- new marker, indented to align under the item's text — vimwiki's "multiline
-- list item" (`VimwikiReturn 2 2`). Off a list item it's a plain `<CR>`.
function M.smart_shift_return()
local line = vim.api.nvim_get_current_line()
local cr = vim.api.nvim_replace_termcodes('<CR>', true, false, true)
local indent, marker, after = line:match('^(%s*)([%-%*%#])%s(.*)$')
if not marker then
local n
indent, n, marker, after = line:match('^(%s*)(%d+)([%.%)])%s(.*)$')
if marker then marker = n .. marker end
end
if not marker then
return cr
end
-- Align under the text: marker width + 1 space (+ 4 for a `[ ] ` checkbox).
local has_cb = after:match('^%[[%sxXoO%.%-]%]') ~= nil
local pad = #marker + 1 + (has_cb and 4 or 0)
-- Mirror smart_return's auto-indent handling: when an auto-indent mechanism
-- is active, Vim already re-inserts the line's indent after `<CR>`.
local auto = vim.bo.autoindent or vim.bo.smartindent or vim.bo.cindent
or (vim.bo.indentexpr ~= nil and vim.bo.indentexpr ~= '')
return cr .. (auto and '' or indent) .. string.rep(' ', pad)
end
-- :VimwikiReturn / :NuwikiReturn — the command form of the smart `<CR>`
-- continuation (upstream's mapping-driven VimwikiReturn). Enters insert at end
-- of line and triggers the buffer-local `<CR>` mapping (smart_return). Args
+6
View File
@@ -181,6 +181,9 @@ function M.attach(bufnr, mappings)
map('n', '+', cmd.normalize_link, { desc = 'nuwiki: wrap word as wikilink' }, bufnr)
map('x', '+', function() cmd.normalize_link(true) end,
{ desc = 'nuwiki: wrap selection as wikilink' }, bufnr)
-- Upstream binds visual <CR> to the same normalize-link as visual `+`.
map('x', '<CR>', function() cmd.normalize_link(true) end,
{ desc = 'nuwiki: wrap selection as wikilink' }, bufnr)
map('n', p .. 'n', cmd.wiki_goto_page, { desc = 'nuwiki: goto page' }, bufnr)
map('n', p .. 'd', cmd.delete_file, { desc = 'nuwiki: delete page' }, bufnr)
map('n', p .. 'r', cmd.rename_file, { desc = 'nuwiki: rename page' }, bufnr)
@@ -277,6 +280,9 @@ function M.attach(bufnr, mappings)
-- result is the keystrokes fed — keeps undo coherent.
map('i', '<CR>', cmd.smart_return,
{ desc = 'nuwiki: smart return (insert)', expr = true }, bufnr)
-- Smart <S-CR>: multiline list item (continuation with no new marker).
map('i', '<S-CR>', cmd.smart_shift_return,
{ desc = 'nuwiki: multiline list item (insert)', expr = true }, bufnr)
end
-- ===== Insert-mode table navigation (Cluster 6) =====