From 82aa8a4e885a54aa636755f45855b0a6ecf56963 Mon Sep 17 00:00:00 2001 From: Mika Vilpas Date: Sun, 14 Apr 2024 08:08:22 +0300 Subject: [PATCH] fix: don't close a removed file if renamed to later sometimes I find myself renaming a file to a new name, and then renaming it back to the original name. This causes the file to be closed and then opened again, which is not necessary. This commit fixes this issue by checking if the file is already open before closing it. --- lua/yazi/event_handling.lua | 28 ++++++++++++++++++++++------ tests/yazi/delete_spec.lua | 30 +++++++++++++++++++++++++++--- tests/yazi/trash_spec.lua | 30 +++++++++++++++++++++++++++--- 3 files changed, 76 insertions(+), 12 deletions(-) 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)