parity(2): insert-mode list bindings (<C-D>/<C-T>/<C-L><C-?>)
Match upstream vimwiki's insert-mode list editing: <C-D> list_change_level(-1) dedent current item <C-T> list_change_level(+1) indent current item <C-L><C-J> list_cycle_symbol(+1) cycle marker forward <C-L><C-K> list_cycle_symbol(-1) cycle marker backward <C-L><C-M> list_toggle_or_add_chk toggle if has checkbox, else add `[ ]` Cycle order matches vimwiki's canonical run: - → * → # → 1. → 1) → a) → A) → i) → I) → (wrap) Both Lua and VimL paths wired. Lua callbacks fire directly (no `<C-o>` dance) since list_change_level / changeSymbol mutate the buffer via the LSP applyEdit pipeline, which works cleanly in insert mode. VimL keeps the `<C-o>:call …<CR>` idiom since that's the standard there. Harness adds 5 cases covering the new insert-mode bindings plus one direct LSP roundtrip for changeSymbol — surfaced a long-standing stale-binary footgun in test-keymaps.sh (rebuilt only when bin was missing; now rebuilds every run since incremental cargo is fast). Harness also captures server log_messages and dumps them on failure so future swallowed-error bugs (Err → log + Ok(None)) are visible. Gates: 421 Rust / 25 Neovim / 12 Vim. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -101,6 +101,16 @@ local function wait_for_lsp(timeout_ms)
|
||||
return nil
|
||||
end
|
||||
|
||||
-- ===== Capture server log_message events =====
|
||||
local server_log = {}
|
||||
local orig_handler = vim.lsp.handlers['window/logMessage']
|
||||
vim.lsp.handlers['window/logMessage'] = function(err, result, ctx, cfg)
|
||||
if result and result.message then
|
||||
table.insert(server_log, '[' .. tostring(result.type) .. '] ' .. result.message)
|
||||
end
|
||||
if orig_handler then return orig_handler(err, result, ctx, cfg) end
|
||||
end
|
||||
|
||||
-- ===== Smoke: LSP attached =====
|
||||
|
||||
vim.defer_fn(function()
|
||||
@@ -272,6 +282,58 @@ vim.defer_fn(function()
|
||||
wait_ms = 100,
|
||||
})
|
||||
|
||||
-- ===== Insert-mode list bindings (Cluster 2) =====
|
||||
|
||||
run('insert.C-L_C-M_adds_checkbox', {
|
||||
lines = { '- task' },
|
||||
cursor = { 1, 0 },
|
||||
keys = 'A<C-L><C-M><Esc>',
|
||||
expect_line = '- [ ] task',
|
||||
expect_at = 1,
|
||||
wait_ms = 200,
|
||||
})
|
||||
run('insert.C-L_C-M_toggles_existing_checkbox', {
|
||||
lines = { '- [ ] task' },
|
||||
cursor = { 1, 0 },
|
||||
keys = 'A<C-L><C-M><Esc>',
|
||||
expect_line = '- [X] task',
|
||||
expect_at = 1,
|
||||
})
|
||||
-- End-to-end regression for changeSymbol over LSP — direct call
|
||||
-- (no keymap) so we can spot a stale `bin/nuwiki-ls` or a dispatch
|
||||
-- error fast. Toggle has separate coverage above via `<C-Space>`.
|
||||
do
|
||||
local ok, err = pcall(function()
|
||||
set_buf({ '- [ ] item', '- [ ] two' })
|
||||
sleep(200)
|
||||
vim.api.nvim_win_set_cursor(0, { 1, 0 })
|
||||
require('nuwiki.commands').list_change_symbol('*', false)
|
||||
sleep(1500)
|
||||
local got = get_line(1)
|
||||
if got ~= '* [ ] item' then
|
||||
error(string.format('change_symbol failed: got %q', got))
|
||||
end
|
||||
end)
|
||||
record(ok, 'direct.list_change_symbol_via_lsp', ok and '' or tostring(err))
|
||||
end
|
||||
run('insert.C-L_C-J_cycles_marker_forward', {
|
||||
lines = { '- item' },
|
||||
cursor = { 1, 0 },
|
||||
keys = 'A<C-L><C-J><Esc>',
|
||||
expect_line = '* item',
|
||||
expect_at = 1,
|
||||
wait_ms = 1500,
|
||||
})
|
||||
run('insert.C-L_C-K_cycles_marker_backward', {
|
||||
-- From `-` going backward wraps to the end of the order (`I)`).
|
||||
lines = { '- item' },
|
||||
cursor = { 1, 0 },
|
||||
keys = 'A<C-L><C-K><Esc>',
|
||||
expect_line = 'I) item',
|
||||
expect_at = 1,
|
||||
wait_ms = 1500,
|
||||
})
|
||||
|
||||
-- ===== Diary nav =====
|
||||
-- Tested via the LSP open-* responses; can't fully validate without
|
||||
-- a populated diary, but at least confirm the maps fire without
|
||||
@@ -280,6 +342,15 @@ vim.defer_fn(function()
|
||||
-- ===== Wrap up =====
|
||||
|
||||
table.insert(out_lines, '')
|
||||
-- Dump captured server log_messages only on failure — useful for
|
||||
-- diagnosing dispatch errors that the LSP swallows into log_message.
|
||||
if fail > 0 and #server_log > 0 then
|
||||
table.insert(out_lines, '--- server log_messages ---')
|
||||
for _, l in ipairs(server_log) do
|
||||
table.insert(out_lines, l)
|
||||
end
|
||||
table.insert(out_lines, '')
|
||||
end
|
||||
table.insert(out_lines, string.format('SUMMARY: %d passed, %d failed', pass, fail))
|
||||
vim.fn.writefile(out_lines, OUT)
|
||||
vim.cmd(fail == 0 and 'qall!' or 'cquit!')
|
||||
|
||||
Reference in New Issue
Block a user