Compare commits
10 Commits
b4672972dc
...
43a62d7e3f
| Author | SHA1 | Date | |
|---|---|---|---|
| 43a62d7e3f | |||
| ddcca1077d | |||
| 6e72a16f7b | |||
| 497e3bf94a | |||
| 5b1ea2ba9a | |||
| 86241f2193 | |||
| 5c75ec687c | |||
| 9a58ea573b | |||
| ecdb456815 | |||
| c2aafde0c8 |
56
README.md
56
README.md
@ -9,12 +9,62 @@ A Neovim plugin to provide `mini.diff`-like functionality for Jujutsu (`jj`) rep
|
||||
|
||||
## Installation
|
||||
|
||||
(TODO: Provide installation instructions using popular Neovim plugin managers like `packer.nvim`, `lazy.nvim`, or `vim-plug`.)
|
||||
You can install `jj-mini.diff` using your favorite Neovim plugin manager.
|
||||
|
||||
**lazy.nvim:**
|
||||
|
||||
```lua
|
||||
{
|
||||
"your-github-username/jj-mini.diff", -- Replace with the actual repository path
|
||||
config = function()
|
||||
require("jj_mini_diff").setup({
|
||||
-- Your configuration options here
|
||||
})
|
||||
end,
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
(TODO: Explain how to activate and use the plugin, including any commands or keybindings.)
|
||||
To activate the plugin, call the `setup()` function in your Neovim configuration:
|
||||
|
||||
```lua
|
||||
require("jj_mini_diff").setup({
|
||||
-- Optional: Customize signs or autocmd events
|
||||
-- signs = {
|
||||
-- add = { text = "++", texthl = "DiffAdd", numhl = "DiffAdd" },
|
||||
-- change = { text = "//", texthl = "DiffChange", numhl = "DiffChange" },
|
||||
-- delete = { text = "--", texthl = "DiffDelete", numhl = "DiffDelete" },
|
||||
-- },
|
||||
-- autocmd_events = { "BufReadPost", "BufWritePost", "CursorHold", "InsertLeave" },
|
||||
})
|
||||
```
|
||||
|
||||
The plugin will automatically place and update signs in files within a Jujutsu repository on `BufReadPost`, `BufWritePost`, and `CursorHold` events by default.
|
||||
|
||||
You can also manually refresh the signs for the current buffer at any time:
|
||||
|
||||
```lua
|
||||
:lua require("jj_mini_diff").refresh_signs()
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
(TODO: Document available configuration options for customizing signs, colors, and behavior.)
|
||||
The `setup()` function accepts an optional table for configuration.
|
||||
|
||||
```lua
|
||||
require("jj_mini_diff").setup({
|
||||
signs = {
|
||||
add = { text = "│", texthl = "JjDiffAdd", numhl = "JjDiffAdd" },
|
||||
change = { text = "│", texthl = "JjDiffChange", numhl = "JjDiffChange" },
|
||||
delete = { text = "─", texthl = "JjDiffDelete", numhl = "JjDiffDelete" },
|
||||
},
|
||||
autocmd_events = { "BufReadPost", "BufWritePost", "CursorHold" },
|
||||
})
|
||||
```
|
||||
|
||||
* **`signs`**: A table to customize the text, text highlight group (`texthl`), and number highlight group (`numhl`) for each sign type.
|
||||
* `add`: For added lines.
|
||||
* `change`: For changed lines.
|
||||
* `delete`: For deleted lines.
|
||||
* **`autocmd_events`**: A list of Neovim autocommand events that will trigger a sign refresh.
|
||||
@ -2,11 +2,156 @@
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.setup(opts)
|
||||
opts = opts or {}
|
||||
-- TODO: Implement configuration options
|
||||
-- Default configuration
|
||||
local config = {
|
||||
signs = {
|
||||
add = { text = "│", texthl = "JjDiffAdd", numhl = "JjDiffAdd" },
|
||||
change = { text = "│", texthl = "JjDiffChange", numhl = "JjDiffChange" },
|
||||
delete = { text = "─", texthl = "JjDiffDelete", numhl = "JjDiffDelete" },
|
||||
},
|
||||
autocmd_events = { "BufReadPost", "BufWritePost", "CursorHold" },
|
||||
}
|
||||
|
||||
-- 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
|
||||
|
||||
-- TODO: Implement core logic for Git signs
|
||||
-- Define Neovim signs for diff
|
||||
local function _define_signs()
|
||||
vim.fn.sign_define("JjDiffAdd", config.signs.add)
|
||||
vim.fn.sign_define("JjDiffChange", config.signs.change)
|
||||
vim.fn.sign_define("JjDiffDelete", config.signs.delete)
|
||||
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
|
||||
|
||||
-- Place signs in the current buffer
|
||||
local function _place_signs_in_buffer()
|
||||
local buf_nr = vim.api.nvim_get_current_buf()
|
||||
vim.fn.sign_unplace("jj_mini_diff", { buffer = buf_nr }) -- Clear existing signs
|
||||
|
||||
local diff_output = _get_jj_diff_for_buffer()
|
||||
if not diff_output then
|
||||
return
|
||||
end
|
||||
|
||||
local added, changed, deleted = _parse_diff_output(diff_output)
|
||||
|
||||
local sign_id = 1
|
||||
for _, line_num in ipairs(added) do
|
||||
vim.fn.sign_place(sign_id, "jj_mini_diff", "JjDiffAdd", buf_nr, { lnum = line_num })
|
||||
sign_id = sign_id + 1
|
||||
end
|
||||
for _, line_num in ipairs(changed) do
|
||||
vim.fn.sign_place(sign_id, "jj_mini_diff", "JjDiffChange", buf_nr, { lnum = line_num })
|
||||
sign_id = sign_id + 1
|
||||
end
|
||||
for _, line_num in ipairs(deleted) do
|
||||
vim.fn.sign_place(sign_id, "jj_mini_diff", "JjDiffDelete", buf_nr, { lnum = line_num })
|
||||
sign_id = sign_id + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if current buffer's file is in a jj repo
|
||||
local function _is_jj_repo()
|
||||
local file_path = vim.api.nvim_buf_get_name(0)
|
||||
if file_path == "" then
|
||||
return false
|
||||
end
|
||||
local dir = vim.fn.fnamemodify(file_path, ":h")
|
||||
while dir ~= "" and dir ~= "/" do
|
||||
if vim.fn.isdirectory(dir .. "/.jj") == 1 then
|
||||
return true
|
||||
end
|
||||
dir = vim.fn.fnamemodify(dir, ":h")
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function M.refresh_signs()
|
||||
if _is_jj_repo() then
|
||||
_place_signs_in_buffer()
|
||||
end
|
||||
end
|
||||
|
||||
function M.setup(opts)
|
||||
opts = opts or {}
|
||||
_define_signs() -- Call to define signs
|
||||
|
||||
-- Autocommands to update signs
|
||||
vim.api.nvim_create_autocmd({ "BufReadPost", "BufWritePost", "CursorHold" }, {
|
||||
group = vim.api.nvim_create_augroup("JjMiniDiff", { clear = true }),
|
||||
callback = function()
|
||||
if _is_jj_repo() then
|
||||
_place_signs_in_buffer()
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
Loading…
Reference in New Issue
Block a user