mirror of
https://github.com/zoriya/jj.nvim.git
synced 2026-08-05 02:36:07 +00:00
fix: describe command reopening log buffer without flicker
- Close terminal buffer before opening describe editor - Capture log state before closing to detect if we should reopen - Add on_unload callback to editor to handle log reopening - Suppress redraws during buffer transitions with lazyredraw - Remove duplicate hardcoded status keymaps from terminal.lua (were referencing undefined functions) - Fix resolve_keymaps_from_specs to validate handlers exist before creating keymaps
This commit is contained in:
+42
-15
@@ -64,7 +64,7 @@ local function resolve_keymaps_from_specs(cfg, specs)
|
||||
|
||||
for key, spec in pairs(specs) do
|
||||
local lhs = cfg[key]
|
||||
if lhs then
|
||||
if lhs and spec.handler then
|
||||
if type(lhs) == "table" then
|
||||
for _, key_lhs in ipairs(lhs) do
|
||||
table.insert(
|
||||
@@ -172,8 +172,12 @@ function M.describe(description, revset, opts)
|
||||
local status_files = parser.get_status_files(status_result)
|
||||
local old_description = vim.trim(old_description_raw)
|
||||
|
||||
local first_line = old_description:match("^[^\n]*") or ""
|
||||
local text = { first_line }
|
||||
-- Split description into lines to preserve multiline descriptions
|
||||
local description_lines = vim.split(old_description, "\n")
|
||||
local text = {}
|
||||
for _, line in ipairs(description_lines) do
|
||||
table.insert(text, line)
|
||||
end
|
||||
table.insert(text, "") -- Empty line to separate from user input
|
||||
table.insert(text, "JJ: Change ID: " .. revset)
|
||||
table.insert(text, "JJ: This commit contains the following changes:")
|
||||
@@ -183,6 +187,12 @@ 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()
|
||||
|
||||
editor.open_editor(text, function(buf_lines)
|
||||
local user_lines = {}
|
||||
for _, line in ipairs(buf_lines) do
|
||||
@@ -193,9 +203,17 @@ function M.describe(description, revset, opts)
|
||||
-- Join lines and trim leading/trailing whitespace
|
||||
local trimmed_description = table.concat(user_lines, "\n"):gsub("^%s+", ""):gsub("%s+$", "")
|
||||
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
|
||||
vim.schedule(function()
|
||||
vim.o.lazyredraw = true
|
||||
M.log({})
|
||||
vim.o.lazyredraw = false
|
||||
vim.cmd("redraw!")
|
||||
end)
|
||||
end
|
||||
end, describe_editor_keymaps())
|
||||
|
||||
terminal.close_terminal_buffer()
|
||||
else
|
||||
-- Use input mode
|
||||
local merged_opts = vim.tbl_deep_extend("force", default_describe_opts, opts or {})
|
||||
@@ -279,8 +297,6 @@ end
|
||||
-- Resolve status keymaps from config, filtering out nil values
|
||||
--- @return jj.core.buffer.keymap[]
|
||||
local function status_keymaps()
|
||||
-- Reduce repetition by declaring a specification table.
|
||||
-- Each entry maps the config key name to:
|
||||
local cfg = M.config.keymaps.status or {}
|
||||
local specs = {
|
||||
open_file = {
|
||||
@@ -407,14 +423,6 @@ function M.squash()
|
||||
end
|
||||
end
|
||||
|
||||
--- @class jj.cmd.log_opts
|
||||
--- @field summary? boolean
|
||||
--- @field reversed? boolean
|
||||
--- @field no_graph? boolean
|
||||
--- @field limit? uinteger
|
||||
--- @field revisions? string
|
||||
|
||||
local default_log_opts = { summary = false, reversed = false, no_graph = false, limit = 20 }
|
||||
---
|
||||
--- Create a new change relative to the revision under the cursor in a jj log buffer.
|
||||
--- Behavior:
|
||||
@@ -595,6 +603,17 @@ local function log_keymaps()
|
||||
return resolve_keymaps_from_specs(cfg, specs)
|
||||
end
|
||||
|
||||
--- @class jj.cmd.log_opts
|
||||
--- @field summary? boolean
|
||||
--- @field reversed? boolean
|
||||
--- @field no_graph? boolean
|
||||
--- @field limit? uinteger
|
||||
--- @field revisions? string
|
||||
--- @field raw_flags? string
|
||||
|
||||
---@type jj.cmd.log_opts
|
||||
local default_log_opts = { summary = false, reversed = false, no_graph = false, limit = 20, raw_flats = nil }
|
||||
|
||||
-- Jujutsu log
|
||||
--- @param opts? jj.cmd.log_opts
|
||||
function M.log(opts)
|
||||
@@ -605,6 +624,11 @@ function M.log(opts)
|
||||
local cmd = "jj log"
|
||||
local merged_opts = vim.tbl_extend("force", default_log_opts, opts or {})
|
||||
|
||||
-- If a raw has been given simply execute it as is
|
||||
if merged_opts.raw then
|
||||
return terminal.run(string.format("%s %s", cmd, merged_opts.raw), log_keymaps())
|
||||
end
|
||||
|
||||
for key, value in pairs(merged_opts) do
|
||||
key = key:gsub("_", "-")
|
||||
if key == "limit" and value then
|
||||
@@ -808,6 +832,9 @@ function M.j(args)
|
||||
redo = function()
|
||||
M.redo()
|
||||
end,
|
||||
log = function()
|
||||
M.log({ raw_flags = remaining_args_str ~= "" and remaining_args_str or nil })
|
||||
end,
|
||||
}
|
||||
|
||||
if handlers[subcommand] then
|
||||
|
||||
@@ -297,4 +297,4 @@ function M.start_insert(buf)
|
||||
vim.cmd("startinsert")
|
||||
end
|
||||
|
||||
return M
|
||||
return M
|
||||
+12
-1
@@ -51,8 +51,9 @@ end
|
||||
|
||||
---@param initial_text string[] Lines to initialize the buffer with
|
||||
---@param on_done fun(buf: string[])? Optional callback called with user text on buffer write
|
||||
---@param on_unload? fun()? Optional callback called when the buffer is closed
|
||||
---@param keymaps? jj.core.buffer.keymap[] Optional keymaps for the buffer
|
||||
function M.open_editor(initial_text, on_done, keymaps)
|
||||
function M.open_editor(initial_text, on_done, on_unload, keymaps)
|
||||
-- Initialize highlight groups once
|
||||
init_highlights()
|
||||
|
||||
@@ -156,6 +157,16 @@ function M.open_editor(initial_text, on_done, keymaps)
|
||||
vim.bo[buf].modified = false
|
||||
end,
|
||||
})
|
||||
|
||||
-- Register the on_close callback
|
||||
if on_unload then
|
||||
vim.api.nvim_create_autocmd("BufWipeout", {
|
||||
buffer = buf,
|
||||
callback = function()
|
||||
on_unload()
|
||||
end,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
@@ -158,6 +158,7 @@ function M.run_floating(cmd)
|
||||
{ modes = { "n", "v" }, lhs = "i", rhs = function() end },
|
||||
{ modes = { "n", "v" }, lhs = "c", rhs = function() end },
|
||||
{ modes = { "n", "v" }, lhs = "a", rhs = function() end },
|
||||
{ modes = { "n", "v" }, lhs = "u", rhs = function() end },
|
||||
{
|
||||
modes = { "n", "v" },
|
||||
lhs = "q",
|
||||
@@ -291,6 +292,7 @@ function M.run(cmd, keymaps)
|
||||
{ modes = { "n", "v" }, lhs = "i", rhs = function() end },
|
||||
{ modes = { "n", "v" }, lhs = "c", rhs = function() end },
|
||||
{ modes = { "n", "v" }, lhs = "a", rhs = function() end },
|
||||
{ modes = { "n", "v" }, lhs = "u", rhs = function() end },
|
||||
-- Close terminal buffer
|
||||
{
|
||||
modes = { "n", "v" },
|
||||
@@ -327,14 +329,8 @@ function M.run(cmd, keymaps)
|
||||
end
|
||||
end
|
||||
|
||||
-- Add Enter key mapping for status buffers to open files
|
||||
if cmd[2] == "st" or cmd[2] == "status" then
|
||||
new_command_keymaps = {
|
||||
{ modes = "n", lhs = "<CR>", rhs = handle_status_enter, opts = { desc = "Open file under cursor" } },
|
||||
{ modes = "n", lhs = "X", rhs = handle_status_restore, opts = { desc = "Restore file under cursor" } },
|
||||
}
|
||||
end
|
||||
|
||||
-- Status keymaps are already handled in cmd.lua via status_keymaps()
|
||||
-- No need to duplicate them here
|
||||
if #new_command_keymaps > 0 then
|
||||
buffer.set_keymaps(state.buf, new_command_keymaps)
|
||||
vim.b[state.buf].jj_command_keymaps = new_command_keymaps
|
||||
|
||||
Reference in New Issue
Block a user