Compare commits
1 commit
main
...
perf/async
| Author | SHA1 | Date | |
|---|---|---|---|
| ec1d9517a7 |
2 changed files with 79 additions and 41 deletions
|
|
@ -3,6 +3,9 @@ local M = {}
|
|||
|
||||
---@type blink.cmp.CompletionItem[]?
|
||||
local cache = nil
|
||||
local loading = false
|
||||
---@type {ctx: blink.cmp.Context, callback: fun(response: blink.cmp.CompletionResponse)}[]
|
||||
local pending = {}
|
||||
|
||||
function M.new()
|
||||
return setmetatable({}, { __index = M })
|
||||
|
|
@ -13,18 +16,17 @@ function M.enabled()
|
|||
return vim.bo.filetype == 'tmux'
|
||||
end
|
||||
|
||||
---@param man_stdout string
|
||||
---@param names_stdout string
|
||||
---@return table<string, string>
|
||||
local function parse_descriptions()
|
||||
local result = vim.system({ 'bash', '-c', 'MANWIDTH=80 man -P cat tmux 2>/dev/null' }):wait()
|
||||
local stdout = result.stdout or ''
|
||||
local function parse_descriptions(man_stdout, names_stdout)
|
||||
local lines = {}
|
||||
for line in (stdout .. '\n'):gmatch('(.-)\n') do
|
||||
for line in (man_stdout .. '\n'):gmatch('(.-)\n') do
|
||||
lines[#lines + 1] = line
|
||||
end
|
||||
|
||||
local cmd_result = vim.system({ 'tmux', 'list-commands', '-F', '#{command_list_name}' }):wait()
|
||||
local cmds = {}
|
||||
for name in (cmd_result.stdout or ''):gmatch('[^\n]+') do
|
||||
for name in names_stdout:gmatch('[^\n]+') do
|
||||
cmds[name] = true
|
||||
end
|
||||
|
||||
|
|
@ -128,27 +130,66 @@ end
|
|||
|
||||
---@param ctx blink.cmp.Context
|
||||
---@param callback fun(response: blink.cmp.CompletionResponse)
|
||||
---@return fun()
|
||||
function M:get_completions(ctx, callback)
|
||||
if not cache then
|
||||
local ok, descs = pcall(parse_descriptions)
|
||||
if not ok then
|
||||
descs = {}
|
||||
end
|
||||
local result = vim.system({ 'tmux', 'list-commands' }):wait()
|
||||
cache = parse(result.stdout or '', descs)
|
||||
end
|
||||
|
||||
local function respond(ctx, callback)
|
||||
local before = ctx.line:sub(1, ctx.cursor[2])
|
||||
if before:match('^%s*[a-z-]*$') then
|
||||
callback({
|
||||
is_incomplete_forward = false,
|
||||
is_incomplete_backward = false,
|
||||
items = vim.deepcopy(cache),
|
||||
items = cache,
|
||||
})
|
||||
else
|
||||
callback({ items = {} })
|
||||
end
|
||||
end
|
||||
|
||||
---@param ctx blink.cmp.Context
|
||||
---@param callback fun(response: blink.cmp.CompletionResponse)
|
||||
---@return fun()
|
||||
function M:get_completions(ctx, callback)
|
||||
if cache then
|
||||
respond(ctx, callback)
|
||||
return function() end
|
||||
end
|
||||
|
||||
pending[#pending + 1] = { ctx = ctx, callback = callback }
|
||||
if not loading then
|
||||
loading = true
|
||||
local man_out, names_out, cmds_out
|
||||
local remaining = 3
|
||||
|
||||
local function on_all_done()
|
||||
remaining = remaining - 1
|
||||
if remaining > 0 then
|
||||
return
|
||||
end
|
||||
vim.schedule(function()
|
||||
local ok, descs = pcall(parse_descriptions, man_out, names_out)
|
||||
if not ok then
|
||||
descs = {}
|
||||
end
|
||||
cache = parse(cmds_out, descs)
|
||||
loading = false
|
||||
for _, p in ipairs(pending) do
|
||||
respond(p.ctx, p.callback)
|
||||
end
|
||||
pending = {}
|
||||
end)
|
||||
end
|
||||
|
||||
vim.system({ 'bash', '-c', 'MANWIDTH=80 man -P cat tmux 2>/dev/null' }, {}, function(result)
|
||||
man_out = result.stdout or ''
|
||||
on_all_done()
|
||||
end)
|
||||
vim.system({ 'tmux', 'list-commands', '-F', '#{command_list_name}' }, {}, function(result)
|
||||
names_out = result.stdout or ''
|
||||
on_all_done()
|
||||
end)
|
||||
vim.system({ 'tmux', 'list-commands' }, {}, function(result)
|
||||
cmds_out = result.stdout or ''
|
||||
on_all_done()
|
||||
end)
|
||||
end
|
||||
return function() end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -26,37 +26,34 @@ local MAN_PAGE = table.concat({
|
|||
}, '\n')
|
||||
|
||||
local function mock_system()
|
||||
local original = vim.system
|
||||
local original_system = vim.system
|
||||
local original_schedule = vim.schedule
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
vim.system = function(cmd)
|
||||
vim.system = function(cmd, _, on_exit)
|
||||
local result
|
||||
if cmd[1] == 'bash' then
|
||||
return {
|
||||
wait = function()
|
||||
return { stdout = MAN_PAGE, code = 0 }
|
||||
end,
|
||||
}
|
||||
result = { stdout = MAN_PAGE, code = 0 }
|
||||
elseif cmd[1] == 'tmux' and cmd[2] == 'list-commands' then
|
||||
if cmd[3] == '-F' then
|
||||
return {
|
||||
wait = function()
|
||||
return { stdout = TMUX_NAMES, code = 0 }
|
||||
end,
|
||||
}
|
||||
result = { stdout = TMUX_NAMES, code = 0 }
|
||||
else
|
||||
result = { stdout = TMUX_COMMANDS, code = 0 }
|
||||
end
|
||||
return {
|
||||
wait = function()
|
||||
return { stdout = TMUX_COMMANDS, code = 0 }
|
||||
end,
|
||||
}
|
||||
else
|
||||
result = { stdout = '', code = 1 }
|
||||
end
|
||||
return {
|
||||
wait = function()
|
||||
return { stdout = '', code = 1 }
|
||||
end,
|
||||
}
|
||||
if on_exit then
|
||||
on_exit(result)
|
||||
return {}
|
||||
end
|
||||
return { wait = function() return result end }
|
||||
end
|
||||
vim.schedule = function(fn)
|
||||
fn()
|
||||
end
|
||||
return function()
|
||||
vim.system = original
|
||||
vim.system = original_system
|
||||
vim.schedule = original_schedule
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue