fix(async): properly trigger callbacks when canceling and fix delays in throttle.sync (#1611)
This commit is contained in:
@@ -383,12 +383,11 @@ entry.match = function(self, input, matching_config)
|
|||||||
score, matches = matcher.match(input, filter_text, option)
|
score, matches = matcher.match(input, filter_text, option)
|
||||||
|
|
||||||
-- Support the language server that doesn't respect VSCode's behaviors.
|
-- Support the language server that doesn't respect VSCode's behaviors.
|
||||||
local prefix = ''
|
|
||||||
if score == 0 then
|
if score == 0 then
|
||||||
if self:get_completion_item().textEdit and not misc.empty(self:get_completion_item().textEdit.newText) then
|
if self:get_completion_item().textEdit and not misc.empty(self:get_completion_item().textEdit.newText) then
|
||||||
local diff = self.source_offset - self:get_offset()
|
local diff = self.source_offset - self:get_offset()
|
||||||
if diff > 0 then
|
if diff > 0 then
|
||||||
prefix = string.sub(self.context.cursor_line, self:get_offset(), self:get_offset() + diff)
|
local prefix = string.sub(self.context.cursor_line, self:get_offset(), self:get_offset() + diff)
|
||||||
local accept = nil
|
local accept = nil
|
||||||
accept = accept or string.match(prefix, '^[^%a]+$')
|
accept = accept or string.match(prefix, '^[^%a]+$')
|
||||||
accept = accept or string.find(self:get_completion_item().textEdit.newText, prefix, 1, true)
|
accept = accept or string.find(self:get_completion_item().textEdit.newText, prefix, 1, true)
|
||||||
|
|||||||
@@ -32,18 +32,24 @@ async.throttle = function(fn, timeout)
|
|||||||
local timer = assert(vim.loop.new_timer())
|
local timer = assert(vim.loop.new_timer())
|
||||||
local _async = nil ---@type Async?
|
local _async = nil ---@type Async?
|
||||||
timers[#timers + 1] = timer
|
timers[#timers + 1] = timer
|
||||||
return setmetatable({
|
local throttle
|
||||||
|
throttle = setmetatable({
|
||||||
running = false,
|
running = false,
|
||||||
timeout = timeout,
|
timeout = timeout,
|
||||||
sync = function(self, timeout_)
|
sync = function(self, timeout_)
|
||||||
|
if not self.running then
|
||||||
|
return
|
||||||
|
end
|
||||||
vim.wait(timeout_ or 1000, function()
|
vim.wait(timeout_ or 1000, function()
|
||||||
return not self.running
|
return not self.running
|
||||||
end)
|
end, 10)
|
||||||
end,
|
end,
|
||||||
stop = function(reset_time)
|
stop = function(reset_time)
|
||||||
if reset_time ~= false then
|
if reset_time ~= false then
|
||||||
time = nil
|
time = nil
|
||||||
end
|
end
|
||||||
|
-- can't use self here unfortunately
|
||||||
|
throttle.running = false
|
||||||
timer:stop()
|
timer:stop()
|
||||||
if _async then
|
if _async then
|
||||||
_async:cancel()
|
_async:cancel()
|
||||||
@@ -57,9 +63,8 @@ async.throttle = function(fn, timeout)
|
|||||||
if time == nil then
|
if time == nil then
|
||||||
time = vim.loop.now()
|
time = vim.loop.now()
|
||||||
end
|
end
|
||||||
|
|
||||||
self.running = true
|
|
||||||
self.stop(false)
|
self.stop(false)
|
||||||
|
self.running = true
|
||||||
timer:start(math.max(1, self.timeout - (vim.loop.now() - time)), 0, function()
|
timer:start(math.max(1, self.timeout - (vim.loop.now() - time)), 0, function()
|
||||||
vim.schedule(function()
|
vim.schedule(function()
|
||||||
time = nil
|
time = nil
|
||||||
@@ -68,6 +73,7 @@ async.throttle = function(fn, timeout)
|
|||||||
---@cast ret Async
|
---@cast ret Async
|
||||||
_async = ret
|
_async = ret
|
||||||
_async:await(function(_, error)
|
_async:await(function(_, error)
|
||||||
|
_async = nil
|
||||||
self.running = false
|
self.running = false
|
||||||
if error and error ~= 'abort' then
|
if error and error ~= 'abort' then
|
||||||
vim.notify(error, vim.log.levels.ERROR)
|
vim.notify(error, vim.log.levels.ERROR)
|
||||||
@@ -80,6 +86,7 @@ async.throttle = function(fn, timeout)
|
|||||||
end)
|
end)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
return throttle
|
||||||
end
|
end
|
||||||
|
|
||||||
---Control async tasks.
|
---Control async tasks.
|
||||||
@@ -217,12 +224,18 @@ end
|
|||||||
---@param result? any
|
---@param result? any
|
||||||
---@param error? string
|
---@param error? string
|
||||||
function Async:_done(result, error)
|
function Async:_done(result, error)
|
||||||
self.running = false
|
if self.running then
|
||||||
self.result = result
|
self.running = false
|
||||||
self.error = error
|
self.result = result
|
||||||
|
self.error = error
|
||||||
|
end
|
||||||
for _, callback in ipairs(self.callbacks) do
|
for _, callback in ipairs(self.callbacks) do
|
||||||
callback(result, error)
|
callback(result, error)
|
||||||
end
|
end
|
||||||
|
-- only run each callback once.
|
||||||
|
-- _done can possibly be called multiple times.
|
||||||
|
-- so we need to clear callbacks after executing them.
|
||||||
|
self.callbacks = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
function Async:_step()
|
function Async:_step()
|
||||||
@@ -237,7 +250,7 @@ function Async:_step()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Async:cancel()
|
function Async:cancel()
|
||||||
self.running = false
|
self:_done(nil, 'abort')
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param cb AsyncCallback
|
---@param cb AsyncCallback
|
||||||
@@ -276,7 +289,7 @@ end
|
|||||||
|
|
||||||
-- This will yield when called from a coroutine
|
-- This will yield when called from a coroutine
|
||||||
function async.yield(...)
|
function async.yield(...)
|
||||||
if not coroutine.isyieldable() then
|
if coroutine.running() == nil then
|
||||||
error('Trying to yield from a non-yieldable context')
|
error('Trying to yield from a non-yieldable context')
|
||||||
return ...
|
return ...
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user