From 7c7ec226c12582c9e88b3c0de1d47b0892a3c27a Mon Sep 17 00:00:00 2001 From: Steven Xu Date: Fri, 6 Dec 2024 04:28:25 +1100 Subject: [PATCH 01/11] feat: support viewing the diff via other pagers, e.g. *Delta* Add the `log_pager` option, which can be set to `delta`. --- README.md | 2 ++ doc/neogit.txt | 5 +++++ lua/neogit/buffers/common.lua | 33 +++++++++++++++++++++++++++++---- lua/neogit/config.lua | 2 ++ lua/neogit/lib/buffer.lua | 15 ++++++++++++++- lua/neogit/lib/git/diff.lua | 2 ++ 6 files changed, 54 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d6060a1b8..40d75eb6e 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,8 @@ neogit.setup { -- Show relative date by default. When set, use `strftime` to display dates commit_date_format = nil, log_date_format = nil, + -- When set, used to format the diff. + log_pager = nil, -- Show message with spinning animation when a git command is running. process_spinner = false, -- Used to generate URL's for branch popup action "pull request". diff --git a/doc/neogit.txt b/doc/neogit.txt index aa2a51574..3d9bff737 100644 --- a/doc/neogit.txt +++ b/doc/neogit.txt @@ -113,6 +113,11 @@ to Neovim users. -- Show relative date by default. When set, use `strftime` to display dates commit_date_format = nil, log_date_format = nil, + -- When set, used to format the diff. Requires *baleia* to colorize text with ANSI escape sequences. An example for + -- *Delta* is `{ 'delta', '--width', '117' }`. For *Delta*, hyperlinks must be disabled in its *Git* config section, + -- for text to be colorized properly. It's recommended to set `disable_context_highlighting = true`, otherwise when + -- the cursor is in the hunk, we lose background highlighting + log_pager = nil, -- Used to generate URL's for branch popup action "pull request". git_services = { ["github.com"] = "https://github.com/${owner}/${repository}/compare/${branch_name}?expand=1", diff --git a/lua/neogit/buffers/common.lua b/lua/neogit/buffers/common.lua index 2fd54566c..e51c19976 100644 --- a/lua/neogit/buffers/common.lua +++ b/lua/neogit/buffers/common.lua @@ -1,3 +1,5 @@ +local Job = require("plenary.job") + local Ui = require("neogit.lib.ui") local Component = require("neogit.lib.ui.component") local util = require("neogit.lib.util") @@ -25,22 +27,45 @@ M.Diff = Component.new(function(diff) }, { foldable = true, folded = false, context = true }) end) --- Use vim iter api? M.DiffHunks = Component.new(function(diff) local hunk_props = vim .iter(diff.hunks) :map(function(hunk) - hunk.content = vim.iter(diff.lines):slice(hunk.diff_from + 1, hunk.diff_to):totable() + local header = diff.lines[hunk.diff_from] + local content = vim.list_slice(diff.lines, hunk.diff_from + 1, hunk.diff_to) + local job = nil + if config.values.log_pager ~= nil then + job = Job:new { + command = config.values.log_pager[1], + args = vim.list_slice(config.values.log_pager, 2), + } + job:start() + for _, part in ipairs { diff.header, { header }, content } do + for _, line in ipairs(part) do + job:send(line .. "\n") + end + end + job.stdin:close() + end return { - header = diff.lines[hunk.diff_from], - content = hunk.content, + header = header, + content = content, + job = job, hunk = hunk, folded = hunk._folded, } end) :totable() + if config.values.log_pager ~= nil then + vim.iter(hunk_props):each(function(hunk) + hunk.job:wait() + hunk.content = hunk.job:result() + hunk.job = nil + end) + end + return col.tag("DiffContent") { col.tag("DiffInfo")(map(diff.info, text)), col.tag("HunkList")(map(hunk_props, M.Hunk)), diff --git a/lua/neogit/config.lua b/lua/neogit/config.lua index fd979e712..d39386968 100644 --- a/lua/neogit/config.lua +++ b/lua/neogit/config.lua @@ -327,6 +327,7 @@ end ---@field graph_style? NeogitGraphStyle Style for graph ---@field commit_date_format? string Commit date format ---@field log_date_format? string Log date format +---@field log_pager? [string] Log pager ---@field disable_hint? boolean Remove the top hint in the Status buffer ---@field disable_context_highlighting? boolean Disable context highlights based on cursor position ---@field disable_signs? boolean Special signs to draw for sections etc. in Neogit @@ -382,6 +383,7 @@ function M.get_default_values() graph_style = "ascii", commit_date_format = nil, log_date_format = nil, + log_pager = nil, process_spinner = false, filewatcher = { enabled = true, diff --git a/lua/neogit/lib/buffer.lua b/lua/neogit/lib/buffer.lua index 911a670ac..25179069d 100644 --- a/lua/neogit/lib/buffer.lua +++ b/lua/neogit/lib/buffer.lua @@ -147,8 +147,21 @@ function Buffer:set_extmarks(extmarks) end function Buffer:set_line_highlights(highlights) + local line_ansi_colorized = {} + for _, hl in ipairs(highlights) do - self:add_line_highlight(unpack(hl)) + local line_nr, hl_group = unpack(hl) + if hl_group == "NeogitDiffContext" then + if not line_ansi_colorized[line_nr] then + local text = self:get_line(line_nr + 1) + vim.g.baleia.buf_set_lines(self.handle, line_nr, line_nr + 1, false, text) + line_ansi_colorized[line_nr] = true + end + end + + if not line_ansi_colorized[line_nr] then + self:add_line_highlight(unpack(hl)) + end end end diff --git a/lua/neogit/lib/git/diff.lua b/lua/neogit/lib/git/diff.lua index 64d3be1fa..1e5d4a9a6 100644 --- a/lua/neogit/lib/git/diff.lua +++ b/lua/neogit/lib/git/diff.lua @@ -12,6 +12,7 @@ local sha256 = vim.fn.sha256 ---@field staged_stats fun(): DiffStagedStats --- ---@class Diff +---@field header string[] ---@field kind string ---@field lines string[] ---@field file string @@ -232,6 +233,7 @@ local function parse_diff(raw_diff, raw_stats) end) return { ---@type Diff + header = header, kind = kind, lines = lines, file = file, From 32006d97109d5fc72e9761ea727fc4e2c2d15710 Mon Sep 17 00:00:00 2001 From: Steven Xu Date: Sat, 7 Dec 2024 02:23:29 +1100 Subject: [PATCH 02/11] refactor: ANSI colorize continuous chunks at once - This improves the speed. - If not done, for large diffs we can get the error `PANIC: unprotected error in call to Lua API (EMFILE: too many open files)`. --- lua/neogit/lib/buffer.lua | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/lua/neogit/lib/buffer.lua b/lua/neogit/lib/buffer.lua index 25179069d..17ef01601 100644 --- a/lua/neogit/lib/buffer.lua +++ b/lua/neogit/lib/buffer.lua @@ -147,21 +147,38 @@ function Buffer:set_extmarks(extmarks) end function Buffer:set_line_highlights(highlights) - local line_ansi_colorized = {} + local line_ansi_colorized_map = {} for _, hl in ipairs(highlights) do local line_nr, hl_group = unpack(hl) if hl_group == "NeogitDiffContext" then - if not line_ansi_colorized[line_nr] then - local text = self:get_line(line_nr + 1) - vim.g.baleia.buf_set_lines(self.handle, line_nr, line_nr + 1, false, text) - line_ansi_colorized[line_nr] = true - end + line_ansi_colorized_map[line_nr] = true + else + self:add_line_highlight(unpack(hl)) end + end - if not line_ansi_colorized[line_nr] then - self:add_line_highlight(unpack(hl)) + local line_ansi_colorized = {} + for k in pairs(line_ansi_colorized_map) do + table.insert(line_ansi_colorized, k) + end + table.sort(line_ansi_colorized) + + local start_line_nr, prev_line_nr + for _, line_nr in ipairs(line_ansi_colorized) do + if start_line_nr == nil then + start_line_nr = line_nr end + if prev_line_nr ~= nil and line_nr ~= prev_line_nr + 1 then + local text = self:get_lines(start_line_nr, prev_line_nr + 1, false) + vim.g.baleia.buf_set_lines(self.handle, start_line_nr, prev_line_nr + 1, false, text) + start_line_nr = line_nr + end + prev_line_nr = line_nr + end + if start_line_nr ~= nil then + local text = self:get_lines(start_line_nr, prev_line_nr + 1, false) + vim.g.baleia.buf_set_lines(self.handle, start_line_nr, prev_line_nr + 1, false, text) end end From c3114011a3d1b92856404391a2bc288163743fc8 Mon Sep 17 00:00:00 2001 From: Steven Xu Date: Mon, 9 Dec 2024 02:15:27 +1100 Subject: [PATCH 03/11] docs: add *Delta* example for `log_pager` --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 40d75eb6e..5593ba1a5 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Here's an example spec for [Lazy](https://github.com/folke/lazy.nvim), but you'r dependencies = { "nvim-lua/plenary.nvim", -- required "sindrets/diffview.nvim", -- optional - Diff integration + "m00qek/baleia.nvim", -- optional - Required for a custom log pager -- Only one of these is needed. "nvim-telescope/telescope.nvim", -- optional @@ -83,7 +84,7 @@ neogit.setup { -- Show relative date by default. When set, use `strftime` to display dates commit_date_format = nil, log_date_format = nil, - -- When set, used to format the diff. + -- When set, used to format the diff. Requires *baleia* to colorize text with ANSI escape sequences. An example for *Delta* is `{ 'delta', '--width', '117' }`. It's recommended to set `disable_context_highlighting = true`, otherwise when the cursor is in the hunk, we lose background highlighting log_pager = nil, -- Show message with spinning animation when a git command is running. process_spinner = false, From 5b66aa050b6d628164f517424942a1b4ec229f40 Mon Sep 17 00:00:00 2001 From: Steven Xu Date: Mon, 9 Dec 2024 18:28:23 +1100 Subject: [PATCH 04/11] docs: for *Delta*, hyperlinks must be disabled in its *Git* config section --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5593ba1a5..66fe5b117 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ neogit.setup { -- Show relative date by default. When set, use `strftime` to display dates commit_date_format = nil, log_date_format = nil, - -- When set, used to format the diff. Requires *baleia* to colorize text with ANSI escape sequences. An example for *Delta* is `{ 'delta', '--width', '117' }`. It's recommended to set `disable_context_highlighting = true`, otherwise when the cursor is in the hunk, we lose background highlighting + -- When set, used to format the diff. Requires *baleia* to colorize text with ANSI escape sequences. An example for *Delta* is `{ 'delta', '--width', '117' }`. For *Delta*, hyperlinks must be disabled in its *Git* config section, for text to be colorized properly. It's recommended to set `disable_context_highlighting = true`, otherwise when the cursor is in the hunk, we lose background highlighting log_pager = nil, -- Show message with spinning animation when a git command is running. process_spinner = false, From d401e70530f7e429837700fb8aaec33078509a40 Mon Sep 17 00:00:00 2001 From: Steven Xu Date: Tue, 10 Dec 2024 04:04:13 +1100 Subject: [PATCH 05/11] refactor: use `vim.system()` instead of *plenary* to run `config.values.log_pager` --- lua/neogit/buffers/common.lua | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/lua/neogit/buffers/common.lua b/lua/neogit/buffers/common.lua index e51c19976..d07204f43 100644 --- a/lua/neogit/buffers/common.lua +++ b/lua/neogit/buffers/common.lua @@ -1,5 +1,3 @@ -local Job = require("plenary.job") - local Ui = require("neogit.lib.ui") local Component = require("neogit.lib.ui.component") local util = require("neogit.lib.util") @@ -35,17 +33,13 @@ M.DiffHunks = Component.new(function(diff) local content = vim.list_slice(diff.lines, hunk.diff_from + 1, hunk.diff_to) local job = nil if config.values.log_pager ~= nil then - job = Job:new { - command = config.values.log_pager[1], - args = vim.list_slice(config.values.log_pager, 2), - } - job:start() + job = vim.system(config.values.log_pager, { stdin = true }) for _, part in ipairs { diff.header, { header }, content } do for _, line in ipairs(part) do - job:send(line .. "\n") + job:write(line .. "\n") end end - job.stdin:close() + job:write() end return { @@ -60,8 +54,7 @@ M.DiffHunks = Component.new(function(diff) if config.values.log_pager ~= nil then vim.iter(hunk_props):each(function(hunk) - hunk.job:wait() - hunk.content = hunk.job:result() + hunk.content = vim.split(hunk.job:wait().stdout, "\n") hunk.job = nil end) end From d47aee8fb36816486e33f15999e811ccf13a13a8 Mon Sep 17 00:00:00 2001 From: Steven Xu Date: Tue, 10 Dec 2024 05:11:36 +1100 Subject: [PATCH 06/11] refactor: run the pager in `neogit.lib.git.diff` `build_pager_contents()` --- lua/neogit/buffers/common.lua | 39 +++++++-------------------------- lua/neogit/lib/git/diff.lua | 41 +++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 33 deletions(-) diff --git a/lua/neogit/buffers/common.lua b/lua/neogit/buffers/common.lua index d07204f43..80a948196 100644 --- a/lua/neogit/buffers/common.lua +++ b/lua/neogit/buffers/common.lua @@ -26,37 +26,14 @@ M.Diff = Component.new(function(diff) end) M.DiffHunks = Component.new(function(diff) - local hunk_props = vim - .iter(diff.hunks) - :map(function(hunk) - local header = diff.lines[hunk.diff_from] - local content = vim.list_slice(diff.lines, hunk.diff_from + 1, hunk.diff_to) - local job = nil - if config.values.log_pager ~= nil then - job = vim.system(config.values.log_pager, { stdin = true }) - for _, part in ipairs { diff.header, { header }, content } do - for _, line in ipairs(part) do - job:write(line .. "\n") - end - end - job:write() - end - - return { - header = header, - content = content, - job = job, - hunk = hunk, - folded = hunk._folded, - } - end) - :totable() - - if config.values.log_pager ~= nil then - vim.iter(hunk_props):each(function(hunk) - hunk.content = vim.split(hunk.job:wait().stdout, "\n") - hunk.job = nil - end) + local hunk_props = {} + for i, hunk in ipairs(diff.hunks) do + table.insert(hunk_props, { + header = diff.lines[hunk.diff_from], + content = diff.pager_contents[i], + hunk = hunk, + folded = hunk._folded, + }) end return col.tag("DiffContent") { diff --git a/lua/neogit/lib/git/diff.lua b/lua/neogit/lib/git/diff.lua index 1e5d4a9a6..fa750dfe4 100644 --- a/lua/neogit/lib/git/diff.lua +++ b/lua/neogit/lib/git/diff.lua @@ -1,6 +1,7 @@ local a = require("plenary.async") local git = require("neogit.lib.git") local util = require("neogit.lib.util") +local config = require("neogit.config") local logger = require("neogit.logger") local insert = table.insert @@ -12,13 +13,13 @@ local sha256 = vim.fn.sha256 ---@field staged_stats fun(): DiffStagedStats --- ---@class Diff ----@field header string[] ---@field kind string ---@field lines string[] ---@field file string ---@field info table ---@field stats table ---@field hunks Hunk +---@field pager_contents string[] --- ---@class DiffStats ---@field additions number @@ -216,6 +217,41 @@ local function build_hunks(lines) return hunks end +---@param diff_header string[] +---@param lines string[] +---@param hunks Hunk[] +---@return string[][] +local function build_pager_contents(diff_header, lines, hunks) + local res = {} + local jobs = {} + vim.iter(hunks):each(function(hunk) + local header = lines[hunk.diff_from] + local content = vim.list_slice(lines, hunk.diff_from + 1, hunk.diff_to) + if config.values.log_pager == nil then + insert(res, content) + return + end + + local job = vim.system(config.values.log_pager, { stdin = true }) + for _, part in ipairs { diff_header, { header }, content } do + for _, line in ipairs(part) do + job:write(line .. "\n") + end + end + job:write() + insert(jobs, job) + end) + + if config.values.log_pager ~= nil then + vim.iter(jobs):each(function(job) + local content = vim.split(job:wait().stdout, "\n") + insert(res, content) + end) + end + + return res +end + ---@param raw_diff string[] ---@param raw_stats string[] ---@return Diff @@ -223,6 +259,7 @@ local function parse_diff(raw_diff, raw_stats) local header, start_idx = build_diff_header(raw_diff) local lines = build_lines(raw_diff, start_idx) local hunks = build_hunks(lines) + local pager_contents = build_pager_contents(header, lines, hunks) local kind, info = build_kind(header) local file = build_file(header, kind) local stats = parse_diff_stats(raw_stats or {}) @@ -233,13 +270,13 @@ local function parse_diff(raw_diff, raw_stats) end) return { ---@type Diff - header = header, kind = kind, lines = lines, file = file, info = info, stats = stats, hunks = hunks, + pager_contents = pager_contents, } end From 2d8fca6fdf07547f705adc23a7723f78d6d59405 Mon Sep 17 00:00:00 2001 From: Steven Xu Date: Thu, 12 Dec 2024 19:15:23 +1100 Subject: [PATCH 07/11] refactor: move `Buffer:set_line_highlights()` ANSI highlights to `Buffer:set_ansi_highlights()`, to avoid finding hunk line numbers manually with the hard-coded `NeogitDiffContext` - Add `ansi_hl` to `ComponentOptions`, to indicate whether the component needs ANSI highlighting. - Add `ansi_highlight` to `RendererBuffer`, to pass hunk line numbers. --- lua/neogit/buffers/common.lua | 8 +++++++- lua/neogit/lib/buffer.lua | 36 +++++++-------------------------- lua/neogit/lib/ui/component.lua | 1 + lua/neogit/lib/ui/init.lua | 1 + lua/neogit/lib/ui/renderer.lua | 9 +++++++++ 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/lua/neogit/buffers/common.lua b/lua/neogit/buffers/common.lua index 80a948196..409599021 100644 --- a/lua/neogit/buffers/common.lua +++ b/lua/neogit/buffers/common.lua @@ -83,7 +83,13 @@ M.Hunk = Component.new(function(props) return col.tag("Hunk")({ text.line_hl("NeogitHunkHeader")(props.header), col.tag("HunkContent")(map(props.content, HunkLine)), - }, { foldable = true, folded = props.folded or false, context = true, hunk = props.hunk }) + }, { + ansi_hl = config.values.log_pager ~= nil, + foldable = true, + folded = props.folded or false, + context = true, + hunk = props.hunk, + }) end) M.List = Component.new(function(props) diff --git a/lua/neogit/lib/buffer.lua b/lua/neogit/lib/buffer.lua index 17ef01601..eacc9de03 100644 --- a/lua/neogit/lib/buffer.lua +++ b/lua/neogit/lib/buffer.lua @@ -147,38 +147,16 @@ function Buffer:set_extmarks(extmarks) end function Buffer:set_line_highlights(highlights) - local line_ansi_colorized_map = {} - for _, hl in ipairs(highlights) do - local line_nr, hl_group = unpack(hl) - if hl_group == "NeogitDiffContext" then - line_ansi_colorized_map[line_nr] = true - else - self:add_line_highlight(unpack(hl)) - end - end - - local line_ansi_colorized = {} - for k in pairs(line_ansi_colorized_map) do - table.insert(line_ansi_colorized, k) + self:add_line_highlight(unpack(hl)) end - table.sort(line_ansi_colorized) +end - local start_line_nr, prev_line_nr - for _, line_nr in ipairs(line_ansi_colorized) do - if start_line_nr == nil then - start_line_nr = line_nr - end - if prev_line_nr ~= nil and line_nr ~= prev_line_nr + 1 then - local text = self:get_lines(start_line_nr, prev_line_nr + 1, false) - vim.g.baleia.buf_set_lines(self.handle, start_line_nr, prev_line_nr + 1, false, text) - start_line_nr = line_nr - end - prev_line_nr = line_nr - end - if start_line_nr ~= nil then - local text = self:get_lines(start_line_nr, prev_line_nr + 1, false) - vim.g.baleia.buf_set_lines(self.handle, start_line_nr, prev_line_nr + 1, false, text) +function Buffer:set_ansi_highlights(highlights) + for _, hl in ipairs(highlights) do + local first_line, last_line = unpack(hl) + local text = self:get_lines(first_line, last_line, false) + vim.g.baleia.buf_set_lines(self.handle, first_line, last_line, false, text) end end diff --git a/lua/neogit/lib/ui/component.lua b/lua/neogit/lib/ui/component.lua index ae737977c..15c8f2375 100644 --- a/lua/neogit/lib/ui/component.lua +++ b/lua/neogit/lib/ui/component.lua @@ -13,6 +13,7 @@ local default_component_options = { ---@class ComponentOptions ---@field line_hl string +---@field ansi_hl boolean ---@field highlight string ---@field align_right integer|nil ---@field padding_left integer diff --git a/lua/neogit/lib/ui/init.lua b/lua/neogit/lib/ui/init.lua index 6e4ef243a..468570553 100644 --- a/lua/neogit/lib/ui/init.lua +++ b/lua/neogit/lib/ui/init.lua @@ -700,6 +700,7 @@ function Ui:update() self.buf:set_highlights(renderer.buffer.highlight) self.buf:set_extmarks(renderer.buffer.extmark) self.buf:set_line_highlights(renderer.buffer.line_highlight) + self.buf:set_ansi_highlights(renderer.buffer.ansi_highlight) self.buf:set_folds(renderer.buffer.fold) self.statuscolumn = {} diff --git a/lua/neogit/lib/ui/renderer.lua b/lua/neogit/lib/ui/renderer.lua index 00fce647c..641e14f3f 100644 --- a/lua/neogit/lib/ui/renderer.lua +++ b/lua/neogit/lib/ui/renderer.lua @@ -65,6 +65,7 @@ end ---@field line string[] ---@field highlight table[] ---@field line_highlight table[] +---@field ansi_highlight table[] ---@field extmark table[] ---@field fold table[] @@ -93,6 +94,7 @@ function Renderer:new(layout, buffer) line = {}, highlight = {}, line_highlight = {}, + ansi_highlight = {}, extmark = {}, fold = {}, }, @@ -194,6 +196,13 @@ function Renderer:_render_child(child) table.insert(self.buffer.line_highlight, { #self.buffer.line - 1, line_hl }) end + if child.options.ansi_hl then + table.insert(self.buffer.ansi_highlight, { + #self.buffer.line - (child.position.row_end - child.position.row_start), + #self.buffer.line, + }) + end + if child.options.virtual_text then table.insert(self.buffer.extmark, { self.namespace, From f693a3a33436b853569bd32dd9fbe663f948d53a Mon Sep 17 00:00:00 2001 From: Steven Xu Date: Wed, 18 Dec 2024 19:37:05 +1100 Subject: [PATCH 08/11] feat: handle "Erase in Line" We don't support coloring the rest of the line. --- lua/neogit/lib/buffer.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lua/neogit/lib/buffer.lua b/lua/neogit/lib/buffer.lua index eacc9de03..538153235 100644 --- a/lua/neogit/lib/buffer.lua +++ b/lua/neogit/lib/buffer.lua @@ -156,6 +156,18 @@ function Buffer:set_ansi_highlights(highlights) for _, hl in ipairs(highlights) do local first_line, last_line = unpack(hl) local text = self:get_lines(first_line, last_line, false) + + for i, line in ipairs(text) do + if line:match("\27%[0K\27%[0m$") then + -- Handle "Erase in Line". We don't support coloring the rest of the line. + line = line:gsub("\27%[0K\27%[0m$", "") + if i < #text then + text[i + 1] = "\27[0m" .. text[i + 1] + end + end + text[i] = line + end + vim.g.baleia.buf_set_lines(self.handle, first_line, last_line, false, text) end end From fab3ce52c43cafb6ccc757d07b0fa6cd3ebeda98 Mon Sep 17 00:00:00 2001 From: Steven Xu Date: Fri, 20 Dec 2024 19:08:29 +1100 Subject: [PATCH 09/11] docs: switch from `*` to ` `` `, as help documents treat that as a tag --- README.md | 2 +- doc/neogit.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 66fe5b117..823e89fe8 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ neogit.setup { -- Show relative date by default. When set, use `strftime` to display dates commit_date_format = nil, log_date_format = nil, - -- When set, used to format the diff. Requires *baleia* to colorize text with ANSI escape sequences. An example for *Delta* is `{ 'delta', '--width', '117' }`. For *Delta*, hyperlinks must be disabled in its *Git* config section, for text to be colorized properly. It's recommended to set `disable_context_highlighting = true`, otherwise when the cursor is in the hunk, we lose background highlighting + -- When set, used to format the diff. Requires *baleia* to colorize text with ANSI escape sequences. An example for `Delta` is `{ 'delta', '--width', '117' }`. For `Delta`, hyperlinks must be disabled in its git config section, for text to be colorized properly. It's recommended to set `disable_context_highlighting = true`, otherwise when the cursor is in the hunk, we lose background highlighting log_pager = nil, -- Show message with spinning animation when a git command is running. process_spinner = false, diff --git a/doc/neogit.txt b/doc/neogit.txt index 3d9bff737..8e4a8bc51 100644 --- a/doc/neogit.txt +++ b/doc/neogit.txt @@ -113,8 +113,8 @@ to Neovim users. -- Show relative date by default. When set, use `strftime` to display dates commit_date_format = nil, log_date_format = nil, - -- When set, used to format the diff. Requires *baleia* to colorize text with ANSI escape sequences. An example for - -- *Delta* is `{ 'delta', '--width', '117' }`. For *Delta*, hyperlinks must be disabled in its *Git* config section, + -- When set, used to format the diff. Requires `baleia` to colorize text with ANSI escape sequences. An example for + -- `Delta` is `{ 'delta', '--width', '117' }`. For `Delta`, hyperlinks must be disabled in its git config section, -- for text to be colorized properly. It's recommended to set `disable_context_highlighting = true`, otherwise when -- the cursor is in the hunk, we lose background highlighting log_pager = nil, From 108985c8a8c77884faec3a753b51eb0fbf24275d Mon Sep 17 00:00:00 2001 From: Steven Xu Date: Fri, 20 Dec 2024 19:28:02 +1100 Subject: [PATCH 10/11] test: add `pager_contents` to `subject.parse()` specs --- tests/specs/neogit/lib/git/log_spec.lua | 74 +++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/tests/specs/neogit/lib/git/log_spec.lua b/tests/specs/neogit/lib/git/log_spec.lua index f3618c353..fd0a8fbc9 100644 --- a/tests/specs/neogit/lib/git/log_spec.lua +++ b/tests/specs/neogit/lib/git/log_spec.lua @@ -232,6 +232,67 @@ describe("lib.git.log.parse", function() " ", " ---@param selection Selection", }, + pager_contents = { + { + " ---@param first_line number", + " ---@param last_line number", + " ---@param partial boolean", + "----@return SelectedHunk[],string[]", + "+---@return SelectedHunk[]", + " function M.get_item_hunks(item, first_line, last_line, partial)", + " if item.folded or item.hunks == nil then", + "- return {}, {}", + "+ return {}", + " end", + " ", + " local hunks = {}", + "- local lines = {}", + " ", + " for _, h in ipairs(item.hunks) do", + "- -- Transform to be relative to the current item/file", + "- local first_line = first_line - item.first", + "- local last_line = last_line - item.first", + "-", + "- if h.diff_from <= last_line and h.diff_to >= first_line then", + "- -- Relative to the hunk", + "+ if h.first <= last_line and h.last >= first_line then", + " local from, to", + "+", + " if partial then", + "- from = h.diff_from + math.max(first_line - h.diff_from, 0)", + "- to = math.min(last_line, h.diff_to)", + "+ local length = last_line - first_line", + "+ from = h.diff_from + math.max((first_line - item.first) - h.diff_from, 0)", + "+ to = from + length", + " else", + " from = h.diff_from + 1", + " to = h.diff_to", + " end", + " ", + " local hunk_lines = {}", + "-", + " for i = from, to do", + " table.insert(hunk_lines, item.diff.lines[i])", + " end", + }, + { + " setmetatable(o, o)", + " ", + " table.insert(hunks, o)", + "-", + "- for i = from, to do", + "- table.insert(lines, item.diff.lines[i + h.diff_from])", + "- end", + " end", + " end", + " ", + "- return hunks, lines", + "+ return hunks", + " end", + " ", + " ---@param selection Selection", + }, + }, stats = { additions = 0, deletions = 0, @@ -320,6 +381,19 @@ describe("lib.git.log.parse", function() ' of this software and associated documentation files (the "Software"), to deal', " in the Software without restriction, including without limitation the rights", }, + pager_contents = { + { + " MIT License", + " ", + "+hello", + " Copyright (c) 2020 TimUntersberger", + " ", + "+world", + " Permission is hereby granted, free of charge, to any person obtaining a copy", + ' of this software and associated documentation files (the "Software"), to deal', + " in the Software without restriction, including without limitation the rights", + }, + }, stats = { additions = 0, deletions = 0, From ceb079111a98dbac4af96bb0946bf9b36660a289 Mon Sep 17 00:00:00 2001 From: Steven Xu Date: Thu, 22 May 2025 19:54:26 +1000 Subject: [PATCH 11/11] fix: match from the start of the line when building hunks, or `.diff` files will be shown incorrectly --- lua/neogit/lib/git/diff.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/neogit/lib/git/diff.lua b/lua/neogit/lib/git/diff.lua index fa750dfe4..ccf7609af 100644 --- a/lua/neogit/lib/git/diff.lua +++ b/lua/neogit/lib/git/diff.lua @@ -168,10 +168,10 @@ local function build_hunks(lines) if line:match("^@@@") then -- Combined diff header - index_from, index_len, disk_from, disk_len = line:match("@@@* %-(%d+),?(%d*) .* %+(%d+),?(%d*) @@@*") + index_from, index_len, disk_from, disk_len = line:match("^@@@* %-(%d+),?(%d*) .* %+(%d+),?(%d*) @@@*") else -- Normal diff header - index_from, index_len, disk_from, disk_len = line:match("@@ %-(%d+),?(%d*) %+(%d+),?(%d*) @@") + index_from, index_len, disk_from, disk_len = line:match("^@@ %-(%d+),?(%d*) %+(%d+),?(%d*) @@") end if index_from then