Summary Files Commits Branches @commit @diff @stats
path: root / lua / plugins / heirline.lua
blob: 126066a50a89556e63f5f4baa4337120c84c0c19 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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)
	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" },
	}
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,
}

local Filename = { provider = "%f", }
local Space    = { provider = " ", }

--[=[ Statusline ]=]--

vim.cmd.highlight({ "ModeNormal",  "ctermfg=236", "ctermbg=117" })
vim.cmd.highlight({ "ModeInsert",  "ctermfg=236", "ctermbg=119" })
vim.cmd.highlight({ "ModeReplace", "ctermfg=236", "ctermbg=203" })
vim.cmd.highlight({ "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,
})


vim.cmd.highlight({ "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
}

--[=[ Setup ]=]--

require("heirline").setup({
	statusline = StatusLine,
})