155 lines
4.4 KiB
Lua
155 lines
4.4 KiB
Lua
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
|
||
})
|