Summary Files Commits Branches @commit @diff @stats
path: root / nvim / .nvim / lua / plugins / heirline.lua
diff options
context:
space:
mode:
Commitc9ca8a09dc3a5e421c50dc3cfa16c573a3e87135 (patch)
Author
 Syndamia <kamen@syndamia.com>
2026-11-01 22:51:04 +0200
Committer
 Syndamia <kamen@syndamia.com>
2026-11-01 22:51:18 +0200
Filesec3e06cdc9099838406b918f5b9347eee46adf88 /nvim/.nvim/lua/plugins/heirline.lua
.files-main.tar
.files-main.tar.gz
.files-main.zip
Parent72d71324e1063d4d7402180e846aeff3056ba177 (diff)
feat(nvim): Implement nvim config HEAD main
Latest version from https://git.syndamia.com/conf/anderson (and formerly https://gitlab.com/Syndamia/anderson). Not edited in 7 months.
1 files changed, 262 insertions, 0 deletions
-rw-r--r--nvim/.nvim/lua/plugins/heirline.lua262
diff --git a/nvim/.nvim/lua/plugins/heirline.lua b/nvim/.nvim/lua/plugins/heirline.lua
new file mode 100644
index 0000000..cd7fbd2
--- /dev/null
+++ b/nvim/.nvim/lua/plugins/heirline.lua
@@ -0,0 +1,262 @@
+return {
+ "rebelot/heirline.nvim",
+ lazy = false,
+ event = "UiEnter",
+ opts = function()
+ local utils = require("heirline.utils")
+ local conditions = require("heirline.conditions")
+
+ --[=[ Helpers ]=]--
+
+ function inverseColors(highlight)
+ if highlight == nil then return nil end
+
+ if type(highlight) == "string" then
+ highlight = utils.get_highlight(highlight)
+ end
+
+ highlight.cterm = { reverse = true }
+ return highlight
+ end
+
+ local delimiters = {
+ FilledCircle = { "", "" },
+ Circle = { "", "" },
+ }
+ local StatusLineColor = utils.get_highlight("StatusLine")
+
+ function surround(delimiters, component, additional_update)
+ return {
+ init = function(self)
+ local highlight
+ if component.hl ~= nil and type(component.hl) == "function" then
+ if component.init ~= nil then
+ component:init()
+ end
+ highlight = component:hl()
+ else
+ highlight = component.hl
+ end
+
+ self.inverse = inverseColors(highlight)
+ self.inverse.ctermfg = StatusLineColor.ctermfg -- Actually sets bg, but both are reversed
+ end,
+
+ {
+ condition = function() return conditions.is_active() end,
+ provider = delimiters[1],
+ hl = function(self) return self.inverse end,
+ },
+ component,
+ {
+ condition = function() return conditions.is_active() end,
+ provider = delimiters[2],
+ hl = function(self) return self.inverse end,
+ },
+
+ update = { "BufEnter", "BufLeave", additional_update },
+ }
+ end
+
+ function set_hl(name, val)
+ val.nocombine = true
+ vim.api.nvim_set_hl(0, name, val)
+ return val
+ end
+
+ --[=[ Common elements ]=]--
+
+ local FileStat = {
+ {
+ condition = function()
+ return vim.bo.readonly
+ end,
+ provider = "",
+ },
+ {
+ condition = function()
+ return vim.bo.modified or not vim.bo.modifiable
+ end,
+ provider = function(self)
+ local prepend = vim.bo.readonly and " " or ""
+ if vim.bo.modified then return prepend.."" end
+ if not vim.bo.modifiable then return prepend.."" end
+ end,
+ },
+ }
+
+ local FileType = {
+ static = {
+ get_icon = require("nvim-web-devicons").get_icon_by_filetype,
+ },
+ provider = function(self)
+ local icon = self.get_icon(vim.bo.filetype)
+ if icon ~= nil then icon = icon.." "
+ else icon = ""
+ end
+ return icon..vim.bo.filetype
+ end,
+ update = "FileType",
+ }
+
+ local Filename = { provider = "%f", }
+ local Space = { provider = " ", }
+
+ --[=[ Statusline ]=]--
+
+ set_hl("ModeNormal", { ctermfg = 236, ctermbg = 117 })
+ set_hl("ModeInsert", { ctermfg = 236, ctermbg = 119 })
+ set_hl("ModeReplace", { ctermfg = 236, ctermbg = 203 })
+ set_hl("ModeVisual", { ctermfg = 236, ctermbg = 216 })
+
+ local Mode = surround(delimiters.FilledCircle, {
+ init = function(self)
+ self.modestr = vim.fn.mode(1)
+ if self.modestr == "\22" then self.modestr = "V^"
+ elseif self.modestr == "\22s" then self.modestr = "V^s"
+ end
+ end,
+
+ provider = function(self)
+ if not conditions.is_active() then return " " end
+ return self.modestr
+ end,
+ hl = function(self)
+ if not conditions.is_active() then return "StatusLineNC" end
+
+ local modeletter = self.modestr:sub(1,1):lower()
+
+ if modeletter == "i" then return "ModeInsert"
+ elseif modeletter == "r" then return "ModeReplace"
+ elseif modeletter == "v" then return "ModeVisual"
+ end
+
+ return "ModeNormal"
+ end,
+ }, "ModeChanged")
+
+
+ set_hl("RowAndColumn", { ctermfg = 238, ctermbg = 244 })
+
+ local LineAndColumn = surround(delimiters.FilledCircle, {
+ provider = function(self)
+ if not conditions.is_active() then
+ local row,col = unpack(vim.api.nvim_win_get_cursor(0))
+ return string.rep(" ", 1 + tostring(row):len() + tostring(col):len())
+ end
+ return "%l:%c"
+ end,
+ hl = function(self)
+ if not conditions.is_active() then return "StatusLineNC" end
+ return "RowAndColumn"
+ end,
+ })
+
+ local LeftShrink = { provider = "%<", }
+ local LeftSep = { provider = " "..delimiters.Circle[2].." " }
+ local RightSep = { provider = " "..delimiters.Circle[1].." " }
+ local ExpandMiddle = { provider = "%=", }
+ local CursorChar = { provider = "%b", }
+
+ local StatusLine = {
+ Mode, LeftShrink, Space, Filename, LeftSep, FileStat,
+ ExpandMiddle,
+ CursorChar, RightSep, FileType, Space, LineAndColumn
+ }
+
+ --[=[ Tabline ]=]--
+ local hl_TabLine = set_hl("TabLine", { ctermfg = 252, ctermbg = 242 })
+ local hl_TabLineSel = set_hl("TabLineSel", { ctermfg = 252, ctermbg = 235 })
+ local hl_TabLineFill = set_hl("TabLineFill", { ctermfg = 248, ctermbg = 238 })
+ set_hl("TabLineRFR", { ctermfg = hl_TabLine.ctermbg, ctermbg = hl_TabLineFill.ctermbg }) -- nonactive Right Full, Rightmost
+ set_hl("TabLineSelRF", { ctermfg = hl_TabLineSel.ctermbg, ctermbg = hl_TabLine.ctermbg }) -- active Right Full
+ set_hl("TabLineSelRFR", { ctermfg = hl_TabLineSel.ctermbg, ctermbg = hl_TabLineFill.ctermbg }) -- active Right Full, Rightmost
+ set_hl("TabLineSelLF", { ctermfg = hl_TabLine.ctermbg, ctermbg = hl_TabLineSel.ctermbg }) -- active Left Full (left one's Right Full)
+
+ local TabPage = {
+ init = function(self)
+ self.pages = vim.api.nvim_list_tabpages()
+ end,
+ {
+ static = {
+ get_icon = require("nvim-web-devicons").get_icon,
+ ft_icon = require("nvim-web-devicons").get_icon_by_filetype,
+ none_icon = "",
+ },
+ init = function(self)
+ self.bufnr = vim.api.nvim_win_get_buf(vim.api.nvim_tabpage_get_win(self.tabpage))
+ end,
+ provider = function(self)
+ --[==[ Filename ]==]--
+ local filename = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(self.bufnr), ":t")
+ if #filename == 0 then filename = "[No Name]" end
+
+ local max_name_len = vim.o.columns / (5 + #self.pages)
+ filename = (self.get_icon(filename, vim.fn.fnamemodify(filename, ":e")) or self.ft_icon(vim.bo[self.bufnr].filetype) or self.none_icon) ..
+ " " .. string.sub(filename, 1, max_name_len)
+
+ --[==[ Readonly ]==]--
+ local readonly = vim.bo[self.bufnr].readonly and " " or ""
+
+ --[==[ Modification ]==]--
+ local mod = vim.bo[self.bufnr].modified and " "
+ or (vim.bo[self.bufnr].modifiable and "" or " ")
+
+ --[==[ Tab ]==]--
+ return
+ "%" .. self.tabnr .. "T" ..
+ " " ..
+ filename .. readonly .. mod ..
+ " "
+ end,
+ hl = function(self)
+ if not self.is_active then
+ return "TabLine"
+ else
+ return "TabLineSel"
+ end
+ end,
+ },
+ {
+ init = function(self)
+ local activenr = vim.api.nvim_tabpage_get_number(vim.api.nvim_get_current_tabpage())
+
+ self.dist = self.tabnr - activenr
+ self.last = self.tabnr == #self.pages
+ end,
+ provider = function(self)
+ return (self.last or self.dist == -1 or self.dist == 0)
+ and delimiters.FilledCircle[2] or delimiters.Circle[2]
+ end,
+ hl = function(self)
+ if not self.is_active then
+ return self.last and "TabLineRFR" or (self.dist == -1 and "TabLineSelLF" or "TabLine")
+ else
+ return self.last and "TabLineSelRFR" or "TabLineSelRF"
+ end
+ end,
+ },
+ {
+ provider = "%T"
+ }
+ }
+
+ local TabPages = {
+ -- only show this component if there's 2 or more tabpages
+ condition = function()
+ return #vim.api.nvim_list_tabpages() >= 2
+ end,
+ utils.make_tablist(TabPage),
+ }
+
+ local TabLine = {
+ TabPages,
+ }
+
+ --[=[ Setup ]=]--
+ return {
+ statusline = StatusLine,
+ tabline = TabLine,
+ }
+ end,
+}