mirror of
https://github.com/LunarVim/LunarVim.git
synced 2025-08-29 14:28:18 +02:00
[Feature] Encapsulate interface logic (#1320)
* Provide a utility function for aligning text * Replace lvim banner with one using only ASCII chars * Use strings.format instead of .. operator * Center text in the popup based on its dimentions * Minor improvements * Provide a popup factory function * Add function documentation * Improve text alignment * Print marker only if provider list is not empty * Format client capabilities as list * Pretty format lsp client capabilities * Add a metatable to popup.lua * Improve rendering when no lsp is available * Take cmdheight into acount when computing popup size and pos Co-authored-by: kylo252 <59826753+kylo252@users.noreply.github.com>
This commit is contained in:
parent
944dd48935
commit
9b36872d88
3 changed files with 242 additions and 136 deletions
|
@ -1,128 +1,63 @@
|
||||||
local M = {}
|
local M = {
|
||||||
local indent = " "
|
banner = {
|
||||||
|
|
||||||
M.banner = {
|
|
||||||
" ",
|
|
||||||
indent
|
|
||||||
.. "⠀⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀ ⠀⠀⠀ ⠀⠀ ⣺⡿⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀",
|
|
||||||
indent
|
|
||||||
.. "⠀⣿⠇⠀⠀⠀⠀⠀⣤⡄⠀⠀⢠⣤⡄⠀.⣠⣤⣤⣤⡀⠀⠀⢀⣤⣤⣤⣤⡄⠀⠀⠀⣤⣄⣤⣤⣤⠀⠀ ⣿⣯ ⣿⡟⠀ ⣤⣤⠀⠀⠀⠀⣠⣤⣤⣤⣄⣤⣤",
|
|
||||||
indent
|
|
||||||
.. "⢠⣿⠀⠀⠀⠀⠀⠀⣿⠃⠀⠀⣸⣿⠁⠀⣿⣿⠉⠀⠈⣿⡇⠀⠀⠛⠋⠀⠀⢹⣿⠀⠀⠀⣿⠏⠀⠸⠿⠃⠀⣿⣿⠀⣰⡟⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⣿⡟⢸⣿⡇⢀⣿",
|
|
||||||
indent
|
|
||||||
.. "⣸⡇⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⣿⡟⠀⢠⣿⡇⠀⠀⢰⣿⡇⠀⣰⣾⠟⠛⠛⣻⡇⠀⠀⢸⡿⠀⠀⠀⠀⠀⠀⢻⣿⢰⣿⠀⠀⠀⠀⠀⠀⣾⡇⠀⠀⠀⢸⣿⠇⢸⣿⠀⢸⡏",
|
|
||||||
indent
|
|
||||||
.. "⣿⣧⣤⣤⣤⡄⠀⠘⣿⣤⣤⡤⣿⠇⠀⢸⣿⠁⠀⠀⣼⣿⠀⠀⢿⣿⣤⣤⠔⣿⠃⠀⠀⣾⡇⠀⠀⠀⠀⠀⠀⢸⣿⣿⠋⠀⠀⠀⢠⣤⣤⣿⣥⣤⡄⠀⣼⣿⠀⣸⡏⠀⣿⠃",
|
|
||||||
indent
|
|
||||||
.. "⠉⠉⠉⠉⠉⠁⠀⠀⠈⠉⠉⠀⠉⠀⠀⠈⠉⠀⠀⠀⠉⠉⠀⠀⠀⠉⠉⠁⠈⠉⠀⠀⠀⠉⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠀⠀⠀⠀⠈⠉⠉⠉⠉⠉⠁⠀⠉⠁⠀⠉⠁⠀⠉⠀",
|
|
||||||
"",
|
"",
|
||||||
|
[[ __ _ ___ ]],
|
||||||
|
[[ / / __ ______ ____ _____| | / (_)___ ___ ]],
|
||||||
|
[[ / / / / / / __ \/ __ `/ ___/ | / / / __ `__ \]],
|
||||||
|
[[ / /___/ /_/ / / / / /_/ / / | |/ / / / / / / /]],
|
||||||
|
[[/_____/\__,_/_/ /_/\__,_/_/ |___/_/_/ /_/ /_/ ]],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local fmt = string.format
|
||||||
|
|
||||||
local function str_list(list)
|
local function str_list(list)
|
||||||
return "[ " .. table.concat(list, ", ") .. " ]"
|
return fmt("[ %s ]", table.concat(list, ", "))
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_formatter_suggestion_msg(ft)
|
local function get_formatter_suggestion_msg(ft)
|
||||||
local null_formatters = require "lsp.null-ls.formatters"
|
local null_formatters = require "lsp.null-ls.formatters"
|
||||||
local supported_formatters = null_formatters.list_available(ft)
|
local supported_formatters = null_formatters.list_available(ft)
|
||||||
return {
|
local section = {
|
||||||
indent
|
" HINT ",
|
||||||
.. "───────────────────────────────────────────────────────────────────",
|
|
||||||
"",
|
|
||||||
indent .. " HINT ",
|
|
||||||
"",
|
|
||||||
indent .. "* List of supported formatters: " .. str_list(supported_formatters),
|
|
||||||
indent .. "* Configured formatter needs to be installed and executable.",
|
|
||||||
indent .. "* Enable installed formatter(s) with following config in ~/.config/lvim/config.lua",
|
|
||||||
"",
|
|
||||||
indent .. " lvim.lang." .. tostring(ft) .. [[.formatters = { { exe = ']] .. table.concat(
|
|
||||||
supported_formatters,
|
|
||||||
"│"
|
|
||||||
) .. [[' } }]],
|
|
||||||
"",
|
"",
|
||||||
|
fmt("* List of supported formatters: %s", str_list(supported_formatters)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if not vim.tbl_isempty(supported_formatters) then
|
||||||
|
vim.list_extend(section, {
|
||||||
|
"* Configured formatter needs to be installed and executable.",
|
||||||
|
fmt("* Enable installed formatter(s) with following config in %s", USER_CONFIG_PATH),
|
||||||
|
"",
|
||||||
|
fmt(" lvim.lang.%s.formatters = { { exe = '%s' } }", ft, table.concat(supported_formatters, "│")),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
return section
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_linter_suggestion_msg(ft)
|
local function get_linter_suggestion_msg(ft)
|
||||||
local null_linters = require "lsp.null-ls.linters"
|
local null_linters = require "lsp.null-ls.linters"
|
||||||
local supported_linters = null_linters.list_available(ft)
|
local supported_linters = null_linters.list_available(ft)
|
||||||
return {
|
local section = {
|
||||||
indent
|
" HINT ",
|
||||||
.. "───────────────────────────────────────────────────────────────────",
|
|
||||||
"",
|
|
||||||
indent .. " HINT ",
|
|
||||||
"",
|
|
||||||
indent .. "* List of supported linters: " .. str_list(supported_linters),
|
|
||||||
indent .. "* Configured linter needs to be installed and executable.",
|
|
||||||
indent .. "* Enable installed linter(s) with following config in ~/.config/lvim/config.lua",
|
|
||||||
"",
|
|
||||||
indent
|
|
||||||
.. " lvim.lang."
|
|
||||||
.. tostring(ft)
|
|
||||||
.. [[.linters = { { exe = ']]
|
|
||||||
.. table.concat(supported_linters, "│")
|
|
||||||
.. [[' } }]],
|
|
||||||
"",
|
"",
|
||||||
|
fmt("* List of supported linters: %s", str_list(supported_linters)),
|
||||||
}
|
}
|
||||||
end
|
|
||||||
|
|
||||||
---creates an average size popup
|
if not vim.tbl_isempty(supported_linters) then
|
||||||
---@param buf_lines a list of lines to print
|
vim.list_extend(section, {
|
||||||
---@param callback could be used to set syntax highlighting rules for example
|
"* Configured linter needs to be installed and executable.",
|
||||||
---@return bufnr buffer number of the created buffer
|
fmt("* Enable installed linter(s) with following config in %s", USER_CONFIG_PATH),
|
||||||
---@return win_id window ID of the created popup
|
"",
|
||||||
function M.create_simple_popup(buf_lines, callback)
|
fmt(" lvim.lang.%s.linters = { { exe = '%s' } }", ft, table.concat(supported_linters, "│")),
|
||||||
-- runtime/lua/vim/lsp/util.lua
|
})
|
||||||
local bufnr = vim.api.nvim_create_buf(false, true)
|
|
||||||
local height_percentage = 0.9
|
|
||||||
local width_percentage = 0.8
|
|
||||||
local row_start_percentage = (1 - height_percentage) / 2
|
|
||||||
local col_start_percentage = (1 - width_percentage) / 2
|
|
||||||
local opts = {}
|
|
||||||
opts.relative = "editor"
|
|
||||||
opts.height = math.min(math.ceil(vim.o.lines * height_percentage), #buf_lines)
|
|
||||||
opts.row = math.ceil(vim.o.lines * row_start_percentage)
|
|
||||||
opts.col = math.floor(vim.o.columns * col_start_percentage)
|
|
||||||
opts.width = math.floor(vim.o.columns * width_percentage)
|
|
||||||
opts.style = "minimal"
|
|
||||||
opts.border = "rounded"
|
|
||||||
--[[
|
|
||||||
opts.border = {
|
|
||||||
lvim.builtin.telescope.defaults.borderchars[5], -- "┌",
|
|
||||||
lvim.builtin.telescope.defaults.borderchars[3], -- "-",
|
|
||||||
lvim.builtin.telescope.defaults.borderchars[6], -- "┐",
|
|
||||||
lvim.builtin.telescope.defaults.borderchars[2], -- "|",
|
|
||||||
lvim.builtin.telescope.defaults.borderchars[7], -- "┘",
|
|
||||||
lvim.builtin.telescope.defaults.borderchars[3], -- "-",
|
|
||||||
lvim.builtin.telescope.defaults.borderchars[8], -- "└",
|
|
||||||
lvim.builtin.telescope.defaults.borderchars[4], -- "|",
|
|
||||||
}
|
|
||||||
--]]
|
|
||||||
|
|
||||||
local win_id = vim.api.nvim_open_win(bufnr, true, opts)
|
|
||||||
|
|
||||||
vim.api.nvim_win_set_buf(win_id, bufnr)
|
|
||||||
-- this needs to be window option!
|
|
||||||
vim.api.nvim_win_set_option(win_id, "number", false)
|
|
||||||
vim.cmd "setlocal nocursorcolumn"
|
|
||||||
vim.cmd "setlocal wrap"
|
|
||||||
-- set buffer options
|
|
||||||
vim.api.nvim_buf_set_option(bufnr, "filetype", "lspinfo")
|
|
||||||
vim.lsp.util.close_preview_autocmd({ "BufHidden", "BufLeave" }, win_id)
|
|
||||||
buf_lines = vim.lsp.util._trim(buf_lines, {})
|
|
||||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, buf_lines)
|
|
||||||
vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
|
|
||||||
if type(callback) == "function" then
|
|
||||||
callback()
|
|
||||||
end
|
end
|
||||||
return bufnr, win_id
|
|
||||||
|
return section
|
||||||
end
|
end
|
||||||
|
|
||||||
local function tbl_set_highlight(terms, highlight_group)
|
local function tbl_set_highlight(terms, highlight_group)
|
||||||
if type(terms) ~= "table" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, v in pairs(terms) do
|
for _, v in pairs(terms) do
|
||||||
vim.cmd('let m=matchadd("' .. highlight_group .. '", "' .. v .. "[ ,│']\")")
|
vim.cmd('let m=matchadd("' .. highlight_group .. '", "' .. v .. "[ ,│']\")")
|
||||||
end
|
end
|
||||||
|
@ -136,67 +71,90 @@ function M.toggle_popup(ft)
|
||||||
local client_name = ""
|
local client_name = ""
|
||||||
local client_id = 0
|
local client_id = 0
|
||||||
local document_formatting = false
|
local document_formatting = false
|
||||||
local num_caps = 0
|
|
||||||
if client ~= nil then
|
if client ~= nil then
|
||||||
is_client_active = not client.is_stopped()
|
is_client_active = not client.is_stopped()
|
||||||
client_enabled_caps = require("lsp").get_ls_capabilities(client.id)
|
client_enabled_caps = require("lsp").get_ls_capabilities(client.id)
|
||||||
num_caps = vim.tbl_count(client_enabled_caps)
|
|
||||||
client_name = client.name
|
client_name = client.name
|
||||||
client_id = client.id
|
client_id = client.id
|
||||||
document_formatting = client.resolved_capabilities.document_formatting
|
document_formatting = client.resolved_capabilities.document_formatting
|
||||||
end
|
end
|
||||||
|
|
||||||
local buf_lines = {}
|
|
||||||
vim.list_extend(buf_lines, M.banner)
|
|
||||||
|
|
||||||
local header = {
|
local header = {
|
||||||
indent .. "Detected filetype: " .. tostring(ft),
|
fmt("Detected filetype: %s", ft),
|
||||||
indent .. "Treesitter active: " .. tostring(next(vim.treesitter.highlighter.active) ~= nil),
|
fmt("Treesitter active: %s", tostring(next(vim.treesitter.highlighter.active) ~= nil)),
|
||||||
"",
|
|
||||||
}
|
}
|
||||||
vim.list_extend(buf_lines, header)
|
|
||||||
|
|
||||||
|
local text = require "interface.text"
|
||||||
local lsp_info = {
|
local lsp_info = {
|
||||||
indent .. "Language Server Protocol (LSP) info",
|
"Language Server Protocol (LSP) info",
|
||||||
indent .. "* Associated server: " .. client_name,
|
fmt("* Associated server: %s", client_name),
|
||||||
indent .. "* Active: " .. tostring(is_client_active) .. " (id: " .. tostring(client_id) .. ")",
|
fmt("* Active: %s (id: %d)", tostring(is_client_active), client_id),
|
||||||
indent .. "* Supports formatting: " .. tostring(document_formatting),
|
fmt("* Supports formatting: %s", tostring(document_formatting)),
|
||||||
indent .. "* Capabilities list: " .. table.concat(vim.list_slice(client_enabled_caps, 1, num_caps / 2), ", "),
|
|
||||||
indent .. indent .. indent .. table.concat(vim.list_slice(client_enabled_caps, ((num_caps / 2) + 1)), ", "),
|
|
||||||
"",
|
|
||||||
}
|
}
|
||||||
vim.list_extend(buf_lines, lsp_info)
|
if not vim.tbl_isempty(client_enabled_caps) then
|
||||||
|
local caps_text = "* Capabilities list: "
|
||||||
|
local caps_text_len = caps_text:len()
|
||||||
|
local enabled_caps = text.format_table(client_enabled_caps, 3, " | ")
|
||||||
|
enabled_caps = text.shift_left(enabled_caps, caps_text_len)
|
||||||
|
enabled_caps[1] = fmt("%s%s", caps_text, enabled_caps[1]:sub(caps_text_len + 1))
|
||||||
|
vim.list_extend(lsp_info, enabled_caps)
|
||||||
|
end
|
||||||
local null_ls = require "lsp.null-ls"
|
local null_ls = require "lsp.null-ls"
|
||||||
local registered_providers = null_ls.list_supported_provider_names(ft)
|
local registered_providers = null_ls.list_supported_provider_names(ft)
|
||||||
|
local registered_count = vim.tbl_count(registered_providers)
|
||||||
local null_ls_info = {
|
local null_ls_info = {
|
||||||
indent .. "Formatters and linters",
|
"Formatters and linters",
|
||||||
indent .. "* Configured providers: " .. table.concat(registered_providers, " , ") .. " ",
|
fmt(
|
||||||
|
"* Configured providers: %s%s",
|
||||||
|
table.concat(registered_providers, " , "),
|
||||||
|
registered_count > 0 and " " or ""
|
||||||
|
),
|
||||||
}
|
}
|
||||||
vim.list_extend(buf_lines, null_ls_info)
|
|
||||||
|
|
||||||
local null_formatters = require "lsp.null-ls.formatters"
|
local null_formatters = require "lsp.null-ls.formatters"
|
||||||
local missing_formatters = null_formatters.list_unsupported_names(ft)
|
local missing_formatters = null_formatters.list_unsupported_names(ft)
|
||||||
if vim.tbl_count(missing_formatters) > 0 then
|
local missing_formatters_status = {}
|
||||||
local missing_formatters_status = {
|
if not vim.tbl_isempty(missing_formatters) then
|
||||||
indent .. "* Missing formatters: " .. table.concat(missing_formatters, " , ") .. " ",
|
missing_formatters_status = {
|
||||||
|
fmt("* Missing formatters: %s", table.concat(missing_formatters, " , ") .. " "),
|
||||||
}
|
}
|
||||||
vim.list_extend(buf_lines, missing_formatters_status)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local null_linters = require "lsp.null-ls.linters"
|
local null_linters = require "lsp.null-ls.linters"
|
||||||
local missing_linters = null_linters.list_unsupported_names(ft)
|
local missing_linters = null_linters.list_unsupported_names(ft)
|
||||||
if vim.tbl_count(missing_linters) > 0 then
|
local missing_linters_status = {}
|
||||||
local missing_linters_status = {
|
if not vim.tbl_isempty(missing_linters) then
|
||||||
indent .. "* Missing linters: " .. table.concat(missing_linters, " , ") .. " ",
|
missing_linters_status = {
|
||||||
|
fmt("* Missing linters: %s", table.concat(missing_linters, " , ") .. " "),
|
||||||
}
|
}
|
||||||
vim.list_extend(buf_lines, missing_linters_status)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.list_extend(buf_lines, { "" })
|
local content_provider = function(popup)
|
||||||
|
local content = {}
|
||||||
|
|
||||||
vim.list_extend(buf_lines, get_formatter_suggestion_msg(ft))
|
for _, section in ipairs {
|
||||||
vim.list_extend(buf_lines, get_linter_suggestion_msg(ft))
|
M.banner,
|
||||||
|
{ "" },
|
||||||
|
{ "" },
|
||||||
|
header,
|
||||||
|
{ "" },
|
||||||
|
lsp_info,
|
||||||
|
{ "" },
|
||||||
|
null_ls_info,
|
||||||
|
missing_formatters_status,
|
||||||
|
missing_linters_status,
|
||||||
|
{ "" },
|
||||||
|
{ "" },
|
||||||
|
get_formatter_suggestion_msg(ft),
|
||||||
|
{ "" },
|
||||||
|
{ "" },
|
||||||
|
get_linter_suggestion_msg(ft),
|
||||||
|
} do
|
||||||
|
vim.list_extend(content, section)
|
||||||
|
end
|
||||||
|
|
||||||
|
return text.align(popup, content, 0.5)
|
||||||
|
end
|
||||||
|
|
||||||
local function set_syntax_hl()
|
local function set_syntax_hl()
|
||||||
vim.cmd [[highlight LvimInfoIdentifier gui=bold]]
|
vim.cmd [[highlight LvimInfoIdentifier gui=bold]]
|
||||||
|
@ -214,6 +172,13 @@ function M.toggle_popup(ft)
|
||||||
vim.cmd('let m=matchadd("LvimInfoIdentifier", "' .. client_name .. '")')
|
vim.cmd('let m=matchadd("LvimInfoIdentifier", "' .. client_name .. '")')
|
||||||
end
|
end
|
||||||
|
|
||||||
return M.create_simple_popup(buf_lines, set_syntax_hl)
|
local Popup = require("interface.popup"):new {
|
||||||
|
win_opts = { number = false },
|
||||||
|
buf_opts = { modifiable = false, filetype = "lspinfo" },
|
||||||
|
}
|
||||||
|
Popup:display(content_provider)
|
||||||
|
set_syntax_hl()
|
||||||
|
|
||||||
|
return Popup
|
||||||
end
|
end
|
||||||
return M
|
return M
|
||||||
|
|
62
lua/interface/popup.lua
Normal file
62
lua/interface/popup.lua
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
local Popup = {}
|
||||||
|
|
||||||
|
--- Create a new floating window
|
||||||
|
-- @param config The configuration passed to vim.api.nvim_open_win
|
||||||
|
-- @param win_opts The options registered with vim.api.nvim_win_set_option
|
||||||
|
-- @param buf_opts The options registered with vim.api.nvim_buf_set_option
|
||||||
|
-- @return A new popup
|
||||||
|
function Popup:new(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
opts.layout = opts.layout or {}
|
||||||
|
opts.win_opts = opts.win_opts or {}
|
||||||
|
opts.buf_opts = opts.buf_opts or {}
|
||||||
|
|
||||||
|
Popup.__index = Popup
|
||||||
|
|
||||||
|
local editor_layout = {
|
||||||
|
height = vim.o.lines - vim.o.cmdheight - 2, -- Add margin for status and buffer line
|
||||||
|
width = vim.o.columns,
|
||||||
|
}
|
||||||
|
local popup_layout = {
|
||||||
|
relative = "editor",
|
||||||
|
height = math.floor(editor_layout.height * 0.9),
|
||||||
|
width = math.floor(editor_layout.width * 0.8),
|
||||||
|
style = "minimal",
|
||||||
|
border = "rounded",
|
||||||
|
}
|
||||||
|
popup_layout.row = math.floor((editor_layout.height - popup_layout.height) / 2)
|
||||||
|
popup_layout.col = math.floor((editor_layout.width - popup_layout.width) / 2)
|
||||||
|
|
||||||
|
local obj = {
|
||||||
|
buffer = vim.api.nvim_create_buf(false, true),
|
||||||
|
layout = vim.tbl_deep_extend("force", popup_layout, opts.layout),
|
||||||
|
win_opts = opts.win_opts,
|
||||||
|
buf_opts = opts.buf_opts,
|
||||||
|
}
|
||||||
|
|
||||||
|
setmetatable(obj, Popup)
|
||||||
|
|
||||||
|
return obj
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Display the popup with the provided content
|
||||||
|
-- @param content_provider A function accepting the popup's layout and returning the content to display
|
||||||
|
function Popup:display(content_provider)
|
||||||
|
self.win_id = vim.api.nvim_open_win(self.buffer, true, self.layout)
|
||||||
|
vim.lsp.util.close_preview_autocmd({ "BufHidden", "BufLeave" }, self.win_id)
|
||||||
|
|
||||||
|
local lines = content_provider(self.layout)
|
||||||
|
vim.api.nvim_buf_set_lines(self.bufnr, 0, -1, false, lines)
|
||||||
|
|
||||||
|
-- window options
|
||||||
|
for key, value in pairs(self.win_opts) do
|
||||||
|
vim.api.nvim_win_set_option(self.win_id, key, value)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- buffer options
|
||||||
|
for key, value in pairs(self.buf_opts) do
|
||||||
|
vim.api.nvim_buf_set_option(self.buffer, key, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Popup
|
79
lua/interface/text.lua
Normal file
79
lua/interface/text.lua
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local function max_len_line(lines)
|
||||||
|
local max_len = 0
|
||||||
|
|
||||||
|
for _, line in ipairs(lines) do
|
||||||
|
local line_len = line:len()
|
||||||
|
if line_len > max_len then
|
||||||
|
max_len = line_len
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return max_len
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Center align lines relatively to the parent container
|
||||||
|
-- @param container The container where lines will be displayed
|
||||||
|
-- @param lines The text to align
|
||||||
|
-- @param alignment The alignment value, range: [0-1]
|
||||||
|
function M.align(container, lines, alignment)
|
||||||
|
local max_len = max_len_line(lines)
|
||||||
|
local indent_amount = math.ceil(math.max(container.width - max_len, 0) * alignment)
|
||||||
|
return M.shift_left(lines, indent_amount)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Shift lines by a given amount
|
||||||
|
-- @params lines The lines the shift
|
||||||
|
-- @param amount The amount of spaces to add
|
||||||
|
function M.shift_left(lines, amount)
|
||||||
|
local output = {}
|
||||||
|
local padding = string.rep(" ", amount)
|
||||||
|
|
||||||
|
for _, line in ipairs(lines) do
|
||||||
|
table.insert(output, padding .. line)
|
||||||
|
end
|
||||||
|
|
||||||
|
return output
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Pretty format tables
|
||||||
|
-- @param entries The table to format
|
||||||
|
-- @param col_count The number of column to span the table on
|
||||||
|
-- @param col_sep The separator between each colummn, default: " "
|
||||||
|
function M.format_table(entries, col_count, col_sep)
|
||||||
|
col_sep = col_sep or " "
|
||||||
|
|
||||||
|
local col_rows = math.ceil(vim.tbl_count(entries) / col_count)
|
||||||
|
local cols = {}
|
||||||
|
local count = 0
|
||||||
|
|
||||||
|
for i, entry in ipairs(entries) do
|
||||||
|
if ((i - 1) % col_rows) == 0 then
|
||||||
|
table.insert(cols, {})
|
||||||
|
count = count + 1
|
||||||
|
end
|
||||||
|
table.insert(cols[count], entry)
|
||||||
|
end
|
||||||
|
|
||||||
|
local col_max_len = {}
|
||||||
|
for _, col in ipairs(cols) do
|
||||||
|
table.insert(col_max_len, max_len_line(col))
|
||||||
|
end
|
||||||
|
|
||||||
|
local output = {}
|
||||||
|
for i, col in ipairs(cols) do
|
||||||
|
for j, entry in ipairs(col) do
|
||||||
|
if not output[j] then
|
||||||
|
output[j] = entry
|
||||||
|
else
|
||||||
|
local padding = string.rep(" ", col_max_len[i - 1] - cols[i - 1][j]:len())
|
||||||
|
output[j] = output[j] .. padding .. col_sep .. entry
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return output
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
Loading…
Add table
Add a link
Reference in a new issue