perf: async enum file read (#10)
Some checks are pending
quality / changes (push) Waiting to run
quality / Lua Format Check (push) Blocked by required conditions
quality / Lua Lint Check (push) Blocked by required conditions
quality / Lua Type Check (push) Blocked by required conditions
quality / Markdown Format Check (push) Blocked by required conditions
test / Test (Neovim nightly) (push) Waiting to run
test / Test (Neovim stable) (push) Waiting to run
luarocks / quality (push) Waiting to run
luarocks / publish (push) Blocked by required conditions

* perf: async enum file read

Problem: parse_enums read the bash-completion file with blocking
io.open/fd:read on the main thread, stalling the event loop.

Solution: read the file via vim.uv.fs_open/fstat/read with callbacks,
running in parallel with the ghostty config system call using the
same remaining-counter pattern as the other blink-cmp plugins.

* fix: lint warning and test mocks for async file read

Problem: selene flagged unused err3 variable, and test mock_enums
still mocked io.open instead of the new vim.uv.fs_* calls.

Solution: rename err3 to _, replace io.open mock with synchronous
vim.uv.fs_open/fs_fstat/fs_read/fs_close mocks using a sentinel fd.
This commit is contained in:
Barrett Ruth 2026-02-22 23:21:54 -05:00 committed by GitHub
parent fe16245881
commit 0b137d64f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 77 additions and 27 deletions

View file

@ -85,18 +85,7 @@ function M.bash_completion_path()
end
---@return table<string, string[]>
local function parse_enums()
local path = M.bash_completion_path()
if not path then
return {}
end
local fd = io.open(path, 'r')
if not fd then
return {}
end
local content = fd:read('*a')
fd:close()
local function parse_enums(content)
local enums = {}
for key, values in content:gmatch('%-%-([a-z][a-z0-9-]*)%) [^\n]* compgen %-W "([^"]+)"') do
local vals = {}
@ -162,17 +151,56 @@ function M:get_completions(ctx, callback)
pending[#pending + 1] = { ctx = ctx, callback = callback }
if not loading then
loading = true
vim.system({ 'ghostty', '+show-config', '--docs' }, {}, function(result)
local config_out, enums_content
local remaining = 2
local function on_all_done()
remaining = remaining - 1
if remaining > 0 then
return
end
vim.schedule(function()
keys_cache = parse_keys(result.stdout or '')
enums_cache = parse_enums()
keys_cache = parse_keys(config_out)
enums_cache = parse_enums(enums_content)
loading = false
for _, p in ipairs(pending) do
respond(p.ctx, p.callback)
end
pending = {}
end)
end
vim.system({ 'ghostty', '+show-config', '--docs' }, {}, function(result)
config_out = result.stdout or ''
on_all_done()
end)
local path = M.bash_completion_path()
if not path then
enums_content = ''
on_all_done()
else
vim.uv.fs_open(path, 'r', 438, function(err, fd)
if err or not fd then
enums_content = ''
on_all_done()
return
end
vim.uv.fs_fstat(fd, function(err2, stat)
if err2 or not stat then
vim.uv.fs_close(fd)
enums_content = ''
on_all_done()
return
end
vim.uv.fs_read(fd, stat.size, 0, function(_, data)
vim.uv.fs_close(fd)
enums_content = data or ''
on_all_done()
end)
end)
end)
end
end
return function() end
end