dotfiles/.config/nvim/after/plugin/heirline.lua

345 lines
9.5 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 augroup = vim.api.nvim_create_augroup('config', {clear = false})
-- stolen from https://gitlab.com/Iron_E/dotfiles/-/blob/master/.config/nvim/lua/plugin/heirline.lua
--[[
_ _ _ _ _
| |__ ___(_)_ __| (_)_ __ ___ _ ____ _(_)_ __ ___
| '_ \ / _ \ | '__| | | '_ \ / _ \ | '_ \ \ / / | '_ ` _ \
| | | | __/ | | | | | | | | __/_| | | \ V /| | | | | | |
|_| |_|\___|_|_| |_|_|_| |_|\___(_)_| |_|\_/ |_|_| |_| |_|
--]]
local devicons = require 'nvim-web-devicons'
--[[/* CONSTANTS */]]
-- Defined in https://github.com/Iron-E/nvim-highlite
local BLACK = '#202020'
local BLUE = '#7766ff'
local CYAN = '#33dbc3'
local GRAY_DARK = '#353535'
local GRAY_LIGHT = '#c0c0c0'
local GREEN = '#22ff22'
local GREEN_DARK = '#70d533'
local GREEN_LIGHT = '#99ff99'
local ICE = '#95c5ff'
local MAGENTA = '#d5508f'
local MAGENTA_DARK = '#bb0099'
local ORANGE = '#ff8900'
local ORANGE_LIGHT = '#f0af00'
local PINK = '#ffa6ff'
local PINK_LIGHT = '#ffb7b7'
local PURPLE = '#cf55f0'
local PURPLE_LIGHT = '#af60af'
local RED = '#ee4a59'
local RED_DARK = '#a80000'
local RED_LIGHT = '#ff4090'
local TAN = '#f4c069'
local TEAL = '#60afff'
local TURQOISE = '#2bff99'
local WHITE = '#ffffff'
local YELLOW = '#f0df33'
local SIDEBAR = BLACK
local MIDBAR = GRAY_DARK
local TEXT = GRAY_LIGHT
--[[/* HELPERS */]]
--- The width of the screen
local columns = vim.api.nvim_get_option_value('columns', {})
vim.api.nvim_create_autocmd('VimResized', {
callback = function() columns = vim.api.nvim_get_option_value('columns', {}) end,
group = 'config',
})
do
local command = 'doautocmd User BufEnterOrGitSignsUpdate'
vim.api.nvim_create_autocmd('BufEnter', {command = command, group = 'config'})
vim.api.nvim_create_autocmd('User', {command = command, group = 'config', pattern = 'GitSignsUpdate'})
end
--- Set buffer variables for file icon and color.
--- @return {color: string, icon: string}
local function buf_init_devicons()
local icon, color = devicons.get_icon(vim.fn.expand '%:t', vim.fn.expand '%:e', {default = true})
local dev_icons = {color = vim.api.nvim_get_hl(0, {link = false, name = color}).fg, icon = icon}
vim.b.dev_icons = dev_icons
return dev_icons
end
--- @return {color: string, icon: string}
local function filetype_info()
return vim.b.dev_icons or buf_init_devicons()
end
--- Redraw the statusline
local redrawstatus = vim.schedule_wrap(function() vim.api.nvim_command 'redrawstatus' end)
--[[/* HEIRLINE CONFIG */]]
--- Components separated by this component will be padded with an equal number of spaces.
local ALIGN = {provider = '%='}
--- A left separator.
local LEFT_SEPARATOR = {provider = ''}
--- A right separator.
local RIGHT_SEPARATOR = {provider = ''}
require('heirline').setup({statusline =
{
-- LEFT {{{
{ -- ViMode {{{
hl = function(self)
vim.api.nvim_set_hl(0, self.group, {bg = SIDEBAR, fg = self.color, bold = true})
return self.group
end,
init = function(self)
if vim.g.libmodalActiveModeName then
self.name = vim.g.libmodalActiveModeName
self.color = self.modes[self.name]
else
local current_mode = self.modes[vim.api.nvim_get_mode().mode]
self.name = current_mode[1]
self.color = current_mode[2]
end
end,
provider = function(self) return '' .. self.name .. ' ' end,
static =
{ -- {{{
group = 'HeirlineViMode',
modes =
{
['c'] = {'COMMAND-LINE', RED},
['ce'] = {'NORMAL EX', RED_DARK},
['cv'] = {'EX', RED_LIGHT},
['i'] = {'INSERT', GREEN},
['ic'] = {'INS-COMPLETE', GREEN_LIGHT},
['ix'] = {'INS-COMPLETE', GREEN_LIGHT},
['Rc'] = {'REP-COMPLETE', GREEN_LIGHT},
['Rvc'] = {'VIRT-REP-COMPLETE', GREEN_LIGHT},
['Rvx'] = {'VIRT-REP-COMPLETE', GREEN_LIGHT},
['Rx'] = {'REP-COMPLETE', GREEN_LIGHT},
['n'] = {'NORMAL', PURPLE_LIGHT},
['niI'] = {'INS-NORMAL', PURPLE_LIGHT},
['niR'] = {'REP-NORMAL', PURPLE_LIGHT},
['niV'] = {'VIRT-REP-NORMAL', PURPLE_LIGHT},
['nt'] = {'TERM-NORMAL', PURPLE_LIGHT},
['ntT'] = {'TERM-NORMAL', PURPLE_LIGHT},
['no'] = {'OPERATOR-PENDING', PURPLE},
['nov'] = {'CHAR OPERATOR-PENDING', PURPLE},
['noV'] = {'LINE OPERATOR-PENDING', PURPLE},
['no'] = {'BLOCK OPERATOR-PENDING', PURPLE},
['R'] = {'REPLACE', PINK},
['Rv'] = {'VIRT-REPLACE', PINK_LIGHT},
['r'] = {'HIT-ENTER', CYAN},
['rm'] = {'--MORE', CYAN},
['r?'] = {':CONFIRM', CYAN},
['s'] = {'SELECT', TURQOISE},
['S'] = {'SELECT LINE', TURQOISE},
[''] = {'SELECT', TURQOISE},
['v'] = {'VISUAL', BLUE},
['vs'] = {'SEL-VISUAL', BLUE},
['V'] = {'VISUAL LINE', BLUE},
['Vs'] = {'SEL-VISUAL LINE', BLUE},
[''] = {'VISUAL BLOCK', BLUE},
['s'] = {'VISUAL BLOCK', BLUE},
['t'] = {'TERMINAL', ORANGE},
['!'] = {'SHELL', YELLOW},
-- libmodal
['BUFFERS'] = TEAL,
['TABLES'] = ORANGE_LIGHT,
['TABS'] = TAN,
}
}, -- }}}
update = {'ModeChanged', callback = redrawstatus, pattern = '*:*'},
}, -- }}}
{ -- File Icon {{{
hl = function(self) return {bg = SIDEBAR, fg = self.file.color} end,
init = function(self) self.file = filetype_info() end,
update = 'BufEnter',
LEFT_SEPARATOR,
{
hl = function(self) return {bg = self.file.color, fg = SIDEBAR} end,
provider = function(self) return ' ' .. self.file.icon .. ' %Y ' end,
},
RIGHT_SEPARATOR,
}, -- }}}
{ -- File Info {{{
hl = {bg = SIDEBAR, bold = true, fg = TEXT},
-- File name
{provider = ' %t '},
{ -- Readonly {{{
condition = function() return vim.api.nvim_get_option_value('readonly', {buf = 0}) end,
provider = '',
update = {'OptionSet', pattern = 'readonly'},
}, -- }}}
{ -- Modified {{{
condition = function() return vim.api.nvim_get_option_value('modified', {}) end,
provider = '',
update = 'BufModifiedSet',
}, -- }}}
{ -- File size {{{
init = function(self) self.stat = vim.loop.fs_stat(vim.api.nvim_buf_get_name(0)) end,
update = {'BufEnter', 'BufWritePost'},
{
condition = function(self) return self.stat end,
provider = function(self)
local size = self.stat.size
local i = 1
while size > self.conversion and i < #self.units do
size = size / self.conversion
i = i + 1
end
return ('%.2f%sb '):format(size, self.units[i])
end,
static = {conversion = 1024, units = {'', 'k', 'm', 'g', 't', 'p', 'e', 'z', 'y'}},
},
}, -- }}}
{hl = {fg = MIDBAR}, LEFT_SEPARATOR},
}, -- }}}
-- }}}
-- MIDDLE {{{
{hl = {bg = MIDBAR}, ALIGN},
{ -- Diagnostics {{{
hl = {bg = MIDBAR, fg = SIDEBAR},
init = function(self)
local diagnostics = vim.diagnostic.get(0) --- @type Diagnostic[]
if #diagnostics < 1 then
self.diagnostics = nil
else
self.diagnostics = {0, 0, 0, 0}
for _, diagnostic in ipairs(diagnostics) do
self.diagnostics[diagnostic.severity] = self.diagnostics[diagnostic.severity] + 1
end
end
end,
update = {'BufEnter', 'DiagnosticChanged'},
{
condition = function(self) return self.diagnostics end,
LEFT_SEPARATOR,
{
hl = {bg = SIDEBAR},
static =
{ -- {{{
icons = {'', '', '', ''},
--- @param severity 1|2|3|4
--- @return nil|string
provide = function(self, severity)
if self.diagnostics[severity] > 0 then
local str = self.icons[severity] .. self.diagnostics[severity]
for i = severity + 1, #self.diagnostics do
if self.diagnostics[i] > 0 then
str = str .. ' '
break
end
end
return str
end
end,
}, -- }}}
{hl = {fg = RED}, provider = function(self) return self:provide(vim.diagnostic.severity.ERROR) end},
{hl = {fg = ORANGE}, provider = function(self) return self:provide(vim.diagnostic.severity.WARN) end},
{hl = {fg = PINK_LIGHT}, provider = function(self) return self:provide(vim.diagnostic.severity.INFO) end},
{hl = {fg = MAGENTA}, provider = function(self) return self:provide(vim.diagnostic.severity.HINT) end},
},
RIGHT_SEPARATOR,
},
}, -- }}}
-- }}}
-- RIGHT {{{
{hl = {bg = MIDBAR}, ALIGN},
{ -- Git {{{
init = function(self) self.status = vim.b.gitsigns_status_dict end,
update = {'User', callback = redrawstatus, pattern = 'BufEnterOrGitSignsUpdate'},
{ -- Diff {{{
hl = {bg = MIDBAR},
{
condition = function(self) return self.status end,
static =
{
--- @param sign string
--- @param change string
--- @return nil|string
provide = function(self, sign, change)
local count = self.status[change] or 0
if count > 0 then return sign .. count end
end,
},
{hl = {fg = GREEN}, provider = function(self) return self:provide('+', 'added') end},
{hl = {fg = ORANGE_LIGHT}, provider = function(self) return self:provide('~', 'changed') end},
{hl = {fg = RED_LIGHT}, provider = function(self) return self:provide('-', 'removed') end},
{provider = ' '},
},
}, -- }}}
{ -- Branch {{{
hl = {bg = GREEN_DARK},
{hl = {fg = MIDBAR}, RIGHT_SEPARATOR},
{provider = ' '},
{
condition = function(self) return self.status end,
hl = {fg = SIDEBAR, bold = true},
provider = function(self) return '' .. self.status.head .. ' ' end,
},
{hl = {fg = SIDEBAR}, LEFT_SEPARATOR},
}, -- }}}
}, -- }}}
-- Column Number
{hl = {fg = TEXT, bg = SIDEBAR}, provider = '  %v '},
{ -- Line Percentage {{{
hl = {bg = MAGENTA_DARK},
{hl = {fg = SIDEBAR}, RIGHT_SEPARATOR},
{hl = {fg = WHITE}, provider = ' %p%% '},
}, -- }}}
-- }}}
}})