mirror of
https://github.com/zoriya/jj.nvim.git
synced 2026-08-05 10:46:08 +00:00
A regresion was introduced by #81 where the log buffer was not being restored when there was no modification after describing from the log buffer. This has been reworked and now the function `on_done` is always called not only when there are lines in the buffer giving the responsibility to check the nilness on the `on_done` function. There was a bug also when restoring cursor position which was being wiped when the buffer was closed which is not actually what we want
165 lines
4.6 KiB
Lua
165 lines
4.6 KiB
Lua
--- @class jj.ui.editor
|
|
local M = {}
|
|
|
|
local buffer = require("jj.core.buffer")
|
|
|
|
--- @class jj.ui.editor.highlights
|
|
---@field added? table Highlight settings for added lines
|
|
---@field modified? table Highlight settings for modified lines
|
|
---@field deleted? table Highlight settings for deleted lines
|
|
---@field renamed? table Highlight settings for renamed lines
|
|
|
|
M.highlights = {
|
|
-- Only init this one by default since it's not handled natively by neovim
|
|
renamed = { fg = "#d29922", ctermfg = "Yellow" },
|
|
}
|
|
M.highlights_initialized = false
|
|
|
|
-- Initialize highlight groups once
|
|
local function init_highlights()
|
|
if M.highlights_initialized then
|
|
return
|
|
end
|
|
|
|
-- Override the highlight groups if user provided custom settings
|
|
if M.highlights.added then
|
|
vim.api.nvim_set_hl(0, "Added", M.highlights.added)
|
|
end
|
|
|
|
if M.highlights.modified then
|
|
vim.api.nvim_set_hl(0, "Changed", M.highlights.modified)
|
|
end
|
|
|
|
if M.highlights.deleted then
|
|
vim.api.nvim_set_hl(0, "Removed", M.highlights.deleted)
|
|
end
|
|
|
|
-- this one will always be executed since the default nvim highlight group does not exist for renames
|
|
if M.highlights.renamed then
|
|
vim.api.nvim_set_hl(0, "jjRenamed", M.highlights.renamed)
|
|
end
|
|
|
|
M.highlights_initialized = true
|
|
end
|
|
|
|
--- Setup function to configure highlights and other options
|
|
---@param opts? { highlights: jj.ui.editor.highlights } Configuration options
|
|
function M.setup(opts)
|
|
opts = opts or {}
|
|
|
|
-- Merge user highlights with defaults
|
|
if opts.highlights then
|
|
M.highlights = vim.tbl_deep_extend("force", M.highlights, opts.highlights)
|
|
end
|
|
|
|
-- Reset highlights flag to force re-initialization with new highlights
|
|
if M.highlights_initialized then
|
|
M.highlights_initialized = false
|
|
init_highlights()
|
|
end
|
|
end
|
|
|
|
---@param initial_text string[] Lines to initialize the buffer with
|
|
---@param on_write fun(buf: string[])? Optional callback called with user text on buffer write
|
|
---@param on_unload? fun(buf: string[])? Optional callback with user text called when the buffer is closed
|
|
---@param keymaps? jj.core.buffer.keymap[] Optional keymaps for the buffer
|
|
function M.open_editor(initial_text, on_write, on_unload, keymaps)
|
|
-- Initialize highlight groups once
|
|
init_highlights()
|
|
|
|
-- Create a namespace for our highlights
|
|
local ns_id = vim.api.nvim_create_namespace("jj_describe_highlights")
|
|
|
|
-- Function to apply highlights to the buffer
|
|
local function apply_highlights(buf)
|
|
-- Clear existing highlights
|
|
vim.api.nvim_buf_clear_namespace(buf, ns_id, 0, -1)
|
|
|
|
-- Get all lines
|
|
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
|
|
|
|
for i, line in ipairs(lines) do
|
|
local line_idx = i - 1 -- 0-indexed
|
|
|
|
-- First, check if line starts with JJ: and highlight it as comment
|
|
if line:match("^JJ:") then
|
|
-- Then check for rename status indicator
|
|
local status_pos = line:find("[R] ", 4) -- Find status after "JJ:"
|
|
if status_pos then
|
|
local status = line:sub(status_pos, status_pos) -- Get the status character
|
|
local hl_group = nil
|
|
|
|
if status == "R" then
|
|
hl_group = "jjRenamed"
|
|
end
|
|
|
|
if hl_group then
|
|
-- Highlight from the status character to the end of the line
|
|
vim.api.nvim_buf_set_extmark(buf, ns_id, line_idx, status_pos - 1, {
|
|
end_col = #line,
|
|
hl_group = hl_group,
|
|
})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Create buffer
|
|
local buf = buffer.create({
|
|
name = "jujutsu:///DESCRIBE_EDITMSG",
|
|
split = "horizontal",
|
|
size = math.floor(vim.o.lines / 2),
|
|
filetype = "jjdescription",
|
|
buftype = "acwrite",
|
|
modifiable = true,
|
|
keymaps = keymaps,
|
|
})
|
|
|
|
-- Set buffer content
|
|
vim.api.nvim_buf_set_lines(buf, 0, -1, false, initial_text)
|
|
|
|
-- Set bufhidden after creation
|
|
vim.bo[buf].bufhidden = "wipe"
|
|
|
|
-- Apply highlights initially
|
|
apply_highlights(buf)
|
|
|
|
-- Reapply highlights when text changes
|
|
vim.api.nvim_create_autocmd({ "TextChanged", "TextChangedI" }, {
|
|
buffer = buf,
|
|
callback = function()
|
|
apply_highlights(buf)
|
|
end,
|
|
})
|
|
|
|
-- Handle :w and :wq commands
|
|
vim.api.nvim_create_autocmd("BufWriteCmd", {
|
|
buffer = buf,
|
|
callback = function()
|
|
-- Get current buffer lines
|
|
local buf_lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
|
|
-- Update the last written lines variable
|
|
vim.b[buf].jj_last_written_lines = buf_lines
|
|
vim.bo[buf].modified = false
|
|
-- Call the on_write callback if provided
|
|
if on_write then
|
|
on_write(buf_lines)
|
|
end
|
|
end,
|
|
})
|
|
|
|
-- Register the on_close callback
|
|
if on_unload then
|
|
vim.api.nvim_create_autocmd("BufWipeout", {
|
|
buffer = buf,
|
|
callback = function()
|
|
local last_written = vim.b[buf].jj_last_written_lines
|
|
on_unload(last_written)
|
|
end,
|
|
})
|
|
end
|
|
end
|
|
|
|
return M
|