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
|
function pipe_visual()
pipe_internal({'<', '>'}, vim.fn.visualmode())
end
function pipe_normal(mode)
local map = {
['char'] = 'v',
['line'] = 'V',
['block'] = '\x16',
}
pipe_internal({'[', ']'}, map[mode])
end
function pipe_internal(marks, mode)
local lines
local sr, sc = unpack(vim.api.nvim_buf_get_mark(0, marks[1]))
local er, ec = unpack(vim.api.nvim_buf_get_mark(0, marks[2]))
if mode == 'v' then -- Visual
lines = vim.api.nvim_buf_get_text(0, sr - 1, sc, er - 1, ec + 1, {})
elseif mode == 'V' then -- Visual Line
lines = vim.api.nvim_buf_get_lines(0, sr - 1, er, true)
elseif mode == '\x16' then -- Visual Block
if sc > ec then
sc, ec = ec, sc
end
lines = {}
for i = sr, er do
lines[#lines+1] = vim.api.nvim_buf_get_text(0, i - 1, sc, i - 1, ec + 1, {})[1]
end
end
local ok, cmd = pcall(vim.fn.input, {
prompt = '… | ',
cancelreturn = vim.NIL,
})
if not ok or cmd == vim.NIL then
return
end
local out = vim.fn.systemlist(cmd, lines)
if mode == 'v' then
vim.api.nvim_buf_set_text(0, sr - 1, sc, er - 1, ec + 1, out)
elseif mode == 'V' then
vim.api.nvim_buf_set_lines(0, sr - 1, er, true, out)
elseif mode == '\x16' then
for i = sr, er do
vim.api.nvim_buf_set_text(0, i - 1, sc, i - 1, ec + 1, { out[i] })
end
end
end
vim.keymap.set('n', '<Plug>PipeNormal', ':set opfunc=v:lua.pipe_normal<CR>g@',
{ silent = true })
vim.keymap.set('x', '<Plug>PipeVisual', ':<C-u>lua pipe_visual()<CR>',
{ silent = true })
vim.keymap.set('n', '|', '<Plug>PipeNormal')
vim.keymap.set('x', '|', '<Plug>PipeVisual')
|