feat: add support for column text alignment (#711)

* feat: add support for column text alignment

* refactor(util): replace rpad with pad_align

* refactor(columns): whitespace handling in parse_col

* refactor: small changes

* doc: add align option to doc generation

* refactor: replace lpad with pad_align

---------

Co-authored-by: Steven Arcangeli <stevearc@stevearc.com>
This commit is contained in:
malewicz1337 2026-01-14 06:28:16 +01:00 committed by GitHub
parent fbbb2a9872
commit 6b59a6cf62
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 64 additions and 46 deletions

View file

@ -98,13 +98,13 @@ end
M.parse_col = function(adapter, line, col_def)
local name, conf = util.split_config(col_def)
-- If rendering failed, there will just be a "-"
local empty_col, rem = line:match("^(-%s+)(.*)$")
local empty_col, rem = line:match("^%s*(-%s+)(.*)$")
if empty_col then
return nil, rem
end
local column = M.get_column(adapter, name)
if column then
return column.parse(line, conf)
return column.parse(line:gsub("^%s+", ""), conf)
end
end

View file

@ -108,7 +108,7 @@ M.show_help = function(keymaps)
local highlights = {}
local max_line = 1
for _, entry in ipairs(keymap_entries) do
local line = string.format(" %s %s", util.rpad(entry.str, max_lhs), entry.desc)
local line = string.format(" %s %s", util.pad_align(entry.str, max_lhs, "left"), entry.desc)
max_line = math.max(max_line, vim.api.nvim_strwidth(line))
table.insert(lines, line)
local start = 1

View file

@ -74,7 +74,8 @@ M.set_loading = function(bufnr, is_loading)
M.set_loading(bufnr, false)
return
end
local lines = { util.lpad("Loading", math.floor(width / 2) - 3), bar_iter() }
local lines =
{ util.pad_align("Loading", math.floor(width / 2) - 3, "right"), bar_iter() }
util.render_text(bufnr, lines)
end)
)

View file

@ -91,34 +91,28 @@ M.get_adapter = function(bufnr, silent)
end
---@param text string
---@param length nil|integer
---@return string
M.rpad = function(text, length)
if not length then
return text
---@param width integer|nil
---@param align oil.ColumnAlign
---@return string padded_text
---@return integer left_padding
M.pad_align = function(text, width, align)
if not width then
return text, 0
end
local textlen = vim.api.nvim_strwidth(text)
local delta = length - textlen
if delta > 0 then
return text .. string.rep(" ", delta)
else
return text
local text_width = vim.api.nvim_strwidth(text)
local total_pad = width - text_width
if total_pad <= 0 then
return text, 0
end
end
---@param text string
---@param length nil|integer
---@return string
M.lpad = function(text, length)
if not length then
return text
end
local textlen = vim.api.nvim_strwidth(text)
local delta = length - textlen
if delta > 0 then
return string.rep(" ", delta) .. text
if align == "right" then
return string.rep(" ", total_pad) .. text, total_pad
elseif align == "center" then
local left_pad = math.floor(total_pad / 2)
local right_pad = total_pad - left_pad
return string.rep(" ", left_pad) .. text .. string.rep(" ", right_pad), left_pad
else
return text
return text .. string.rep(" ", total_pad), 0
end
end
@ -314,11 +308,15 @@ M.split_config = function(name_or_config)
end
end
---@alias oil.ColumnAlign "left"|"center"|"right"
---@param lines oil.TextChunk[][]
---@param col_width integer[]
---@param col_align? oil.ColumnAlign[]
---@return string[]
---@return any[][] List of highlights {group, lnum, col_start, col_end}
M.render_table = function(lines, col_width)
M.render_table = function(lines, col_width, col_align)
col_align = col_align or {}
local str_lines = {}
local highlights = {}
for _, cols in ipairs(lines) do
@ -332,9 +330,12 @@ M.render_table = function(lines, col_width)
else
text = chunk
end
text = M.rpad(text, col_width[i])
local unpadded_len = text:len()
local padding
text, padding = M.pad_align(text, col_width[i], col_align[i] or "left")
table.insert(pieces, text)
local col_end = col + text:len() + 1
if hl then
if type(hl) == "table" then
-- hl has the form { [1]: hl_name, [2]: col_start, [3]: col_end }[]
@ -344,15 +345,15 @@ M.render_table = function(lines, col_width)
table.insert(highlights, {
sub_hl[1],
#str_lines,
col + sub_hl[2],
col + sub_hl[3],
col + padding + sub_hl[2],
col + padding + sub_hl[3],
})
end
else
table.insert(highlights, { hl, #str_lines, col, col_end })
table.insert(highlights, { hl, #str_lines, col + padding, col + padding + unpadded_len })
end
end
col = col_end
col = col + text:len() + 1
end
table.insert(str_lines, table.concat(pieces, " "))
end

View file

@ -668,8 +668,11 @@ local function render_buffer(bufnr, opts)
local column_defs = columns.get_supported_columns(scheme)
local line_table = {}
local col_width = {}
for i in ipairs(column_defs) do
local col_align = {}
for i, col_def in ipairs(column_defs) do
col_width[i + 1] = 1
local _, conf = util.split_config(col_def)
col_align[i + 1] = conf and conf.align or "left"
end
if M.should_display("..", bufnr) then
@ -692,7 +695,7 @@ local function render_buffer(bufnr, opts)
end
end
local lines, highlights = util.render_table(line_table, col_width)
local lines, highlights = util.render_table(line_table, col_width, col_align)
vim.bo[bufnr].modifiable = true
vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, lines)