1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
-- Helpers shared by the atom-capture specs (mcursor_spec.lua, cmdatom_spec.lua).
local t = require('test.testutil')
local n = require('test.functional.testnvim')()
local m = {}
function m.get_lines()
return n.buf_lines(0)
end
--- vim.keycode(): |key-notation| => the raw bytes of the CmdAtom event's keys/lhs.
function m.k(s)
return n.api.nvim_replace_termcodes(s, true, true, true)
end
--- Starts collecting CmdAtom event-data.
function m.atoms_start()
n.exec_lua([[
_G.atoms = {}
vim.api.nvim_create_autocmd('CmdAtom', {
callback = function(ev)
table.insert(_G.atoms, ev.data)
end,
})
]])
end
--- Gets the collected CmdAtom event-data.
function m.atoms()
n.poke_eventloop() -- CmdAtom is deferred, so drain the event loop first.
return n.exec_lua('return _G.atoms')
end
--- Gets the last collected CmdAtom event.
function m.atom_last()
local evs = m.atoms()
return evs[#evs]
end
--- Gets the last `count` collected CmdAtom events: bare `keys` strings by default, or
--- projections of the named `fields`.
function m.atoms_tail(count, ...)
local evs = m.atoms()
local fields = select('#', ...) > 0 and { ... } or nil
local tail = {}
for i = #evs - count + 1, #evs do
table.insert(tail, fields and t.pick(evs[i], unpack(fields)) or evs[i].keys)
end
return tail
end
--- Gets `ev`'s subatoms (`CmdAtom.atoms`): bare `keys` strings by default, or projections of the
--- named `fields`.
function m.subatoms(ev, ...)
local fields = select('#', ...) > 0 and { ... } or nil
local subs = {}
for _, c in ipairs(ev.atoms) do
table.insert(subs, fields and t.pick(c, unpack(fields)) or c.keys)
end
return subs
end
--- Minimal vim-surround "ys": an <expr> mapping sets 'operatorfunc' and returns "g@"; the opfunc
--- reads the wrap char with getchar() and wraps the motion region (yank, modify register, paste
--- back).
m.minisurround_vim = [[
function! MiniSurroundSetup() abort
set operatorfunc=MiniSurround
return 'g@'
endfunction
function! MiniSurround(type) abort
let char = nr2char(getchar())
let save = getreg('"')
silent exe "norm! v`[o`]y"
call setreg('"', char .. getreg('"') .. char, 'v')
silent exe "norm! gvp`["
call setreg('"', save)
endfunction
nnoremap <expr> ys MiniSurroundSetup()
]]
--- Minimal vim-sneak: :omap whose ":call" reads a 2-char getchar() and moves the cursor.
m.minisneak_vim = [[
function! MiniSneak() abort
let c1 = nr2char(getchar())
let c2 = nr2char(getchar())
call search('\V' . c1 . c2, 'W')
endfunction
onoremap <silent> z :<C-U>call MiniSneak()<CR>
]]
--- Minimal vim-surround "ds": a ":call" mapping whose edit runs through :normal inside a
--- function, with a getchar() payload naming the surround to delete.
m.delsurround_vim = [[
function! DelSurround() abort
call getchar()
" cursor is on the "("; delete it and its matching ")".
normal! mz%x`zx
endfunction
nnoremap <silent> ds :<C-U>call DelSurround()<CR>
]]
return m
|