summaryrefslogtreecommitdiff
path: root/.config/nvim/lua/statusline.lua
blob: b7b6ed9d09c957c3eb79445a3a8c1d35b124fa1a (plain)
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
local fn = vim.fn
local api = vim.api

-- possible values are 'arrow' | 'rounded' | 'blank'
local active_sep = 'blank'

-- change them if you want to different separator
local separators = {
	arrow = { '', '' },
	rounded = { '', '' },
	blank = { '', '' },
}

-- highlight groups
local 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#',
}

local trunc_width = setmetatable({
	mode       = 80,
	git_status = 90,
	filename   = 140,
	line_col   = 60,
}, {
	__index = function()
		return 80
	end
})

local is_truncated = function(_, width)
	local current_width = api.nvim_win_get_width(0)
	return current_width < width
end

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

local get_current_mode = function()
	return string.format('[%s]', api.nvim_get_mode().mode )
end

local get_git_status = function()
	-- 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 is_truncated(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

local get_filename = function()
	--if is_truncated(trunc_width.filename) then return "%<%f" end
	return "%<%F"
end

local get_filetype = function()
	local filetype = vim.bo.filetype
	if filetype == '' then
		return ''
	end
	return string.format('%s', filetype):lower()
end

local get_line_col = function()
	return '%l:%c'
end

Statusline = {}

Statusline.active = function()
	local navic = require('nvim-navic')

	--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() .. colors.git_alt
	--local location = ""
	--if navic.is_available() then
	--location = navic.get_location()
	--end
	--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]

	local mode = get_current_mode()
	--local git = get_git_status()
	local filename = get_filename() .. colors.git_alt
	local location = ""
	if navic.is_available() then
		location = navic.get_location()
	end
	local filetype = get_filetype()
	local line_col = get_line_col()

	return table.concat({
		mode, " ", filename, " ", "%m%r%q", " ", filetype,
		"%=",
		location, " ", line_col, " "
	})
end

Statusline.inactive = function()
	return colors.inactive .. '%F'
end

Statusline.set_explorer = function()
	local title = colors.mode .. '   '
	local title_alt = colors.mode_alt .. Statusline.separators[active_sep][2]

	return table.concat({ 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
--})

local augroup = api.nvim_create_augroup('Statusline', { clear = true})
api.nvim_create_autocmd({"WinEnter", "BufEnter"}, {
	command = "setlocal statusline=%!v:lua.Statusline.active()",
	group = augroup
})
api.nvim_create_autocmd({"WinLeave", "BufLeave"}, {
	command = "setlocal statusline=%!v:lua.Statusline.inactive()",
	group = augroup
})

----[[
--  NOTE: I don't use this since the statusline already has
--  so much stuff going on. Feel free to use it!
--  credit: https://github.com/nvim-lua/lsp-status.nvim
--
--  I now use `tabline` to display these errors, go to `_bufferline.lua` if you
--  want to check that out
----]]
-- Statusline.get_lsp_diagnostic = function(self)
--   local result = {}
--   local levels = {
--     errors = 'Error',
--     warnings = 'Warning',
--     info = 'Information',
--     hints = 'Hint'
--   }

--   for k, level in pairs(levels) do
--     result[k] = vim.lsp.diagnostic.get_count(0, level)
--   end

--   if self:is_truncated(120) then
--     return ''
--   else
--     return string.format(
--       "| :%s :%s :%s :%s ",
--       result['errors'] or 0, result['warnings'] or 0,
--       result['info'] or 0, result['hints'] or 0
--     )
--   end
-- end