Skip to content

Commit 7bf4e53

Browse files
committed
feat(margin): add margin popup
1 parent 7a3daec commit 7bf4e53

File tree

8 files changed

+172
-1
lines changed

8 files changed

+172
-1
lines changed

lua/neogit/buffers/status/actions.lua

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,11 @@ M.v_log_popup = function(_self)
445445
return popups.open("log")
446446
end
447447

448+
---@param _self StatusBuffer
449+
M.v_margin_popup = function(_self)
450+
return popups.open("margin")
451+
end
452+
448453
---@param _self StatusBuffer
449454
M.v_worktree_popup = function(_self)
450455
return popups.open("worktree")
@@ -1408,6 +1413,11 @@ M.n_log_popup = function(_self)
14081413
return popups.open("log")
14091414
end
14101415

1416+
---@param _self StatusBuffer
1417+
M.n_margin_popup = function(_self)
1418+
return popups.open("margin")
1419+
end
1420+
14111421
---@param _self StatusBuffer
14121422
M.n_worktree_popup = function(_self)
14131423
return popups.open("worktree")

lua/neogit/buffers/status/init.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ function M:open(kind)
128128
[popups.mapping_for("HelpPopup")] = self:_action("v_help_popup"),
129129
[popups.mapping_for("IgnorePopup")] = self:_action("v_ignore_popup"),
130130
[popups.mapping_for("LogPopup")] = self:_action("v_log_popup"),
131+
[popups.mapping_for("MarginPopup")] = self:_action("v_margin_popup"),
131132
[popups.mapping_for("MergePopup")] = self:_action("v_merge_popup"),
132133
[popups.mapping_for("PullPopup")] = self:_action("v_pull_popup"),
133134
[popups.mapping_for("PushPopup")] = self:_action("v_push_popup"),
@@ -182,6 +183,7 @@ function M:open(kind)
182183
[popups.mapping_for("HelpPopup")] = self:_action("n_help_popup"),
183184
[popups.mapping_for("IgnorePopup")] = self:_action("n_ignore_popup"),
184185
[popups.mapping_for("LogPopup")] = self:_action("n_log_popup"),
186+
[popups.mapping_for("MarginPopup")] = self:_action("n_margin_popup"),
185187
[popups.mapping_for("MergePopup")] = self:_action("n_merge_popup"),
186188
[popups.mapping_for("PullPopup")] = self:_action("n_pull_popup"),
187189
[popups.mapping_for("PushPopup")] = self:_action("n_push_popup"),

lua/neogit/buffers/status/ui.lua

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ local Ui = require("neogit.lib.ui")
22
local Component = require("neogit.lib.ui.component")
33
local util = require("neogit.lib.util")
44
local common = require("neogit.buffers.common")
5+
local config = require("neogit.config")
56
local a = require("plenary.async")
67

78
local col = Ui.col
@@ -359,6 +360,78 @@ local SectionItemCommit = Component.new(function(item)
359360
end
360361
end
361362

363+
-- Render date
364+
if item.commit.rel_date:match(" years?,") then
365+
item.commit.rel_date, _ = item.commit.rel_date:gsub(" years?,", "y")
366+
item.commit.rel_date = item.commit.rel_date .. " "
367+
elseif item.commit.rel_date:match("^%d ") then
368+
item.commit.rel_date = " " .. item.commit.rel_date
369+
end
370+
371+
-- Render author and date in margin
372+
local state = require("neogit.lib.state")
373+
local visibility = state.get({ "margin", "visibility" }, false)
374+
local margin_date_style = state.get({ "margin", "date_style" }, 1)
375+
local details = state.get({ "margin", "details" }, false)
376+
local date
377+
local author_table = { "" }
378+
local date_table
379+
local date_width = 10
380+
local clamp_width = 30 -- to avoid having too much space when relative date is short
381+
382+
if margin_date_style == 1 then -- relative date (short)
383+
local unpacked = vim.split(item.commit.rel_date, " ")
384+
-- above, we added a space if the rel_date started with a single number
385+
-- we get the last two elements to deal with that
386+
local date_number = unpacked[#unpacked - 1]
387+
local date_quantifier = unpacked[#unpacked]
388+
if date_quantifier:match("months?") then
389+
date_quantifier = date_quantifier:gsub("m", "M") -- to distinguish from minutes
390+
end
391+
-- add back the space if we have a single number
392+
local left_pad
393+
if #unpacked > 2 then
394+
left_pad = " "
395+
else
396+
left_pad = ""
397+
end
398+
date = left_pad .. date_number .. date_quantifier:sub(1, 1)
399+
date_width = 3
400+
clamp_width = 23
401+
elseif margin_date_style == 2 then -- relative date (long)
402+
date = item.commit.rel_date
403+
date_width = 10
404+
else -- local iso date
405+
if config.values.log_date_format == nil then
406+
-- we get the unix date to be able to convert the date to
407+
-- the local timezone
408+
date = os.date("%Y-%m-%d %H:%M", item.commit.unix_date)
409+
date_width = 16 -- TODO: what should the width be here?
410+
else
411+
date = item.commit.log_date
412+
date_width = 16
413+
end
414+
end
415+
416+
date_table = { util.str_min_width(date, date_width), "Special" }
417+
418+
if details then
419+
author_table = {
420+
util.str_clamp(item.commit.author_name, clamp_width - (#date > date_width and #date or date_width)),
421+
"NeogitGraphAuthor",
422+
}
423+
end
424+
425+
if visibility then
426+
Virt = {
427+
{ " ", "Constant" },
428+
author_table,
429+
date_table,
430+
}
431+
else
432+
Virt = {}
433+
end
434+
362435
return row(
363436
util.merge(
364437
{ text.highlight("NeogitObjectId")(item.commit.abbreviated_commit) },
@@ -367,7 +440,12 @@ local SectionItemCommit = Component.new(function(item)
367440
ref_last,
368441
{ text(item.commit.subject) }
369442
),
370-
{ oid = item.commit.oid, yankable = item.commit.oid, item = item }
443+
{
444+
virtual_text = Virt,
445+
oid = item.commit.oid,
446+
yankable = item.commit.oid,
447+
item = item,
448+
}
371449
)
372450
end)
373451

lua/neogit/config.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ end
238238
---| "PushPopup"
239239
---| "CommitPopup"
240240
---| "LogPopup"
241+
---| "MarginPopup"
241242
---| "RevertPopup"
242243
---| "StashPopup"
243244
---| "IgnorePopup"
@@ -626,6 +627,7 @@ function M.get_default_values()
626627
["c"] = "CommitPopup",
627628
["f"] = "FetchPopup",
628629
["l"] = "LogPopup",
630+
["L"] = "MarginPopup",
629631
["m"] = "MergePopup",
630632
["p"] = "PullPopup",
631633
["r"] = "RebasePopup",

lua/neogit/lib/git/log.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ local commit_header_pat = "([| ]*)(%*?)([| ]*)commit (%w+)"
3030
---@field verification_flag string?
3131
---@field rel_date string
3232
---@field log_date string
33+
---@field unix_date string
3334

3435
---Parses the provided list of lines into a CommitLogEntry
3536
---@param raw string[]
@@ -340,6 +341,7 @@ local function format(show_signature)
340341
committer_date = "%cD",
341342
rel_date = "%cr",
342343
log_date = "%cd",
344+
unix_date = "%ct",
343345
}
344346

345347
if show_signature then

lua/neogit/popups/help/actions.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ M.popups = function(env)
7575
{ "LogPopup", "Log", popups.open("log", function(p)
7676
p(env.log)
7777
end) },
78+
{ "MarginPopup", "Margin", popups.open("margin", function(p)
79+
p(env.log)
80+
end) },
7881
{
7982
"CherryPickPopup",
8083
"Cherry Pick",

lua/neogit/popups/margin/actions.lua

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
local M = {}
2+
3+
local state = require("neogit.lib.state")
4+
5+
function M.toggle_visibility()
6+
local visibility = state.get({ "margin", "visibility" }, false)
7+
local new_visibility = not visibility
8+
state.set({ "margin", "visibility" }, new_visibility)
9+
end
10+
11+
function M.cycle_date_style()
12+
local styles = { "relative_short", "relative_long", "local_datetime" }
13+
local current_index = state.get({ "margin", "date_style" }, #styles)
14+
local next_index = (current_index % #styles) + 1 -- wrap around to the first style
15+
16+
state.set({ "margin", "date_style" }, next_index)
17+
end
18+
19+
function M.toggle_details()
20+
local details = state.get({ "margin", "details" }, false)
21+
local new_details = not details
22+
state.set({ "margin", "details" }, new_details)
23+
end
24+
25+
return M

lua/neogit/popups/margin/init.lua

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
local popup = require("neogit.lib.popup")
2+
local config = require("neogit.config")
3+
local actions = require("neogit.popups.margin.actions")
4+
5+
local M = {}
6+
7+
function M.create(env)
8+
local p = popup
9+
.builder()
10+
:name("NeogitMarginPopup")
11+
:option("n", "max-count", "256", "Limit number of commits", { default = "256", key_prefix = "-" })
12+
:switch("o", "topo", "Order commits by", {
13+
cli_suffix = "-order",
14+
options = {
15+
{ display = "", value = "" },
16+
{ display = "topo", value = "topo" },
17+
{ display = "author-date", value = "author-date" },
18+
{ display = "date", value = "date" },
19+
},
20+
})
21+
:switch("g", "graph", "Show graph", {
22+
enabled = true,
23+
internal = true,
24+
incompatible = { "reverse" },
25+
dependent = { "color" },
26+
})
27+
:switch_if(
28+
config.values.graph_style == "ascii" or config.values.graph_style == "kitty",
29+
"c",
30+
"color",
31+
"Show graph in color",
32+
{ internal = true, incompatible = { "reverse" } }
33+
)
34+
:switch("d", "decorate", "Show refnames", { enabled = true, internal = true })
35+
:group_heading("Refresh")
36+
:action("g", "buffer", actions.log_current)
37+
:new_action_group("Margin")
38+
:action("L", "toggle visibility", actions.toggle_visibility)
39+
:action("l", "cycle style", actions.cycle_date_style)
40+
:action("d", "toggle details", actions.toggle_details)
41+
:action("x", "toggle shortstat", actions.log_current)
42+
:build()
43+
44+
p:show()
45+
46+
return p
47+
end
48+
49+
return M

0 commit comments

Comments
 (0)