Skip to content

Commit

Permalink
feat: allow yazi_closed_successfully hook to know the last yazi dir
Browse files Browse the repository at this point in the history
related: #83
  • Loading branch information
mikavilpas committed May 23, 2024
1 parent fe2dac3 commit 4541e44
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 20 deletions.
29 changes: 20 additions & 9 deletions lua/yazi.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ local M = {}
M.yazi_loaded = false

---@param config? YaziConfig?
---@param path? string
---@param input_path? string
---@diagnostic disable-next-line: redefined-local
function M.yazi(config, path)
function M.yazi(config, input_path)
if utils.is_yazi_available() ~= true then
print('Please install yazi. Check documentation for more information')
return
Expand All @@ -21,7 +21,7 @@ function M.yazi(config, path)
config =
vim.tbl_deep_extend('force', configModule.default(), M.config, config or {})

path = utils.selected_file_path(path)
local path = utils.selected_file_path(input_path)

local prev_win = vim.api.nvim_get_current_win()

Expand All @@ -33,8 +33,8 @@ function M.yazi(config, path)

os.remove(config.chosen_file_path)
local cmd = string.format(
'yazi %s --local-events "rename,delete,trash,move" --chooser-file "%s" > "%s"',
vim.fn.shellescape(path),
'yazi %s --local-events "rename,delete,trash,move,cd" --chooser-file "%s" > "%s"',
vim.fn.shellescape(path.filename),
config.chosen_file_path,
config.events_file_path
)
Expand All @@ -53,14 +53,25 @@ function M.yazi(config, path)
return
end

utils.on_yazi_exited(prev_win, win, config)

local events = utils.read_events_file(config.events_file_path)
event_handling.process_events_emitted_from_yazi(events)
local event_info =
event_handling.process_events_emitted_from_yazi(events)

local last_directory = event_info.last_directory
if last_directory == nil then
if path:is_file() then
last_directory = path:parent()
else
last_directory = path
end
end
utils.on_yazi_exited(prev_win, win, config, {
last_directory = event_info.last_directory or path:parent(),
})
end,
})

config.hooks.yazi_opened(path, win.content_buffer, config)
config.hooks.yazi_opened(path.filename, win.content_buffer, config)
config.set_keymappings_function(win.content_buffer, config)
win.on_resized = function(event)
vim.fn.jobresize(job_id, event.win_width, event.win_height)
Expand Down
12 changes: 12 additions & 0 deletions lua/yazi/event_handling.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local utils = require('yazi.utils')
local plenaryIterators = require('plenary.iterators')
local plenary_path = require('plenary.path')
local lsp_delete = require('yazi.lsp.delete')
local lsp_rename = require('yazi.lsp.rename')

Expand Down Expand Up @@ -58,9 +59,13 @@ function M.get_buffers_that_need_renaming_after_yazi_exited(
end

---@param events YaziEvent[]
---@return {last_directory?: Path}
function M.process_events_emitted_from_yazi(events)
-- process events emitted from yazi

---@type Path | nil
local last_directory = nil

for i, event in ipairs(events) do
if event.type == 'rename' then
---@cast event YaziRenameEvent
Expand Down Expand Up @@ -91,8 +96,15 @@ function M.process_events_emitted_from_yazi(events)
local remaining_events = vim.list_slice(events, i)
---@cast event YaziTrashEvent
M.process_delete_event(event, remaining_events)
elseif event.type == 'cd' then
---@cast event YaziChangeDirectoryEvent
if event.url ~= nil and event.url ~= '' then
last_directory = plenary_path:new(event.url)
end
end
end

return { last_directory = last_directory }
end

return M
13 changes: 11 additions & 2 deletions lua/yazi/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@

---@class YaziConfigHooks
---@field public yazi_opened fun(preselected_path: string | nil, buffer: integer, config: YaziConfig):nil
---@field public yazi_closed_successfully fun(chosen_file: string | nil, config: YaziConfig): nil
---@field public yazi_closed_successfully fun(chosen_file: string | nil, config: YaziConfig, state: YaziClosedState): nil
---@field public yazi_opened_multiple_files fun(chosen_files: string[], config: YaziConfig): nil

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

---@class 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

---@class YaziRenameEvent
---@field public type "rename"
Expand Down Expand Up @@ -46,6 +49,12 @@
---@field public id string
---@field public data {urls: string[]}

---@class YaziChangeDirectoryEvent
---@field public type "cd"
---@field public timestamp string
---@field public id string
---@field public url string

---@class yazi.AutoCmdEvent # the nvim_create_autocmd() event object copied from the nvim help docs
---@field public id number
---@field public event string
Expand Down
28 changes: 24 additions & 4 deletions lua/yazi/utils.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local fn = vim.fn
local RenameableBuffer = require('yazi.renameable_buffer')
local plenary_path = require('plenary.path')

local M = {}

Expand All @@ -19,7 +20,7 @@ function M.file_exists(name)
end

---@param path string?
---@return string
---@return Path
function M.selected_file_path(path)
if path == '' or path == nil then
path = vim.fn.expand('%:p')
Expand All @@ -31,7 +32,7 @@ function M.selected_file_path(path)
path = vim.fn.expand('%:p')
end

return path
return plenary_path:new(path)
end

-- Returns parsed events from the yazi events file
Expand Down Expand Up @@ -109,6 +110,22 @@ function M.parse_events(events_file_lines)
data = vim.fn.json_decode(data_string),
}
table.insert(events, event)
elseif type == 'cd' then
-- example of a change directory (cd) event:
-- cd,1716307611001689,1716307611001689,{"tab":0,"url":"/tmp/test-directory"}

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

