mirror of
https://github.com/zoriya/jj.nvim.git
synced 2026-08-05 02:36:07 +00:00
Update README with new config structure
- Document describe.editor configuration for type and keymaps - Document keymaps configuration for log, status, and close keybindings - Update examples to show the new nested config structure - Add section on customizing describe editor keymaps - Preserve multiline descriptions in describe editor buffer
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
⚠️ **WORK IN PROGRESS** ⚠️
|
||||
|
||||
> **Note:** This project is pre-v1. Breaking changes may occur in the configuration, API, and features until v1.0.0 is released.
|
||||
|
||||
A Neovim plugin for [Jujutsu (jj)](https://github.com/jj-vcs/jj) version control system.
|
||||
|
||||
## About
|
||||
@@ -19,12 +21,17 @@ This plugin aims to be something like vim-fugitive but for driving the jj-vcs CL
|
||||
- `describe` / `desc` - Set change descriptions with a Git-style commit message editor
|
||||
- `status` / `st` - Show repository status
|
||||
- `log` - Display log history with configurable options
|
||||
- `diff` - Show changes
|
||||
- `new` - Create a new change
|
||||
- `diff` - Show changes with optional filtering by current file
|
||||
- `new` - Create a new change with optional parent selection
|
||||
- `edit` - Edit a change
|
||||
- `squash` - Squash the current diff to it's parent
|
||||
- `rebase` - Rebase changes to a destination
|
||||
- `bookmark create/delete` - Create and delete bookmarks
|
||||
- `undo` - Undo the last operation
|
||||
- `redo` - Redo the last undone operation
|
||||
- Diff commands
|
||||
- `:Jdiff [revision]` - Vertical split diff against a jj revision
|
||||
- `:Jhdiff [revision]` - Horizontal split diff
|
||||
- Picker for for [Snacks.nvim](https://github.com/folke/snacks.nvim)
|
||||
- `jj status` Displays the current changes diffs
|
||||
- `jj file_history` Displays a buffer's history changes and allows to edit it's change (including immutable changes)
|
||||
@@ -35,7 +42,7 @@ Here are some cool features you can do with jj.nvim
|
||||
|
||||
### Diff any change
|
||||
|
||||
You can diff any change in your log history by simply pressing `d` on it's line, yeah just like that!
|
||||
You can diff any change in your log history by simply pressing `d` on its line, yeah just like that!
|
||||

|
||||
|
||||
### Edit changes
|
||||
@@ -58,8 +65,8 @@ You can create new changes directly from the log buffer with multiple options:
|
||||
|
||||
You can undo/redo changes directly from the log buffer:
|
||||
|
||||
- `u` - Undo the last operation
|
||||
- `r` - Redo the last undone operation
|
||||
- `<S-u>` - Undo the last operation
|
||||
- `<S-r>` - Redo the last undone operation
|
||||
|
||||
### Open a changed file
|
||||
|
||||
@@ -68,7 +75,7 @@ Just press enter to open the a file from the `status` output in your current win
|
||||
|
||||
### Restore a changed file
|
||||
|
||||
Press `X` on a file from the `status` output and that's it, it's restored.
|
||||
Press `<S-x>` on a file from the `status` output and that's it, it's restored.
|
||||
|
||||

|
||||
|
||||
@@ -98,7 +105,18 @@ The plugin provides a `:J` command that accepts jj subcommands:
|
||||
:J <your-alias>
|
||||
```
|
||||
|
||||
## Setup config
|
||||
### Diff Commands
|
||||
|
||||
The plugin also provides `:Jdiff`, `:Jvdiff`, and `:Jhdiff` commands for diffing against specific revisions:
|
||||
|
||||
```sh
|
||||
:Jdiff " Vertical diff against @- (parent)
|
||||
:Jdiff @-2 " Vertical diff against specific revision
|
||||
:Jvdiff main " Vertical diff against main bookmark
|
||||
:Jhdiff trunk() " Horizontal diff against trunk
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```lua
|
||||
{
|
||||
@@ -106,22 +124,56 @@ The plugin provides a `:J` command that accepts jj subcommands:
|
||||
picker = {
|
||||
-- Here you can pass the options as you would for snacks.
|
||||
-- It will be used when using the picker
|
||||
snacks = {
|
||||
|
||||
}
|
||||
snacks = {}
|
||||
},
|
||||
|
||||
-- Choose the editor mode for describe command
|
||||
-- "buffer" - Opens a Git-style commit message buffer with syntax highlighting (default)
|
||||
-- "input" - Uses a simple vim.ui.input prompt
|
||||
describe_editor = "buffer",
|
||||
|
||||
-- Customize syntax highlighting colors for the describe buffer
|
||||
highlights = {
|
||||
added = { fg = "#3fb950", ctermfg = "Green" }, -- Added files
|
||||
modified = { fg = "#56d4dd", ctermfg = "Cyan" }, -- Modified files
|
||||
deleted = { fg = "#f85149", ctermfg = "Red" }, -- Deleted files
|
||||
renamed = { fg = "#d29922", ctermfg = "Yellow" }, -- Renamed files
|
||||
},
|
||||
|
||||
-- Configure cmd module (describe editor, keymaps)
|
||||
cmd = {
|
||||
-- Configure describe editor
|
||||
describe = {
|
||||
editor = {
|
||||
-- Choose the editor mode for describe command
|
||||
-- "buffer" - Opens a Git-style commit message buffer with syntax highlighting (default)
|
||||
-- "input" - Uses a simple vim.ui.input prompt
|
||||
type = "buffer",
|
||||
-- Customize keymaps for the describe editor buffer
|
||||
keymaps = {
|
||||
close = { "<Esc>", "<C-c>", "q" }, -- Keys to close editor without saving
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
-- Configure keymaps for command buffers
|
||||
keymaps = {
|
||||
-- Log buffer keymaps (set to nil to disable)
|
||||
log = {
|
||||
checkout = "<CR>", -- Edit revision under cursor
|
||||
checkout_immutable = "<S-CR>", -- Edit revision (ignore immutability)
|
||||
describe = "d", -- Describe revision under cursor
|
||||
diff = "<S-d>", -- Diff revision under cursor
|
||||
edit = "e", -- Edit revision under cursor
|
||||
new = "n", -- Create new change branching off
|
||||
new_after = "<C-n>", -- Create new change after revision
|
||||
new_after_immutable = "<S-n>", -- Create new change after (ignore immutability)
|
||||
undo = "<S-u>", -- Undo last operation
|
||||
redo = "<S-r>", -- Redo last undone operation
|
||||
},
|
||||
-- Status buffer keymaps (set to nil to disable)
|
||||
status = {
|
||||
open_file = "<CR>", -- Open file under cursor
|
||||
restore_file = "<S-x>", -- Restore file under cursor
|
||||
},
|
||||
-- Close keymaps (shared across all buffers)
|
||||
close = { "q", "<Esc>" },
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +181,7 @@ The plugin provides a `:J` command that accepts jj subcommands:
|
||||
|
||||
### Describe Editor Modes
|
||||
|
||||
The `describe_editor` option lets you choose how you want to write commit descriptions:
|
||||
The `describe.editor.type` option lets you choose how you want to write commit descriptions:
|
||||
|
||||
- **`"buffer"`** (default) - Opens a full buffer editor similar to Git's commit message editor
|
||||
- Shows file changes with syntax highlighting
|
||||
@@ -144,7 +196,26 @@ Example:
|
||||
|
||||
```lua
|
||||
require("jj").setup({
|
||||
describe_editor = "input", -- Use simple input mode
|
||||
describe = {
|
||||
editor = {
|
||||
type = "input", -- Use simple input mode
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
You can also customize the keymaps for the describe editor buffer:
|
||||
|
||||
```lua
|
||||
require("jj").setup({
|
||||
describe = {
|
||||
editor = {
|
||||
type = "buffer",
|
||||
keymaps = {
|
||||
close = { "q", "<Esc>", "<C-c>" }, -- Customize close keybindings
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
@@ -169,25 +240,93 @@ require("jj").setup({
|
||||
})
|
||||
```
|
||||
|
||||
## Lua API Usage
|
||||
|
||||
Beyond the `:J` command, you can call functions directly from Lua for more control. The example config below shows how to use them with custom keymaps.
|
||||
|
||||
### Log Command Options
|
||||
|
||||
The `log` function accepts an options table:
|
||||
|
||||
```lua
|
||||
jj.log({
|
||||
summary = false, -- Show summary of changes (default: false)
|
||||
reversed = false, -- Reverse the log order (default: false)
|
||||
no_graph = false, -- Hide the graph (default: false)
|
||||
limit = 20, -- Limit number of entries (default: 20)
|
||||
revisions = "'all()'" -- Revision specifier (default: all reachable)
|
||||
})
|
||||
|
||||
-- Examples:
|
||||
jj.log({ limit = 50 }) -- Show 50 entries
|
||||
jj.log({ revisions = "'main::@'" }) -- Show commits between main and current
|
||||
jj.log({ summary = true, limit = 100 }) -- Show summary with high limit
|
||||
jj.log({ raw = "-r 'main::@' --summary --no-graph" }) -- Pass raw flags directly
|
||||
```
|
||||
|
||||
### New Command Options
|
||||
|
||||
The `new` function accepts an options table:
|
||||
|
||||
```lua
|
||||
jj.new({
|
||||
show_log = false, -- Display log after creating new change (default: false)
|
||||
with_input = false, -- Prompt for parent revision (default: false)
|
||||
args = "" -- Additional arguments to pass to jj new
|
||||
})
|
||||
|
||||
-- Examples:
|
||||
jj.new({ show_log = true }) -- Create new and show log
|
||||
jj.new({ show_log = true, with_input = true }) -- Prompt for parent
|
||||
jj.new({ args = "--before @" }) -- Pass custom args
|
||||
```
|
||||
|
||||
### Diff Split Views
|
||||
|
||||
Use the `diff` module for opening splits:
|
||||
|
||||
```lua
|
||||
jj.diff.vsplit() -- Vertical split diff against parent
|
||||
jj.diff.vsplit({ rev = "main" }) -- Vertical split against specific revision
|
||||
jj.diff.hsplit() -- Horizontal split diff
|
||||
jj.diff.hsplit({ rev = "@-2" }) -- Horizontal split against @-2
|
||||
```
|
||||
|
||||
## Example config
|
||||
|
||||
```lua
|
||||
|
||||
{
|
||||
|
||||
"nicolasgb/jj.nvim",
|
||||
|
||||
dependencies = {
|
||||
|
||||
"folke/snacks.nvim", -- Optional only if you use picker's
|
||||
|
||||
},
|
||||
|
||||
config = function()
|
||||
|
||||
local jj = require("jj")
|
||||
jj.setup({
|
||||
|
||||
cmd = {
|
||||
describe = {
|
||||
editor = {
|
||||
type = "buffer",
|
||||
keymaps = {
|
||||
close = { "q", "<Esc>", "<C-c>" },
|
||||
}
|
||||
}
|
||||
},
|
||||
keymaps = {
|
||||
log = {
|
||||
checkout = "<CR>",
|
||||
describe = "d",
|
||||
diff = "<S-d>",
|
||||
},
|
||||
status = {
|
||||
open_file = "<CR>",
|
||||
restore_file = "<S-x>",
|
||||
},
|
||||
close = { "q", "<Esc>" },
|
||||
},
|
||||
},
|
||||
highlights = {
|
||||
-- Customize colors if desired
|
||||
modified = { fg = "#89ddff" },
|
||||
@@ -196,40 +335,28 @@ require("jj").setup({
|
||||
|
||||
|
||||
|
||||
-- Core commands
|
||||
vim.keymap.set("n", "<leader>jd", jj.describe, { desc = "JJ describe" })
|
||||
|
||||
vim.keymap.set("n", "<leader>jl", jj.log, { desc = "JJ log" })
|
||||
|
||||
vim.keymap.set("n", "<leader>je", jj.edit, { desc = "JJ edit" })
|
||||
|
||||
vim.keymap.set("n", "<leader>jn", jj.new, { desc = "JJ new" })
|
||||
|
||||
vim.keymap.set("n", "<leader>js", jj.status, { desc = "JJ status" })
|
||||
|
||||
vim.keymap.set("n", "<leader>sj", jj.squash, { desc = "JJ squash" })
|
||||
|
||||
vim.keymap.set("n", "<leader>ju", jj.undo, { desc = "JJ undo" })
|
||||
|
||||
vim.keymap.set("n", "<leader>jy", jj.redo, { desc = "JJ redo" })
|
||||
vim.keymap.set("n", "<leader>jr", jj.rebase, { desc = "JJ rebase" })
|
||||
vim.keymap.set("n", "<leader>jb", jj.bookmark_create, { desc = "JJ bookmark create" })
|
||||
vim.keymap.set("n", "<leader>jB", jj.bookmark_delete, { desc = "JJ bookmark delete" })
|
||||
|
||||
|
||||
|
||||
-- Using the new `diff` table for clarity
|
||||
|
||||
-- Diff commands
|
||||
vim.keymap.set("n", "<leader>dj", jj.diff.vsplit, { desc = "JJ diff vertical" })
|
||||
|
||||
|
||||
vim.keymap.set("n", "<leader>dJ", jj.diff.hsplit, { desc = "JJ diff horizontal" })
|
||||
|
||||
-- Pickers
|
||||
|
||||
vim.keymap.set("n", "<leader>gj", jj.picker.status, { desc = "JJ Picker status" })
|
||||
|
||||
vim.keymap.set("n", "<leader>gl", jj.picker.file_history, { desc = "JJ Picker file history" })
|
||||
|
||||
|
||||
|
||||
-- Some functions like `log` can take parameters
|
||||
|
||||
vim.keymap.set("n", "<leader>jL", function()
|
||||
jj.log {
|
||||
revisions = "'all()'", -- equivalent to jj log -r ::
|
||||
@@ -237,9 +364,7 @@ require("jj").setup({
|
||||
end, { desc = "JJ log all" })
|
||||
|
||||
|
||||
|
||||
-- This is an alias i use for moving bookmarks its so good
|
||||
|
||||
vim.keymap.set("n", "<leader>jt", function()
|
||||
jj.j "tug"
|
||||
jj.log {}
|
||||
|
||||
+44
-9
@@ -9,24 +9,52 @@ local editor = require("jj.ui.editor")
|
||||
local diff = require("jj.diff")
|
||||
|
||||
-- Config for cmd module
|
||||
--- @class jj.cmd.describe.editor.keymaps
|
||||
--- @field close? string|string[] Keymaps to close the editor buffer without saving
|
||||
|
||||
--- @class jj.cmd.describe.editor
|
||||
--- @field type? "buffer"|"input" Editor mode for describe command: "buffer" (Git-style editor) or "input" (simple input prompt)
|
||||
--- @field keymaps? jj.cmd.describe.editor.keymaps Keymaps for the describe editor only when on "buffer" mode.
|
||||
|
||||
--- @class jj.cmd.describe
|
||||
--- @field editor? jj.cmd.describe.editor Options for the describe message editor
|
||||
|
||||
--- @class jj.cmd.log.keymaps
|
||||
--- @field checkout? string|string[] Keymaps for the log command buffer, setting a keymap to nil will disable it
|
||||
--- @field checkout_immutable? string|string[]
|
||||
--- @field describe? string|string[]
|
||||
--- @field diff? string|string[]
|
||||
--- @field edit? string|string[]
|
||||
--- @field new? string|string[]
|
||||
--- @field new_after? string|string[]
|
||||
--- @field new_after_immutable? string|string[]
|
||||
--- @field undo? string|string[]
|
||||
--- @field redo? 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
|
||||
--- @field restore_file? string|string[]
|
||||
|
||||
--- @class jj.cmd.keymaps
|
||||
--- @field log? jj.cmd.log.keymaps Keymaps for the log command buffer
|
||||
--- @field status? jj.cmd.status.keymaps Keymaps for the status command buffer
|
||||
--- @field close? string|string[] Keymaps for the close keybind
|
||||
|
||||
--- @class jj.cmd.opts
|
||||
--- @field describe? jj.cmd.describe
|
||||
--- @field keymaps? jj.cmd.keymaps Keymaps for the buffers containing the output of the commands
|
||||
|
||||
--- @type jj.cmd.opts
|
||||
M.config = {
|
||||
--- @class jj.cmd.describe
|
||||
describe = {
|
||||
--- @class jj.cmd.describe.editor Options for the describe message editor
|
||||
editor = {
|
||||
--- @type "buffer"|"input" Editor mode for describe command: "buffer" (Git-style editor) or "input" (simple input prompt)
|
||||
type = "buffer",
|
||||
--- @class jj.cmd.describe.editor.keymaps Keymaps for the describe editor buffer
|
||||
keymaps = {
|
||||
--- @type string|string[] Keymaps to close the editor buffer without saving
|
||||
close = { "<Esc>", "<C-c>", "q" },
|
||||
},
|
||||
},
|
||||
},
|
||||
--- @class jj.cmd.keymaps Keymaps for the buffers containing the ouptut of the commands
|
||||
keymaps = {
|
||||
--- @class jj.cmd.log.keymaps: { [string]: string|string[] } Keymaps for the log command buffer, setting a keymap to nil will disable it
|
||||
log = {
|
||||
checkout = "<CR>",
|
||||
checkout_immutable = "<S-CR>",
|
||||
@@ -39,12 +67,10 @@ M.config = {
|
||||
undo = "<S-u>",
|
||||
redo = "<S-r>",
|
||||
},
|
||||
--- @class jj.cmd.status.keymaps: { [string]: string|string[] } Keymaps for the status command buffer, setting a keymap to nil will disable it
|
||||
status = {
|
||||
open_file = "<CR>",
|
||||
restore_file = "<S-x>",
|
||||
},
|
||||
--- @type string|string[] Keymaps for the close keybind
|
||||
close = { "q", "<Esc>" },
|
||||
},
|
||||
}
|
||||
@@ -835,6 +861,15 @@ function M.j(args)
|
||||
log = function()
|
||||
M.log({ raw_flags = remaining_args_str ~= "" and remaining_args_str or nil })
|
||||
end,
|
||||
diff = function()
|
||||
M.diff({ current = false })
|
||||
end,
|
||||
status = function()
|
||||
M.status()
|
||||
end,
|
||||
st = function()
|
||||
M.status()
|
||||
end,
|
||||
}
|
||||
|
||||
if handlers[subcommand] then
|
||||
|
||||
+3
-34
@@ -2,13 +2,12 @@ local M = {}
|
||||
local cmd = require("jj.cmd")
|
||||
local picker = require("jj.picker")
|
||||
local editor = require("jj.ui.editor")
|
||||
local diff = require("jj.diff")
|
||||
local utils = require("jj.utils")
|
||||
|
||||
--- Jujutsu plugin configuration
|
||||
--- @class jj.Config
|
||||
--- @field cmd? jj.cmd.opts Options for command module
|
||||
--- @field picker? jj.picker.config Options for picker module
|
||||
--- @field highlights? jj.ui.editor.highlights Highlight configuration for describe buffer
|
||||
M.config = {
|
||||
-- Default configuration
|
||||
--- @type jj.picker.config
|
||||
@@ -16,12 +15,7 @@ M.config = {
|
||||
snacks = {},
|
||||
},
|
||||
--- @type jj.ui.editor.highlights Highlight configuration for describe buffer
|
||||
highlights = {
|
||||
added = { fg = "#3fb950", ctermfg = "Green" },
|
||||
modified = { fg = "#56d4dd", ctermfg = "Cyan" },
|
||||
deleted = { fg = "#f85149", ctermfg = "Red" },
|
||||
renamed = { fg = "#d29922", ctermfg = "Yellow" },
|
||||
},
|
||||
highlights = {},
|
||||
}
|
||||
|
||||
--- Setup the plugin
|
||||
@@ -32,34 +26,9 @@ function M.setup(opts)
|
||||
-- Setup for sub-modules
|
||||
picker.setup(opts and opts.picker or {})
|
||||
editor.setup({ highlights = M.config.highlights })
|
||||
cmd.setup(opts.cmd)
|
||||
utils.setup(opts) -- Keep for future-proofing, even if it's a no-op now
|
||||
cmd.setup(opts and opts.cmd or {})
|
||||
|
||||
cmd.register_command()
|
||||
|
||||
-- Expose public API functions on the top-level module
|
||||
M.status = cmd.status
|
||||
M.describe = cmd.describe
|
||||
M.log = cmd.log
|
||||
M.new = cmd.new
|
||||
M.edit = cmd.edit
|
||||
M.squash = cmd.squash
|
||||
M.rebase = cmd.rebase
|
||||
M.undo = cmd.undo
|
||||
M.redo = cmd.redo
|
||||
M.bookmark_create = cmd.bookmark_create
|
||||
M.bookmark_delete = cmd.bookmark_delete
|
||||
M.j = cmd.j
|
||||
|
||||
M.picker = {
|
||||
status = picker.status,
|
||||
file_history = picker.file_history,
|
||||
}
|
||||
|
||||
M.diff = {
|
||||
vsplit = diff.open_vdiff,
|
||||
hsplit = diff.open_hdiff,
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
@@ -4,10 +4,10 @@ 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
|
||||
---@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 = {
|
||||
added = { fg = "#3fb950", ctermfg = "Green" },
|
||||
|
||||
Reference in New Issue
Block a user