From 0e73dd0e0fc4e148c4f8b33934b80e7f4d7cfd7a Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 30 Dec 2023 00:02:48 +0100 Subject: [PATCH 1/7] Add Next/Previous message to editor. --- lua/neogit/buffers/editor/init.lua | 35 ++++++++++++++++++++++++++++++ lua/neogit/config.lua | 4 +++- lua/neogit/lib/git/log.lua | 8 +++++++ lua/neogit/lib/util.lua | 28 ++++++++++++------------ 4 files changed, 60 insertions(+), 15 deletions(-) diff --git a/lua/neogit/buffers/editor/init.lua b/lua/neogit/buffers/editor/init.lua index ab4ef9a4d..c48be5ff4 100644 --- a/lua/neogit/buffers/editor/init.lua +++ b/lua/neogit/buffers/editor/init.lua @@ -2,6 +2,7 @@ local Buffer = require("neogit.lib.buffer") local config = require("neogit.config") local input = require("neogit.lib.input") local util = require("neogit.lib.util") +local git = require("neogit.lib.git") local pad = util.pad_right @@ -41,6 +42,9 @@ function M:open(kind) local mapping = config.get_reversed_commit_editor_maps() local aborted = false + local message_index = -1 + local current_message + local footer self.buffer = Buffer.create { name = self.filename, @@ -64,6 +68,8 @@ function M:open(kind) string.format("# %s Close", pad_mapping("Close")), string.format("# %s Submit", pad_mapping("Submit")), string.format("# %s Abort", pad_mapping("Abort")), + string.format("# %s Previous Message", pad_mapping("PrevMessage")), + string.format("# %s Next Message", pad_mapping("NextMessage")), } help_lines = util.filter_map(help_lines, function(line) @@ -77,6 +83,8 @@ function M:open(kind) buffer:write() buffer:move_cursor(1) + footer = buffer:get_lines(1, -1, false) + -- Start insert mode if user has configured it local disable_insert = config.values.disable_insert_on_commit if @@ -127,6 +135,33 @@ function M:open(kind) buffer:write() buffer:close(true) end, + [mapping["PrevMessage"]] = function(buffer) + if message_index == -1 then + current_message = buffer:get_lines(0, -1, false) + current_message = util.slice(current_message, 1, #current_message - #footer) + end + + message_index = message_index + 1 + + local message = git.log.reflog_message(message_index) + buffer:set_lines(0, -1, false, util.merge(message, footer)) + buffer:move_cursor(1) + end, + [mapping["NextMessage"]] = function(buffer) + if message_index >= 0 then + message_index = message_index - 1 + end + + local message + if message_index < 0 then + message = current_message + else + message = git.log.reflog_message(message_index) + end + + buffer:set_lines(0, -1, false, util.merge(message, footer)) + buffer:move_cursor(1) + end, }, }, } diff --git a/lua/neogit/config.lua b/lua/neogit/config.lua index 011e39c6e..7a33d4191 100644 --- a/lua/neogit/config.lua +++ b/lua/neogit/config.lua @@ -114,7 +114,7 @@ end ---@alias NeogitConfigMappingsRebaseEditor "Pick" | "Reword" | "Edit" | "Squash" | "Fixup" | "Execute" | "Drop" | "Break" | "MoveUp" | "MoveDown" | "Close" | "OpenCommit" | "Submit" | "Abort" | false | fun() --- ----@alias NeogitConfigMappingsCommitEditor "Close" | "Submit" | "Abort" | false | fun() +---@alias NeogitConfigMappingsCommitEditor "Close" | "Submit" | "Abort" | "PrevMessage" | "NextMessage" | false | fun() ---@class NeogitConfigMappings Consult the config file or documentation for values ---@field finder? { [string]: NeogitConfigMappingsFinder } A dictionary that uses finder commands to set multiple keybinds @@ -301,6 +301,8 @@ function M.get_default_values() ["q"] = "Close", [""] = "Submit", [""] = "Abort", + [""] = "PrevMessage", + [""] = "NextMessage", }, rebase_editor = { ["p"] = "Pick", diff --git a/lua/neogit/lib/git/log.lua b/lua/neogit/lib/git/log.lua index 3d5da4c5c..a1cbd1ef6 100644 --- a/lua/neogit/lib/git/log.lua +++ b/lua/neogit/lib/git/log.lua @@ -535,4 +535,12 @@ M.branch_info = util.memoize(function(ref, remotes) return result end) +function M.reflog_message(skip) + return cli.log + .format("%B") + .max_count(1) + .args("--reflog", "--no-merges", "--skip=" .. tostring(skip)) + .call_sync({ ignore_error = true }).stdout +end + return M diff --git a/lua/neogit/lib/util.lua b/lua/neogit/lib/util.lua index d9bb00fd1..bab107485 100644 --- a/lua/neogit/lib/util.lua +++ b/lua/neogit/lib/util.lua @@ -193,20 +193,20 @@ function M.str_min_width(str, len, sep) return str .. string.rep(sep or " ", len - length) end --- function M.slice(tbl, s, e) --- local pos, new = 1, {} --- --- if e == nil then --- e = #tbl --- end --- --- for i = s, e do --- new[pos] = tbl[i] --- pos = pos + 1 --- end --- --- return new --- end +function M.slice(tbl, s, e) + local pos, new = 1, {} + + if e == nil then + e = #tbl + end + + for i = s, e do + new[pos] = tbl[i] + pos = pos + 1 + end + + return new +end -- function M.str_count(str, target) -- local count = 0 From 88ca8b283fd6437493a3c559780d4bc05e2b2b53 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 30 Dec 2023 00:03:00 +0100 Subject: [PATCH 2/7] Buffer: When moving cursor, place it at beginning of line. --- lua/neogit/lib/buffer.lua | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lua/neogit/lib/buffer.lua b/lua/neogit/lib/buffer.lua index bb7dbcc1a..ef5973f68 100644 --- a/lua/neogit/lib/buffer.lua +++ b/lua/neogit/lib/buffer.lua @@ -148,13 +148,7 @@ function Buffer:set_text(first_line, last_line, first_col, last_col, lines) end function Buffer:move_cursor(line) - if line < 0 then - self:focus() - vim.cmd("norm! G") - else - self:focus() - vim.cmd("norm! " .. line .. "G") - end + api.nvim_win_set_cursor(0, { line, 0 }) end function Buffer:close(force) From cf33c52b83e834459dc7742f4fc35cac7f1f75a0 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 30 Dec 2023 13:18:11 +0100 Subject: [PATCH 3/7] Add default value to strict --- lua/neogit/lib/buffer.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/neogit/lib/buffer.lua b/lua/neogit/lib/buffer.lua index ef5973f68..cfbd6eed3 100644 --- a/lua/neogit/lib/buffer.lua +++ b/lua/neogit/lib/buffer.lua @@ -81,7 +81,7 @@ function Buffer:write() end function Buffer:get_lines(first, last, strict) - return api.nvim_buf_get_lines(self.handle, first, last, strict) + return api.nvim_buf_get_lines(self.handle, first, last, strict or false) end function Buffer:get_line(line) From 09f6d3aabf308c7646c87560e16810fa9706e948 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 30 Dec 2023 13:18:19 +0100 Subject: [PATCH 4/7] Add reset message command --- lua/neogit/config.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lua/neogit/config.lua b/lua/neogit/config.lua index 7a33d4191..9c3a420ac 100644 --- a/lua/neogit/config.lua +++ b/lua/neogit/config.lua @@ -114,7 +114,7 @@ end ---@alias NeogitConfigMappingsRebaseEditor "Pick" | "Reword" | "Edit" | "Squash" | "Fixup" | "Execute" | "Drop" | "Break" | "MoveUp" | "MoveDown" | "Close" | "OpenCommit" | "Submit" | "Abort" | false | fun() --- ----@alias NeogitConfigMappingsCommitEditor "Close" | "Submit" | "Abort" | "PrevMessage" | "NextMessage" | false | fun() +---@alias NeogitConfigMappingsCommitEditor "Close" | "Submit" | "Abort" | "PrevMessage" | "ResetMessage" | "NextMessage" | false | fun() ---@class NeogitConfigMappings Consult the config file or documentation for values ---@field finder? { [string]: NeogitConfigMappingsFinder } A dictionary that uses finder commands to set multiple keybinds @@ -303,6 +303,7 @@ function M.get_default_values() [""] = "Abort", [""] = "PrevMessage", [""] = "NextMessage", + [""] = "ResetMessage", }, rebase_editor = { ["p"] = "Pick", From 7b2163eaf3e74caf6b84277fffe630da06c6d0c0 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 30 Dec 2023 13:18:28 +0100 Subject: [PATCH 5/7] Only call CLI once for each index - we want to capture user changes to a message for the current buffer. Also, allow user to reset message to the "real" value by force calling CLI. --- lua/neogit/buffers/editor/init.lua | 51 +++++++++++++++++++----------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/lua/neogit/buffers/editor/init.lua b/lua/neogit/buffers/editor/init.lua index c48be5ff4..775552341 100644 --- a/lua/neogit/buffers/editor/init.lua +++ b/lua/neogit/buffers/editor/init.lua @@ -42,10 +42,26 @@ function M:open(kind) local mapping = config.get_reversed_commit_editor_maps() local aborted = false - local message_index = -1 - local current_message + + local message_index = 1 + local message_buffer = { { "" } } local footer + local function reflog_message(index) + return git.log.reflog_message(index - 2) + end + + local function commit_message() + return message_buffer[message_index] or reflog_message(message_index) + end + + local function current_message(buffer) + local message = buffer:get_lines(0, -1) + message = util.slice(message, 1, math.max(1, #message - #footer)) + + return message + end + self.buffer = Buffer.create { name = self.filename, filetype = filetypes[self.filename:match("[%u_]+$")] or "NeogitEditor", @@ -70,6 +86,7 @@ function M:open(kind) string.format("# %s Abort", pad_mapping("Abort")), string.format("# %s Previous Message", pad_mapping("PrevMessage")), string.format("# %s Next Message", pad_mapping("NextMessage")), + string.format("# %s Reset Message", pad_mapping("ResetMessage")), } help_lines = util.filter_map(help_lines, function(line) @@ -83,7 +100,7 @@ function M:open(kind) buffer:write() buffer:move_cursor(1) - footer = buffer:get_lines(1, -1, false) + footer = buffer:get_lines(1, -1) -- Start insert mode if user has configured it local disable_insert = config.values.disable_insert_on_commit @@ -136,32 +153,30 @@ function M:open(kind) buffer:close(true) end, [mapping["PrevMessage"]] = function(buffer) - if message_index == -1 then - current_message = buffer:get_lines(0, -1, false) - current_message = util.slice(current_message, 1, #current_message - #footer) - end + local message = current_message(buffer) + message_buffer[message_index] = message message_index = message_index + 1 - local message = git.log.reflog_message(message_index) - buffer:set_lines(0, -1, false, util.merge(message, footer)) + buffer:set_lines(0, #message, false, commit_message()) buffer:move_cursor(1) end, [mapping["NextMessage"]] = function(buffer) - if message_index >= 0 then - message_index = message_index - 1 - end + local message = current_message(buffer) - local message - if message_index < 0 then - message = current_message - else - message = git.log.reflog_message(message_index) + if message_index > 1 then + message_buffer[message_index] = message + message_index = message_index - 1 end - buffer:set_lines(0, -1, false, util.merge(message, footer)) + buffer:set_lines(0, #message, false, commit_message()) buffer:move_cursor(1) end, + [mapping["ResetMessage"]] = function(buffer) + local message = current_message(buffer) + buffer:set_lines(0, #message, false, reflog_message(message_index)) + buffer:move_cursor(1) + end }, }, } From 3e68e50a7ecbdce93a8740c5f24cc488c4e00c2d Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 30 Dec 2023 13:24:38 +0100 Subject: [PATCH 6/7] Lint --- lua/neogit/buffers/editor/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/neogit/buffers/editor/init.lua b/lua/neogit/buffers/editor/init.lua index 775552341..9bc9e43f0 100644 --- a/lua/neogit/buffers/editor/init.lua +++ b/lua/neogit/buffers/editor/init.lua @@ -176,7 +176,7 @@ function M:open(kind) local message = current_message(buffer) buffer:set_lines(0, #message, false, reflog_message(message_index)) buffer:move_cursor(1) - end + end, }, }, } From 5d2ad30be6ad1043e312852a6f20fc254096021c Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 30 Dec 2023 13:39:47 +0100 Subject: [PATCH 7/7] Update docs with editor commands --- doc/neogit.txt | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/doc/neogit.txt b/doc/neogit.txt index 646481e2a..328fcb0e7 100644 --- a/doc/neogit.txt +++ b/doc/neogit.txt @@ -56,6 +56,7 @@ CONTENTS *neogit_contents* 7. Buffers |neogit_buffers| • Status |neogit_status_buffer| + • Editor |neogit_editor_buffer| • Log |neogit_log_buffer| • Reflog |neogit_reflog_buffer| • Commit |neogit_commit_buffer| @@ -1428,9 +1429,11 @@ Actions: *neogit_worktree_popup_actions* 7. Buffers *neogit_buffers* • Status |neogit_status_buffer| +• Editor |neogit_editor_buffer| • Log |neogit_log_buffer| • Reflog |neogit_reflog_buffer| • Commit |neogit_commit_buffer| +• Rebase Todo |neogit_rebase_todo_buffer| ============================================================================== Status Buffer *neogit_status_buffer* @@ -1441,6 +1444,47 @@ Untracked Files *neogit_status_buffer_untracked* untracked files entirely, "normal" to show files and directories (default), or "all" to show all files in all directories. +============================================================================== +Editor Buffer *neogit_editor_buffer* + +Commands: *neogit_editor_commands* + • Close *neogit_editor_close* + Default key: `q` + + Closes the editor buffer. If there are unsaved changes, user will be + prompted to save them. Discarding the changes will abort. + + • Submit *neogit_editor_submit* + Default key: `` + + Writes and closes the editor. + + • Abort *neogit_editor_abort* + Default key: `` + + Closes the editor buffer, discarding any changes that might have been + written. + + • PrevMessage *neogit_editor_prev_message* + Default key: `` + + Replaces the current commit message with the previously used one, via + reflog. Messages that have been discarded via reset will be included as + well. Any changes a user makes to a message will be stored while the + editor is open. + + • NextMessage *neogit_editor_next_message* + Default key: `` + + Replaces the current commit message with the next used one, via + reflog. Same semantics as |neogit_editor_prev_message| apply. + + • ResetMessage *neogit_editor_reset_message* + Default key: `` + + If a user has changed a message that was found via reflog, reset it to how + it appeared in reflog. + ============================================================================== Log Buffer *neogit_log_buffer* (TODO)