mirror of
https://github.com/zoriya/jj.nvim.git
synced 2026-08-05 10:46:08 +00:00
fix(picker): Reformat the file history picker (#127)
This commit is contained in:
+24
-43
@@ -17,11 +17,9 @@ local parser = require("jj.core.parser")
|
||||
|
||||
--- @class jj.picker.log_line
|
||||
--- @field text string The text to display in the picker
|
||||
--- @field symbol string The symbol of the log entry
|
||||
--- @field rev string The revision of the log entry
|
||||
--- @field author string The author of the log entry
|
||||
--- @field time string The time of the log entry
|
||||
--- @field commit_id string The commit id of the log entry
|
||||
--- @field description string The description of the log entry
|
||||
--- @field preview_cmd string[] The command used to preview the item
|
||||
--- @field confirm_action string The default picker action for the item
|
||||
@@ -160,13 +158,17 @@ function M.status()
|
||||
end
|
||||
end
|
||||
|
||||
---Parse jj log oneline
|
||||
--- Parse file history with a stable no-graph template.
|
||||
---@param file_path string The path of the file to log
|
||||
---@return jj.picker.log_line[]|nil A list of log lines or nil if not in a jj repo
|
||||
local function log_history(file_path)
|
||||
local format =
|
||||
"jj --no-pager log %s -r 'all()' -T builtin_log_oneline --config 'template-aliases.\"format_timestamp(timestamp)\"=timestamp'"
|
||||
local output, ok = runner.execute_command(string.format(format, file_path))
|
||||
local format = table.concat({
|
||||
"jj --no-pager log %s",
|
||||
"-r 'all() ~ @'",
|
||||
"--no-graph",
|
||||
[[ -T 'change_id.shortest() ++ "\t" ++ coalesce(author.name(), "(no author)") ++ "\t" ++ committer.timestamp() ++ "\t" ++ coalesce(description.first_line(), "(no description)") ++ "\n"' ]],
|
||||
}, " ")
|
||||
local output, ok = runner.execute_command(string.format(format, vim.fn.shellescape(file_path)))
|
||||
if not ok then
|
||||
return
|
||||
end
|
||||
@@ -179,45 +181,24 @@ local function log_history(file_path)
|
||||
local lines = vim.split(output, "\n", { trimempty = true })
|
||||
|
||||
for _, line in ipairs(lines) do
|
||||
-- Skip root line and elided revisions
|
||||
local not_empty = line:match("%S")
|
||||
local root = line:match("root%(%)")
|
||||
local elided = line:match("~%s*%(elided revisions%)%s*$")
|
||||
local parts = vim.split(line, "\t", { plain = true })
|
||||
if #parts >= 4 then
|
||||
local rev = parts[1]
|
||||
local author = parts[2]
|
||||
local time_part = parts[3]
|
||||
local description = table.concat(vim.list_slice(parts, 4), "\t")
|
||||
local short_time = time_part:match("^%d%d%d%d%-%d%d%-%d%d") or time_part
|
||||
|
||||
if not_empty and not root and not elided then
|
||||
-- Pattern: [symbol] [rev] [author] [time] [commit_id] [description]
|
||||
-- Example: @ w ngou0210 10 seconds ago e (no description set)
|
||||
-- Split at the first double space which signifies the end of the symbols
|
||||
local first_spaces = line:find("%s%s")
|
||||
if not first_spaces then
|
||||
goto continue
|
||||
end
|
||||
-- Split the line into parts
|
||||
-- The first part is the symbol, the second part is the revision, the third part is the author,
|
||||
local symbol = line:sub(1, first_spaces - 1)
|
||||
local rest_of_line = line:sub(first_spaces + 1)
|
||||
|
||||
local rev, author, time_part, commit_id, description =
|
||||
rest_of_line:match("^%s*(%S+)%s+(%S+)%s+(.-)%s+([%w]+)%s+(.*)$")
|
||||
|
||||
-- It does not make much sense to show the current commit
|
||||
if symbol and symbol ~= "@" then
|
||||
if rev and author and commit_id then
|
||||
table.insert(file_history, {
|
||||
symbol = symbol or "",
|
||||
rev = rev,
|
||||
author = author,
|
||||
time = time_part or "",
|
||||
commit_id = commit_id,
|
||||
description = description or "",
|
||||
text = line,
|
||||
preview_cmd = { "jj", "--no-pager", "diff", file_path, "-r", rev, "--stat", "--git" },
|
||||
confirm_action = "edit_revision",
|
||||
})
|
||||
end
|
||||
end
|
||||
table.insert(file_history, {
|
||||
rev = rev,
|
||||
author = author,
|
||||
time = time_part,
|
||||
description = description,
|
||||
text = string.format("%s %s %s %s", rev, author, short_time, description),
|
||||
preview_cmd = { "jj", "--no-pager", "diff", file_path, "-r", rev, "--stat", "--git" },
|
||||
confirm_action = "edit_revision",
|
||||
})
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
|
||||
return file_history
|
||||
|
||||
@@ -125,45 +125,17 @@ local function format_jj_log(item)
|
||||
local a = Snacks.picker.util.align
|
||||
local ret = {} ---@type snacks.picker.Highlight[]
|
||||
|
||||
-- Add symbol (if available) and revision
|
||||
if item.symbol and item.symbol ~= "" then
|
||||
ret[#ret + 1] = { a(item.symbol, 1, { truncate = true }), "SnacksPickerGitMsg" }
|
||||
else
|
||||
ret[#ret + 1] = { "?", "SnacksPickerGitMsg" }
|
||||
end
|
||||
|
||||
local rev = item.rev or "unknown"
|
||||
ret[#ret + 1] = { a(rev, 12, { truncate = true }), "SnacksPickerGitBreaking" }
|
||||
ret[#ret + 1] = { " " }
|
||||
|
||||
local rev = item.rev or "unknown"
|
||||
-- INFO: This highlight is kind of a nice hack to avoid doing my own highlighs for the moment
|
||||
--- At some point i'll probably do mines
|
||||
ret[#ret + 1] = { a(rev, 4, { truncate = true }), "SnacksPickerGitBreaking" }
|
||||
if #rev >= 4 then
|
||||
ret[#ret + 1] = { " " }
|
||||
end
|
||||
local author = item.author or "(no author)"
|
||||
ret[#ret + 1] = { a(author, 16, { truncate = true }), "Identifier" }
|
||||
ret[#ret + 1] = { " " }
|
||||
|
||||
if item.author then
|
||||
ret[#ret + 1] = { a(item.author, 8, { truncate = true }), "Identifier" }
|
||||
if #item.author >= 8 then
|
||||
ret[#ret + 1] = { " " }
|
||||
end
|
||||
end
|
||||
|
||||
if item.time then
|
||||
local year, month, day = item.time:match("(%d+)-(%d+)-(%d+)")
|
||||
local formatted = string.format("%s-%s-%s", year, day, month)
|
||||
ret[#ret + 1] = { a(formatted, 10), "SnacksPickerGitDate" }
|
||||
if #formatted >= 10 then
|
||||
ret[#ret + 1] = { " " }
|
||||
end
|
||||
end
|
||||
|
||||
if item.commit_id then
|
||||
ret[#ret + 1] = { a(item.commit_id, 10, { truncate = true }), "SnacksPickerGitCommit" }
|
||||
if #item.commit_id >= 4 then
|
||||
ret[#ret + 1] = { " " }
|
||||
end
|
||||
end
|
||||
local formatted_time = item.time and (item.time:match("^%d%d%d%d%-%d%d%-%d%d") or item.time) or ""
|
||||
ret[#ret + 1] = { a(formatted_time, 10, { truncate = true }), "SnacksPickerGitDate" }
|
||||
ret[#ret + 1] = { " " }
|
||||
|
||||
append_description_hl(ret, item.description)
|
||||
return ret
|
||||
|
||||
Reference in New Issue
Block a user