parity(5): smart <CR> in insert mode (VimwikiReturn)
Bind `<CR>` in insert mode as an `<expr>` map to a `smart_return`
helper. Behaviour matches upstream vimwiki's `:VimwikiReturn`:
- On a list line with content → continue the list with the same
marker on a new line (preserving leading checkbox `[ ]` if any).
- On an empty list line (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>`.
Implementation note: the helper is `<expr>`-bound, which means
textlock is active and the buffer can't be mutated from inside the
callback. The function returns key sequences only — including
`<Esc>0DA<CR>` for the empty-list break and `<Esc>0li` for the
table-row cursor jump — so every effect flows through Vim's normal
keystroke pipeline and stays undo-coherent.
Both Lua and VimL counterparts shipped.
Tests: 4 new in scripts/test-keymaps.lua covering list continuation,
checkbox preservation, empty-marker break-out, and new table row.
Gates: 421 Rust / 35 Neovim / 12 Vim.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -684,6 +684,48 @@ function! nuwiki#commands#paste_url() abort
|
||||
call s:exec('nuwiki.link.pasteUrl', l:args)
|
||||
endfunction
|
||||
|
||||
" Smart <CR> for insert mode — vimwiki `:VimwikiReturn` parity.
|
||||
" Used as `inoremap <expr> <CR> nuwiki#commands#smart_return()`. The
|
||||
" returned string is fed into Vim's input stream after the function
|
||||
" finishes, keeping the undo block coherent.
|
||||
function! nuwiki#commands#smart_return() abort
|
||||
let l:line = getline('.')
|
||||
if l:line =~# '^\s*|.*|\s*$'
|
||||
let l:n = max([len(split(l:line, '|', 1)) - 2, 1])
|
||||
let l:new_row = '|' . repeat(' |', l:n)
|
||||
let l:row = line('.')
|
||||
call append(l:row, l:new_row)
|
||||
call cursor(l:row + 1, 3)
|
||||
return ''
|
||||
endif
|
||||
let l:m = matchlist(l:line, '^\(\s*\)\([-*#]\)\s\(.*\)$')
|
||||
if empty(l:m)
|
||||
let l:m2 = matchlist(l:line, '^\(\s*\)\(\d\+\)\([.)]\)\s\(.*\)$')
|
||||
if !empty(l:m2)
|
||||
let l:m = [l:line, l:m2[1], l:m2[2] . l:m2[3], l:m2[4]]
|
||||
endif
|
||||
endif
|
||||
if !empty(l:m)
|
||||
let l:indent = l:m[1]
|
||||
let l:marker = l:m[2]
|
||||
let l:rest = l:m[3]
|
||||
let l:cb = matchlist(l:rest, '^\(\[[ xXoO.\-]\]\)\s*\(.*\)$')
|
||||
let l:has_cb = !empty(l:cb)
|
||||
let l:body = l:has_cb ? l:cb[2] : l:rest
|
||||
if l:body =~# '^\s*$'
|
||||
call setline('.', '')
|
||||
call cursor(line('.'), 1)
|
||||
return "\<CR>"
|
||||
endif
|
||||
let l:cont = l:indent . l:marker . ' '
|
||||
if l:has_cb
|
||||
let l:cont .= '[ ] '
|
||||
endif
|
||||
return "\<CR>" . l:cont
|
||||
endif
|
||||
return "\<CR>"
|
||||
endfunction
|
||||
|
||||
" `:VimwikiNormalizeLink` — wrap the word at cursor as `[[word]]`
|
||||
" without following. Pure-VimL.
|
||||
function! nuwiki#commands#normalize_link() abort
|
||||
|
||||
Reference in New Issue
Block a user