2022-12-19 17:50:20 +01:00
|
|
|
|
local wezterm = require("wezterm")
|
2023-03-06 11:58:51 +01:00
|
|
|
|
local utils = require("utils")
|
2022-12-19 17:50:20 +01:00
|
|
|
|
|
2023-03-04 10:00:08 +01:00
|
|
|
|
local M = {}
|
|
|
|
|
|
2023-03-05 05:40:35 +01:00
|
|
|
|
-- default configuration
|
|
|
|
|
local config = {
|
|
|
|
|
position = "bottom",
|
|
|
|
|
max_width = 32,
|
2023-03-04 10:00:08 +01:00
|
|
|
|
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",
|
|
|
|
|
},
|
2022-12-19 17:50:20 +01:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-05 05:40:35 +01:00
|
|
|
|
-- parsed config
|
|
|
|
|
local C = {}
|
|
|
|
|
|
|
|
|
|
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),
|
|
|
|
|
},
|
|
|
|
|
}
|
2023-03-04 10:00:08 +01:00
|
|
|
|
|
2023-03-05 05:40:35 +01:00
|
|
|
|
-- 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
|
2023-03-04 10:00:08 +01:00
|
|
|
|
|
2023-03-05 05:40:35 +01:00
|
|
|
|
-- combine user config with defaults
|
2023-03-06 11:58:51 +01:00
|
|
|
|
config = utils.tableMerge(config, opts)
|
2023-03-04 10:00:08 +01:00
|
|
|
|
C.div = {
|
|
|
|
|
l = "",
|
|
|
|
|
r = "",
|
|
|
|
|
}
|
2023-03-05 05:40:35 +01:00
|
|
|
|
|
|
|
|
|
if config.dividers then
|
|
|
|
|
C.div.l = dividers[config.dividers].left
|
|
|
|
|
C.div.r = dividers[config.dividers].right
|
2023-03-04 10:00:08 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
C.leader = {
|
2023-03-05 05:40:35 +01:00
|
|
|
|
enabled = config.indicator.leader.enabled or true,
|
|
|
|
|
off = config.indicator.leader.off,
|
|
|
|
|
on = config.indicator.leader.on,
|
2023-03-04 10:00:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
C.mode = {
|
2023-03-05 05:40:35 +01:00
|
|
|
|
enabled = config.indicator.mode.enabled,
|
|
|
|
|
names = config.indicator.mode.names,
|
2023-03-04 10:00:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
C.tabs = {
|
2023-03-05 05:40:35 +01:00
|
|
|
|
numerals = config.tabs.numerals,
|
|
|
|
|
pane_count_style = config.tabs.pane_count,
|
2023-03-04 10:00:08 +01:00
|
|
|
|
brackets = {
|
2023-03-05 05:40:35 +01:00
|
|
|
|
active = config.tabs.brackets.active,
|
|
|
|
|
inactive = config.tabs.brackets.inactive,
|
2023-03-04 10:00:08 +01:00
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
C.clock = {
|
2023-03-05 05:40:35 +01:00
|
|
|
|
enabled = config.clock.enabled,
|
|
|
|
|
format = config.clock.format,
|
2023-03-04 10:00:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-05 05:40:35 +01:00
|
|
|
|
-- set the right-hand padding to 0 spaces, if the rounded style is active
|
|
|
|
|
C.p = (config.dividers == "rounded") and "" or " "
|
2023-03-04 10:00:08 +01:00
|
|
|
|
|
2023-03-05 05:40:35 +01:00
|
|
|
|
-- 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
|
2023-03-04 10:00:08 +01:00
|
|
|
|
end
|
|
|
|
|
|
2023-01-01 15:36:39 +01:00
|
|
|
|
-- 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
|
|
|
|
|
|
2023-03-04 10:00:08 +01:00
|
|
|
|
local roman_numerals = {
|
|
|
|
|
"Ⅰ",
|
|
|
|
|
"Ⅱ",
|
|
|
|
|
"Ⅲ",
|
|
|
|
|
"Ⅳ",
|
|
|
|
|
"Ⅴ",
|
|
|
|
|
"Ⅵ",
|
|
|
|
|
"Ⅶ",
|
|
|
|
|
"Ⅷ",
|
|
|
|
|
"Ⅸ",
|
|
|
|
|
"Ⅹ",
|
|
|
|
|
"Ⅺ",
|
|
|
|
|
"Ⅻ",
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-19 17:50:20 +01:00
|
|
|
|
-- custom tab bar
|
2023-01-04 13:22:00 +01:00
|
|
|
|
wezterm.on(
|
|
|
|
|
"format-tab-title",
|
2023-03-05 05:40:35 +01:00
|
|
|
|
function(tab, tabs, _panes, conf, _hover, _max_width)
|
2023-03-06 11:32:18 +01:00
|
|
|
|
local colors = conf.resolved_palette.tab_bar
|
2023-01-04 13:22:00 +01:00
|
|
|
|
|
|
|
|
|
local active_tab_index = 0
|
|
|
|
|
for _, t in ipairs(tabs) do
|
|
|
|
|
if t.is_active == true then
|
|
|
|
|
active_tab_index = t.tab_index
|
|
|
|
|
end
|
2023-01-01 15:36:39 +01:00
|
|
|
|
end
|
|
|
|
|
|
2023-03-05 05:40:35 +01:00
|
|
|
|
-- TODO: make colors configurable
|
2023-01-04 13:22:00 +01:00
|
|
|
|
local rainbow = {
|
2023-03-05 05:40:35 +01:00
|
|
|
|
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],
|
2023-01-04 13:22:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
local i = tab.tab_index % 6
|
|
|
|
|
local active_bg = rainbow[i + 1]
|
2023-03-06 11:32:18 +01:00
|
|
|
|
local active_fg = colors.background
|
|
|
|
|
local inactive_bg = colors.inactive_tab.bg_color
|
|
|
|
|
local inactive_fg = colors.inactive_tab.fg_color
|
|
|
|
|
local new_tab_bg = colors.new_tab.bg_color
|
2023-01-04 13:22:00 +01:00
|
|
|
|
|
|
|
|
|
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
|
2023-01-01 15:36:39 +01:00
|
|
|
|
s_bg = active_bg
|
|
|
|
|
s_fg = active_fg
|
2023-01-04 13:22:00 +01:00
|
|
|
|
e_bg = inactive_bg
|
2023-01-01 15:36:39 +01:00
|
|
|
|
e_fg = active_bg
|
|
|
|
|
else
|
|
|
|
|
s_bg = inactive_bg
|
|
|
|
|
s_fg = inactive_fg
|
2023-01-04 13:22:00 +01:00
|
|
|
|
e_bg = inactive_bg
|
2023-01-01 15:36:39 +01:00
|
|
|
|
e_fg = inactive_bg
|
|
|
|
|
end
|
|
|
|
|
|
2023-03-04 10:00:08 +01:00
|
|
|
|
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
|
|
|
|
|
|
2023-03-05 05:40:35 +01:00
|
|
|
|
local index
|
2023-03-04 10:00:08 +01:00
|
|
|
|
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
|
2023-01-04 13:22:00 +01:00
|
|
|
|
|
2023-02-17 22:04:50 +01:00
|
|
|
|
-- start and end hardcoded numbers are the Powerline + " " padding
|
2023-03-04 10:00:08 +01:00
|
|
|
|
local fillerwidth = 2 + string.len(index) + string.len(pane_count) + 2
|
2023-02-17 22:04:50 +01:00
|
|
|
|
|
|
|
|
|
local tabtitle = tab.active_pane.title
|
2023-03-05 05:40:35 +01:00
|
|
|
|
local width = conf.tab_max_width - fillerwidth - 1
|
|
|
|
|
if (#tabtitle + fillerwidth) > conf.tab_max_width then
|
2023-03-04 10:00:08 +01:00
|
|
|
|
tabtitle = wezterm.truncate_right(tabtitle, width) .. "…"
|
2023-02-17 22:04:50 +01:00
|
|
|
|
end
|
|
|
|
|
|
2023-03-04 10:00:08 +01:00
|
|
|
|
local title = string.format(" %s%s%s%s", index, tabtitle, pane_count, C.p)
|
2023-02-17 22:04:50 +01:00
|
|
|
|
|
2023-01-04 13:22:00 +01:00
|
|
|
|
return {
|
|
|
|
|
{ Background = { Color = s_bg } },
|
|
|
|
|
{ Foreground = { Color = s_fg } },
|
2023-02-17 22:04:50 +01:00
|
|
|
|
{ Text = title },
|
2023-01-04 13:22:00 +01:00
|
|
|
|
{ Background = { Color = e_bg } },
|
|
|
|
|
{ Foreground = { Color = e_fg } },
|
2023-03-04 10:00:08 +01:00
|
|
|
|
{ Text = C.div.r },
|
2023-01-04 13:22:00 +01:00
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
)
|
2023-01-01 15:36:39 +01:00
|
|
|
|
|
2023-03-05 05:40:35 +01:00
|
|
|
|
wezterm.on("update-status", function(window, _pane)
|
2023-03-04 10:00:08 +01:00
|
|
|
|
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
|
2023-01-01 15:36:39 +01:00
|
|
|
|
end
|
|
|
|
|
|
2023-03-05 05:40:35 +01:00
|
|
|
|
local present, conf = pcall(window.effective_config, window)
|
|
|
|
|
if not present then
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
local palette = conf.resolved_palette
|
2023-01-01 15:36:39 +01:00
|
|
|
|
|
2023-03-04 10:00:08 +01:00
|
|
|
|
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 },
|
|
|
|
|
})
|
2023-01-04 13:22:00 +01:00
|
|
|
|
end
|
2023-01-01 15:36:39 +01:00
|
|
|
|
|
2023-03-04 10:00:08 +01:00
|
|
|
|
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",
|
|
|
|
|
})
|
2023-03-04 05:50:49 +01:00
|
|
|
|
end
|
|
|
|
|
|
2023-03-04 10:00:08 +01:00
|
|
|
|
local first_tab_active = window:mux_window():tabs_with_info()[1].is_active
|
2023-01-04 13:22:00 +01:00
|
|
|
|
local divider_bg = first_tab_active and palette.ansi[2]
|
|
|
|
|
or palette.tab_bar.inactive_tab.bg_color
|
2023-01-01 15:36:39 +01:00
|
|
|
|
|
2023-03-04 10:00:08 +01:00
|
|
|
|
local divider = wezterm.format({
|
2023-01-01 15:36:39 +01:00
|
|
|
|
{ Background = { Color = divider_bg } },
|
|
|
|
|
{ Foreground = { Color = palette.ansi[5] } },
|
2023-03-04 10:00:08 +01:00
|
|
|
|
{ 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
|
2022-12-19 17:50:20 +01:00
|
|
|
|
end)
|
2023-03-04 10:00:08 +01:00
|
|
|
|
|
|
|
|
|
return M
|