211 lines
5.6 KiB
Lua
211 lines
5.6 KiB
Lua
|
-- Badge utilities
|
||
|
-- https://github.com/plex/vim-config
|
||
|
|
||
|
local plugin_icons = {
|
||
|
DiffviewFiles = { '' },
|
||
|
fugitive = { ' ' },
|
||
|
fugitiveblame = { '', 'Blame' },
|
||
|
lazy = { ' ', 'Lazy.nvim' },
|
||
|
loclist = { '', 'Location List' },
|
||
|
mason = { ' ', 'Mason' },
|
||
|
NeogitStatus = { '' },
|
||
|
['neo-tree'] = { ' ', 'Neo-tree' },
|
||
|
['neo-tree-popup'] = { '', 'Neo-tree' },
|
||
|
Outline = { ' ' },
|
||
|
quickfix = { ' ', 'Quickfix List' }, --
|
||
|
spectre_panel = { ' ', 'Spectre' },
|
||
|
TelescopePrompt = { '', 'Telescope' },
|
||
|
terminal = { ' ' },
|
||
|
toggleterm = { ' ', 'Terminal' },
|
||
|
Trouble = { '' }, --
|
||
|
undotree = { '' },
|
||
|
}
|
||
|
|
||
|
local cache_keys = {
|
||
|
'badge_cache_filepath',
|
||
|
'badge_cache_filepath_tab',
|
||
|
'badge_cache_icon',
|
||
|
}
|
||
|
|
||
|
local augroup = vim.api.nvim_create_augroup('plex_badge', {})
|
||
|
|
||
|
-- Clear cached values that relate to buffer filename.
|
||
|
vim.api.nvim_create_autocmd(
|
||
|
{ 'BufReadPost', 'BufFilePost', 'BufNewFile', 'BufWritePost' },
|
||
|
{
|
||
|
group = augroup,
|
||
|
callback = function()
|
||
|
if vim.bo.buftype ~= '' then
|
||
|
return
|
||
|
end
|
||
|
for _, cache_key in ipairs(cache_keys) do
|
||
|
pcall(vim.api.nvim_buf_del_var, 0, cache_key)
|
||
|
end
|
||
|
end,
|
||
|
}
|
||
|
)
|
||
|
-- Clear cached values that relate to buffer content.
|
||
|
vim.api.nvim_create_autocmd(
|
||
|
{ 'BufWritePre', 'FileChangedShellPost', 'TextChanged', 'InsertLeave' },
|
||
|
{
|
||
|
group = augroup,
|
||
|
callback = function()
|
||
|
pcall(vim.api.nvim_buf_del_var, 0, 'badge_cache_trails')
|
||
|
end,
|
||
|
}
|
||
|
)
|
||
|
|
||
|
local M = {}
|
||
|
|
||
|
-- Try to guess the project's name
|
||
|
---@return string
|
||
|
function M.project()
|
||
|
return vim.fn.fnamemodify(require('plex.lib.utils').get_root(), ':t') or ''
|
||
|
end
|
||
|
|
||
|
-- Provides relative path with limited characters in each directory name, and
|
||
|
-- limits number of total directories. Caches the result for current buffer.
|
||
|
---@param bufnr integer buffer number
|
||
|
---@param max_dirs integer max dirs to show
|
||
|
---@param dir_max_chars integer max chars in dir
|
||
|
---@param cache_suffix string? cache suffix
|
||
|
---@return string
|
||
|
function M.filepath(bufnr, max_dirs, dir_max_chars, cache_suffix)
|
||
|
local msg = ''
|
||
|
local cache_key = 'badge_cache_filepath' -- _'..ft
|
||
|
if cache_suffix then
|
||
|
cache_key = cache_key .. cache_suffix
|
||
|
end
|
||
|
local cache_ok, cache = pcall(vim.api.nvim_buf_get_var, bufnr, cache_key)
|
||
|
if cache_ok then
|
||
|
return cache
|
||
|
end
|
||
|
|
||
|
local bufname = vim.api.nvim_buf_get_name(bufnr)
|
||
|
local buftype = vim.bo[bufnr].buftype
|
||
|
local filetype = vim.bo[bufnr].filetype
|
||
|
|
||
|
-- Normalize bufname
|
||
|
if bufname:len() < 1 and buftype:len() < 1 then
|
||
|
return 'N/A'
|
||
|
end
|
||
|
bufname = vim.fn.fnamemodify(bufname, ':~:.') or ''
|
||
|
|
||
|
-- Reduce directory count according to 'max_dirs' setting.
|
||
|
local formatter = string.format('([^%s]+)', M.path_sep)
|
||
|
local parts = {}
|
||
|
for str in string.gmatch(bufname, formatter) do
|
||
|
table.insert(parts, str)
|
||
|
end
|
||
|
|
||
|
local short_parts = {}
|
||
|
for i = #parts, 1, -1 do
|
||
|
if #short_parts <= max_dirs then
|
||
|
table.insert(short_parts, 1, parts[i])
|
||
|
end
|
||
|
end
|
||
|
bufname = table.concat(short_parts, M.path_sep)
|
||
|
|
||
|
-- Reduce each directory character count according to setting.
|
||
|
bufname = vim.fn.pathshorten(bufname, dir_max_chars + 1)
|
||
|
|
||
|
-- Override with plugin names.
|
||
|
local plugin_type = filetype == 'qf' and vim.fn.win_gettype() or filetype
|
||
|
if plugin_icons[plugin_type] ~= nil and #plugin_icons[plugin_type] > 1 then
|
||
|
msg = msg .. plugin_icons[plugin_type][2]
|
||
|
else
|
||
|
msg = msg .. bufname
|
||
|
end
|
||
|
|
||
|
vim.api.nvim_buf_set_var(bufnr, cache_key, msg)
|
||
|
return msg
|
||
|
end
|
||
|
|
||
|
function M.filemedia(separator)
|
||
|
local parts = {}
|
||
|
if vim.bo.fileformat ~= '' and vim.bo.fileformat ~= 'unix' then
|
||
|
table.insert(parts, vim.bo.fileformat)
|
||
|
end
|
||
|
if vim.bo.fileencoding ~= '' and vim.bo.fileencoding ~= 'utf-8' then
|
||
|
table.insert(parts, vim.bo.fileencoding)
|
||
|
end
|
||
|
if vim.bo.filetype ~= '' then
|
||
|
table.insert(parts, vim.bo.filetype)
|
||
|
end
|
||
|
return table.concat(parts, separator)
|
||
|
end
|
||
|
|
||
|
function M.icon(bufnr)
|
||
|
bufnr = bufnr or 0
|
||
|
local cache_key = 'badge_cache_icon'
|
||
|
local cache_ok, cache = pcall(vim.api.nvim_buf_get_var, bufnr, cache_key)
|
||
|
if cache_ok then
|
||
|
return cache
|
||
|
end
|
||
|
|
||
|
local icon = ''
|
||
|
local ft = vim.bo[bufnr].filetype
|
||
|
local buftype = vim.bo[bufnr].buftype
|
||
|
local bufname = vim.api.nvim_buf_get_name(bufnr)
|
||
|
|
||
|
local plugin_type = ft == 'qf' and vim.fn.win_gettype() or ft
|
||
|
if buftype ~= '' and plugin_icons[plugin_type] ~= nil then
|
||
|
icon = plugin_icons[plugin_type][1]
|
||
|
else
|
||
|
-- Try nvim-tree/nvim-web-devicons
|
||
|
local ok, devicons = pcall(require, 'nvim-web-devicons')
|
||
|
if ok then
|
||
|
if buftype == '' and bufname == '' then
|
||
|
return devicons.get_default_icon().icon
|
||
|
end
|
||
|
local f_name = vim.fn.fnamemodify(bufname, ':t')
|
||
|
local f_extension = vim.fn.fnamemodify(bufname, ':e')
|
||
|
icon, _ = devicons.get_icon(f_name, f_extension)
|
||
|
if icon == '' or icon == nil then
|
||
|
icon = devicons.get_default_icon().icon
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
vim.api.nvim_buf_set_var(bufnr, cache_key, icon)
|
||
|
return icon
|
||
|
end
|
||
|
|
||
|
-- Detect trailing whitespace and cache result per buffer
|
||
|
---@param symbol string
|
||
|
---@return string
|
||
|
function M.trails(symbol)
|
||
|
local cache_key = 'badge_cache_trails'
|
||
|
local cache_ok, cache = pcall(vim.api.nvim_buf_get_var, 0, cache_key)
|
||
|
if cache_ok then
|
||
|
return cache
|
||
|
end
|
||
|
|
||
|
local msg = ''
|
||
|
if not vim.bo.readonly and vim.bo.modifiable and vim.fn.line('$') < 9000 then
|
||
|
local trailing = vim.fn.search('\\s$', 'nw')
|
||
|
if trailing > 0 then
|
||
|
local label = symbol or 'WS:'
|
||
|
msg = msg .. label .. trailing
|
||
|
end
|
||
|
end
|
||
|
vim.api.nvim_buf_set_var(0, cache_key, msg)
|
||
|
|
||
|
return msg
|
||
|
end
|
||
|
|
||
|
-- Variable holds OS directory separator.
|
||
|
M.path_sep = (function()
|
||
|
if jit then
|
||
|
local os = string.lower(jit.os)
|
||
|
if os ~= 'windows' then
|
||
|
return '/'
|
||
|
else
|
||
|
return '\\'
|
||
|
end
|
||
|
else
|
||
|
return package.config:sub(1, 1)
|
||
|
end
|
||
|
end)()
|
||
|
|
||
|
return M
|