Skip to content

Commit

Permalink
fix: not handling bulk renaming events correctly
Browse files Browse the repository at this point in the history
This commit fixes a bug where yazi.nvim would not handle bulk renaming
events like rename,move,delete events are handled. This bug had the
following impact:

- open buffers would not be renamed after a bulk rename operation
- LSP servers would not be notified of the rename operation
  • Loading branch information
mikavilpas committed Jul 12, 2024
1 parent b8f0f65 commit 607db68
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,30 +65,64 @@ describe("opening files", () => {
})
})

it("can bulk rename files", () => {
startNeovimWithYa().then((_dir) => {
// in yazi, bulk renaming is done by
// - selecting files and pressing "r".
// - It opens the editor with the names of the selected files.
// - Next, the editor must make changes to the file names and save the
// file.
// - Finally, yazi should rename the files to match the new names.
cy.typeIntoTerminal("{upArrow}")
cy.typeIntoTerminal("{control+a}r")
describe("bulk renaming", () => {
it("can bulk rename files", () => {
startNeovimWithYa().then((_dir) => {
// in yazi, bulk renaming is done by
// - selecting files and pressing "r".
// - It opens the editor with the names of the selected files.
// - Next, the editor must make changes to the file names and save the
// file.
// - Finally, yazi should rename the files to match the new names.
cy.typeIntoTerminal("{upArrow}")
cy.typeIntoTerminal("{control+a}r")

// yazi should now have opened an embedded Neovim. The file name should say
// "bulk" somewhere to indicate this
cy.contains(new RegExp("yazi/bulk-\\d+"))

// edit the name of the first file
cy.typeIntoTerminal("xxx")
cy.typeIntoTerminal(":xa{enter}")

// yazi must now ask for confirmation
cy.contains("Continue to rename? (y/N):")

// answer yes
cy.typeIntoTerminal("y{enter}")
})
})

it("can rename a buffer that's open in Neovim", () => {
startNeovimWithYa().then((_dir) => {
cy.typeIntoTerminal("{upArrow}")
// select only the current file to make the test easier
cy.typeIntoTerminal("v")
cy.typeIntoTerminal("r") // start renaming

// yazi should now have opened an embedded Neovim. The file name should say
// "bulk" somewhere to indicate this
cy.contains(new RegExp("yazi/bulk-\\d+"))

// edit the name of the file
cy.typeIntoTerminal("cc")
cy.typeIntoTerminal("renamed-file.txt{esc}")
cy.typeIntoTerminal(":xa{enter}")

// yazi must now ask for confirmation
cy.contains("Continue to rename? (y/N):")

// yazi should now have opened an embedded Neovim. The file name should say
// "bulk" somewhere to indicate this
cy.contains(new RegExp("yazi/bulk-\\d+"))
// answer yes
cy.typeIntoTerminal("y{enter}")

// edit the name of the first file
cy.typeIntoTerminal("xxx")
cy.typeIntoTerminal(":xa{enter}")
// close yazi
cy.typeIntoTerminal("q")

// yazi must now ask for confirmation
cy.contains("Continue to rename? (y/N):")
// the file should now be renamed - ask neovim to confirm this
cy.typeIntoTerminal(":buffers{enter}")

// answer yes
cy.typeIntoTerminal("y{enter}")
cy.contains("renamed-file.txt")
})
})
})

Expand Down
14 changes: 14 additions & 0 deletions lua/yazi/event_handling.lua
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,20 @@ function M.process_events_emitted_from_yazi(events)
utils.rename_or_close_buffer(instruction)
end
end
elseif event.type == 'bulk' then
---@cast event YaziBulkEvent
for from, to in pairs(event.changes) do
lsp_rename.file_renamed(from, to)

local rename_instructions =
M.get_buffers_that_need_renaming_after_yazi_exited({
from = from,
to = to,
})
for _, instruction in ipairs(rename_instructions) do
utils.rename_or_close_buffer(instruction)
end
end
elseif event.type == 'delete' then
local remaining_events = vim.list_slice(events, i)
---@cast event YaziDeleteEvent
Expand Down
2 changes: 1 addition & 1 deletion lua/yazi/process/ya_process.lua
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function YaProcess:wait(timeout)
end

function YaProcess:start()
local ya_command = { 'ya', 'sub', 'rename,delete,trash,move,cd,hover' }
local ya_command = { 'ya', 'sub', 'rename,delete,trash,move,cd,hover,bulk' }
Log:debug(
string.format(
'Opening ya with the command: (%s), attempt %s',
Expand Down
6 changes: 5 additions & 1 deletion lua/yazi/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
---@class (exact) YaziConfigHighlightGroups # Defines the highlight groups that will be used in yazi
---@field public hovered_buffer_background? vim.api.keyset.highlight # the color of the background of buffer that is hovered over

---@alias YaziEvent YaziRenameEvent | YaziMoveEvent | YaziDeleteEvent | YaziTrashEvent | YaziChangeDirectoryEvent | YaziHoverEvent
---@alias YaziEvent YaziRenameEvent | YaziMoveEvent | YaziDeleteEvent | YaziTrashEvent | YaziChangeDirectoryEvent | YaziHoverEvent | YaziBulkEvent

---@class (exact) YaziClosedState # describes the state of yazi when it was closed; the last known state
---@field public last_directory Path # the last directory that yazi was in before it was closed
Expand Down Expand Up @@ -72,6 +72,10 @@
---@field public type "hover"
---@field public url string

---@class (exact) YaziBulkEvent "Like `rename` and `move` but for bulk renaming"
---@field public type "bulk"
---@field public changes table<string, string> # a table of old paths to new paths

---@class (exact) yazi.AutoCmdEvent # the nvim_create_autocmd() event object copied from the nvim help docs
---@field public id number
---@field public event string
Expand Down
12 changes: 11 additions & 1 deletion lua/yazi/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,20 @@ function M.parse_events(events_file_lines)
data = vim.json.decode(data_string),
}
table.insert(events, event)
elseif type == 'bulk' then
-- example of a bulk event:
-- bulk,0,1720800121065599,{"changes":{"/tmp/test-directory/test":"/tmp/test-directory/test2"}}
local data = vim.json.decode(table.concat(parts, ',', 4, #parts))

---@type YaziBulkEvent
local event = {
type = 'bulk',
changes = data['changes'],
}
table.insert(events, event)
elseif type == 'delete' then
-- example of a delete event:
-- delete,1712766606832135,1712766606832135,{"urls":["/tmp/test-directory/test_2"]}

local timestamp = parts[2]
local id = parts[3]
local data_string = table.concat(parts, ',', 4, #parts)
Expand Down

0 comments on commit 607db68

Please sign in to comment.