feat: can restore Oil progress window when minimized

This commit is contained in:
Steven Arcangeli 2024-04-19 14:16:23 -04:00
parent 78aeb665e2
commit fa3820ebf1
4 changed files with 92 additions and 21 deletions

View file

@ -955,6 +955,14 @@ M.setup = function(opts)
elseif v == "--trash" then elseif v == "--trash" then
trash = true trash = true
table.remove(args.fargs, i) table.remove(args.fargs, i)
elseif v == "--progress" then
local mutator = require("oil.mutator")
if mutator.is_mutating() then
mutator.show_progress()
else
vim.notify("No mutation in progress", vim.log.levels.WARN)
end
return
else else
i = i + 1 i = i + 1
end end

View file

@ -364,6 +364,8 @@ M.enforce_action_order = function(actions)
return ret return ret
end end
local progress
---@param actions oil.Action[] ---@param actions oil.Action[]
---@param cb fun(err: nil|string) ---@param cb fun(err: nil|string)
M.process_actions = function(actions, cb) M.process_actions = function(actions, cb)
@ -390,11 +392,12 @@ M.process_actions = function(actions, cb)
end end
local finished = false local finished = false
local progress = Progress.new() progress = Progress.new()
local function finish(err) local function finish(err)
if not finished then if not finished then
finished = true finished = true
progress:close() progress:close()
progress = nil
vim.api.nvim_exec_autocmds( vim.api.nvim_exec_autocmds(
"User", "User",
{ pattern = "OilActionsPost", modeline = false, data = { err = err, actions = actions } } { pattern = "OilActionsPost", modeline = false, data = { err = err, actions = actions } }
@ -455,6 +458,12 @@ M.process_actions = function(actions, cb)
next_action() next_action()
end end
M.show_progress = function()
if progress then
progress:restore()
end
end
local mutation_in_progress = false local mutation_in_progress = false
---@return boolean ---@return boolean

View file

@ -8,13 +8,11 @@ local Progress = {}
local FPS = 20 local FPS = 20
function Progress.new() function Progress.new()
local bufnr = vim.api.nvim_create_buf(false, true)
vim.bo[bufnr].bufhidden = "wipe"
return setmetatable({ return setmetatable({
lines = { "", "" }, lines = { "", "" },
count = "", count = "",
spinner = "", spinner = "",
bufnr = bufnr, bufnr = nil,
winid = nil, winid = nil,
min_bufnr = nil, min_bufnr = nil,
min_winid = nil, min_winid = nil,
@ -25,6 +23,15 @@ function Progress.new()
}) })
end end
---@private
---@return boolean
function Progress:is_minimized()
return not self.closing
and not self.bufnr
and self.min_bufnr
and vim.api.nvim_buf_is_valid(self.min_bufnr)
end
---@param opts nil|table ---@param opts nil|table
--- cancel fun() --- cancel fun()
function Progress:show(opts) function Progress:show(opts)
@ -32,10 +39,13 @@ function Progress:show(opts)
if self.winid and vim.api.nvim_win_is_valid(self.winid) then if self.winid and vim.api.nvim_win_is_valid(self.winid) then
return return
end end
self.closing = false local bufnr = vim.api.nvim_create_buf(false, true)
self.cancel = opts.cancel vim.bo[bufnr].bufhidden = "wipe"
self.bufnr = bufnr
self.cancel = opts.cancel or self.cancel
local loading_iter = loading.get_bar_iter() local loading_iter = loading.get_bar_iter()
local spinner = loading.get_iter("dots") local spinner = loading.get_iter("dots")
if not self.timer then
self.timer = vim.loop.new_timer() self.timer = vim.loop.new_timer()
self.timer:start( self.timer:start(
0, 0,
@ -46,6 +56,7 @@ function Progress:show(opts)
self:_render() self:_render()
end) end)
) )
end
local width, height = layout.calculate_dims(120, 10, config.progress) local width, height = layout.calculate_dims(120, 10, config.progress)
self.winid = vim.api.nvim_open_win(self.bufnr, true, { self.winid = vim.api.nvim_open_win(self.bufnr, true, {
relative = "editor", relative = "editor",
@ -89,6 +100,16 @@ function Progress:show(opts)
vim.keymap.set("n", "M", minimize, { buffer = self.bufnr, nowait = true }) vim.keymap.set("n", "M", minimize, { buffer = self.bufnr, nowait = true })
end end
function Progress:restore()
if self.closing then
return
elseif not self:is_minimized() then
error("Cannot restore progress window: not minimized")
end
self:_cleanup_minimized_win()
self:show()
end
function Progress:_render() function Progress:_render()
if self.bufnr and vim.api.nvim_buf_is_valid(self.bufnr) then if self.bufnr and vim.api.nvim_buf_is_valid(self.bufnr) then
util.render_text( util.render_text(
@ -139,6 +160,14 @@ function Progress:_cleanup_main_win()
self.bufnr = nil self.bufnr = nil
end end
function Progress:_cleanup_minimized_win()
if self.min_winid and vim.api.nvim_win_is_valid(self.min_winid) then
vim.api.nvim_win_close(self.min_winid, true)
end
self.min_winid = nil
self.min_bufnr = nil
end
function Progress:minimize() function Progress:minimize()
if self.closing then if self.closing then
return return
@ -160,6 +189,7 @@ function Progress:minimize()
self.min_bufnr = bufnr self.min_bufnr = bufnr
self.min_winid = winid self.min_winid = winid
self:_render() self:_render()
vim.notify_once("Restore progress window with :Oil --progress")
end end
---@param action oil.Action ---@param action oil.Action
@ -187,11 +217,7 @@ function Progress:close()
self.timer = nil self.timer = nil
end end
self:_cleanup_main_win() self:_cleanup_main_win()
if self.min_winid and vim.api.nvim_win_is_valid(self.min_winid) then self:_cleanup_minimized_win()
vim.api.nvim_win_close(self.min_winid, true)
end
self.min_winid = nil
self.min_bufnr = nil
end end
return Progress return Progress

28
tests/manual_progress.lua Normal file
View file

@ -0,0 +1,28 @@
-- Manual test for minimizing/restoring progress window
local Progress = require("oil.mutator.progress")
local progress = Progress.new()
progress:show({
cancel = function()
progress:close()
end,
})
for i = 1, 10, 1 do
vim.defer_fn(function()
progress:set_action({
type = "create",
url = string.format("oil:///tmp/test_%d.txt", i),
entry_type = "file",
}, i, 10)
end, (i - 1) * 1000)
end
vim.defer_fn(function()
progress:close()
end, 10000)
vim.keymap.set("n", "R", function()
progress:restore()
end, {})