feat: can cancel out of progress window
This commit is contained in:
parent
9871ca9737
commit
273c2cecbf
7 changed files with 128 additions and 58 deletions
|
|
@ -387,22 +387,33 @@ M.process_actions = function(actions, cb)
|
|||
|
||||
local finished = false
|
||||
local progress = Progress.new()
|
||||
local function finish(...)
|
||||
if not finished then
|
||||
finished = true
|
||||
progress:close()
|
||||
cb(...)
|
||||
end
|
||||
end
|
||||
|
||||
-- Defer showing the progress to avoid flicker for fast operations
|
||||
vim.defer_fn(function()
|
||||
if not finished then
|
||||
progress:show()
|
||||
progress:show({
|
||||
-- TODO some actions are actually cancelable.
|
||||
-- We should stop them instead of stopping after the current action
|
||||
cancel = function()
|
||||
finish("Canceled")
|
||||
end,
|
||||
})
|
||||
end
|
||||
end, 100)
|
||||
|
||||
local function finish(...)
|
||||
finished = true
|
||||
progress:close()
|
||||
cb(...)
|
||||
end
|
||||
|
||||
local idx = 1
|
||||
local next_action
|
||||
next_action = function()
|
||||
if finished then
|
||||
return
|
||||
end
|
||||
if idx > #actions then
|
||||
finish()
|
||||
return
|
||||
|
|
@ -415,7 +426,10 @@ M.process_actions = function(actions, cb)
|
|||
return finish(adapter)
|
||||
end
|
||||
local callback = vim.schedule_wrap(function(err)
|
||||
if err then
|
||||
if finished then
|
||||
-- This can happen if the user canceled out of the progress window
|
||||
return
|
||||
elseif err then
|
||||
finish(err)
|
||||
else
|
||||
cache.perform_action(action)
|
||||
|
|
|
|||
|
|
@ -45,25 +45,11 @@ end
|
|||
---@param bufnr integer
|
||||
---@param lines string[]
|
||||
local function render_lines(winid, bufnr, lines)
|
||||
-- Finish setting the last line and highlights on the buffer
|
||||
local width = vim.api.nvim_win_get_width(winid)
|
||||
local height = vim.api.nvim_win_get_height(winid)
|
||||
while #lines < height do
|
||||
table.insert(lines, "")
|
||||
end
|
||||
local last_line = "[O]k [C]ancel"
|
||||
local padding = string.rep(" ", math.floor((width - last_line:len()) / 2))
|
||||
local p_len = padding:len()
|
||||
local padded_last_line = padding .. last_line
|
||||
lines[#lines] = padded_last_line
|
||||
vim.bo[bufnr].modifiable = true
|
||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, lines)
|
||||
vim.bo[bufnr].modified = false
|
||||
vim.bo[bufnr].modifiable = false
|
||||
local ns = vim.api.nvim_create_namespace("Oil")
|
||||
vim.api.nvim_buf_clear_namespace(bufnr, ns, #lines - 1, #lines)
|
||||
vim.api.nvim_buf_add_highlight(bufnr, ns, "Special", #lines - 1, p_len, p_len + 3)
|
||||
vim.api.nvim_buf_add_highlight(bufnr, ns, "Special", #lines - 1, p_len + 8, p_len + 11)
|
||||
util.render_text(
|
||||
bufnr,
|
||||
lines,
|
||||
{ v_align = "top", h_align = "left", winid = winid, actions = { "[O]k", "[C]ancel" } }
|
||||
)
|
||||
end
|
||||
|
||||
---@param actions oil.Action[]
|
||||
|
|
@ -170,11 +156,9 @@ M.show = vim.schedule_wrap(function(actions, should_confirm, cb)
|
|||
end,
|
||||
})
|
||||
)
|
||||
vim.keymap.set("n", "q", cancel, { buffer = bufnr })
|
||||
vim.keymap.set("n", "C", cancel, { buffer = bufnr })
|
||||
vim.keymap.set("n", "c", cancel, { buffer = bufnr })
|
||||
vim.keymap.set("n", "<Esc>", cancel, { buffer = bufnr })
|
||||
vim.keymap.set("n", "<C-c>", cancel, { buffer = bufnr })
|
||||
for _, cancel_key in ipairs({ "q", "C", "c", "<C-c>", "<Esc>" }) do
|
||||
vim.keymap.set("n", cancel_key, cancel, { buffer = bufnr, nowait = true })
|
||||
end
|
||||
vim.keymap.set("n", "O", confirm, { buffer = bufnr })
|
||||
vim.keymap.set("n", "o", confirm, { buffer = bufnr })
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ function Progress.new()
|
|||
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||
vim.bo[bufnr].bufhidden = "wipe"
|
||||
return setmetatable({
|
||||
lines = { "", "", "" },
|
||||
lines = { "", "" },
|
||||
count = "",
|
||||
bufnr = bufnr,
|
||||
autocmds = {},
|
||||
}, {
|
||||
|
|
@ -19,17 +20,21 @@ function Progress.new()
|
|||
})
|
||||
end
|
||||
|
||||
function Progress:show()
|
||||
---@param opts nil|table
|
||||
--- cancel fun()
|
||||
function Progress:show(opts)
|
||||
opts = opts or {}
|
||||
if self.winid and vim.api.nvim_win_is_valid(self.winid) then
|
||||
return
|
||||
end
|
||||
self.cancel = opts.cancel
|
||||
local loading_iter = loading.get_bar_iter()
|
||||
self.timer = vim.loop.new_timer()
|
||||
self.timer:start(
|
||||
0,
|
||||
math.floor(1000 / FPS),
|
||||
vim.schedule_wrap(function()
|
||||
self.lines[2] = loading_iter()
|
||||
self.lines[2] = string.format("%s %s", self.count, loading_iter())
|
||||
self:_render()
|
||||
end)
|
||||
)
|
||||
|
|
@ -56,10 +61,13 @@ function Progress:show()
|
|||
end,
|
||||
})
|
||||
)
|
||||
local cancel = self.cancel or function() end
|
||||
vim.keymap.set("n", "c", cancel, { buffer = self.bufnr, nowait = true })
|
||||
vim.keymap.set("n", "C", cancel, { buffer = self.bufnr, nowait = true })
|
||||
end
|
||||
|
||||
function Progress:_render()
|
||||
util.render_centered_text(self.bufnr, self.lines)
|
||||
util.render_text(self.bufnr, self.lines, { winid = self.winid, actions = { "[C]ancel" } })
|
||||
end
|
||||
|
||||
function Progress:_reposition()
|
||||
|
|
@ -93,7 +101,7 @@ function Progress:set_action(action, idx, total)
|
|||
change_line = adapter.render_action(action)
|
||||
end
|
||||
self.lines[1] = change_line
|
||||
self.lines[3] = string.format("[%d/%d]", idx, total)
|
||||
self.count = string.format("%d/%d", idx, total)
|
||||
self:_reposition()
|
||||
self:_render()
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue