mirror of
https://github.com/zoriya/jj.nvim.git
synced 2026-08-05 18:56:13 +00:00
134 lines
3.4 KiB
Lua
134 lines
3.4 KiB
Lua
--- @class jj.cmd.status
|
|
local M = {}
|
|
|
|
local utils = require("jj.utils")
|
|
local runner = require("jj.core.runner")
|
|
local parser = require("jj.core.parser")
|
|
local terminal = require("jj.ui.terminal")
|
|
local jj_args = require("jj.core.args")
|
|
|
|
--- Handle restoring a file from the jj status buffer
|
|
--- Supports both renamed and non-renamed files
|
|
function M.handle_status_restore()
|
|
local lines = utils.get_visual_selection(terminal.state.buf)
|
|
if not lines then
|
|
lines = { vim.api.nvim_get_current_line() }
|
|
end
|
|
|
|
--- @type jj.core.parser.status_file[]
|
|
local files = {}
|
|
|
|
for _, line in ipairs(lines) do
|
|
local file_info = parser.parse_file_info_from_status_line(line)
|
|
if file_info then
|
|
table.insert(files, file_info)
|
|
end
|
|
end
|
|
|
|
-- Return early if no files were found in the selection
|
|
if #files == 0 then
|
|
utils.notify("No files selected to restore", vim.log.levels.WARN)
|
|
return
|
|
end
|
|
|
|
-- For each file found restore it
|
|
local cmd = { "jj", "restore" }
|
|
for _, file in ipairs(files) do
|
|
if file.is_rename then
|
|
-- If it's a rename add both old and new paths to the restore command
|
|
vim.list_extend(cmd, { jj_args.fileset(file.old_path), jj_args.fileset(file.new_path) })
|
|
else
|
|
table.insert(cmd, jj_args.fileset(file.old_path))
|
|
end
|
|
end
|
|
|
|
local _, restore_success = runner.execute(cmd, "Failed to restore original file")
|
|
if restore_success then
|
|
local notif_msg = "Restored file:\n"
|
|
if #files > 1 then
|
|
notif_msg = "Restored files:\n"
|
|
end
|
|
|
|
for _, file in ipairs(files) do
|
|
if file.is_rename then
|
|
notif_msg = notif_msg .. "- `" .. file.old_path .. "` -> `" .. file.new_path .. "`\n"
|
|
else
|
|
notif_msg = notif_msg .. "- `" .. file.old_path .. "`\n"
|
|
end
|
|
end
|
|
utils.notify(notif_msg, vim.log.levels.INFO)
|
|
M.status() -- Refresh the status buffer after restoring files
|
|
end
|
|
end
|
|
|
|
--- Handle opening a file from the jj status buffer
|
|
function M.handle_status_enter()
|
|
local file_info = parser.parse_file_info_from_status_line(vim.api.nvim_get_current_line())
|
|
|
|
if not file_info then
|
|
return
|
|
end
|
|
|
|
if require("jj").config.terminal.window.type == "floating" then
|
|
terminal.close_floating_buffer()
|
|
end
|
|
|
|
local filepath = file_info.new_path
|
|
local stat = vim.uv.fs_stat(filepath)
|
|
if not stat then
|
|
utils.notify("File not found: " .. filepath, vim.log.levels.ERROR)
|
|
return
|
|
end
|
|
|
|
-- Go to the previous window (split above)
|
|
vim.cmd("wincmd p")
|
|
|
|
-- Open the file in that window, replacing current buffer
|
|
vim.cmd("edit " .. vim.fn.fnameescape(filepath))
|
|
end
|
|
|
|
--- Resolve status keymaps from config
|
|
--- @return jj.core.buffer.keymap[]
|
|
function M.status_keymaps()
|
|
local cmd = require("jj.cmd")
|
|
local cfg = cmd.config.keymaps.status or {}
|
|
|
|
--- @type jj.cmd.keymap_specs
|
|
local specs = {
|
|
open_file = {
|
|
desc = "Open file under cursor",
|
|
handler = M.handle_status_enter,
|
|
modes = { "n" },
|
|
},
|
|
restore_file = {
|
|
desc = "Restore file under cursor",
|
|
handler = M.handle_status_restore,
|
|
modes = { "n", "v" },
|
|
},
|
|
}
|
|
|
|
return cmd.resolve_keymaps_from_specs(cfg, specs)
|
|
end
|
|
|
|
--- Jujutsu status
|
|
--- @param opts? table Options for the status command
|
|
function M.status(opts)
|
|
if not utils.ensure_jj() then
|
|
return
|
|
end
|
|
|
|
local cmd = { "jj", "status", "--no-pager" }
|
|
|
|
if opts and opts.notify then
|
|
local output, success = runner.execute(cmd, "Failed to get status")
|
|
if success then
|
|
utils.notify(output and output or "", vim.log.levels.INFO)
|
|
end
|
|
else
|
|
-- Default behavior: show in buffer
|
|
terminal.run(cmd, M.status_keymaps())
|
|
end
|
|
end
|
|
|
|
return M
|