diff options
| author | William Boman <william@redwill.se> | 2022-12-05 17:48:34 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-05 17:48:34 +0100 |
| commit | 2381f507189e3e10a43c3932a3ec6c2847180abc (patch) | |
| tree | af51bec9c83583b6033bd193effc289c2c2b590a /lua/mason-core/terminator.lua | |
| parent | chore: update generated code (#728) (diff) | |
| download | mason-2381f507189e3e10a43c3932a3ec6c2847180abc.tar mason-2381f507189e3e10a43c3932a3ec6c2847180abc.tar.gz mason-2381f507189e3e10a43c3932a3ec6c2847180abc.tar.bz2 mason-2381f507189e3e10a43c3932a3ec6c2847180abc.tar.lz mason-2381f507189e3e10a43c3932a3ec6c2847180abc.tar.xz mason-2381f507189e3e10a43c3932a3ec6c2847180abc.tar.zst mason-2381f507189e3e10a43c3932a3ec6c2847180abc.zip | |
fix(package): don't call vim API functions inside fast event (#730)
Diffstat (limited to 'lua/mason-core/terminator.lua')
| -rw-r--r-- | lua/mason-core/terminator.lua | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/lua/mason-core/terminator.lua b/lua/mason-core/terminator.lua new file mode 100644 index 00000000..b7acefe8 --- /dev/null +++ b/lua/mason-core/terminator.lua @@ -0,0 +1,104 @@ +local a = require "mason-core.async" + +-- Hasta la vista, baby. +-- ______ +-- <((((((\\\ +-- / . }\ +-- ;--..--._|} +-- (\ '--/\--' ) +-- \\ | '-' :'| +-- \\ . -==- .-| +-- \\ \.__.' \--._ +-- [\\ __.--| // _/'--. +-- \ \\ .'-._ ('-----'/ __/ \ +-- \ \\ / __>| | '--. | +-- \ \\ | \ | / / / +-- \ '\ / \ | | _/ / +-- \ \ \ | | / / +-- snd \ \ \ / + +local M = {} + +---@async +---@param handles InstallHandle[] +---@param grace_ms integer +local function terminate_handles(handles, grace_ms) + a.wait_all(vim.tbl_map( + ---@param handle InstallHandle + function(handle) + return function() + a.wait_first { + function() + if not handle:is_closed() then + handle:terminate() + end + a.wait(function(resolve) + if handle:is_closed() then + resolve() + else + handle:once("closed", resolve) + end + end) + end, + function() + a.sleep(grace_ms) + if not handle:is_closed() then + handle:kill(9) -- SIGKILL + end + end, + } + end + end, + handles + )) +end + +local active_handles = {} + +---@parma handle InstallHandle +function M.register(handle) + if handle:is_closed() then + return + end + active_handles[handle] = true + handle:once("closed", function() + active_handles[handle] = nil + end) +end + +---@param grace_ms integer +function M.terminate(grace_ms) + local handles = vim.tbl_keys(active_handles) + if #handles > 0 then + local package_names = vim.tbl_map(function(h) + return h.package.name + end, handles) + table.sort(package_names) + + -- 1. Print warning message. + vim.api.nvim_echo({ + { + "[mason.nvim] Neovim is exiting while packages are still installing. Terminating all installations…", + "WarningMsg", + }, + }, true, {}) + vim.cmd "redraw" + + -- 2. Synchronously terminate all installation handles. + a.run_blocking(function() + terminate_handles(handles, grace_ms) + end) + + -- 3. Schedule error message to be displayed so that Neovim prints it to the tty. + -- XXX: does this need to be conditional on which UIs are attached? + vim.schedule(function() + vim.api.nvim_err_writeln( + ("[mason.nvim] Neovim exited while the following packages were installing. Installation was aborted.\n- %s"):format( + table.concat(package_names, #package_names > 5 and ", " or "\n- ") + ) + ) + end) + end +end + +return M |
