diff --git a/doc/oil.txt b/doc/oil.txt index 33ae00a..7738156 100644 --- a/doc/oil.txt +++ b/doc/oil.txt @@ -414,6 +414,7 @@ type *column-typ Parameters: {highlight} `string|fun(value: string): string` Highlight group, or function that returns a highlight group + {align} `"left"|"center"|"right"` Text alignment within the column {icons} `table` Mapping of entry type to icon icon *column-icon* @@ -423,6 +424,7 @@ icon *column-ico Parameters: {highlight} `string|fun(value: string): string` Highlight group, or function that returns a highlight group + {align} `"left"|"center"|"right"` Text alignment within the column {default_file} `string` Fallback icon for files when nvim-web-devicons returns nil {directory} `string` Icon for directories @@ -437,6 +439,7 @@ size *column-siz Parameters: {highlight} `string|fun(value: string): string` Highlight group, or function that returns a highlight group + {align} `"left"|"center"|"right"` Text alignment within the column permissions *column-permissions* Adapters: files, ssh @@ -446,6 +449,7 @@ permissions *column-permission Parameters: {highlight} `string|fun(value: string): string` Highlight group, or function that returns a highlight group + {align} `"left"|"center"|"right"` Text alignment within the column ctime *column-ctime* Adapters: files @@ -455,6 +459,7 @@ ctime *column-ctim Parameters: {highlight} `string|fun(value: string): string` Highlight group, or function that returns a highlight group + {align} `"left"|"center"|"right"` Text alignment within the column {format} `string` Format string (see :help strftime) mtime *column-mtime* @@ -465,6 +470,7 @@ mtime *column-mtim Parameters: {highlight} `string|fun(value: string): string` Highlight group, or function that returns a highlight group + {align} `"left"|"center"|"right"` Text alignment within the column {format} `string` Format string (see :help strftime) atime *column-atime* @@ -475,6 +481,7 @@ atime *column-atim Parameters: {highlight} `string|fun(value: string): string` Highlight group, or function that returns a highlight group + {align} `"left"|"center"|"right"` Text alignment within the column {format} `string` Format string (see :help strftime) birthtime *column-birthtime* @@ -485,6 +492,7 @@ birthtime *column-birthtim Parameters: {highlight} `string|fun(value: string): string` Highlight group, or function that returns a highlight group + {align} `"left"|"center"|"right"` Text alignment within the column {format} `string` Format string (see :help strftime) -------------------------------------------------------------------------------- diff --git a/lua/oil/columns.lua b/lua/oil/columns.lua index 46ef96b..975576f 100644 --- a/lua/oil/columns.lua +++ b/lua/oil/columns.lua @@ -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 diff --git a/lua/oil/keymap_util.lua b/lua/oil/keymap_util.lua index 04b8066..8c58738 100644 --- a/lua/oil/keymap_util.lua +++ b/lua/oil/keymap_util.lua @@ -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 diff --git a/lua/oil/loading.lua b/lua/oil/loading.lua index 35a6bba..6e575c5 100644 --- a/lua/oil/loading.lua +++ b/lua/oil/loading.lua @@ -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) ) diff --git a/lua/oil/util.lua b/lua/oil/util.lua index 894027e..0ec1acd 100644 --- a/lua/oil/util.lua +++ b/lua/oil/util.lua @@ -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 diff --git a/lua/oil/view.lua b/lua/oil/view.lua index 999ae5c..b3a216e 100644 --- a/lua/oil/view.lua +++ b/lua/oil/view.lua @@ -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) diff --git a/scripts/generate.py b/scripts/generate.py index 6e347fd..4e02550 100755 --- a/scripts/generate.py +++ b/scripts/generate.py @@ -110,11 +110,16 @@ class ColumnDef: params: List["LuaParam"] = field(default_factory=list) -HL = [ +UNIVERSAL = [ LuaParam( "highlight", "string|fun(value: string): string", "Highlight group, or function that returns a highlight group", + ), + LuaParam( + "align", + '"left"|"center"|"right"', + "Text alignment within the column", ) ] TIME = [ @@ -127,7 +132,7 @@ COL_DEFS = [ False, True, "The type of the entry (file, directory, link, etc)", - HL + UNIVERSAL + [LuaParam("icons", "table", "Mapping of entry type to icon")], ), ColumnDef( @@ -136,7 +141,7 @@ COL_DEFS = [ False, False, "An icon for the entry's type (requires nvim-web-devicons)", - HL + UNIVERSAL + [ LuaParam( "default_file", @@ -151,23 +156,23 @@ COL_DEFS = [ ), ], ), - ColumnDef("size", "files, ssh, s3", False, True, "The size of the file", HL + []), + ColumnDef("size", "files, ssh, s3", False, True, "The size of the file", UNIVERSAL + []), ColumnDef( "permissions", "files, ssh", True, False, "Access permissions of the file", - HL + [], + UNIVERSAL + [], ), ColumnDef( - "ctime", "files", False, True, "Change timestamp of the file", HL + TIME + [] + "ctime", "files", False, True, "Change timestamp of the file", UNIVERSAL + TIME + [] ), ColumnDef( - "mtime", "files", False, True, "Last modified time of the file", HL + TIME + [] + "mtime", "files", False, True, "Last modified time of the file", UNIVERSAL + TIME + [] ), ColumnDef( - "atime", "files", False, True, "Last access time of the file", HL + TIME + [] + "atime", "files", False, True, "Last access time of the file", UNIVERSAL + TIME + [] ), ColumnDef( "birthtime", @@ -175,7 +180,7 @@ COL_DEFS = [ False, True, "The time the file was created", - HL + TIME + [], + UNIVERSAL + TIME + [], ), ]