Skip to content

Commit

Permalink
perf: shutdown Noice on VimLeave to prevent close delay
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Oct 28, 2022
1 parent bb023e9 commit de1d5dc
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 29 deletions.
7 changes: 7 additions & 0 deletions lua/noice/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ function M.setup(opts)
require("noice.commands").setup()
require("noice.message.router").setup()
M.enable()
vim.api.nvim_create_autocmd("VimLeave", {
callback = function()
if Config.is_running() then
pcall(M.disable)
end
end,
})
end)
end

Expand Down
25 changes: 11 additions & 14 deletions lua/noice/message/router.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,26 @@ local Manager = require("noice.message.manager")
---@field opts? NoiceRouteOptions|NoiceViewOptions

local M = {}
M._running = false
---@type NoiceRoute[]
M._routes = {}
M._tick = 0
M._need_redraw = false

local function run()
if not M._running then
return
end
Util.try(M.update)
vim.defer_fn(run, Config.options.throttle)
end
---@type fun()|Interval?
M._updater = nil

function M.enable()
M._running = true
vim.schedule(run)
if not M._updater then
M._updater = Util.interval(Config.options.throttle, Util.protect(M.update))
end
M._updater()
end

function M.disable()
M._running = false
Manager.clear()
M.update()
if M._updater then
M._updater.stop()
Manager.clear()
M.update()
end
end

---@param route NoiceRouteConfig
Expand Down
50 changes: 35 additions & 15 deletions lua/noice/util/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -77,25 +77,45 @@ end
---@param fn F
---@param ms integer
---@param opts? {enabled?:fun():boolean}
---@return F
---@return F|Interval
function M.interval(ms, fn, opts)
opts = opts or {}
fn = vim.schedule_wrap(fn)
local timer = vim.loop.new_timer()
local running = false
return function(...)
local args = vim.F.pack_len(...)
if not running then
running = true
timer:start(ms, ms, function()
fn(vim.F.unpack_len(args))
if not (opts.enabled and opts.enabled()) then
timer:stop()
running = false
end
end)
---@type vim.loop.Timer?
local timer = nil

---@class Interval
local T = {}

function T.keep()
return opts.enabled == nil or opts.enabled()
end

function T.running()
return timer and not timer:is_closing()
end

function T.stop()
if timer and T.running() then
timer:stop()
end
end

function T.fn()
pcall(fn)
if timer and T.running() and not T.keep() then
timer:stop()
elseif T.keep() and not T.running() then
timer = vim.defer_fn(T.fn, ms)
end
end

function T.__call()
if not T.running() and T.keep() then
timer = vim.defer_fn(T.fn, ms)
end
end

return setmetatable(T, T)
end

---@param a table<string, any>
Expand Down

0 comments on commit de1d5dc

Please sign in to comment.