-
Notifications
You must be signed in to change notification settings - Fork 11
/
init.lua
369 lines (331 loc) · 8.39 KB
/
init.lua
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
local wezterm = require("wezterm")
local M = {}
-- default configuration
local config = {
position = "bottom",
max_width = 32,
dividers = "slant_right",
indicator = {
leader = {
enabled = true,
off = " ",
on = " ",
},
mode = {
enabled = true,
names = {
resize_mode = "RESIZE",
copy_mode = "VISUAL",
search_mode = "SEARCH",
},
},
},
tabs = {
numerals = "arabic",
pane_count = "superscript",
brackets = {
active = { "", ":" },
inactive = { "", ":" },
},
},
clock = {
enabled = true,
format = "%H:%M",
},
}
-- parsed config
local C = {}
local function tableMerge(t1, t2)
for k, v in pairs(t2) do
if type(v) == "table" then
if type(t1[k] or false) == "table" then
tableMerge(t1[k] or {}, t2[k] or {})
else
t1[k] = v
end
else
t1[k] = v
end
end
return t1
end
local dividers = {
slant_right = {
left = utf8.char(0xe0be),
right = utf8.char(0xe0bc),
},
slant_left = {
left = utf8.char(0xe0ba),
right = utf8.char(0xe0b8),
},
arrows = {
left = utf8.char(0xe0b2),
right = utf8.char(0xe0b0),
},
rounded = {
left = utf8.char(0xe0b6),
right = utf8.char(0xe0b4),
},
}
-- conforming to https://github.com/wez/wezterm/commit/e4ae8a844d8feaa43e1de34c5cc8b4f07ce525dd
-- exporting an apply_to_config function, even though we don't change the users config
M.apply_to_config = function(c, opts)
-- make the opts arg optional
if not opts then
opts = {}
end
-- combine user config with defaults
config = tableMerge(config, opts)
C.div = {
l = "",
r = "",
}
if config.dividers then
C.div.l = dividers[config.dividers].left
C.div.r = dividers[config.dividers].right
end
C.leader = {
enabled = config.indicator.leader.enabled and true,
off = config.indicator.leader.off,
on = config.indicator.leader.on,
}
C.mode = {
enabled = config.indicator.mode.enabled,
names = config.indicator.mode.names,
}
C.tabs = {
numerals = config.tabs.numerals,
pane_count_style = config.tabs.pane_count,
brackets = {
active = config.tabs.brackets.active,
inactive = config.tabs.brackets.inactive,
},
}
C.clock = {
enabled = config.clock.enabled,
format = config.clock.format,
}
-- set the right-hand padding to 0 spaces, if the rounded style is active
C.p = (config.dividers == "rounded") and "" or " "
-- set wezterm config options according to the parsed config
c.use_fancy_tab_bar = false
c.tab_bar_at_bottom = config.position == "bottom"
c.tab_max_width = config.max_width
end
-- superscript/subscript
local function numberStyle(number, script)
local scripts = {
superscript = {
"⁰",
"¹",
"²",
"³",
"⁴",
"⁵",
"⁶",
"⁷",
"⁸",
"⁹",
},
subscript = {
"₀",
"₁",
"₂",
"₃",
"₄",
"₅",
"₆",
"₇",
"₈",
"₉",
},
}
local numbers = scripts[script]
local number_string = tostring(number)
local result = ""
for i = 1, #number_string do
local char = number_string:sub(i, i)
local num = tonumber(char)
if num then
result = result .. numbers[num + 1]
else
result = result .. char
end
end
return result
end
local roman_numerals = {
"Ⅰ",
"Ⅱ",
"Ⅲ",
"Ⅳ",
"Ⅴ",
"Ⅵ",
"Ⅶ",
"Ⅷ",
"Ⅸ",
"Ⅹ",
"Ⅺ",
"Ⅻ",
}
-- custom tab bar
wezterm.on(
"format-tab-title",
function(tab, tabs, _panes, conf, _hover, _max_width)
local colours = conf.resolved_palette.tab_bar
local active_tab_index = 0
for _, t in ipairs(tabs) do
if t.is_active == true then
active_tab_index = t.tab_index
end
end
-- TODO: make colors configurable
local rainbow = {
conf.resolved_palette.ansi[2],
conf.resolved_palette.indexed[16],
conf.resolved_palette.ansi[4],
conf.resolved_palette.ansi[3],
conf.resolved_palette.ansi[5],
conf.resolved_palette.ansi[6],
}
local i = tab.tab_index % 6
local active_bg = rainbow[i + 1]
local active_fg = colours.background
local inactive_bg = colours.inactive_tab.bg_color
local inactive_fg = colours.inactive_tab.fg_color
local new_tab_bg = colours.new_tab.bg_color
local s_bg, s_fg, e_bg, e_fg
-- the last tab
if tab.tab_index == #tabs - 1 then
if tab.is_active then
s_bg = active_bg
s_fg = active_fg
e_bg = new_tab_bg
e_fg = active_bg
else
s_bg = inactive_bg
s_fg = inactive_fg
e_bg = new_tab_bg
e_fg = inactive_bg
end
elseif tab.tab_index == active_tab_index - 1 then
s_bg = inactive_bg
s_fg = inactive_fg
e_bg = rainbow[(i + 1) % 6 + 1]
e_fg = inactive_bg
elseif tab.is_active then
s_bg = active_bg
s_fg = active_fg
e_bg = inactive_bg
e_fg = active_bg
else
s_bg = inactive_bg
s_fg = inactive_fg
e_bg = inactive_bg
e_fg = inactive_bg
end
local pane_count = ""
if C.tabs.pane_count_style then
local tabi = wezterm.mux.get_tab(tab.tab_id)
local muxpanes = tabi:panes()
local count = #muxpanes == 1 and "" or tostring(#muxpanes)
pane_count = numberStyle(count, C.tabs.pane_count_style)
end
local index_i
if C.tabs.numerals == "roman" then
index_i = roman_numerals[tab.tab_index + 1]
else
index_i = tab.tab_index + 1
end
local index
if tab.is_active then
index = string.format(
"%s%s%s ",
C.tabs.brackets.active[1],
index_i,
C.tabs.brackets.active[2]
)
else
index = string.format(
"%s%s%s ",
C.tabs.brackets.inactive[1],
index_i,
C.tabs.brackets.inactive[2]
)
end
-- start and end hardcoded numbers are the Powerline + " " padding
local fillerwidth = 2 + string.len(index) + string.len(pane_count) + 2
local tabtitle = tab.active_pane.title
local width = conf.tab_max_width - fillerwidth - 1
if (#tabtitle + fillerwidth) > conf.tab_max_width then
tabtitle = wezterm.truncate_right(tabtitle, width) .. "…"
end
local title = string.format(" %s%s%s%s", index, tabtitle, pane_count, C.p)
return {
{ Background = { Color = s_bg } },
{ Foreground = { Color = s_fg } },
{ Text = title },
{ Background = { Color = e_bg } },
{ Foreground = { Color = e_fg } },
{ Text = C.div.r },
}
end
)
wezterm.on("update-status", function(window, _pane)
local active_kt = window:active_key_table() ~= nil
local show = C.leader.enabled or (active_kt and C.mode.enabled)
if not show then
window:set_left_status("")
return
end
local present, conf = pcall(window.effective_config, window)
if not present then
return
end
local palette = conf.resolved_palette
local leader = ""
if C.leader.enabled then
local leader_text = C.leader.off
if window:leader_is_active() then
leader_text = C.leader.on
end
leader = wezterm.format({
{ Foreground = { Color = palette.background } },
{ Background = { Color = palette.ansi[5] } },
{ Text = " " .. leader_text .. C.p },
})
end
local mode = ""
if C.mode.enabled then
local mode_text = ""
local active = window:active_key_table()
if C.mode.names[active] ~= nil then
mode_text = C.mode.names[active] .. ""
end
mode = wezterm.format({
{ Foreground = { Color = palette.background } },
{ Background = { Color = palette.ansi[5] } },
{ Attribute = { Intensity = "Bold" } },
{ Text = mode_text },
"ResetAttributes",
})
end
local first_tab_active = window:mux_window():tabs_with_info()[1].is_active
local divider_bg = first_tab_active and palette.ansi[2]
or palette.tab_bar.inactive_tab.bg_color
local divider = wezterm.format({
{ Background = { Color = divider_bg } },
{ Foreground = { Color = palette.ansi[5] } },
{ Text = C.div.r },
})
window:set_left_status(leader .. mode .. divider)
if C.clock.enabled then
local time = wezterm.time.now():format(C.clock.format)
window:set_right_status(wezterm.format({
{ Background = { Color = palette.tab_bar.background } },
{ Foreground = { Color = palette.ansi[6] } },
{ Text = time },
}))
end
end)
return M