dotfiles/.config/nvim/lua/core/statusline.lua

155 lines
4.4 KiB
Lua
Raw Normal View History

2022-10-21 06:15:28 -04:00
local fn = vim.fn
local api = vim.api
local M = {}
-- possible values are 'arrow' | 'rounded' | 'blank'
local active_sep = 'blank'
-- change them if you want to different separator
M.separators = {
arrow = { '', '' },
rounded = { '', '' },
blank = { '', '' },
}
-- highlight groups
M.colors = {
active = '%#StatusLine#',
inactive = '%#StatuslineNC#',
mode = '%#Mode#',
mode_alt = '%#ModeAlt#',
git = '%#Git#',
git_alt = '%#GitAlt#',
filetype = '%#Filetype#',
filetype_alt = '%#FiletypeAlt#',
line_col = '%#LineCol#',
line_col_alt = '%#LineColAlt#',
}
M.trunc_width = setmetatable({
mode = 80,
git_status = 90,
filename = 140,
line_col = 60,
}, {
__index = function()
return 80
end
})
M.is_truncated = function(_, width)
local current_width = api.nvim_win_get_width(0)
return current_width < width
end
M.modes = setmetatable({
['n'] = {'Normal', 'N'};
['no'] = {'N·Pending', 'N·P'} ;
['v'] = {'Visual', 'V' };
['V'] = {'V·Line', 'V·L' };
[''] = {'V·Block', 'V·B'}; -- this is not ^V, but it's , they're different
['s'] = {'Select', 'S'};
['S'] = {'S·Line', 'S·L'};
[''] = {'S·Block', 'S·B'}; -- same with this one, it's not ^S but it's 
['i'] = {'Insert', 'I'};
['ic'] = {'Insert', 'I'};
['R'] = {'Replace', 'R'};
['Rv'] = {'V·Replace', 'V·R'};
['c'] = {'Command', 'C'};
['cv'] = {'Vim·Ex ', 'V·E'};
['ce'] = {'Ex ', 'E'};
['r'] = {'Prompt ', 'P'};
['rm'] = {'More ', 'M'};
['r?'] = {'Confirm ', 'C'};
['!'] = {'Shell ', 'S'};
['t'] = {'Terminal ', 'T'};
}, {
__index = function()
return {'Unknown', 'U'} -- handle edge cases
end
})
M.get_current_mode = function(self)
local current_mode = api.nvim_get_mode().mode
if self:is_truncated(self.trunc_width.mode) then
return string.format(' %s ', self.modes[current_mode][2]):upper()
end
return string.format(' %s ', self.modes[current_mode][1]):upper()
end
M.get_git_status = function(self)
-- use fallback because it doesn't set this variable on the initial `BufEnter`
local signs = vim.b.gitsigns_status_dict or {head = '', added = 0, changed = 0, removed = 0}
local is_head_empty = signs.head ~= ''
if self:is_truncated(self.trunc_width.git_status) then
return is_head_empty and string.format('  %s ', signs.head or '') or ''
end
return is_head_empty and string.format(
' +%s ~%s -%s |  %s ',
signs.added, signs.changed, signs.removed, signs.head
) or ''
end
M.get_filename = function(self)
if self:is_truncated(self.trunc_width.filename) then return " %<%f " end
return " %<%F "
end
M.get_filetype = function()
local file_name, file_ext = fn.expand("%:t"), fn.expand("%:e")
local icon = require'nvim-web-devicons'.get_icon(file_name, file_ext, { default = true })
local filetype = vim.bo.filetype
if filetype == '' then return '' end
return string.format(' %s %s ', icon, filetype):lower()
end
M.get_line_col = function(self)
if self:is_truncated(self.trunc_width.line_col) then return ' %l:%c ' end
return ' Ln %l, Col %c '
end
M.set_active = function(self)
local colors = self.colors
local mode = colors.mode .. self:get_current_mode()
local mode_alt = colors.mode_alt .. self.separators[active_sep][1]
local git = colors.git .. self:get_git_status()
local git_alt = colors.git_alt .. self.separators[active_sep][1]
local filename = colors.inactive .. self:get_filename()
local filetype_alt = colors.filetype_alt .. self.separators[active_sep][2]
local filetype = colors.filetype .. self:get_filetype()
local line_col = colors.line_col .. self:get_line_col()
local line_col_alt = colors.line_col_alt .. self.separators[active_sep][2]
return table.concat({
colors.active, mode, mode_alt, git, git_alt,
"%=", filename, "%=",
filetype_alt, filetype, line_col_alt, line_col
})
end
M.set_inactive = function(self)
return self.colors.inactive .. '%= %F %='
end
M.set_explorer = function(self)
local title = self.colors.mode .. ''
local title_alt = self.colors.mode_alt .. self.separators[active_sep][2]
return table.concat({ self.colors.active, title, title_alt })
end
Statusline = setmetatable(M, {
__call = function(statusline, mode)
if mode == "active" then return statusline:set_active() end
if mode == "inactive" then return statusline:set_inactive() end
if mode == "explorer" then return statusline:set_explorer() end
end
})