Skip to content

Commit

Permalink
fix: completion menu not triggering automatically
Browse files Browse the repository at this point in the history
When the `autoupdate_throttle` delay wasn't set to 0, the completion
source wasn't able to retrieve information about the crate on the
current line, because parsing the toml is deferred.
This is fixed by waiting for the update to happen and then running the
completion logic.
  • Loading branch information
saecki committed Sep 29, 2023
1 parent b1dc53b commit b6ddc0b
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 13 deletions.
37 changes: 37 additions & 0 deletions lua/crates/core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ local M = {}






local api = require("crates.api")
local async = require("crates.async")
local diagnostic = require("crates.diagnostic")
Expand All @@ -13,6 +16,9 @@ local Version = types.Version
local ui = require("crates.ui")
local util = require("crates.util")

M.throttled_updates = {}


M.reload_deps = async.wrap(function(crate_name, versions, version)
local deps, cancelled = api.fetch_deps(crate_name, version.num)
if cancelled then return end
Expand Down Expand Up @@ -133,6 +139,37 @@ function M.update(buf, reload)

::continue::
end

local callbacks = M.throttled_updates[buf]
if callbacks then
for _, callback in ipairs(callbacks) do
callback()
end
end
M.throttled_updates[buf] = nil
end

function M.throttled_update(buf, reload)
buf = buf or util.current_buf()
local existing = M.throttled_updates[buf]
if not existing then
M.throttled_updates[buf] = {}
end

M.inner_throttled_update(buf, reload)
end

function M.await_throttled_update_if_any(buf)
local existing = M.throttled_updates[buf]
if not existing then
return false
end

coroutine.yield(function(resolve)
table.insert(existing, resolve)
end)

return true
end

return M
16 changes: 10 additions & 6 deletions lua/crates/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ local M = {}


local actions = require("crates.actions")
local async = require("crates.async")
local config = require("crates.config")
local Config = config.Config
local core = require("crates.core")
Expand All @@ -90,27 +91,30 @@ function M.setup(cfg)
local group = vim.api.nvim_create_augroup("Crates", {})
if state.cfg.autoload then
if vim.fn.expand("%:t") == "Cargo.toml" then
M.update()
core.update(nil, false)
state.cfg.on_attach(vim.api.nvim_get_current_buf())
end

vim.api.nvim_create_autocmd("BufRead", {
group = group,
pattern = "Cargo.toml",
callback = function(info)
M.update()
core.update(nil, false)
state.cfg.on_attach(info.buf)
end,
})
end


core.inner_throttled_update = async.throttle(M.update, state.cfg.autoupdate_throttle)

if state.cfg.autoupdate then
local async = require("crates.async")
vim.api.nvim_create_autocmd({ "TextChanged", "TextChangedI", "TextChangedP" }, {
group = group,
pattern = "Cargo.toml",
callback = async.throttle(function()
M.update()
end, state.cfg.autoupdate_throttle),
callback = function()
core.throttled_update(nil, false)
end,
})
end

Expand Down
7 changes: 7 additions & 0 deletions lua/crates/src/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ local CompletionList = M.CompletionList

local api = require("crates.api")
local async = require("crates.async")
local core = require("crates.core")
local state = require("crates.state")
local toml = require("crates.toml")
local types = require("crates.types")
Expand Down Expand Up @@ -98,6 +99,12 @@ end

local function complete()
local buf = util.current_buf()

local awaited = core.await_throttled_update_if_any(buf)
if awaited and buf ~= util.current_buf() then
return
end

local line, col = util.cursor_pos()
local crates = util.get_line_crates(buf, Range.new(line, line + 1))
local _, crate = next(crates)
Expand Down
37 changes: 37 additions & 0 deletions teal/crates/core.tl
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
local record M
reload_crate: function(string)
reload_deps: function(string, {Version}, Version)

throttled_updates: {integer:{function()}}
inner_throttled_update: function(integer|nil, boolean)
end

local api = require("crates.api")
Expand All @@ -13,6 +16,9 @@ local Version = types.Version
local ui = require("crates.ui")
local util = require("crates.util")

M.throttled_updates = {}


M.reload_deps = async.wrap(function(crate_name: string, versions: {Version}, version: Version)
local deps, cancelled = api.fetch_deps(crate_name, version.num)
if cancelled then return end
Expand Down Expand Up @@ -133,6 +139,37 @@ function M.update(buf: integer|nil, reload: boolean)

::continue::
end

local callbacks = M.throttled_updates[buf]
if callbacks then
for _,callback in ipairs(callbacks) do
callback()
end
end
M.throttled_updates[buf] = nil
end

function M.throttled_update(buf: integer|nil, reload: boolean)
buf = buf or util.current_buf()
local existing = M.throttled_updates[buf]
if not existing then
M.throttled_updates[buf] = {}
end

M.inner_throttled_update(buf, reload)
end

function M.await_throttled_update_if_any(buf: integer): boolean
local existing = M.throttled_updates[buf]
if not existing then
return false
end

coroutine.yield(function(resolve: function())
table.insert(existing, resolve)
end)

return true
end

return M
18 changes: 11 additions & 7 deletions teal/crates/init.tl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ local record M
end

local actions = require("crates.actions")
local async = require("crates.async")
local config = require("crates.config")
local Config = config.Config
local core = require("crates.core")
Expand All @@ -90,27 +91,30 @@ function M.setup(cfg: Config)
local group = vim.api.nvim_create_augroup("Crates", {})
if state.cfg.autoload then
if vim.fn.expand("%:t") == "Cargo.toml" then
M.update()
state.cfg.on_attach(vim.api.nvim_get_current_buf())
core.update(nil, false)
state.cfg.on_attach(vim.api.nvim_get_current_buf())
end

vim.api.nvim_create_autocmd("BufRead", {
group = group,
pattern = "Cargo.toml",
callback = function(info: AutocmdInfo)
M.update()
core.update(nil, false)
state.cfg.on_attach(info.buf)
end,
})
end

-- initialize the throttled update function with timeout
core.inner_throttled_update = async.throttle(M.update, state.cfg.autoupdate_throttle) as function()

if state.cfg.autoupdate then
local async = require("crates.async")
vim.api.nvim_create_autocmd({ "TextChanged", "TextChangedI", "TextChangedP" }, {
group = group,
pattern = "Cargo.toml",
callback = async.throttle(function()
M.update()
end, state.cfg.autoupdate_throttle),
callback = function()
core.throttled_update(nil, false)
end,
})
end

Expand Down
7 changes: 7 additions & 0 deletions teal/crates/src/common.tl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ local CompletionList = M.CompletionList

local api = require("crates.api")
local async = require("crates.async")
local core = require("crates.core")
local state = require("crates.state")
local toml = require("crates.toml")
local types = require("crates.types")
Expand Down Expand Up @@ -98,6 +99,12 @@ end

local function complete(): CompletionList|nil
local buf = util.current_buf()

local awaited = core.await_throttled_update_if_any(buf)
if awaited and buf ~= util.current_buf() then
return
end

local line, col = util.cursor_pos()
local crates = util.get_line_crates(buf, Range.new(line, line + 1))
local _,crate = next(crates)
Expand Down

0 comments on commit b6ddc0b

Please sign in to comment.