From 6dc4a48c586201f545a9bac6c1e69474d3059c93 Mon Sep 17 00:00:00 2001 From: Mika Vilpas Date: Wed, 5 Jun 2024 22:09:56 +0300 Subject: [PATCH] fix: open buffers deleted in yazi were not closed When a buffer was opened in neovim and being edited, and then yazi deleted it, the buffer was not closed. I'm not sure what broke it. The fix is to close the buffer asynchronously. I don't understand why that fixes the issue, but it does. `vim.await` is really cool. I found it here: https://www.reddit.com/r/neovim/comments/1cv5q45/comment/l4s2ya0/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button --- lua/yazi/event_handling.lua | 13 +++++++++++-- tests/yazi/delete_spec.lua | 22 ++++++++++++++++------ tests/yazi/trash_spec.lua | 23 +++++++++++++++-------- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/lua/yazi/event_handling.lua b/lua/yazi/event_handling.lua index 22361e1..5f2694a 100644 --- a/lua/yazi/event_handling.lua +++ b/lua/yazi/event_handling.lua @@ -11,6 +11,9 @@ local M = {} function M.process_delete_event(event, remaining_events) local open_buffers = utils.get_open_buffers() + ---@type RenameableBuffer[] + local deleted_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 @@ -26,12 +29,18 @@ function M.process_delete_event(event, remaining_events) if is_renamed_in_later_event then break else - vim.api.nvim_buf_delete(buffer.bufnr, { force = false }) - lsp_delete.file_deleted(buffer.path.filename) + deleted_buffers[#deleted_buffers + 1] = buffer + + vim.schedule(function() + vim.api.nvim_buf_delete(buffer.bufnr, { force = false }) + lsp_delete.file_deleted(buffer.path.filename) + end) end end end end + + return deleted_buffers end ---@param rename_or_move_event YaziEventDataRenameOrMove diff --git a/tests/yazi/delete_spec.lua b/tests/yazi/delete_spec.lua index ce3bf1c..49e3f9b 100644 --- a/tests/yazi/delete_spec.lua +++ b/tests/yazi/delete_spec.lua @@ -22,6 +22,9 @@ describe('process_delete_event', function() event_handling.process_delete_event(event, {}) + vim.wait(1000, function() + return not vim.api.nvim_buf_is_valid(buffer) + end) assert.is_false(vim.api.nvim_buf_is_valid(buffer)) end) @@ -38,11 +41,14 @@ describe('process_delete_event', function() event_handling.process_delete_event(event, {}) + vim.wait(1000, function() + return not vim.api.nvim_buf_is_valid(buffer) + end) assert.is_false(vim.api.nvim_buf_is_valid(buffer)) end) it("doesn't delete a buffer that doesn't match the delete event", function() - local buffer = vim.fn.bufadd('/abc/def') + vim.fn.bufadd('/abc/def') ---@type YaziDeleteEvent local event = { @@ -52,13 +58,16 @@ describe('process_delete_event', function() data = { urls = { '/abc/ghi' } }, } - event_handling.process_delete_event(event, {}) + local deletions = event_handling.process_delete_event(event, {}) - assert.is_true(vim.api.nvim_buf_is_valid(buffer)) + -- NOTE waiting for something not to happen is not possible to do reliably. + -- Inspect the return value so we can at least get some level of + -- confidence. + assert.are.same({}, deletions) end) it("doesn't delete a buffer that was renamed to in a later event", function() - local buffer1 = vim.fn.bufadd('/def/file') + vim.fn.bufadd('/def/file') ---@type YaziDeleteEvent local delete_event = { @@ -76,8 +85,9 @@ describe('process_delete_event', function() data = { from = '/def/other-file', to = '/def/file' }, } - event_handling.process_delete_event(delete_event, { rename_event }) + local deletions = + event_handling.process_delete_event(delete_event, { rename_event }) - assert.is_true(vim.api.nvim_buf_is_valid(buffer1)) + assert.are.same({}, deletions) end) end) diff --git a/tests/yazi/trash_spec.lua b/tests/yazi/trash_spec.lua index c2747d8..16b9fd7 100644 --- a/tests/yazi/trash_spec.lua +++ b/tests/yazi/trash_spec.lua @@ -22,6 +22,10 @@ describe('process_trash_event', function() event_handling.process_delete_event(event, {}) + vim.wait(1000, function() + return not vim.api.nvim_buf_is_valid(buffer) + end) + assert.is_false(vim.api.nvim_buf_is_valid(buffer)) end) @@ -38,11 +42,15 @@ describe('process_trash_event', function() event_handling.process_delete_event(event, {}) + vim.wait(1000, function() + return not vim.api.nvim_buf_is_valid(buffer) + end) + assert.is_false(vim.api.nvim_buf_is_valid(buffer)) end) it("doesn't delete a buffer that doesn't match the trash event", function() - local buffer = vim.fn.bufadd('/abc/def') + vim.fn.bufadd('/abc/def') ---@type YaziTrashEvent local event = { @@ -52,13 +60,12 @@ describe('process_trash_event', function() data = { urls = { '/abc/ghi' } }, } - event_handling.process_delete_event(event, {}) - - assert.is_true(vim.api.nvim_buf_is_valid(buffer)) + local deletions = event_handling.process_delete_event(event, {}) + assert.are.same({}, deletions) end) it("doesn't delete a buffer that was renamed to in a later event", function() - local buffer1 = vim.fn.bufadd('/def/file') + vim.fn.bufadd('/def/file') ---@type YaziTrashEvent local delete_event = { @@ -76,8 +83,8 @@ describe('process_trash_event', function() 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)) + local deletions = + event_handling.process_delete_event(delete_event, { rename_event }) + assert.are.same({}, deletions) end) end)