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
|
local M = {}
local function get_visual_selection(intact)
intact = intact or false
local top = vim.fn.getpos("'<")
top = { ln = top[2], col = top[3] }
local bot = vim.fn.getpos("'>")
bot = { ln = bot[2], col = bot[3] }
local lines = vim.api.nvim_buf_get_lines(0, (top.ln - 1), bot.ln, false)
if not intact then
if vim.opt.selection:get() == 'inclusive' then
lines[#lines] = lines[#lines]:sub(1, bot.col)
else
lines[#lines] = lines[#lines]:sub(1, (bot.col - 1))
end
lines[1] = lines[1]:sub(top.col)
end
return top, bot, lines
end
local function sortline(line, a, o, separator)
separator = separator or ' '
local result, _ = string.gsub(line, string.sub(line, a, o),
table.concat(vim.fn.sort(vim.fn.split(string.sub(line, a, o), separator)), separator), 1)
return result
end
function M.sort_lines(_, preview_ns, preview_bufnr)
local bufnr = vim.api.nvim_get_current_buf()
local top, bot, lines = get_visual_selection(true)
vim.pretty_print(top, bot, lines)
for i = 1, #lines do
local a = 0; if i == 1 then a = top.col end
local o = -1; if i == #lines then o = bot.col end
lines[i] = sortline(lines[i], a, o, ' ')
end
if not preview_ns then
vim.api.nvim_buf_set_lines(bufnr, top.ln - 1, bot.ln, false, lines)
return 0
end
-- inccommand preview
if preview_ns ~= nil then
for i, line in ipairs(lines) do
vim.api.nvim_buf_set_extmark(bufnr, preview_ns, top.ln + i - 2, 0, {
hl_mode = 'combine',
virt_text_pos = 'overlay',
virt_text = { { line, 'Substitute' } },
})
if preview_bufnr ~= nil then
local prefix = string.format('|%d| ', top.ln + i - 1)
vim.api.nvim_buf_set_lines(preview_bufnr, i - 1, -1, false, { prefix .. line })
vim.api.nvim_buf_add_highlight(
preview_bufnr,
preview_ns,
'Substitute',
i,
#prefix,
#prefix + #line
)
end
end
return (#lines > 1 and 2 or 1)
end
end
function M.setup(opts)
vim.api.nvim_create_user_command(
'SortLine',
M.sort_lines,
{ desc = 'sort line', range = '%', preview = M.sort_lines }
)
end
return M
|