mirror of
https://github.com/zoriya/jj.nvim.git
synced 2026-08-05 18:56:13 +00:00
Migrate command execution to structured argv lists across the plugin, replacing shell-string command construction with `vim.system` argv execution. The runner API now exposes argv-based execution as the default path:
- `runner.execute_command` -> `runner.execute`
- `runner.execute_command_async` -> `runner.execute_async`
- `runner.execute_command_raw` -> `runner.execute_raw`
- `runner.execute_command_raw_async` -> `runner.execute_raw_async`
- `runner.execute_command_sync` was removed; use `runner.execute` and handle the result directly
BREAKING CHANGES:
- `cmd.new({ args = ... })` now requires `args` as `string[]` argv tokens, not a single string.
- `cmd.log({ ... })` now uses `raw_flags` as `string[]` for raw passthrough flags; `raw = "..."` is no longer supported.
- Direct users of `jj.core.runner` must migrate from the old `execute_command*` string helpers to the new argv-based `execute*` helpers.
135 lines
3.7 KiB
Lua
135 lines
3.7 KiB
Lua
--- @class jj.cmd.describe
|
|
local M = {}
|
|
|
|
local utils = require("jj.utils")
|
|
local runner = require("jj.core.runner")
|
|
local terminal = require("jj.ui.terminal")
|
|
local editor = require("jj.ui.editor")
|
|
|
|
--- @class jj.cmd.describe_opts
|
|
--- @field with_status boolean: Whether or not `jj st` should be displayed in a buffer while describing the commit
|
|
--- @field type? "buffer"|"input" Editor mode for describe command: "buffer" (Git-style editor) or "input" (simple input prompt)
|
|
--- @type jj.cmd.describe_opts
|
|
local default_describe_opts = {
|
|
with_status = true,
|
|
}
|
|
|
|
--- Execute jj describe command with the given description
|
|
--- @param description string The description text
|
|
--- @param revset? string The revision to describe
|
|
--- @param sync? boolean Whether to execute command synchronously
|
|
local function execute_describe(description, revset, sync)
|
|
local cmd = {
|
|
"jj",
|
|
"describe",
|
|
}
|
|
if revset then
|
|
table.insert(cmd, "-r")
|
|
table.insert(cmd, revset)
|
|
end
|
|
table.insert(cmd, "--stdin")
|
|
|
|
-- Use --stdin to properly handle multi-line and special characters
|
|
if sync then
|
|
runner.execute(cmd, "Failed to describe", description)
|
|
utils.notify("Description set.", vim.log.levels.INFO)
|
|
return
|
|
end
|
|
|
|
runner.execute_async(cmd, function()
|
|
utils.notify("Description set.", vim.log.levels.INFO)
|
|
end, "Failed to describe", description)
|
|
end
|
|
|
|
--- Resolve describe editor keymaps from config
|
|
--- @return jj.core.buffer.keymap
|
|
local function describe_editor_keymaps()
|
|
local cmd = require("jj.cmd")
|
|
local cfg = cmd.config.describe.editor.keymaps or {}
|
|
return cmd.resolve_keymaps_from_specs(cfg, {
|
|
close = {
|
|
desc = "Close describe editor without saving",
|
|
handler = "<cmd>close!<CR>",
|
|
modes = { "n" },
|
|
},
|
|
})
|
|
end
|
|
|
|
--- Jujutsu describe
|
|
--- @param description? string Optional description text
|
|
--- @param revset? string The revision to describe
|
|
--- @param opts? jj.cmd.describe_opts Optional command options
|
|
--- @param on_close function|nil Optional callback when editor is closed
|
|
function M.describe(description, revset, opts, on_close)
|
|
if not utils.ensure_jj() then
|
|
return
|
|
end
|
|
|
|
-- Check if a description was provided otherwise require for input
|
|
if description then
|
|
-- Description provided directly
|
|
execute_describe(description, revset, false)
|
|
return
|
|
end
|
|
|
|
if not revset then
|
|
revset = "@"
|
|
end
|
|
|
|
local cmd = require("jj.cmd")
|
|
local merged_opts = vim.tbl_deep_extend("force", default_describe_opts, opts or {})
|
|
|
|
-- Use buffer editor mode (defaults to "buffer" if not configured)
|
|
local editor_mode = merged_opts.type or cmd.config.describe.editor.type or "buffer"
|
|
if editor_mode == "buffer" then
|
|
local text = utils.get_describe_text(revset)
|
|
if not text then
|
|
return
|
|
end
|
|
|
|
-- Close the terminal buffer before opening editor
|
|
terminal.close_terminal_buffer()
|
|
|
|
editor.open_editor(text, function(buf_lines)
|
|
local trimmed_description = utils.extract_description_from_describe(buf_lines)
|
|
if not trimmed_description then
|
|
trimmed_description = ""
|
|
end
|
|
execute_describe(trimmed_description, revset, true)
|
|
-- Once editing is done, reopen the log if we came from there
|
|
end, function()
|
|
-- If an on close callback is provided, call it
|
|
if on_close then
|
|
vim.schedule(function()
|
|
on_close()
|
|
end)
|
|
end
|
|
end, describe_editor_keymaps())
|
|
else
|
|
-- Use input mode
|
|
if merged_opts.with_status then
|
|
-- Show the status in a terminal buffer
|
|
cmd.status()
|
|
end
|
|
|
|
vim.ui.input({
|
|
prompt = "Description: ",
|
|
default = "",
|
|
}, function(input)
|
|
-- If the user inputed something, execute the describe command
|
|
if input then
|
|
execute_describe(input, revset, true)
|
|
end
|
|
-- Close the current terminal when finished
|
|
terminal.close_terminal_buffer()
|
|
if on_close then
|
|
vim.schedule(function()
|
|
on_close()
|
|
end)
|
|
end
|
|
end)
|
|
end
|
|
end
|
|
|
|
return M
|