neovim-confs/lua/plex/lib/badge.lua

211 lines
5.6 KiB
Lua
Raw Permalink Normal View History

2023-09-06 00:26:45 +02:00
-- Badge utilities
2023-09-06 01:26:46 +02:00
-- https://github.com/rafi/vim-config
2023-09-06 00:26:45 +02:00
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',
}
2023-09-06 10:19:56 +02:00
local augroup = vim.api.nvim_create_augroup('plex_badge', {})
2023-09-06 00:26:45 +02:00
-- 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()
2023-09-06 10:19:56 +02:00
return vim.fn.fnamemodify(require('plex.lib.utils').get_root(), ':t') or ''
2023-09-06 00:26:45 +02:00
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