Skip to content

Commit 60a196e

Browse files
committed
feat(config): add options visual appearance options
1 parent 56b617b commit 60a196e

8 files changed

Lines changed: 148 additions & 20 deletions

File tree

doc/diffview.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,14 @@ file_panel *diffview-config-file_panel*
785785
contain a single directory. Default: `true`
786786
• {folder_statuses} ("never"|"only_folded"|"always")
787787
Show folder statuses. Default: `"only_folded"`
788+
• {folder_count_style} ("grouped"|"simple")
789+
How to display file counts on collapsed folders.
790+
`"grouped"` shows per-status counts (e.g. "2M 1D"),
791+
`"simple"` shows a plain total (e.g. "3").
792+
Default: `"grouped"`
793+
• {folder_trailing_slash} (boolean)
794+
Append "/" to folder names in the file tree.
795+
Default: `true`
788796

789797
{win_config} (table|function)
790798
See |diffview-config-win_config|.
@@ -815,6 +823,12 @@ file_history_panel *diffview-config-file_history_pa
815823
"5, 3", `"bar"` shows e.g. "| 8 +++++---". Default:
816824
`"number"`
817825

826+
{subject_highlight} ("ref_aware"|"plain")
827+
How to highlight commit subjects. `"ref_aware"` uses
828+
different colours for pushed vs unpushed commits.
829+
`"plain"` uses a single colour for all.
830+
Default: `"ref_aware"`
831+
818832
{commit_format} (string[])
819833
Ordered list of components to show for each commit entry.
820834
Available components: `"status"`, `"files"`, `"stats"`,

