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

155 lines
4.4 KiB
Lua
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
})