diff --git a/lua/yazi/event_handling.lua b/lua/yazi/event_handling.lua index 5e1eb8f5..6f19f719 100644 --- a/lua/yazi/event_handling.lua +++ b/lua/yazi/event_handling.lua @@ -1,16 +1,30 @@ local utils = require('yazi.utils') +local plenaryIterators = require('plenary.iterators') local M = {} ---@param event YaziDeleteEvent | YaziTrashEvent -function M.process_delete_event(event) +---@param remaining_events YaziEvent[] +function M.process_delete_event(event, remaining_events) local open_buffers = utils.get_open_buffers() for _, buffer in ipairs(open_buffers) do for _, url in ipairs(event.data.urls) do if buffer:matches_exactly(url) or buffer:matches_parent(url) then - -- allow the user to cancel the deletion - vim.api.nvim_buf_delete(buffer.bufnr, { force = false }) + local is_renamed_in_later_event = plenaryIterators + .iter(remaining_events) + :find( + ---@param e YaziEvent + function(e) + return e.type == 'rename' and e.data.to == url + end + ) + + if is_renamed_in_later_event then + break + else + vim.api.nvim_buf_delete(buffer.bufnr, { force = false }) + end end end end @@ -43,7 +57,7 @@ function M.process_events_emitted_from_yazi(config) -- process events emitted from yazi local events = utils.read_events_file(config.events_file_path) - for _, event in ipairs(events) do + for i, event in ipairs(events) do if event.type == 'rename' then ---@cast event YaziRenameEvent local rename_instructions = @@ -64,12 +78,14 @@ function M.process_events_emitted_from_yazi(config) end end elseif event.type == 'delete' then + local remaining_events = vim.list_slice(events, i) ---@cast event YaziDeleteEvent - M.process_delete_event(event) + M.process_delete_event(event, remaining_events) elseif event.type == 'trash' then -- selene: allow(if_same_then_else) + local remaining_events = vim.list_slice(events, i) ---@cast event YaziTrashEvent - M.process_delete_event(event) + M.process_delete_event(event, remaining_events) end end end diff --git a/tests/yazi/delete_spec.lua b/tests/yazi/delete_spec.lua index b60e7e4c..ce3bf1c8 100644 --- a/tests/yazi/delete_spec.lua +++ b/tests/yazi/delete_spec.lua @@ -20,7 +20,7 @@ describe('process_delete_event', function() data = { urls = { '/abc/def' } }, } - event_handling.process_delete_event(event) + event_handling.process_delete_event(event, {}) assert.is_false(vim.api.nvim_buf_is_valid(buffer)) end) @@ -36,7 +36,7 @@ describe('process_delete_event', function() data = { urls = { '/abc' } }, } - event_handling.process_delete_event(event) + event_handling.process_delete_event(event, {}) assert.is_false(vim.api.nvim_buf_is_valid(buffer)) end) @@ -52,8 +52,32 @@ describe('process_delete_event', function() data = { urls = { '/abc/ghi' } }, } - event_handling.process_delete_event(event) + event_handling.process_delete_event(event, {}) assert.is_true(vim.api.nvim_buf_is_valid(buffer)) end) + + it("doesn't delete a buffer that was renamed to in a later event", function() + local buffer1 = vim.fn.bufadd('/def/file') + + ---@type YaziDeleteEvent + local delete_event = { + type = 'delete', + timestamp = '1712766606832135', + id = '1712766606832135', + data = { urls = { '/def/file' } }, + } + + ---@type YaziRenameEvent + local rename_event = { + type = 'rename', + timestamp = '1712766606832135', + id = '1712766606832135', + data = { from = '/def/other-file', to = '/def/file' }, + } + + event_handling.process_delete_event(delete_event, { rename_event }) + + assert.is_true(vim.api.nvim_buf_is_valid(buffer1)) + end) end) diff --git a/tests/yazi/trash_spec.lua b/tests/yazi/trash_spec.lua index c570cc8b..c2747d80 100644 --- a/tests/yazi/trash_spec.lua +++ b/tests/yazi/trash_spec.lua @@ -20,7 +20,7 @@ describe('process_trash_event', function() data = { urls = { '/abc/def' } }, } - event_handling.process_delete_event(event) + event_handling.process_delete_event(event, {}) assert.is_false(vim.api.nvim_buf_is_valid(buffer)) end) @@ -36,7 +36,7 @@ describe('process_trash_event', function() data = { urls = { '/abc' } }, } - event_handling.process_delete_event(event) + event_handling.process_delete_event(event, {}) assert.is_false(vim.api.nvim_buf_is_valid(buffer)) end) @@ -52,8 +52,32 @@ describe('process_trash_event', function() data = { urls = { '/abc/ghi' } }, } - event_handling.process_delete_event(event) + event_handling.process_delete_event(event, {}) assert.is_true(vim.api.nvim_buf_is_valid(buffer)) end) + + it("doesn't delete a buffer that was renamed to in a later event", function() + local buffer1 = vim.fn.bufadd('/def/file') + + ---@type YaziTrashEvent + local delete_event = { + type = 'trash', + timestamp = '1712766606832135', + id = '1712766606832135', + data = { urls = { '/def/file' } }, + } + + ---@type YaziRenameEvent + local rename_event = { + type = 'rename', + timestamp = '1712766606832135', + id = '1712766606832135', + data = { from = '/def/other-file', to = '/def/file' }, + } + + event_handling.process_delete_event(delete_event, { rename_event }) + + assert.is_true(vim.api.nvim_buf_is_valid(buffer1)) + end) end)