]> Git — Sourcephile - julm/julm-nix.git/blob - home-manager/profiles/nvim/lua/plugins/jj.lua
+use/op(nvim): tweak config
[julm/julm-nix.git] / home-manager / profiles / nvim / lua / plugins / jj.lua
1 -- This plugin aims to be something like vim-fugitive but for driving the jj-vcs CLI.
2 -- https://github.com/NicolasGB/jj.nvim
3 return {
4 "jj.nvim",
5 cmd = { "J", "Jdiff", "Jvdiff", "Jhdiff", "Jopen", "Jreview", "Jopen", "Jclose" },
6 after = function()
7 require("jj").setup({ ["describe_editor"] = "input" })
8 local jj = require("jj.cmd")
9
10 require("jj").setup({
11 -- Setup snacks as a picker
12 picker = {
13 -- Here you can pass the options as you would for snacks.
14 -- It will be used when using the picker
15 snacks = {},
16 },
17
18 -- Customize syntax highlighting colors for the describe buffer
19 highlights = {
20 added = { fg = "#3fb950", ctermfg = "Green" }, -- Added files
21 modified = { fg = "#56d4dd", ctermfg = "Cyan" }, -- Modified files
22 deleted = { fg = "#f85149", ctermfg = "Red" }, -- Deleted files
23 renamed = { fg = "#d29922", ctermfg = "Yellow" }, -- Renamed files
24 },
25
26 -- Configure terminal behavior
27 terminal = {
28 -- Cursor render delay in milliseconds (default: 10)
29 -- If cursor column is being reset to 0 when refreshing commands, try increasing this value
30 -- This delay allows the terminal emulator to complete rendering before restoring cursor position
31 cursor_render_delay = 10,
32 },
33
34 -- Configure cmd module (describe editor, keymaps)
35 cmd = {
36 -- Configure describe editor
37 describe = {
38 editor = {
39 -- Choose the editor mode for describe command
40 -- "buffer" - Opens a Git-style commit message buffer with syntax highlighting (default)
41 -- "input" - Uses a simple vim.ui.input prompt
42 type = "buffer",
43 -- Customize keymaps for the describe editor buffer
44 keymaps = {
45 close = { "<Esc>", "<C-c>", "q" }, -- Keys to close editor without saving
46 },
47 },
48 },
49
50 -- Configure log command behavior
51 log = {
52 close_on_edit = false, -- Close log buffer after editing a change
53 },
54
55 -- Configure keymaps for command buffers
56 keymaps = {
57 -- Log buffer keymaps (set to nil to disable)
58 log = {
59 checkout = "<CR>", -- Edit revision under cursor
60 checkout_immutable = "<S-CR>", -- Edit revision (ignore immutability)
61 describe = "d", -- Describe revision under cursor
62 diff = "<S-d>", -- Diff revision under cursor
63 edit = "e", -- Edit revision under cursor
64 new = "n", -- Create new change branching off
65 new_after = "<C-n>", -- Create new change after revision
66 new_after_immutable = "<S-n>", -- Create new change after (ignore immutability)
67 undo = "<S-u>", -- Undo last operation
68 redo = "<S-r>", -- Redo last undone operation
69 abandon = "a", -- Abandon revision under cursor
70 bookmark = "b", -- Create or move bookmark to revision under cursor
71 fetch = "f", -- Fetch from remote
72 push = "p", -- Push bookmark of revision under cursor
73 push_all = "<S-p>", -- Push all changes to remote
74 open_pr = "o", -- Open PR/MR for revision under cursor
75 open_pr_list = "<S-o>", -- Open PR/MR by selecting from all bookmarks
76 },
77 -- Status buffer keymaps (set to nil to disable)
78 status = {
79 open_file = "<CR>", -- Open file under cursor
80 restore_file = "<S-x>", -- Restore file under cursor
81 },
82 -- Close keymaps (shared across all buffers)
83 close = { "q", "<Esc>" },
84 },
85 },
86 })
87
88 vim.keymap.set("n", "<leader>jl", jj.log, { desc = "JJ log" })
89 vim.keymap.set("n", "<leader>jl", jj.log, { desc = "JJ log" })
90 vim.keymap.set("n", "<leader>jd", jj.describe, { desc = "JJ describe" })
91 vim.keymap.set("n", "<leader>je", jj.edit, { desc = "JJ edit" })
92 vim.keymap.set("n", "<leader>jn", jj.new, { desc = "JJ new" })
93 vim.keymap.set("n", "<leader>js", jj.status, { desc = "JJ status" })
94 vim.keymap.set("n", "<leader>dj", jj.diff, { desc = "JJ diff" })
95 vim.keymap.set("n", "<leader>sj", jj.squash, { desc = "JJ squash" })
96
97 vim.api.nvim_create_user_command("Jopen", function(opts)
98 local revset = #opts.fargs > 0 and opts.fargs[1] or "@"
99
100 if not require("jj.utils").ensure_jj() then
101 return
102 end
103
104 -- Get the files changed by given revset
105 local runner = require("jj.core.runner")
106 local output, ok = runner.execute_command(
107 string.format("jj diff --name-only --revisions %s", vim.fn.shellescape(revset)),
108 string.format("Error getting diff of revset: %s", revset)
109 )
110 if not ok then
111 return
112 end
113
114 -- Split the output into lines and open each file
115 for file in output:gmatch("[^\r\n]+") do
116 local buf
117 if vim.fn.bufexists(file) ~= 0 then
118 buf = vim.fn.bufnr(file)
119 else
120 buf = vim.fn.bufadd(file)
121 end
122 -- Explanation: loading many buffers here causes slow down and even Git errors in Neo-tree
123 -- so let any needed loading happen whenever the user browses the buffers.
124 -- if not vim.api.nvim_buf_is_loaded(buf) then
125 -- vim.fn.bufload(buf)
126 -- end
127 vim.api.nvim_set_option_value("buflisted", true, { buf = buf })
128 end
129 end, { desc = "Open files changed by given revset", nargs = "?" })
130
131 vim.api.nvim_create_user_command("Jclose", function(opts)
132 local revset = #opts.fargs > 0 and opts.fargs[1] or "@"
133
134 if not require("jj.utils").ensure_jj() then
135 return
136 end
137
138 -- Get the files changed by given revset
139 local runner = require("jj.core.runner")
140 local output, ok = runner.execute_command(
141 string.format("jj diff --name-only --revisions %s", vim.fn.shellescape(revset)),
142 string.format("Error getting diff of revset: %s", revset)
143 )
144 if not ok then
145 return
146 end
147
148 -- Split the output into lines and close each file
149 for file in output:gmatch("[^\r\n]+") do
150 local buf
151 if vim.fn.bufexists(file) ~= 0 then
152 vim.api.nvim_buf_delete(vim.fn.bufnr(file), { force = false, unload = false })
153 end
154 end
155
156 -- Refresh Neo-tree of buffers
157 local manager = require("neo-tree.sources.manager")
158 local utils = require("neo-tree.utils")
159 local refresh = utils.wrap(manager.refresh, "buffers")
160 refresh()
161 end, { desc = "Close buffers for files changed by given revset", nargs = "?" })
162
163 vim.api.nvim_create_user_command("Jreview", function(opts)
164 local revset
165 if #opts.fargs > 0 then
166 revset = opts.fargs[1]
167 else
168 revset = "trunk()"
169 end
170 require("jj.diff").open_vdiff({ rev = revset })
171 end, { desc = "Diff current buffer with the version in given revset", nargs = "?" })
172
173 -- Pickers
174 local picker = require("jj.picker")
175 vim.keymap.set("n", "<leader>gj", picker.status, { desc = "JJ Picker status" })
176 vim.keymap.set("n", "<leader>gl", picker.file_history, { desc = "JJ Picker file history" })
177
178 -- Some functions like `describe` or `log` can take parameters
179 vim.keymap.set("n", "<leader>jL", function()
180 jj.log({
181 revisions = "'all()'",
182 })
183 end, { desc = "JJ log all" })
184
185 -- tug is an alias to move a bookmark
186 vim.keymap.set("n", "<leader>jt", function()
187 local cmd = require("jj.cmd")
188 cmd.j("tug")
189 cmd.log({})
190 end, { desc = "JJ tug" })
191 end,
192 }