feat(cmd): Add jj commit as a native command

This commit is contained in:
NicolasGB
2026-01-22 11:00:07 +01:00
committed by Nicolas GB
parent d13a5c9aec
commit 9a20b24849
4 changed files with 43 additions and 11 deletions
+3
View File
@@ -61,6 +61,7 @@
- `redo` - Redo the last undone operation
- `open_pr` - Open a PR/MR on your remote (GitHub, GitLab, Gitea, Forgejo, etc.)
- `annotate` / `annotate_line` - View file blame and line history with change ID, author, and timestamp
- `commit` - Describe the current change and create a new one after
- Diff commands
- `:Jdiff [revision]` - Vertical split diff against a jj revision
- `:Jhdiff [revision]` - Horizontal split diff
@@ -234,6 +235,8 @@ The plugin provides a `:J` command that accepts jj subcommands:
:J bookmark create/move/delete
:J # This will use your defined default command
:J <your-alias>
:J commit " Opens your configured editor describes @ and then creates a new change -A immediately
:J commit <any text here> " Automatically describes @ and creates a new change -A immediately
```
### Diff Commands
+15 -10
View File
@@ -18,7 +18,8 @@ local default_describe_opts = {
--- Execute jj describe command with the given description
--- @param description string The description text
--- @param revset? string The revision to describe
local function execute_describe(description, revset)
--- @param on_close function|nil The function to run on success
local function execute_describe(description, revset, on_close)
if not description or description == "" then
utils.notify("Description cannot be empty", vim.log.levels.ERROR)
return
@@ -33,6 +34,12 @@ local function execute_describe(description, revset)
-- Use --stdin to properly handle multi-line and special characters
runner.execute_command_async(cmd, function()
utils.notify("Description set.", vim.log.levels.INFO)
-- If an on close callback is provided, call it
if on_close then
vim.schedule(function()
on_close()
end)
end
end, "Failed to describe", description)
end
@@ -53,7 +60,8 @@ end
--- @param description? string Optional description text
--- @param revset? string The revision to describe
--- @param opts? jj.cmd.describe_opts Optional command options
function M.describe(description, revset, opts)
--- @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
@@ -61,7 +69,7 @@ function M.describe(description, revset, opts)
-- Check if a description was provided otherwise require for input
if description then
-- Description provided directly
execute_describe(description, revset)
execute_describe(description, revset, on_close)
return
end
@@ -105,9 +113,6 @@ function M.describe(description, revset, opts)
table.insert(text, "JJ:") -- blank line
table.insert(text, 'JJ: Lines starting with "JJ:" (like this one) will be removed')
-- Check if we're coming from the log view so we can reopen it after editing
local open_log_on_close = terminal.state.buf_cmd == "log"
-- Close the terminal buffer before opening editor
terminal.close_terminal_buffer()
@@ -123,9 +128,10 @@ function M.describe(description, revset, opts)
execute_describe(trimmed_description, revset)
-- Once editing is done, reopen the log if we came from there
end, function()
if open_log_on_close then
-- If an on close callback is provided, call it
if on_close then
vim.schedule(function()
cmd.log({})
on_close()
end)
end
end, describe_editor_keymaps())
@@ -142,7 +148,7 @@ function M.describe(description, revset, opts)
}, function(input)
-- If the user inputed something, execute the describe command
if input then
execute_describe(input, revset)
execute_describe(input, revset, on_close)
end
-- Close the current terminal when finished
terminal.close_terminal_buffer()
@@ -151,4 +157,3 @@ function M.describe(description, revset, opts)
end
return M
+17
View File
@@ -682,6 +682,19 @@ function M.open_pr(opts)
utils.open_pr_for_bookmark(bookmark)
end
-- Jujutsu commit
--- @param description string|nil Commit changes in the current change
function M.commit(description)
if not utils.ensure_jj() then
return
end
M.describe(description, nil, nil, function()
-- Opinionated -A flag since it seems more intuitive when editing and commiting past changes and has no effect on top changes
M.new({ args = "-A @" })
end)
end
--- @param args string|string[] jj command arguments
function M.j(args)
if not utils.ensure_jj() then
@@ -795,6 +808,9 @@ function M.j(args)
annotate_line = function()
require("jj.annotate").line()
end,
commit = function()
M.commit(remaining_args_str ~= "" and remaining_args_str or nil)
end,
}
if handlers[subcommand] then
@@ -841,6 +857,7 @@ function M.register_command()
"open_pr",
"annotate",
"annotate_line",
"commit",
}
local matches = {}
for _, cmd in ipairs(subcommands) do
+8 -1
View File
@@ -343,9 +343,16 @@ end
--- Handle describing a log line
function M.handle_log_describe()
-- Store the cursor pos for when we exit the describe
terminal.store_cursor_position()
local revset = get_revset()
if revset then
require("jj.cmd").describe(nil, revset)
require("jj.cmd").describe(nil, revset, nil, function()
-- Execute log
M.log()
-- Restore previous cursor pos
terminal.restore_cursor_position()
end)
else
utils.notify("No valid revision found in the log line", vim.log.levels.ERROR)
end