gi/lua/jj_mini_diff/init.lua

93 lines
2.7 KiB
Lua

-- jj-mini.diff Neovim plugin
local M = {}
-- Helper function to run jj commands
local function _run_jj_command(args)
local cmd = "jj " .. table.concat(args, " ")
local handle = io.popen(cmd)
if not handle then
return nil, "Failed to run command: " .. cmd
end
local output = handle:read("*a")
local status = handle:close()
if not status then
return nil, "Command failed: " .. cmd
end
return output
end
-- Define Neovim signs for diff
local function _define_signs()
vim.fn.sign_define("JjDiffAdd", { text = "", texthl = "JjDiffAdd", numhl = "JjDiffAdd" })
vim.fn.sign_define("JjDiffChange", { text = "", texthl = "JjDiffChange", numhl = "JjDiffChange" })
vim.fn.sign_define("JjDiffDelete", { text = "", texthl = "JjDiffDelete", numhl = "JjDiffDelete" })
end
-- Get jj diff output for the current buffer
local function _get_jj_diff_for_buffer()
local file_path = vim.api.nvim_buf_get_name(0)
if file_path == "" then
return nil, "Current buffer is not associated with a file."
end
-- Run 'jj diff' for the specific file
local diff_output, err = _run_jj_command({ "diff", "--color=never", file_path })
if err then
return nil, err
end
return diff_output
end
-- Parse jj diff output
local function _parse_diff_output(diff_output)
local added_lines = {}
local changed_lines = {}
local deleted_lines = {}
local current_line_num = 0
local lines = vim.split(diff_output, "\n", { plain = true })
local prev_line_was_deleted = false
for _, line in ipairs(lines) do
if line:match("^@@ .- +(%d+)") then
-- Extract new_start_line from hunk header
local _, _, new_start_line_str = line:find("^@@ .- +(%d+)")
current_line_num = tonumber(new_start_line_str) - 1
prev_line_was_deleted = false
elseif line:match("^[ ]") then
current_line_num = current_line_num + 1
prev_line_was_deleted = false
elseif line:match("^[+]") then
current_line_num = current_line_num + 1
if prev_line_was_deleted then
table.insert(changed_lines, current_line_num)
else
table.insert(added_lines, current_line_num)
end
prev_line_was_deleted = false
elseif line:match("^[-]") then
-- For deleted lines, we mark the line *before* the deletion as changed,
-- or if it's the first line, we can't mark it.
-- This is a simplification for now.
if current_line_num > 0 then
table.insert(deleted_lines, current_line_num)
end
prev_line_was_deleted = true
end
end
return added_lines, changed_lines, deleted_lines
end
function M.setup(opts)
opts = opts or {}
_define_signs() -- Call to define signs
-- TODO: Implement configuration options
end
-- TODO: Implement core logic for Git signs
return M