Last active
October 5, 2024 00:27
-
-
Save neogeographica/ee94d8510e7623ca7f8d5473e59e5a4d to your computer and use it in GitHub Desktop.
WezTerm config
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Customize fonts and colors. | |
local always_switch_all_window_schemes = true | |
local wezterm = require 'wezterm' | |
local schemes = require 'schemes' | |
local util = require 'util' | |
local module = {} | |
-- Common utility function to modify color props in config or overrides. | |
local function setColorSchemeProperties(config, color_scheme_name) | |
local color_scheme = wezterm.get_builtin_color_schemes()[color_scheme_name] | |
config.color_scheme = color_scheme_name | |
config.colors = { | |
tab_bar = { | |
active_tab = { | |
bg_color = color_scheme.background, | |
fg_color = color_scheme.foreground, | |
}, | |
}, | |
} | |
-- Also set grey for scrollbar. | |
config.colors.scrollbar_thumb = '#555555' | |
-- And grey for the selected-text background? | |
-- XXX Not sure when to override this for different schemes. For most | |
-- schemes the scheme-specified color is OK. Leaving this alone for now. | |
-- config.colors.selection_bg = '#555555' | |
end | |
-- Common utility function to update one window's color scheme. | |
local function setColorSchemeForWindow(color_scheme_name, window) | |
local overrides = window:get_config_overrides() or {} | |
setColorSchemeProperties(overrides, color_scheme_name) | |
window:set_config_overrides(overrides) | |
end | |
-- Common utility function to set color scheme for all existing and future | |
-- windows. Except for skipWindow, if non-nil. | |
local function applySchemeToAllWindows(color_scheme_name, skipWindow) | |
for _, mux_window in ipairs(wezterm.mux.all_windows()) do | |
local window = mux_window:gui_window() | |
if window ~= skipWindow then | |
setColorSchemeForWindow(color_scheme_name, window) | |
end | |
end | |
wezterm.GLOBAL.color_scheme_name = color_scheme_name | |
wezterm.reload_configuration() | |
end | |
-- Keybound action to set current window's color scheme for all existing and | |
-- future windows. | |
local function applyWindowSchemeToAllWindows(window, _) | |
applySchemeToAllWindows(window:effective_config().color_scheme, window) | |
end | |
-- Change one window's color scheme to next or previous in list. Used by the | |
-- keybound actions for cycling scheme forward or backward. | |
local function cycleScheme(window, isForward) | |
local currentScheme = window:effective_config().color_scheme | |
local color_scheme_name = schemes[1] | |
for i = 1, #schemes, 1 do | |
if schemes[i] == currentScheme then | |
-- 1-based arrays can look goofy for mod math... | |
if isForward then | |
color_scheme_name = schemes[i % #schemes + 1] | |
else | |
color_scheme_name = schemes[(i-2) % #schemes + 1] | |
end | |
break | |
end | |
end | |
setColorSchemeForWindow(color_scheme_name, window) | |
if always_switch_all_window_schemes then | |
applySchemeToAllWindows(color_scheme_name, window) | |
end | |
end | |
-- Keybound actions for cycling window color scheme forward or backward. | |
local function cycleSchemeForward(window, _) | |
cycleScheme(window, true) | |
end | |
local function cycleSchemeBackward(window, _) | |
cycleScheme(window, false) | |
end | |
function module.configure(config) | |
-- Set color scheme. | |
local color_scheme_name | |
if wezterm.GLOBAL.color_scheme_name == nil then | |
color_scheme_name = schemes[1] | |
else | |
color_scheme_name = wezterm.GLOBAL.color_scheme_name | |
end | |
setColorSchemeProperties(config, color_scheme_name) | |
-- Configure window widgets. | |
-- XXX INTEGRATED_BUTTONS has issues with the minimize button not working | |
-- if on Linux. | |
if util.platform.is_mac then | |
config.window_decorations = "INTEGRATED_BUTTONS|RESIZE" | |
end | |
config.enable_scroll_bar = true | |
-- Set font family and size. | |
config.font = wezterm.font 'MonaspiceAr NFM' | |
config.font_size = 11 | |
-- macOS differences: | |
-- Using WebGpu on macOS for its color aesthetics. | |
-- Also punching up text brightness a bit on macOS. Note that this | |
-- will interfere with building the foreground/background color matching | |
-- in status.lua; we'll compensate over there. If this brightness value | |
-- is changed then that compensation will also need to be changed. | |
if util.platform.is_mac then | |
config.front_end = 'WebGpu' | |
config.foreground_text_hsb = { | |
hue = 1.0, | |
saturation = 1.0, | |
brightness = 1.2, | |
} | |
wezterm.GLOBAL.brightness_boosted = true | |
end | |
-- Make inactive panes a bit dimmer. | |
config.inactive_pane_hsb = { | |
saturation = 0.5, | |
brightness = 0.3, | |
} | |
-- Set keys to cycle and apply color schemes. | |
table.insert( | |
config.keys, | |
{ | |
key = 's', | |
mods = 'ALT', | |
action = wezterm.action_callback(cycleSchemeForward), | |
} | |
) | |
table.insert( | |
config.keys, | |
{ | |
key = 's', | |
mods = 'SHIFT|ALT', | |
action = wezterm.action_callback(cycleSchemeBackward), | |
} | |
) | |
table.insert( | |
config.keys, | |
{ | |
key = 's', | |
mods = 'CTRL|ALT', | |
action = wezterm.action_callback(applyWindowSchemeToAllWindows), | |
} | |
) | |
end | |
return module |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Customize domain definitions and attachment. | |
local wezterm = require 'wezterm' | |
local module = {} | |
-- Predictive key display seems distracting ... some flickering and the cursor | |
-- bouncing back and forth. Disable it for now unless lag is really bad. | |
local ECHO_THRESHOLD_MS = 2000 | |
local function find_and_raise_domain_panes(domain_name) | |
local stop_checking_tabs = false | |
local found_attached_pane = false | |
for _, check_mux_window in ipairs(wezterm.mux.all_windows()) do | |
stop_checking_tabs = false | |
for _, check_tab in ipairs(check_mux_window:tabs()) do | |
for _, check_pane in ipairs(check_tab:panes()) do | |
if check_pane:get_domain_name() == domain_name then | |
check_tab:activate() | |
check_pane:activate() | |
check_mux_window:gui_window():focus() | |
stop_checking_tabs = true | |
found_attached_pane = true | |
break | |
end | |
end | |
if stop_checking_tabs then | |
break | |
end | |
end | |
end | |
return found_attached_pane | |
end | |
function module.configure(config) | |
-- Build the list of ssh-accessible domains. | |
-- XXX Note these hosts will need to have wezterm installed too! | |
-- XXX Not showing real hostnames/usernames/keys here for obvious reasons. | |
config.ssh_domains = { | |
{ | |
name = 'example-host', | |
remote_address = 'host.dns.or.ip', | |
username = 'whatever-username', | |
local_echo_threshold_ms = ECHO_THRESHOLD_MS, | |
ssh_option = { | |
IdentityFile = wezterm.home_dir .. '/.ssh/appropriate-ssh-key', | |
-- This is an often-redeployed test VM so don't check the host key. | |
UserKnownHostsFile = '/dev/null', | |
StrictHostKeyChecking = 'no', | |
}, | |
}, | |
-- XXX and etc. for more hosts. | |
} | |
-- Also specify a domain to use for persisting local state. | |
local this_host_domain_name = wezterm.hostname() | |
config.unix_domains = { | |
{ | |
name = this_host_domain_name, | |
}, | |
} | |
-- Use that domain on startup. Note that if a Linux desktop file is used | |
-- to launch Wezterm and it specifies other args, this will be ignored. | |
config.default_gui_startup_args = { 'connect', this_host_domain_name } | |
-- Now make a list of the domains in the order they should be presented | |
-- in the domain-selector. | |
domain_choices = {} | |
for _, ssh_domain in ipairs(config.ssh_domains) do | |
table.insert(domain_choices, { label = ssh_domain.name }) | |
end | |
for _, ssh_domain in ipairs(config.unix_domains) do | |
table.insert(domain_choices, { label = ssh_domain.name }) | |
end | |
table.insert(domain_choices, { label = 'local' }) | |
-- Define the action of the domain-selector keybinding, as follows: | |
-- * Present a list of domains to select from, w/ fuzzy select enabled. | |
-- * If the selected domain is already attached, move its windows to the | |
-- front (with a domain-relevant pane/tab activated in each). | |
-- * Otherwise attach the domain, opening its windows/tabs/panes in new | |
-- windows. If it has no panes, start one in a new window. | |
table.insert( | |
config.keys, | |
{ | |
key = 'o', | |
mods = 'SHIFT|CTRL', | |
action = wezterm.action.InputSelector { | |
title = "Domains", | |
choices = domain_choices, | |
fuzzy = true, | |
action = wezterm.action_callback(function(_window, _pane, _id, label) | |
if not label then | |
-- No domain selected; do nothing. | |
return | |
end | |
mux_domain = wezterm.mux.get_domain(label) | |
if mux_domain == nil then | |
-- Can't find the selected domain; do nothing. | |
-- XXX Ideally, play an error beep? post a notification? | |
return | |
end | |
if mux_domain:state() == "Attached" then | |
-- Selected domain is already attached. Raise its windows and | |
-- make sure that a domain-relevant pane is active in each. If | |
-- we find any such panes, exit. | |
if find_and_raise_domain_panes(label) then | |
return | |
end | |
end | |
-- Selected domain is not attached (or has no panes). | |
if mux_domain:state() ~= "Attached" then | |
-- Unattached. So, let's attach! | |
mux_domain:attach() | |
-- If there are panes, we're done. | |
if find_and_raise_domain_panes(label) then | |
return | |
end | |
end | |
-- Attached but no panes. Let's make a new window/tab/pane. | |
wezterm.mux.spawn_window { domain = { DomainName = label } } | |
end), | |
}, | |
} | |
) | |
end | |
return module |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Customize behavior for the windowing interface. | |
local wezterm = require 'wezterm' | |
local module = {} | |
function module.configure(config) | |
-- Disable "are you sure" prompt when closing tab. | |
-- XXX Trying to disable tab close confirmation using all the mechanisms | |
-- below. This works for the ctrl-shift-w key shortcut, and also works for | |
-- the tab "x" in the local domain. In ssh or unix domains however the "x" | |
-- closure still shows the confirm prompt. | |
config.window_close_confirmation = 'NeverPrompt' | |
table.insert( | |
config.keys, | |
{ | |
key = 'w', | |
mods = 'SHIFT|CTRL', | |
action = wezterm.action.CloseCurrentTab { confirm = false }, | |
} | |
) | |
table.insert( | |
config.keys, | |
{ | |
key = 'w', | |
mods = 'CMD', | |
action = wezterm.action.CloseCurrentTab { confirm = false }, | |
} | |
) | |
wezterm.on( | |
'mux-is-process-stateful', | |
function(_proc) | |
return false | |
end | |
) | |
end | |
return module |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Array of cycle-able color schemes. | |
-- Manually edit this value to choose allowlist or denylist. | |
local mode = 'allowlist' | |
-- If allowlist mode, just return a list of chosen schemes. First one in the | |
-- list will be the scheme at startup. | |
if mode == 'allowlist' then | |
return { | |
'Poimandres', | |
'SpaceGray Eighties', | |
'SpaceGray Eighties Dull', | |
'3024 (base16)', | |
'Dracula (Gogh)', | |
'Guezwhoz', | |
'nightfox', | |
} | |
end | |
-- If not allowlist mode, then first let's identify the schemes that should | |
-- NOT be cycle-able. Building this list by browsing the schemes and | |
-- discarding the ones I'm sure I don't want, or duplicates... also in this | |
-- mode any new schemes that appear in future releases will be available by | |
-- default. Only looking at dark themes here (see below). | |
local wezterm = require 'wezterm' | |
local schemes_denylist = { | |
'3024 (dark) (terminal.sexy)', | |
'3024 Night', | |
'3024 Night (Gogh)', | |
'3024Night (Gogh)', | |
'Aardvark Blue', | |
'Abernathy', | |
'Adventure', | |
'Adventure Time (Gogh)', | |
'AdventureTime', | |
'Afterglow', | |
'Afterglow (Gogh)', | |
'Alien Blood (Gogh)', | |
'AlienBlood', | |
'Andromeda', | |
'Apathy (base16)', | |
'Apple Classic', | |
'Apprentice (Gogh)', | |
'Apprentice (base16)', | |
'Argonaut', | |
'Arthur', | |
'Arthur (Gogh)', | |
'Ashes (base16)', | |
'Ashes (dark) (terminal.sexy)', | |
'Atelier Cave (base16)', | |
'Atelier Dune (base16)', | |
'Atelier Estuary (base16)', | |
'Atelier Heath (base16)', | |
'Atelier Lakeside (base16)', | |
'Atelier Sulphurpool (base16)', | |
'AtelierSulphurpool', | |
'Atom', | |
'Atom (Gogh)', | |
'Aura (Gogh)', | |
'Aurora', | |
'Ayu Dark (Gogh)', | |
'AyuDark (Gogh)', | |
'Ayu Mirage', | |
'Ayu Mirage (Gogh)', | |
'AyuMirage (Gogh)', | |
'Azu (Gogh)', | |
'Bamboo Multiplex', | |
'Banana Blueberry', | |
'Batman', | |
'Belafonte Night', | |
'Belafonte Night (Gogh)', | |
'BelafonteNight (Gogh)', | |
'Belge (terminal.sexy)', | |
'Bespin (base16)', | |
'Bespin (dark) (terminal.sexy)', | |
'Bim (Gogh)', | |
'Birds Of Paradise (Gogh)', | |
'BirdsOfParadise', | |
'Bitmute (terminal.sexy)', | |
'Black Metal (Bathory) (base16)', | |
'Black Metal (Burzum) (base16)', | |
'Black Metal (Dark Funeral) (base16)', | |
'Black Metal (Gorgoroth) (base16)', | |
'Black Metal (Immortal) (base16)', | |
'Black Metal (Khold) (base16)', | |
'Black Metal (Marduk) (base16)', | |
'Black Metal (Mayhem) (base16)', | |
'Black Metal (Nile) (base16)', | |
'Black Metal (Venom) (base16)', | |
'Black Metal (base16)', | |
'Blazer', | |
'Blazer (Gogh)', | |
'Blue Matrix', | |
'BlueBerryPie', | |
'BlueDolphin', | |
'Borland', | |
'Borland (Gogh)', | |
'Breath (Gogh)', | |
'Breath Darker (Gogh)', | |
'BreathSilverfox (Gogh)', | |
'Breeze', | |
'Brewer (dark) (terminal.sexy)', | |
'Bright (base16)', | |
'Broadcast', | |
'Broadcast (Gogh)', | |
'Brogrammer', | |
'Brogrammer (Gogh)', | |
'Brogrammer (base16)', | |
'Brush Trees Dark (base16)', | |
'Builtin Pastel Dark', | |
'Builtin Solarized Dark', | |
'Builtin Tango Dark', | |
'C64', | |
'C64 (Gogh)', | |
'Cai (Gogh)', | |
'Calamity', | |
'Canvased Pastel (terminal.sexy)', | |
'Catch Me If You Can (terminal.sexy)', | |
'Catppuccin Frappe', | |
'Catppuccin Frappé (Gogh)', | |
'Catppuccin Macchiato', | |
'Catppuccin Mocha', | |
'Chalk', | |
'Chalk (base16)', | |
'Chalk (Gogh)', | |
'Chalk (dark) (terminal.sexy)', | |
'Chalkboard', | |
'Chalkboard (Gogh)', | |
'ChallengerDeep', | |
'Chameleon (Gogh)', | |
'Ciapre', | |
'Ciapre (Gogh)', | |
'Circus (base16)', | |
'City Streets (terminal.sexy)', | |
'Classic Dark (base16)', | |
'Clone Of Ubuntu (Gogh)', | |
'CloneofUbuntu (Gogh)', | |
'Cloud (terminal.sexy)', | |
'Cobalt 2 (Gogh)', | |
'Cobalt Neon', | |
'Cobalt Neon (Gogh)', | |
'Cobalt2', | |
'CobaltNeon (Gogh)', | |
'Codeschool (base16)', | |
'Codeschool (dark) (terminal.sexy)', | |
'Color Star (terminal.sexy)', | |
'Colorful Colors (terminal.sexy)', | |
'Colors (base16)', | |
'Count Von Count (terminal.sexy)', | |
'Crayon Pony Fish (Gogh)', | |
'CrayonPonyFish', | |
'Cyberdyne', | |
'DWM rob (terminal.sexy)', | |
'DanQing (base16)', | |
'Darcula (base16)', | |
'Dark Pastel (Gogh)', | |
'Dark Violet (base16)', | |
'Dark+', | |
'DarkPastel (Gogh)', | |
'Darkside', | |
'Darktooth (base16)', | |
'Dawn (terminal.sexy)', | |
'Deafened (terminal.sexy)', | |
'DeHydration (Gogh)', | |
'Decaf (base16)', | |
'Default Dark (base16)', | |
'Derp (terminal.sexy)', | |
'Desert', | |
'Desert (Gogh)', | |
'Dimmed Monokai (Gogh)', | |
'DimmedMonokai', | |
'Dissonance (Gogh)', | |
'Django', | |
'DjangoRebornAgain', | |
'DjangoSmooth', | |
'Doom Peacock', | |
'Dracula', | |
'Dracula (base16)', | |
'Dracula (Official)', | |
'Dracula+', | |
'Duotone Dark', | |
'ENCOM', | |
'Earthsong', | |
'Earthsong (Gogh)', | |
'Edge Dark (base16)', | |
'Ef-Autumn', | |
'Ef-Bio', | |
'Ef-Cherie', | |
'Ef-Elea-Dark', | |
'Ef-Maris-Dark', | |
'Ef-Melissa-Dark', | |
'Ef-Rosa', | |
'Ef-Symbiosis', | |
'Ef-Trio-Dark', | |
'Ef-Tritanopia-Dark', | |
'Eighties (base16)', | |
'Eighties (dark) (terminal.sexy)', | |
'Eldorado dark (terminal.sexy)', | |
'Elemental', | |
'Elemental (Gogh)', | |
'Elementary', | |
'Elementary (Gogh)', | |
'Elic (Gogh)', | |
'Elio (Gogh)', | |
'Embers (base16)', | |
'Embers (dark) (terminal.sexy)', | |
'Epiphany (terminal.sexy)', | |
'Eqie6 (terminal.sexy)', | |
'Equilibrium Dark (base16)', | |
'Equilibrium Gray Dark (base16)', | |
'Erebus (terminal.sexy)', | |
'Espresso', | |
'Espresso (Gogh)', | |
'Espresso (base16)', | |
'Espresso Libre', | |
'Espresso Libre (Gogh)', | |
'EspressoLibre (Gogh)', | |
'Eva (base16)', | |
'Eva Dim (base16)', | |
'Everblush', | |
'Everforest Dark (Gogh)', | |
'EverforestDark (Gogh)', | |
'Fahrenheit', | |
'Fairy Floss (Gogh)', | |
'Fairy Floss Dark (Gogh)', | |
'FairyFloss (Gogh)', | |
'FairyFlossDark (Gogh)', | |
'Fairyfloss', | |
'FarSide (terminal.sexy)', | |
'Fideloper', | |
'Firefly Traditional', | |
'FishTank', | |
'Fishtank (Gogh)', | |
'Flat', | |
'Flat (Gogh)', | |
'Flat (base16)', | |
'FlatRemix (Gogh)', | |
'Flatland', | |
'Flatland (Gogh)', | |
'flexoki-dark', | |
'Floraverse', | |
'Foxnightly (Gogh)', | |
'Framer', | |
'Freya (Gogh)', | |
'FrontEndDelight', | |
'Frontend Delight (Gogh)', | |
'Frontend Fun Forrest (Gogh)', | |
'FrontendDelight (Gogh)', | |
'FrontendFunForrest (Gogh)', | |
'FrontendGalaxy (Gogh)', | |
'FunForrest', | |
'Galizur', | |
'GJM (terminal.sexy)', | |
'GeoHot (Gogh)', | |
'Geohot (Gogh)', | |
'Glacier', | |
'Gogh (Gogh)', | |
'Google (dark) (terminal.sexy)', | |
'GoogleDark (Gogh)', | |
'gotham (Gogh)', | |
'Gotham (Gogh)', | |
'Gotham (terminal.sexy)', | |
'Grandshell (terminal.sexy)', | |
'Grape', | |
'Grape (Gogh)', | |
'Grass', | |
'Grass (Gogh)', | |
'Grayscale (dark) (terminal.sexy)', | |
'Grayscale Dark (base16)', | |
'Green Screen (base16)', | |
'Greenscreen (dark) (terminal.sexy)', | |
'Grey-green', | |
'Gruber (base16)', | |
'Gruvbox Dark (Gogh)', | |
'Gruvbox Material (Gogh)', | |
'Gruvbox dark, hard (base16)', | |
'Gruvbox dark, medium (base16)', | |
'Gruvbox dark, pale (base16)', | |
'Gruvbox dark, soft (base16)', | |
'GruvboxDark', | |
'GruvboxDarkHard', | |
'Hacktober', | |
'Hardcore', | |
'Hardcore (Gogh)', | |
'Hardcore (base16)', | |
'Harper', | |
'Harper (Gogh)', | |
'Helios (base16)', | |
'Hemisu Dark (Gogh)', | |
'HemisuDark (Gogh)', | |
-- Got to this point so far, looking at color schemes in order. | |
-- Some other misc denies: | |
'HaX0R_BLUE', | |
'HaX0R_GR33N', | |
'HaX0R_R3D', | |
'Heetch Dark (base16)', | |
'Highway', | |
'Highway (Gogh)', | |
'Hipster Green', | |
'Hipster Green (Gogh)', | |
'HipsterGreen (Gogh)', | |
'Homebrew', | |
'Homebrew (Gogh)', | |
'hund (terminal.sexy)', | |
'IBM3270(HighContrast) (Gogh)', | |
'Ibm 3270 (HighContrast) (Gogh)', | |
'iceberg-dark', | |
'ICOrangePPL (Gogh)', | |
'IC_Green_PPL', | |
'IC_Orange_PPL', | |
'Ic Orange Ppl (Gogh)', | |
'iTerm2 Pastel Dark Background', | |
'iTerm2 Solarized Dark', | |
'jmbi (terminal.sexy)', | |
'kokuban (Gogh)', | |
'matrix', | |
'mono-amber (Gogh)', | |
'mono-cyan (Gogh)', | |
'mono-green (Gogh)', | |
'mono-red (Gogh)', | |
'mono-white (Gogh)', | |
'mono-yellow (Gogh)', | |
'pinky (base16)', | |
'purplepeter', | |
's3r0 modified (terminal.sexy)', | |
'seoulbones_dark', | |
'summercamp (base16)', | |
'synthwave-everything', | |
'theme2 (terminal.sexy)', | |
'tlh (terminal.sexy)', | |
'zenburned', | |
} | |
-- Turn the array into a set to make it easy to check membership. | |
local schemes_denylist_set = {} | |
for _, scheme_name in ipairs(schemes_denylist) do | |
schemes_denylist_set[scheme_name] = true | |
end | |
-- Build a list of dark themes that aren't in the deny set. | |
local allSchemes = wezterm.color.get_builtin_schemes() | |
local darkSchemes = {} | |
for name, scheme in pairs(allSchemes) do | |
if schemes_denylist_set[name] == nil then | |
if scheme.background then | |
local bg = wezterm.color.parse(scheme.background) | |
---@diagnostic disable-next-line: unused-local | |
local h, s, l, a = bg:hsla() | |
if l < 0.4 then | |
table.insert(darkSchemes, name) | |
end | |
end | |
end | |
end | |
table.sort(darkSchemes) | |
return darkSchemes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Customize status displays. | |
local wezterm = require 'wezterm' | |
local util = require 'util' | |
local module = {} | |
local SOLID_LEFT_ARROW = wezterm.nerdfonts.pl_right_hard_divider | |
local YELLOW_SUN = utf8.char(0x2600) | |
local MAGNIFYING_GLASS = utf8.char(0x1f50d) | |
local HOURGLASS = utf8.char(0x231b) | |
-- Utility function to toggle (or initially set) the global controlling | |
-- whether to show color scheme name in the status bar. | |
local function toggleSchemeNameStatus(_, _) | |
if wezterm.GLOBAL.show_scheme_name == true then | |
wezterm.GLOBAL.show_scheme_name = false | |
else | |
wezterm.GLOBAL.show_scheme_name = true | |
end | |
end | |
-- Utility function for composing tab title for display. | |
local function tab_title(tab_info) | |
local retval = tab_info.active_pane.title | |
local title = tab_info.tab_title | |
if title and #title > 0 then | |
retval = title | |
end | |
-- We already have a copy mode / search mode indicator in the status bar, so | |
-- no need to add it to the tab title. Also weirdly it says "Copy mode" | |
-- here even in search mode. So just remove it from the tab title. | |
return retval:gsub('^Copy mode: ', '') | |
end | |
-- Build the list of labels that make up the status bar. | |
local function segments_for_right_status(window, pane) | |
-- Always show workspace and domain name segments. | |
local workspace_name = window:active_workspace() | |
local domain_name = pane:get_domain_name() | |
local segments = { | |
' ' .. workspace_name .. ' ', | |
' ' .. domain_name .. ' ', | |
} | |
-- Add a magnifying glass icon if current pane is zoomed. | |
local tab = pane:tab() | |
if tab ~= nil then | |
for _, p in ipairs(tab:panes_with_info()) do | |
if p.is_zoomed then | |
table.insert(segments, 1, ' ' .. MAGNIFYING_GLASS) | |
end | |
end | |
end | |
-- Add mode (from key table name) if active. | |
local keytable_name = window:active_key_table() | |
if keytable_name then | |
mode_name = keytable_name:gsub("_", " "):upper() | |
table.insert(segments, 1, ' ' .. mode_name .. ' ') | |
end | |
-- Show color scheme name if requested. | |
if wezterm.GLOBAL.show_scheme_name == true then | |
table.insert(segments, 1, ' ' .. window:effective_config().color_scheme .. ' ') | |
end | |
-- Add a lag indicator if the mux server is being slow to respond. | |
-- XXX The lag indicator seems to flicker on even when there's not any actual | |
-- noticeable problem... commenting it out for now. | |
--[[ | |
local meta = pane:get_metadata() or {} | |
if meta.is_tardy then | |
local secs = meta.since_last_response_ms / 1000.0 | |
table.insert(segments, 1, string.format('%5.1fs ' .. HOURGLASS, secs)) | |
end | |
--]] | |
return segments | |
end | |
function module.configure(config) | |
-- Define callback for setting the displayed tab title. | |
wezterm.on( | |
'format-tab-title', | |
function(tab, tabs, panes, config, hover, max_width) | |
return tab_title(tab) | |
end | |
) | |
-- Alternately to the above... modify tab title when a not-currently-focused | |
-- tab has unseen output (e.g. from a running program there). | |
-- XXX Marking a tab that has "unseen output" is kind of a cool idea, but | |
-- the marker can also be triggered just when resizing an existing window. | |
-- Not 100% convinced about the utility. Leaving it out for now. | |
--[[ | |
wezterm.on( | |
'format-tab-title', | |
function(tab, tabs, panes, config, hover, max_width) | |
local title = tab_title(tab) | |
if tab.is_active then | |
return title | |
end | |
for _, pane in ipairs(tab.panes) do | |
if pane.has_unseen_output then | |
return { | |
-- The "x" on the tab seems to always be the same color as the | |
-- first character of text. So I guess let's stick a char up | |
-- front before setting different colors for the title. | |
-- In this case I'm using a "sun" character that looks OK as an | |
-- "indicator light" in my chosen font. | |
{ Text = YELLOW_SUN .. ' ' }, | |
-- Color 4 is the "yellow" for the palette. | |
{ Foreground = { Color = config.resolved_palette.brights[4] } }, | |
{ Text = title }, | |
} | |
end | |
end | |
return title | |
end | |
) | |
--]] | |
-- Draw some powerline-style info segments on the right side of the tab bar. | |
-- Largely taken from https://alexplescan.com/posts/2024/08/10/wezterm/ | |
wezterm.on( | |
'update-status', | |
function(window, pane) | |
local segments = segments_for_right_status(window, pane) | |
local color_scheme = window:effective_config().resolved_palette | |
local bg = wezterm.color.parse(color_scheme.background) | |
local fg = color_scheme.foreground | |
local gradient_to, gradient_from = bg | |
gradient_from = gradient_to:lighten(0.2) | |
local gradient = wezterm.color.gradient( | |
{ | |
orientation = 'Horizontal', | |
colors = { gradient_from, gradient_to }, | |
}, | |
#segments | |
) | |
local elements = {} | |
for i, seg in ipairs(segments) do | |
local is_first = i == 1 | |
if is_first then | |
table.insert(elements, { Background = { Color = 'none' } }) | |
end | |
-- See comments in appearance.lua for why this darkening in macOS. | |
if wezterm.GLOBAL.brightness_boosted == true then | |
table.insert(elements, { Foreground = { Color = gradient[i]:darken(0.085) } }) | |
else | |
table.insert(elements, { Foreground = { Color = gradient[i] } }) | |
end | |
table.insert(elements, { Text = SOLID_LEFT_ARROW }) | |
-- If this is not one of the two rightmost constant segments, use a | |
-- yellow foreground color. | |
if (#segments - i) <= 1 then | |
table.insert(elements, { Foreground = { Color = fg } }) | |
else | |
table.insert(elements, { Foreground = { Color = color_scheme.brights[4] } }) | |
end | |
table.insert(elements, { Background = { Color = gradient[i] } }) | |
table.insert(elements, { Text = seg }) | |
end | |
window:set_right_status(wezterm.format(elements)) | |
end | |
) | |
-- Set key for toggling color scheme name in status. | |
table.insert( | |
config.keys, | |
{ | |
key = 's', | |
mods = 'CTRL', | |
action = wezterm.action_callback(toggleSchemeNameStatus), | |
} | |
) | |
end | |
return module |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Commonly shared utility functions. | |
local wezterm = require 'wezterm' | |
local module = {} | |
-- This part is similar to platform-detect code in multiple repos e.g. : | |
-- https://github.com/sravioli/wezterm | |
-- https://github.com/KevinSilvester/wezterm-config | |
-- For me, I don't really care if this value gets recalculated every time this | |
-- module is require'd, but I do want to avoid recalculation every time the | |
-- value is referenced. So just do a simple precalculation here. | |
local is_win = wezterm.target_triple:find "windows" ~= nil | |
local is_linux = wezterm.target_triple:find "linux" ~= nil | |
local is_mac = wezterm.target_triple:find "apple" ~= nil | |
local os = is_win and "windows" or is_linux and "linux" or is_mac and "mac" or "unknown" | |
module.platform = { os = os, is_win = is_win, is_linux = is_linux, is_mac = is_mac } | |
return module |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Top-level WezTerm config. Only exists to load the config pieces that have | |
-- been parceled out into other modules. | |
local wezterm = require 'wezterm' | |
local interface = require 'interface' | |
local appearance = require 'appearance' | |
local workspaces = require 'workspaces' | |
local domains = require 'domains' | |
local status = require 'status' | |
local config = wezterm.config_builder() | |
config.keys = {} | |
config.key_tables = {} | |
interface.configure(config) | |
appearance.configure(config) | |
workspaces.configure(config) | |
domains.configure(config) | |
status.configure(config) | |
-- Let's try a plugin! | |
local cmd_sender = wezterm.plugin.require("https://github.com/aureolebigben/wezterm-cmd-sender") | |
cmd_sender.apply_to_config(config, { | |
key = 'y', | |
mods = 'CTRL|SHIFT', | |
description = 'Enter command to send to all panes of active tab' | |
}) | |
return config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Customize workspace management. | |
local wezterm = require 'wezterm' | |
local module = {} | |
function module.configure(config) | |
-- Not much here at the moment. Just add a key shortcut for opening the | |
-- launcher to select/create workspace. | |
table.insert( | |
config.keys, | |
{ | |
key = 'o', | |
mods = 'CTRL', | |
action = wezterm.action.ShowLauncherArgs { | |
flags = 'FUZZY|WORKSPACES', | |
}, | |
} | |
) | |
end | |
return module |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment