feat(object): render author/committer/tagger dates in human form
This commit is contained in:
+1
-16
@@ -56,21 +56,6 @@ function M.state(buf)
|
|||||||
return states[buf]
|
return states[buf]
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param ts integer
|
|
||||||
---@param tz string
|
|
||||||
---@return string
|
|
||||||
local function format_author_time(ts, tz)
|
|
||||||
local sign, hh, mm = tz:match("^([+-])(%d%d)(%d%d)$")
|
|
||||||
---@type number
|
|
||||||
local offset = 0
|
|
||||||
if sign then
|
|
||||||
local h = tonumber(hh) or 0
|
|
||||||
local m = tonumber(mm) or 0
|
|
||||||
offset = (h * 3600 + m * 60) * (sign == "-" and -1 or 1)
|
|
||||||
end
|
|
||||||
return os.date("!%Y-%m-%d %T ", ts + offset) .. tz
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param stdout string
|
---@param stdout string
|
||||||
---@return ow.Git.Blame.Result
|
---@return ow.Git.Blame.Result
|
||||||
local function parse_porcelain(stdout)
|
local function parse_porcelain(stdout)
|
||||||
@@ -534,7 +519,7 @@ local function open_popup(state, lnum, watch_buf)
|
|||||||
head = { "Not Committed Yet" }
|
head = { "Not Committed Yet" }
|
||||||
else
|
else
|
||||||
local short = sha:sub(1, 8)
|
local short = sha:sub(1, 8)
|
||||||
local date = format_author_time(commit.author_time, commit.author_tz)
|
local date = util.format_git_time(commit.author_time, commit.author_tz)
|
||||||
sha_len = #short
|
sha_len = #short
|
||||||
date_col = sha_len + 2 + #commit.author + 2
|
date_col = sha_len + 2 + #commit.author + 2
|
||||||
head = {
|
head = {
|
||||||
|
|||||||
@@ -120,6 +120,23 @@ function M.split_lines(content)
|
|||||||
return lines
|
return lines
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param ts integer
|
||||||
|
---@param tz string
|
||||||
|
---@return string
|
||||||
|
function M.format_git_time(ts, tz)
|
||||||
|
local sign, hh, mm = tz:match("^([+-])(%d%d)(%d%d)$")
|
||||||
|
local offset = 0
|
||||||
|
if sign then
|
||||||
|
local h = tonumber(hh) or 0
|
||||||
|
local m = tonumber(mm) or 0
|
||||||
|
offset = math.floor(h * 3600 + m * 60)
|
||||||
|
if sign == "-" then
|
||||||
|
offset = -offset
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return os.date("!%a %b %e %T %Y ", ts + offset) .. tz
|
||||||
|
end
|
||||||
|
|
||||||
---@param buf integer
|
---@param buf integer
|
||||||
---@param ns integer
|
---@param ns integer
|
||||||
---@param lines string[]
|
---@param lines string[]
|
||||||
|
|||||||
+26
-1
@@ -159,6 +159,29 @@ function M.buf_for(r, rev)
|
|||||||
return buf
|
return buf
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param lines string[]
|
||||||
|
local function format_header_dates(lines)
|
||||||
|
for i, line in ipairs(lines) do
|
||||||
|
if line == "" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local prefix, ts, tz = line:match("^(author .-) (%d+) ([+-]%d%d%d%d)$")
|
||||||
|
if not prefix then
|
||||||
|
prefix, ts, tz = line:match("^(committer .-) (%d+) ([+-]%d%d%d%d)$")
|
||||||
|
end
|
||||||
|
if not prefix then
|
||||||
|
prefix, ts, tz = line:match("^(tagger .-) (%d+) ([+-]%d%d%d%d)$")
|
||||||
|
end
|
||||||
|
if prefix then
|
||||||
|
local n = math.floor(assert(tonumber(ts)))
|
||||||
|
lines[i] = ("%s %s"):format(
|
||||||
|
prefix,
|
||||||
|
util.format_git_time(n, tz --[[@as string]])
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---@param buf integer
|
---@param buf integer
|
||||||
---@param r ow.Git.Repo
|
---@param r ow.Git.Repo
|
||||||
---@param rev ow.Git.Revision
|
---@param rev ow.Git.Revision
|
||||||
@@ -189,7 +212,9 @@ local function populate(buf, r, rev, state, rev_sha)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
util.set_buf_lines(buf, 0, -1, util.split_lines(stdout))
|
local lines = util.split_lines(stdout)
|
||||||
|
format_header_dates(lines)
|
||||||
|
util.set_buf_lines(buf, 0, -1, lines)
|
||||||
state.sha = rev_sha
|
state.sha = rev_sha
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -86,9 +86,9 @@ t.test("line popup formats the datetime in the author timezone", function()
|
|||||||
)
|
)
|
||||||
t.truthy(
|
t.truthy(
|
||||||
(lines[1] or ""):match(
|
(lines[1] or ""):match(
|
||||||
"%d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d [+%-]%d%d%d%d$"
|
"%u%l%l %u%l%l +%d+ %d%d:%d%d:%d%d %d%d%d%d [+%-]%d%d%d%d$"
|
||||||
),
|
),
|
||||||
"the head line ends with an ISO datetime and numeric timezone"
|
"the head line ends with a human datetime and numeric timezone"
|
||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -134,6 +134,45 @@ t.test("read_uri opens stage-0 entry as a writable index buffer", function()
|
|||||||
t.eq(vim.api.nvim_buf_get_lines(buf, 0, -1, false), { "first" })
|
t.eq(vim.api.nvim_buf_get_lines(buf, 0, -1, false), { "first" })
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
t.test("M.open renders author/committer dates, not unix timestamps", function()
|
||||||
|
local dir = h.make_repo({ a = "first\n" })
|
||||||
|
local r = assert(require("git.core.repo").resolve(dir))
|
||||||
|
|
||||||
|
object.open(r, "HEAD", { split = false })
|
||||||
|
local author = assert(find_line(0, "author "), "expected an author line")
|
||||||
|
local committer =
|
||||||
|
assert(find_line(0, "committer "), "expected a committer line")
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||||||
|
for _, lnum in ipairs({ author, committer }) do
|
||||||
|
local line = assert(lines[lnum])
|
||||||
|
t.truthy(
|
||||||
|
line:match(
|
||||||
|
" %u%l%l %u%l%l +%d+ %d%d:%d%d:%d%d %d%d%d%d [+-]%d%d%d%d$"
|
||||||
|
),
|
||||||
|
"expected formatted date on: " .. line
|
||||||
|
)
|
||||||
|
t.falsy(
|
||||||
|
line:match(" %d%d%d%d%d%d%d%d%d%d? [+-]%d%d%d%d$"),
|
||||||
|
"expected no unix timestamp on: " .. line
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
t.test("M.open renders tagger dates on annotated tags", function()
|
||||||
|
local dir = h.make_repo({ a = "first\n" })
|
||||||
|
h.git(dir, "tag", "-m", "rel", "v1")
|
||||||
|
local r = assert(require("git.core.repo").resolve(dir))
|
||||||
|
|
||||||
|
object.open(r, "v1", { split = false })
|
||||||
|
local tagger = assert(find_line(0, "tagger "), "expected a tagger line")
|
||||||
|
local line =
|
||||||
|
assert(vim.api.nvim_buf_get_lines(0, tagger - 1, tagger, false)[1])
|
||||||
|
t.truthy(
|
||||||
|
line:match(" %u%l%l %u%l%l +%d+ %d%d:%d%d:%d%d %d%d%d%d [+-]%d%d%d%d$"),
|
||||||
|
"expected formatted date on: " .. line
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
|
||||||
t.test("open_under_cursor on a 'tree <sha>' line opens the tree", function()
|
t.test("open_under_cursor on a 'tree <sha>' line opens the tree", function()
|
||||||
local dir = h.make_repo({ a = "first\n" })
|
local dir = h.make_repo({ a = "first\n" })
|
||||||
local r = assert(require("git.core.repo").resolve(dir))
|
local r = assert(require("git.core.repo").resolve(dir))
|
||||||
|
|||||||
Reference in New Issue
Block a user