---@type YaziChangeDirectoryEvent
local event = {
type = type,
timestamp = timestamp,
id = id,
url = vim.fn.json_decode(data_string)['url'],
}
table.insert(events, event)
end
end

Expand Down Expand Up @@ -177,7 +194,8 @@ end
---@param prev_win integer
---@param window YaziFloatingWindow
---@param config YaziConfig
function M.on_yazi_exited(prev_win, window, config)
---@param state YaziClosedState
function M.on_yazi_exited(prev_win, window, config, state)
vim.cmd('silent! :checktime')

-- open the file that was chosen
Expand All @@ -195,11 +213,13 @@ function M.on_yazi_exited(prev_win, window, config)
config.hooks.yazi_opened_multiple_files(chosen_files, config)
else
local chosen_file = chosen_files[1]
config.hooks.yazi_closed_successfully(chosen_file, config)
config.hooks.yazi_closed_successfully(chosen_file, config, state)
if chosen_file then
config.open_file_function(chosen_file, config)
end
end
else
config.hooks.yazi_closed_successfully(nil, config, state)
end
end

Expand Down
2 changes: 1 addition & 1 deletion tests/yazi/open_dir_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('when the user set open_for_directories = true', function()
vim.api.nvim_command('edit /')

assert.stub(api_mock.termopen).was_called_with(
'yazi \'/\' --local-events "rename,delete,trash,move" --chooser-file "/tmp/yazi_filechosen" > "/tmp/yazi.nvim.events.txt"',
'yazi \'/\' --local-events "rename,delete,trash,move,cd" --chooser-file "/tmp/yazi_filechosen" > "/tmp/yazi.nvim.events.txt"',
match.is_table()
)
end)
Expand Down
10 changes: 6 additions & 4 deletions tests/yazi/yazi_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ describe('opening a file', function()
})

assert.stub(api_mock.termopen).was_called_with(
'yazi \'/abc/test file-$1.txt\' --local-events "rename,delete,trash,move" --chooser-file "/tmp/yazi_filechosen" > "/tmp/yazi.nvim.events.txt"',
'yazi \'/abc/test file-$1.txt\' --local-events "rename,delete,trash,move,cd" --chooser-file "/tmp/yazi_filechosen" > "/tmp/yazi.nvim.events.txt"',
match.is_table()
)
end)
Expand All @@ -56,7 +56,7 @@ describe('opening a file', function()
})

assert.stub(api_mock.termopen).was_called_with(
'yazi \'/tmp/\' --local-events "rename,delete,trash,move" --chooser-file "/tmp/yazi_filechosen" > "/tmp/yazi.nvim.events.txt"',
'yazi \'/tmp/\' --local-events "rename,delete,trash,move,cd" --chooser-file "/tmp/yazi_filechosen" > "/tmp/yazi.nvim.events.txt"',
match.is_table()
)
end)
Expand Down Expand Up @@ -92,8 +92,10 @@ describe('opening a file', function()
function()
local target_file = '/abc/test-file-potato.txt'
setup_fake_yazi_opens_file(target_file)
local spy_hook = spy.new(function(chosen_file)
---@param state YaziClosedState
local spy_hook = spy.new(function(chosen_file, _config, state)
assert.equals('/abc/test-file-potato.txt', chosen_file)
assert.equals('/abc', state.last_directory.filename)
end)

vim.api.nvim_command('edit /abc/test-file.txt')
Expand All @@ -110,7 +112,7 @@ describe('opening a file', function()

assert
.spy(spy_hook)
.was_called_with('/abc/test-file-potato.txt', match.is_table())
.was_called_with('/abc/test-file-potato.txt', match.is_table(), match.is_table())
end
)

Expand Down

0 comments on commit 4541e44

Please sign in to comment.