feat(columns): per-character permission column highlights (#375) (#146)

Problem: the permissions column rendered as a monolithic unstyled
string, making it hard to scan `rwx` bits at a glance.

Solution: add per-character highlight groups for permission characters
following the `eza`/`lsd` convention. All groups link to standard
Neovim highlights so every colorscheme works out of the box.
This commit is contained in:
Barrett Ruth 2026-03-16 15:53:23 -04:00 committed by GitHub
parent 79a40b5feb
commit adff65b377
6 changed files with 81 additions and 3 deletions

View file

@ -100,7 +100,8 @@ if not fs.is_windows then
if not stat then
return columns.EMPTY
end
return permissions.mode_to_str(stat.mode)
local str = permissions.mode_to_str(stat.mode)
return { str, permissions.mode_to_highlights(str) }
end,
parse = function(line, conf)

View file

@ -25,6 +25,31 @@ M.mode_to_str = function(mode)
.. perm_to_str(bit.band(extra, 1) ~= 0 and 't', mode)
end
local char_hl = {
r = 'OilPermissionRead',
w = 'OilPermissionWrite',
x = 'OilPermissionExec',
s = 'OilPermissionSetuid',
S = 'OilPermissionSetuid',
t = 'OilPermissionSticky',
T = 'OilPermissionSticky',
['-'] = 'OilPermissionNone',
}
---@param str string
---@return table[]
M.mode_to_highlights = function(str)
local highlights = {}
for i = 1, #str do
local c = str:sub(i, i)
local hl = char_hl[c]
if hl then
table.insert(highlights, { hl, i - 1, i })
end
end
return highlights
end
---@param mode integer
---@return string
M.mode_to_octal_str = function(mode)

View file

@ -118,7 +118,11 @@ local ssh_columns = {}
ssh_columns.permissions = {
render = function(entry, conf)
local meta = entry[FIELD_META]
return meta and permissions.mode_to_str(meta.mode)
if not meta then
return
end
local str = permissions.mode_to_str(meta.mode)
return { str, permissions.mode_to_highlights(str) }
end,
parse = function(line, conf)

View file

@ -1066,6 +1066,36 @@ M._get_highlights = function()
link = 'OilHidden',
desc = 'Hidden executable files in an oil buffer',
},
{
name = 'OilPermissionRead',
link = 'DiagnosticWarn',
desc = 'Read permission character in the permissions column',
},
{
name = 'OilPermissionWrite',
link = 'DiagnosticError',
desc = 'Write permission character in the permissions column',
},
{
name = 'OilPermissionExec',
link = 'DiagnosticOk',
desc = 'Execute permission character in the permissions column',
},
{
name = 'OilPermissionSetuid',
link = 'DiagnosticError',
desc = 'Setuid/setgid permission character in the permissions column',
},
{
name = 'OilPermissionSticky',
link = 'DiagnosticInfo',
desc = 'Sticky bit permission character in the permissions column',
},
{
name = 'OilPermissionNone',
link = 'NonText',
desc = 'No permission character in the permissions column',
},
{
name = 'OilCreate',
link = 'DiagnosticInfo',