mirror of
https://github.com/zoriya/jj.nvim.git
synced 2026-08-15 23:53:18 +00:00
fix(filesets): Correclty escape filesets in different commands to avoid
special characters breaking jj's parsing
This commit is contained in:
@@ -20,7 +20,9 @@ function M.resolve(opts)
|
||||
-- Extra arguments
|
||||
vim.list_extend(cmd_args, args)
|
||||
-- Append the filestes
|
||||
vim.list_extend(cmd_args, filesets)
|
||||
for _, fileset in ipairs(filesets) do
|
||||
table.insert(cmd_args, utils.escape_fileset(fileset))
|
||||
end
|
||||
|
||||
local escaped_cmd_args = {}
|
||||
for _, arg in ipairs(cmd_args) do
|
||||
|
||||
@@ -25,7 +25,7 @@ local function build_split_command(opts)
|
||||
|
||||
if opts.filesets then
|
||||
for _, fileset in ipairs(opts.filesets) do
|
||||
table.insert(args, fileset)
|
||||
table.insert(args, utils.escape_fileset(fileset))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -39,8 +39,7 @@ function M.split(opts)
|
||||
return
|
||||
end
|
||||
|
||||
local cmd_mod = require("jj.cmd")
|
||||
opts = vim.tbl_deep_extend("force", cmd_mod.config.split or {}, opts or {}) --[[@as jj.cmd.split.opts]]
|
||||
opts = opts or {} --[[@as jj.cmd.split.opts]]
|
||||
|
||||
-- If it's empty do nothing
|
||||
if utils.is_change_empty(opts.rev or "@") then
|
||||
|
||||
@@ -16,8 +16,8 @@ function M.handle_status_restore()
|
||||
|
||||
if file_info.is_rename then
|
||||
-- For renamed files, remove the new file and restore the old one from parent revision
|
||||
local rm_cmd = "rm " .. vim.fn.shellescape(file_info.new_path)
|
||||
local restore_cmd = "jj restore --from @- " .. vim.fn.shellescape(file_info.old_path)
|
||||
local rm_cmd = string.format("rm %s", vim.fn.shellescape(file_info.new_path))
|
||||
local restore_cmd = string.format("jj restore --from @- %s", utils.escape_fileset(file_info.old_path))
|
||||
|
||||
local _, rm_success = runner.execute_command(rm_cmd, "Failed to remove renamed file")
|
||||
if rm_success then
|
||||
@@ -32,7 +32,8 @@ function M.handle_status_restore()
|
||||
end
|
||||
else
|
||||
-- For non-renamed files, use regular restore
|
||||
local restore_cmd = "jj restore " .. vim.fn.shellescape(file_info.old_path)
|
||||
utils.notify(utils.escape_fileset(file_info.old_path))
|
||||
local restore_cmd = string.format("jj restore %s", utils.escape_fileset(file_info.old_path))
|
||||
|
||||
local _, success = runner.execute_command(restore_cmd, "Failed to restore")
|
||||
if success then
|
||||
|
||||
+12
-3
@@ -121,7 +121,7 @@ local function get_files()
|
||||
text = line:sub(3),
|
||||
file = file_path,
|
||||
status = change .. " ",
|
||||
diff_cmd = string.format("jj --no-pager diff %s", vim.fn.shellescape(file_path)),
|
||||
diff_cmd = string.format("jj --no-pager diff %s", utils.escape_fileset(file_path)),
|
||||
confirm_action = "open_and_diff",
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ local function log_history(file_path)
|
||||
"--no-graph",
|
||||
[[ -T 'change_id.shortest() ++ "\t" ++ coalesce(author.name(), "(no author)") ++ "\t" ++ committer.timestamp() ++ "\t" ++ coalesce(description.first_line(), "(no description)") ++ "\n"' ]],
|
||||
}, " ")
|
||||
local output, ok = runner.execute_command(string.format(format, vim.fn.shellescape(file_path)))
|
||||
local output, ok = runner.execute_command(string.format(format, utils.escape_fileset(file_path)))
|
||||
if not ok then
|
||||
return
|
||||
end
|
||||
@@ -201,7 +201,16 @@ local function log_history(file_path)
|
||||
time = time_part,
|
||||
description = description,
|
||||
text = string.format("%s %s %s %s", rev, author, short_time, description),
|
||||
preview_cmd = { "jj", "--no-pager", "diff", file_path, "-r", rev, "--stat", "--git" },
|
||||
preview_cmd = {
|
||||
"jj",
|
||||
"--no-pager",
|
||||
"diff",
|
||||
utils.escape_fileset(file_path),
|
||||
"-r",
|
||||
rev,
|
||||
"--stat",
|
||||
"--git",
|
||||
},
|
||||
confirm_action = "edit_revision",
|
||||
})
|
||||
end
|
||||
|
||||
@@ -982,4 +982,14 @@ function M.open_first_conflicted_file(revset)
|
||||
end
|
||||
end
|
||||
|
||||
--- Build a shell-safe jj fileset argument for a literal path.
|
||||
--- jj path arguments use fileset syntax, so special characters like `$`
|
||||
--- must be wrapped in jj string quotes before shell-escaping.
|
||||
---@param path string
|
||||
---@return string
|
||||
function M.escape_fileset(path)
|
||||
local fileset_literal = string.format('"%s"', path:gsub("\\", "\\\\"):gsub('"', '\\"'))
|
||||
return vim.fn.shellescape(fileset_literal)
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
Reference in New Issue
Block a user