doc/diffview_defaults.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ DEFAULT CONFIG *diffview.defaults*
8989
tree_options = { -- Only applies when listing_style is 'tree'
9090
flatten_dirs = true, -- Flatten dirs that only contain one single dir
9191
folder_statuses = "only_folded", -- One of 'never', 'only_folded' or 'always'.
92+
folder_count_style = "grouped", -- "grouped" (e.g. "2M 1D") or "simple" (e.g. "3").
93+
folder_trailing_slash = true, -- Append "/" to folder names in the file tree.
9294
},
9395
win_config = { -- See |diffview-config-win_config|
9496
position = "left",
@@ -102,6 +104,7 @@ DEFAULT CONFIG *diffview.defaults*
102104
},
103105
file_history_panel = {
104106
stat_style = "number", -- "number" (e.g. "5, 3"), "bar" (e.g. "| 8 +++++---"), or "both".
107+
subject_highlight = "ref_aware", -- "ref_aware" (colour by pushed/unpushed) or "plain".
105108
-- Ordered list of components to show for each commit entry.
106109
-- Available: "status", "files", "stats", "hash", "reflog", "ref", "subject", "author", "date"
107110
commit_format = { "status", "files", "stats", "hash", "reflog", "ref", "subject", "author", "date" },

lua/diffview/config.lua

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ M.defaults = {
152152
sort_file = nil, -- Custom file comparator: function(a_name, b_name, a_data, b_data) -> boolean
153153
tree_options = {
154154
flatten_dirs = true,
155-
folder_statuses = "only_folded"
155+
folder_statuses = "only_folded",
156+
folder_count_style = "grouped", -- "grouped" (e.g. "2M 1D") or "simple" (e.g. "3").
157+
folder_trailing_slash = true, -- Append "/" to folder names in the file tree.
156158
},
157159
win_config = {
158160
position = "left",
@@ -166,6 +168,7 @@ M.defaults = {
166168
},
167169
file_history_panel = {
168170
stat_style = "number", -- "number" (e.g. "5, 3"), "bar" (e.g. "| 8 +++++---"), or "both".
171+
subject_highlight = "ref_aware", -- "ref_aware" (colour by pushed/unpushed) or "plain".
169172
-- Ordered list of components to show for each commit entry.
170173
-- Available: "status", "files", "stats", "hash", "reflog", "ref", "subject", "author", "date"
171174
commit_format = { "status", "files", "stats", "hash", "reflog", "ref", "subject", "author", "date" },

lua/diffview/scene/views/diff/file_panel.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ local M = {}
99
---@class TreeOptions
1010
---@field flatten_dirs boolean
1111
---@field folder_statuses "never"|"only_folded"|"always"
12+
---@field folder_count_style "grouped"|"simple"
13+
---@field folder_trailing_slash boolean
1214

1315
---@class FilePanel : Panel
1416
---@field adapter VCSAdapter

lua/diffview/scene/views/diff/render.lua

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -161,28 +161,34 @@ local function render_file_tree_recurse(conf, panel, depth, comp)
161161
"DiffviewFolderSign"
162162
)
163163

164-
dir:add_text(ctx.name .. "/", "DiffviewFolderName")
165-
-- Show file count grouped by status when folder is collapsed.
164+
local tree_options = conf.file_panel.tree_options
165+
dir:add_text(ctx.name .. (tree_options.folder_trailing_slash and "/" or ""), "DiffviewFolderName")
166+
-- Show file count when folder is collapsed.
166167
if ctx.collapsed and ctx._node then
167-
local leaves = ctx._node:leaves()
168-
local status_counts = {}
169-
for _, node in ipairs(leaves) do
170-
local s = node.data.status or "?"
171-
status_counts[s] = (status_counts[s] or 0) + 1
172-
end
168+
if tree_options.folder_count_style == "grouped" then
169+
local leaves = ctx._node:leaves()
170+
local status_counts = {}
171+
for _, node in ipairs(leaves) do
172+
local s = node.data.status or "?"
173+
status_counts[s] = (status_counts[s] or 0) + 1
174+
end
173175

174-
-- Sort status letters for consistent display order.
175-
local statuses = vim.tbl_keys(status_counts)
176-
table.sort(statuses)
176+
-- Sort status letters for consistent display order.
177+
local statuses = vim.tbl_keys(status_counts)
178+
table.sort(statuses)
177179

178-
dir:add_text(" (", "DiffviewDim1")
179-
for i, s in ipairs(statuses) do
180-
if i > 1 then
181-
dir:add_text(" ", "DiffviewDim1")
180+
dir:add_text(" (", "DiffviewDim1")
181+
for i, s in ipairs(statuses) do
182+
if i > 1 then
183+
dir:add_text(" ", "DiffviewDim1")
184+
end
185+
dir:add_text(tostring(status_counts[s]) .. hl.get_status_icon(s), hl.get_git_hl(s))
182186
end
183-
dir:add_text(tostring(status_counts[s]) .. hl.get_status_icon(s), hl.get_git_hl(s))
187+
dir:add_text(")", "DiffviewDim1")
188+
else
189+
local file_count = #ctx._node:leaves()
190+
dir:add_text(" (" .. file_count .. ")", "DiffviewDim1")
184191
end
185-
dir:add_text(")", "DiffviewDim1")
186192
end
187193
dir:ln()
188194

lua/diffview/scene/views/file_history/render.lua

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,12 @@ local formatters = {
180180
local subject_hl
181181
if ctx.panel.cur_item[1] == entry then
182182
subject_hl = "DiffviewFilePanelSelected"
183-
elseif entry.has_remote_ref then
183+
elseif ctx.conf.file_history_panel.subject_highlight == "ref_aware" and entry.has_remote_ref then
184184
subject_hl = "DiffviewCommitRemoteRef"
185-
else
185+
elseif ctx.conf.file_history_panel.subject_highlight == "ref_aware" then
186186
subject_hl = "DiffviewCommitLocalOnly"
187+
else
188+
subject_hl = "DiffviewFilePanelFileName"
187189
end
188190

189191
comp:add_text(" " .. subject, subject_hl)

lua/diffview/tests/functional/file_history_render_spec.lua

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,69 @@ describe("file_history_render", function()
340340
end)
341341
end)
342342

343+
-- -----------------------------------------------------------------------
344+
-- subject_highlight
345+
-- -----------------------------------------------------------------------
346+
347+
describe("subject_highlight", function()
348+
---Replicate the subject highlight selection logic from render.lua.
349+
---@param conf table
350+
---@param entry table
351+
---@param is_selected boolean
352+
---@return string
353+
local function resolve_subject_hl(conf, entry, is_selected)
354+
if is_selected then
355+
return "DiffviewFilePanelSelected"
356+
elseif conf.file_history_panel.subject_highlight == "ref_aware" and entry.has_remote_ref then
357+
return "DiffviewCommitRemoteRef"
358+
elseif conf.file_history_panel.subject_highlight == "ref_aware" then
359+
return "DiffviewCommitLocalOnly"
360+
else
361+
return "DiffviewFilePanelFileName"
362+
end
363+
end
364+
365+
it("uses DiffviewFilePanelFileName for 'plain' mode", function()
366+
local conf = config.get_config()
367+
conf.file_history_panel.subject_highlight = "plain"
368+
config.setup(conf)
369+
370+
local entry = { has_remote_ref = true }
371+
eq("DiffviewFilePanelFileName", resolve_subject_hl(config.get_config(), entry, false))
372+
end)
373+
374+
it("uses DiffviewCommitRemoteRef for 'ref_aware' with remote ref", function()
375+
local conf = config.get_config()
376+
conf.file_history_panel.subject_highlight = "ref_aware"
377+
config.setup(conf)
378+
379+
local entry = { has_remote_ref = true }
380+
eq("DiffviewCommitRemoteRef", resolve_subject_hl(config.get_config(), entry, false))
381+
end)
382+
383+
it("uses DiffviewCommitLocalOnly for 'ref_aware' without remote ref", function()
384+
local conf = config.get_config()
385+
conf.file_history_panel.subject_highlight = "ref_aware"
386+
config.setup(conf)
387+
388+
local entry = { has_remote_ref = false }
389+
eq("DiffviewCommitLocalOnly", resolve_subject_hl(config.get_config(), entry, false))
390+
end)
391+
392+
it("uses DiffviewFilePanelSelected when entry is selected", function()
393+
local conf = config.get_config()
394+
conf.file_history_panel.subject_highlight = "ref_aware"
395+
config.setup(conf)
396+
397+
local entry = { has_remote_ref = true }
398+
eq("DiffviewFilePanelSelected", resolve_subject_hl(config.get_config(), entry, true))
399+
end)
400+
401+
it("defaults to 'ref_aware'", function()
402+
eq("ref_aware", config.get_config().file_history_panel.subject_highlight)
403+
end)
404+
end)
405+
343406
-- -----------------------------------------------------------------------
344407
-- date_format config default
345408
-- -----------------------------------------------------------------------

lua/diffview/tests/functional/panel_render_spec.lua

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,41 @@ describe("panel_render", function()
269269
end)
270270
end)
271271

272+
-- -----------------------------------------------------------------------
273+
-- folder_trailing_slash
274+
-- -----------------------------------------------------------------------
275+
276+
describe("folder_trailing_slash option", function()
277+
---Replicate the folder-name rendering logic from render.lua.
278+
---@param conf table
279+
---@param name string
280+
---@return string
281+
local function render_folder_name(conf, name)
282+
local tree_options = conf.file_panel.tree_options
283+
return name .. (tree_options.folder_trailing_slash and "/" or "")
284+
end
285+
286+
it("appends trailing slash when enabled", function()
287+
local conf = config.get_config()
288+
conf.file_panel.tree_options.folder_trailing_slash = true
289+
config.setup(conf)
290+
291+
eq("src/", render_folder_name(config.get_config(), "src"))
292+
end)
293+
294+
it("omits trailing slash when disabled", function()
295+
local conf = config.get_config()
296+
conf.file_panel.tree_options.folder_trailing_slash = false
297+
config.setup(conf)
298+
299+
eq("src", render_folder_name(config.get_config(), "src"))
300+
end)
301+
302+
it("defaults to true", function()
303+
eq(true, config.get_config().file_panel.tree_options.folder_trailing_slash)
304+
end)
305+
end)
306+
272307
-- -----------------------------------------------------------------------
273308
-- Loading indicator (commit 5f1603a)
274309
-- -----------------------------------------------------------------------

0 commit comments

Comments
 (0)