From 8f1a60342ac8ce07b1b5e82f68064d7fca6a6b24 Mon Sep 17 00:00:00 2001 From: NicolasGB Date: Thu, 27 Nov 2025 15:47:10 +0100 Subject: [PATCH] feat: implement jj abandon as native --- lua/jj/cmd/init.lua | 25 +++++++++++++++++++++++++ lua/jj/cmd/log.lua | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/lua/jj/cmd/init.lua b/lua/jj/cmd/init.lua index c2b0f4a..df93622 100644 --- a/lua/jj/cmd/init.lua +++ b/lua/jj/cmd/init.lua @@ -35,6 +35,7 @@ local status_module = require("jj.cmd.status") --- @field new_after_immutable? string|string[] --- @field undo? string|string[] --- @field redo? string|string[] +--- @field abandon? string|string[] --- @class jj.cmd.status.keymaps --- @field open_file? string|string[] Keymaps for the status command buffer, setting a keymap to nil will disable it @@ -86,6 +87,7 @@ M.config = { new_after_immutable = "", undo = "", redo = "", + abandon = "a", }, status = { open_file = "", @@ -408,6 +410,29 @@ function M.redo() end end +-- Jujutsu abandon +function M.abandon() + if not utils.ensure_jj() then + return + end + + M.log({}) + vim.ui.input({ + prompt = "Change to abandon: ", + default = "", + }, function(input) + if input then + local cmd = string.format("jj abandon %s", input) + local _, success = runner.execute_command(cmd, "Error abandoning change") + if success then + utils.notify("Change abandoned successfully.", vim.log.levels.INFO) + M.log({}) + end + else + terminal.close_terminal_buffer() + end + end) +end --- @param args string|string[] jj command arguments function M.j(args) if not utils.ensure_jj() then diff --git a/lua/jj/cmd/log.lua b/lua/jj/cmd/log.lua index d9fa252..cc42efb 100644 --- a/lua/jj/cmd/log.lua +++ b/lua/jj/cmd/log.lua @@ -158,16 +158,45 @@ function M.handle_log_edit(ignore_immut, close_on_exit) -- Try to execute cmd local _, success = runner.execute_command(cmd, "Error editing change") if not success then +--- Handle abandon `jj log` buffer. +--- If ignore_immut is true, adds --ignore-immutable to the command. +--- Silently returns if no revision is found or the jj command fails. +--- On success, notifies and refreshes the log buffer. +--- @param ignore_immut? boolean Pass --ignore-immutable to jj abandon when true. +function M.handle_log_abandon(ignore_immut) + local line = vim.api.nvim_get_current_line() + local revset = parser.get_rev_from_log_line(line) + if not revset or revset == "" then return end -- Close the terminal buffer + -- If we found a revision, abandon it. if close_on_exit then + utils.notify(string.format("Editing change: `%s`", revset), vim.log.levels.INFO) + -- Build command parts. terminal.close_terminal_buffer() + local cmd_parts = { "jj", "abandon" } else + if ignore_immut then M.log({}) + table.insert(cmd_parts, "--ignore-immutable") end + + table.insert(cmd_parts, revset) + + -- Build cmd string + local cmd = table.concat(cmd_parts, " ") + + -- Try to execute cmd + runner.execute_command_async(cmd, function() + utils.notify(string.format("Abandoned change: `%s`", revset), vim.log.levels.INFO) + M.log({}) + end, function() + utils.notify("Error abandoning change", vim.log.levels.ERROR) + end) +end end --- Resolve log keymaps from config, filtering out nil values @@ -225,6 +254,13 @@ function M.log_keymaps() desc = "Redo last undone change", handler = cmd.redo, }, + abandon = { + desc = "Abandon revision under cursor", + handler = M.handle_log_abandon, + -- As of now i'm only exposing the non ignore-immutable version of abandon in the keymaps + -- Maybe in the future we can add another keymap for that, if people request it + args = { false }, + }, } return cmd.merge_keymaps(cmd.resolve_keymaps_from_specs(keymaps, specs), cmd.terminal_keymaps())