-- This plugin aims to be something like vim-fugitive but for driving the jj-vcs CLI. -- https://github.com/NicolasGB/jj.nvim return { "jj.nvim", cmd = { "J", "Jdiff", "Jvdiff", "Jhdiff", "Jopen", "Jreview", "Jopen", "Jclose" }, after = function() require("jj").setup({ ["describe_editor"] = "input" }) local jj = require("jj.cmd") require("jj").setup({ -- Setup snacks as a picker picker = { -- Here you can pass the options as you would for snacks. -- It will be used when using the picker snacks = {}, }, -- 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 terminal behavior terminal = { -- Cursor render delay in milliseconds (default: 10) -- If cursor column is being reset to 0 when refreshing commands, try increasing this value -- This delay allows the terminal emulator to complete rendering before restoring cursor position cursor_render_delay = 10, }, -- 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 = { "", "", "q" }, -- Keys to close editor without saving }, }, }, -- Configure log command behavior log = { close_on_edit = false, -- Close log buffer after editing a change }, -- Configure keymaps for command buffers keymaps = { -- Log buffer keymaps (set to nil to disable) log = { checkout = "", -- Edit revision under cursor checkout_immutable = "", -- Edit revision (ignore immutability) describe = "d", -- Describe revision under cursor diff = "", -- Diff revision under cursor edit = "e", -- Edit revision under cursor new = "n", -- Create new change branching off new_after = "", -- Create new change after revision new_after_immutable = "", -- Create new change after (ignore immutability) undo = "", -- Undo last operation redo = "", -- Redo last undone operation abandon = "a", -- Abandon revision under cursor bookmark = "b", -- Create or move bookmark to revision under cursor fetch = "f", -- Fetch from remote push = "p", -- Push bookmark of revision under cursor push_all = "", -- Push all changes to remote open_pr = "o", -- Open PR/MR for revision under cursor open_pr_list = "", -- Open PR/MR by selecting from all bookmarks }, -- Status buffer keymaps (set to nil to disable) status = { open_file = "", -- Open file under cursor restore_file = "", -- Restore file under cursor }, -- Close keymaps (shared across all buffers) close = { "q", "" }, }, }, }) vim.keymap.set("n", "jl", jj.log, { desc = "JJ log" }) vim.keymap.set("n", "jl", jj.log, { desc = "JJ log" }) vim.keymap.set("n", "jd", jj.describe, { desc = "JJ describe" }) vim.keymap.set("n", "je", jj.edit, { desc = "JJ edit" }) vim.keymap.set("n", "jn", jj.new, { desc = "JJ new" }) vim.keymap.set("n", "js", jj.status, { desc = "JJ status" }) vim.keymap.set("n", "dj", jj.diff, { desc = "JJ diff" }) vim.keymap.set("n", "sj", jj.squash, { desc = "JJ squash" }) vim.api.nvim_create_user_command("Jopen", function(opts) local revset = #opts.fargs > 0 and opts.fargs[1] or "@" if not require("jj.utils").ensure_jj() then return end -- Get the files changed by given revset local runner = require("jj.core.runner") local output, ok = runner.execute_command( string.format("jj diff --name-only --revisions %s", vim.fn.shellescape(revset)), string.format("Error getting diff of revset: %s", revset) ) if not ok then return end -- Split the output into lines and open each file for file in output:gmatch("[^\r\n]+") do local buf if vim.fn.bufexists(file) ~= 0 then buf = vim.fn.bufnr(file) else buf = vim.fn.bufadd(file) end -- Explanation: loading many buffers here causes slow down and even Git errors in Neo-tree -- so let any needed loading happen whenever the user browses the buffers. -- if not vim.api.nvim_buf_is_loaded(buf) then -- vim.fn.bufload(buf) -- end vim.api.nvim_set_option_value("buflisted", true, { buf = buf }) end end, { desc = "Open files changed by given revset", nargs = "?" }) vim.api.nvim_create_user_command("Jclose", function(opts) local revset = #opts.fargs > 0 and opts.fargs[1] or "@" if not require("jj.utils").ensure_jj() then return end -- Get the files changed by given revset local runner = require("jj.core.runner") local output, ok = runner.execute_command( string.format("jj diff --name-only --revisions %s", vim.fn.shellescape(revset)), string.format("Error getting diff of revset: %s", revset) ) if not ok then return end -- Split the output into lines and close each file for file in output:gmatch("[^\r\n]+") do local buf if vim.fn.bufexists(file) ~= 0 then vim.api.nvim_buf_delete(vim.fn.bufnr(file), { force = false, unload = false }) end end -- Refresh Neo-tree of buffers local manager = require("neo-tree.sources.manager") local utils = require("neo-tree.utils") local refresh = utils.wrap(manager.refresh, "buffers") refresh() end, { desc = "Close buffers for files changed by given revset", nargs = "?" }) vim.api.nvim_create_user_command("Jreview", function(opts) local revset if #opts.fargs > 0 then revset = opts.fargs[1] else revset = "trunk()" end require("jj.diff").open_vdiff({ rev = revset }) end, { desc = "Diff current buffer with the version in given revset", nargs = "?" }) -- Pickers local picker = require("jj.picker") vim.keymap.set("n", "gj", picker.status, { desc = "JJ Picker status" }) vim.keymap.set("n", "gl", picker.file_history, { desc = "JJ Picker file history" }) -- Some functions like `describe` or `log` can take parameters vim.keymap.set("n", "jL", function() jj.log({ revisions = "'all()'", }) end, { desc = "JJ log all" }) -- tug is an alias to move a bookmark vim.keymap.set("n", "jt", function() local cmd = require("jj.cmd") cmd.j("tug") cmd.log({}) end, { desc = "JJ tug" }) end, }