fix: new oil buffers are nomodifiable during mutation processing
This commit is contained in:
parent
931453fc09
commit
d631d9fc5a
3 changed files with 43 additions and 10 deletions
|
|
@ -431,19 +431,24 @@ M.process_actions = function(actions, cb)
|
||||||
next_action()
|
next_action()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local mutation_in_progress = false
|
||||||
|
|
||||||
---@param confirm nil|boolean
|
---@param confirm nil|boolean
|
||||||
M.try_write_changes = function(confirm)
|
M.try_write_changes = function(confirm)
|
||||||
|
if mutation_in_progress then
|
||||||
|
error("Cannot perform mutation when already in progress")
|
||||||
|
return
|
||||||
|
end
|
||||||
local current_buf = vim.api.nvim_get_current_buf()
|
local current_buf = vim.api.nvim_get_current_buf()
|
||||||
local was_modified = vim.bo.modified
|
local was_modified = vim.bo.modified
|
||||||
local buffers = view.get_all_buffers()
|
local buffers = view.get_all_buffers()
|
||||||
local all_diffs = {}
|
local all_diffs = {}
|
||||||
local all_errors = {}
|
local all_errors = {}
|
||||||
|
|
||||||
local was_modifiable = {}
|
mutation_in_progress = true
|
||||||
|
-- Lock the buffer to prevent race conditions from the user modifying them during parsing
|
||||||
|
view.lock_buffers()
|
||||||
for _, bufnr in ipairs(buffers) do
|
for _, bufnr in ipairs(buffers) do
|
||||||
was_modifiable[bufnr] = vim.bo[bufnr].modifiable
|
|
||||||
-- Lock the buffer to prevent race conditions
|
|
||||||
vim.bo[bufnr].modifiable = false
|
|
||||||
if vim.bo[bufnr].modified then
|
if vim.bo[bufnr].modified then
|
||||||
local diffs, errors = parser.parse(bufnr)
|
local diffs, errors = parser.parse(bufnr)
|
||||||
all_diffs[bufnr] = diffs
|
all_diffs[bufnr] = diffs
|
||||||
|
|
@ -453,13 +458,12 @@ M.try_write_changes = function(confirm)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function unlock()
|
local function unlock()
|
||||||
for _, bufnr in ipairs(buffers) do
|
view.unlock_buffers()
|
||||||
pcall(vim.api.nvim_buf_set_option, bufnr, "modifiable", was_modifiable[bufnr])
|
|
||||||
end
|
|
||||||
-- The ":write" will set nomodified even if we cancel here, so we need to restore it
|
-- The ":write" will set nomodified even if we cancel here, so we need to restore it
|
||||||
if was_modified then
|
if was_modified then
|
||||||
vim.bo[current_buf].modified = true
|
vim.bo[current_buf].modified = true
|
||||||
end
|
end
|
||||||
|
mutation_in_progress = false
|
||||||
end
|
end
|
||||||
|
|
||||||
local ns = vim.api.nvim_create_namespace("Oil")
|
local ns = vim.api.nvim_create_namespace("Oil")
|
||||||
|
|
@ -500,8 +504,10 @@ M.try_write_changes = function(confirm)
|
||||||
M.process_actions(
|
M.process_actions(
|
||||||
actions,
|
actions,
|
||||||
vim.schedule_wrap(function(err)
|
vim.schedule_wrap(function(err)
|
||||||
|
view.unlock_buffers()
|
||||||
if err then
|
if err then
|
||||||
vim.notify(string.format("[oil] Error applying actions: %s", err), vim.log.levels.ERROR)
|
vim.notify(string.format("[oil] Error applying actions: %s", err), vim.log.levels.ERROR)
|
||||||
|
view.rerender_all_oil_buffers({ preserve_undo = false })
|
||||||
else
|
else
|
||||||
local current_entry = oil.get_cursor_entry()
|
local current_entry = oil.get_cursor_entry()
|
||||||
if current_entry then
|
if current_entry then
|
||||||
|
|
@ -513,6 +519,7 @@ M.try_write_changes = function(confirm)
|
||||||
end
|
end
|
||||||
view.rerender_all_oil_buffers({ preserve_undo = M.trash })
|
view.rerender_all_oil_buffers({ preserve_undo = M.trash })
|
||||||
end
|
end
|
||||||
|
mutation_in_progress = false
|
||||||
end)
|
end)
|
||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,9 @@ function Progress:close()
|
||||||
self.timer = nil
|
self.timer = nil
|
||||||
end
|
end
|
||||||
if self.winid then
|
if self.winid then
|
||||||
|
if vim.api.nvim_win_is_valid(self.winid) then
|
||||||
vim.api.nvim_win_close(self.winid, true)
|
vim.api.nvim_win_close(self.winid, true)
|
||||||
|
end
|
||||||
self.winid = nil
|
self.winid = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,30 @@ M.get_all_buffers = function()
|
||||||
return vim.tbl_filter(vim.api.nvim_buf_is_loaded, vim.tbl_keys(session))
|
return vim.tbl_filter(vim.api.nvim_buf_is_loaded, vim.tbl_keys(session))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local buffers_locked = false
|
||||||
|
---Make all oil buffers nomodifiable
|
||||||
|
M.lock_buffers = function()
|
||||||
|
buffers_locked = true
|
||||||
|
for bufnr in pairs(session) do
|
||||||
|
if vim.api.nvim_buf_is_loaded(bufnr) then
|
||||||
|
vim.bo[bufnr].modifiable = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---Restore normal modifiable settings for oil buffers
|
||||||
|
M.unlock_buffers = function()
|
||||||
|
buffers_locked = false
|
||||||
|
for bufnr in pairs(session) do
|
||||||
|
if vim.api.nvim_buf_is_loaded(bufnr) then
|
||||||
|
local adapter = util.get_adapter(bufnr)
|
||||||
|
if adapter then
|
||||||
|
vim.bo[bufnr].modifiable = adapter.is_modifiable(bufnr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---@param opts table
|
---@param opts table
|
||||||
---@note
|
---@note
|
||||||
--- This DISCARDS ALL MODIFICATIONS a user has made to oil buffers
|
--- This DISCARDS ALL MODIFICATIONS a user has made to oil buffers
|
||||||
|
|
@ -350,7 +374,7 @@ local function render_buffer(bufnr, opts)
|
||||||
})
|
})
|
||||||
local scheme = util.parse_url(bufname)
|
local scheme = util.parse_url(bufname)
|
||||||
local adapter = util.get_adapter(bufnr)
|
local adapter = util.get_adapter(bufnr)
|
||||||
if not adapter then
|
if not scheme or not adapter then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local entries = cache.list_url(bufname)
|
local entries = cache.list_url(bufname)
|
||||||
|
|
@ -539,7 +563,7 @@ M.render_buffer_async = function(bufnr, opts, callback)
|
||||||
if not preserve_undo then
|
if not preserve_undo then
|
||||||
vim.bo[bufnr].undolevels = vim.api.nvim_get_option("undolevels")
|
vim.bo[bufnr].undolevels = vim.api.nvim_get_option("undolevels")
|
||||||
end
|
end
|
||||||
vim.bo[bufnr].modifiable = adapter.is_modifiable(bufnr)
|
vim.bo[bufnr].modifiable = not buffers_locked and adapter.is_modifiable(bufnr)
|
||||||
if callback then
|
if callback then
|
||||||
callback()
|
callback()
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue