Skip to content

Commit

Permalink
feat: can restore Oil progress window when minimized
Browse files Browse the repository at this point in the history
  • Loading branch information
stevearc committed Apr 19, 2024
1 parent 78aeb66 commit fa3820e
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 21 deletions.
8 changes: 8 additions & 0 deletions lua/oil/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,14 @@ M.setup = function(opts)
elseif v == "--trash" then
trash = true
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
i = i + 1
end
Expand Down
11 changes: 10 additions & 1 deletion lua/oil/mutator/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ M.enforce_action_order = function(actions)
return ret
end

local progress

---@param actions oil.Action[]
---@param cb fun(err: nil|string)
M.process_actions = function(actions, cb)
Expand All @@ -390,11 +392,12 @@ M.process_actions = function(actions, cb)
end

local finished = false
local progress = Progress.new()
progress = Progress.new()
local function finish(err)
if not finished then
finished = true
progress:close()
progress = nil
vim.api.nvim_exec_autocmds(
"User",
{ pattern = "OilActionsPost", modeline = false, data = { err = err, actions = actions } }
Expand Down Expand Up @@ -455,6 +458,12 @@ M.process_actions = function(actions, cb)
next_action()
end

M.show_progress = function()
if progress then
progress:restore()
end
end

local mutation_in_progress = false

---@return boolean
Expand Down
66 changes: 46 additions & 20 deletions lua/oil/mutator/progress.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ local Progress = {}
local FPS = 20

function Progress.new()
local bufnr = vim.api.nvim_create_buf(false, true)
vim.bo[bufnr].bufhidden = "wipe"
return setmetatable({
lines = { "", "" },
count = "",
spinner = "",
bufnr = bufnr,
bufnr = nil,
winid = nil,
min_bufnr = nil,
min_winid = nil,
Expand All @@ -25,27 +23,40 @@ function Progress.new()
})
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
--- 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.closing = false
self.cancel = opts.cancel
local bufnr = vim.api.nvim_create_buf(false, true)
vim.bo[bufnr].bufhidden = "wipe"
self.bufnr = bufnr
self.cancel = opts.cancel or self.cancel
local loading_iter = loading.get_bar_iter()
local spinner = loading.get_iter("dots")
self.timer = vim.loop.new_timer()
self.timer:start(
0,
math.floor(1000 / FPS),
vim.schedule_wrap(function()
self.lines[2] = string.format("%s %s", self.count, loading_iter())
self.spinner = spinner()
self:_render()
end)
)
if not self.timer then
self.timer = vim.loop.new_timer()
self.timer:start(
0,
math.floor(1000 / FPS),
vim.schedule_wrap(function()
self.lines[2] = string.format("%s %s", self.count, loading_iter())
self.spinner = spinner()
self:_render()
end)
)
end
local width, height = layout.calculate_dims(120, 10, config.progress)
self.winid = vim.api.nvim_open_win(self.bufnr, true, {
relative = "editor",
Expand Down Expand Up @@ -89,6 +100,16 @@ function Progress:show(opts)
vim.keymap.set("n", "M", minimize, { buffer = self.bufnr, nowait = true })
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()
if self.bufnr and vim.api.nvim_buf_is_valid(self.bufnr) then
util.render_text(
Expand Down Expand Up @@ -139,6 +160,14 @@ function Progress:_cleanup_main_win()
self.bufnr = nil
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()
if self.closing then
return
Expand All @@ -160,6 +189,7 @@ function Progress:minimize()
self.min_bufnr = bufnr
self.min_winid = winid
self:_render()
vim.notify_once("Restore progress window with :Oil --progress")
end

---@param action oil.Action
Expand Down Expand Up @@ -187,11 +217,7 @@ function Progress:close()
self.timer = nil
end
self:_cleanup_main_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
self:_cleanup_minimized_win()
end

return Progress
28 changes: 28 additions & 0 deletions tests/manual_progress.lua
Original file line number Diff line number Diff line change
@@ -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, {})

0 comments on commit fa3820e

Please sign in to comment.