-- Pull in the wezterm API local wezterm = require 'wezterm' local config = {} local act = wezterm.action if wezterm.config_builder then config = wezterm.config_builder() end -- -------------------------------------------------------------------- -- 1. HELPERS & STATE -- -------------------------------------------------------------------- local function is_vim(pane) -- This checks the process name of the active pane local process_name = pane:get_foreground_process_name() return process_name:find('n?vim') ~= nil or process_name:find('vim.exe') ~= nil end local key_to_dir = { h = 'Left', j = 'Down', k = 'Up', l = 'Right', } local function split_nav(resize_or_move, key) return { key = key, mods = resize_or_move == 'resize' and 'META' or 'CTRL', action = wezterm.action_callback(function(win, pane) if is_vim(pane) then -- pass the keys through to vim/nvim win:perform_action({ SendKey = { key = key, mods = resize_or_move == 'resize' and 'META' or 'CTRL' }, }, pane) else if resize_or_move == 'resize' then win:perform_action({ AdjustPaneSize = { key_to_dir[key], 3 } }, pane) else win:perform_action({ ActivatePaneDirection = key_to_dir[key] }, pane) end end end), } end -- -------------------------------------------------------------------- -- 2. EVENTS (Status Bar & Workspace Tracking) -- -------------------------------------------------------------------- wezterm.on('update-right-status', function(window, pane) local cells = {} -- Workspace Name table.insert(cells, "󱔐 " .. window:active_workspace()) -- Battery/Power (check if battery info exists to avoid errors on desktops) local battery = wezterm.battery_info() if battery and #battery > 0 then for _, b in ipairs(battery) do table.insert(cells, string.format('%.0f%%', b.state_of_charge * 100)) end end -- Date & Day table.insert(cells, wezterm.strftime('󰃭 %a %d %b')) -- Time table.insert(cells, wezterm.strftime('󱑒 %H:%M')) local colors = { '#313244', '#45475a', '#585b70', '#6c7086' } -- Catppuccin Mocha colors local text_fg = '#cdd6f4' local elements = {} for i, seg in ipairs(cells) do table.insert(elements, { Background = { Color = colors[i] or '#313244' } }) table.insert(elements, { Foreground = { Color = text_fg } }) table.insert(elements, { Text = ' ' .. seg .. ' ' }) end window:set_right_status(wezterm.format(elements)) end) wezterm.on('format-window-title', function(tab, pane, tabs, panes, config) local zoomed = 'wezterm: ' if tab.active_pane.is_zoomed then zoomed = '[Z] ' end local index = #tabs > 1 and string.format('[%d/%d] ', tab.tab_index + 1, #tabs) or '' return zoomed .. index .. tab.active_pane.title end) -- -------------------------------------------------------------------- -- 3. VISUALS (Windows 11 Mica & Aesthetics) -- -------------------------------------------------------------------- {{- if eq .chezmoi.os "windows" }} config.win32_system_backdrop = 'Mica' config.window_background_opacity = 0.85 config.prefer_egl = true -- Often smoother on Windows {{- else }} config.window_background_opacity = 1.0 {{- end }} config.text_background_opacity = 1.0 config.color_scheme = 'Adventure' config.front_end = "WebGpu" config.webgpu_power_preference = 'HighPerformance' config.max_fps = 120 config.animation_fps = 1 -- Disable UI animations for "snappier" feel config.font = wezterm.font('CaskaydiaCove NF', { weight = 'Regular' }) config.font_size = 10.0 config.line_height = 1.1 -- Slightly more breathing room config.default_cursor_style = "SteadyBar" config.window_decorations = "INTEGRATED_BUTTONS | RESIZE" config.use_fancy_tab_bar = false -- Faster rendering than fancy tab bar config.enable_scroll_bar = false -- Cleaner look config.initial_rows = 48 config.initial_cols = 160 -- -------------------------------------------------------------------- -- 4. GENERAL CONFIG -- -------------------------------------------------------------------- config.use_ime = false -- Reduces input latency config.use_dead_keys = false -- Better for coding (no double-quote issues) config.pane_focus_follows_mouse = true config.inactive_pane_hsb = { saturation = 0.8, brightness = 0.5, } -- Colors for the UI config.colors = { split = '#313244', } -- Default Shell Configuration {{- if eq .chezmoi.os "windows" }} config.default_prog = { 'pwsh.exe', '-NoLogo' } {{- else }} config.default_prog = { 'zsh', '-l' } {{- end }} config.scrollback_lines = 20000 config.enable_kitty_graphics = true config.ssh_backend = "Ssh2" -- Leader key Configuration config.leader = { key = ' ', mods = 'CTRL', timeout_milliseconds = 1000 } config.launch_menu = { {{- if eq .chezmoi.os "windows" }} { label = "PowerShell", args = {"C:/Program Files/PowerShell/7/pwsh.exe"}, domain = {DomainName="local"}}, { label = 'cmd', args = {'cmd.exe'}}, { label = 'Ubuntu', args = {'wsl','-d','Ubuntu'}} {{- else }} { label = "Zsh", args = {"zsh", "-l"}}, {{- end }} } -- -------------------------------------------------------------------- -- 5. KEYBINDINGS -- -------------------------------------------------------------------- config.keys = { -- Leader passthrough { key = 'b', mods = 'LEADER|CTRL', action = act.SendKey { key = 'a', mods = 'CTRL' }}, -- Smart Splits (CTRL+h/j/k/l to move between WezTerm and Neovim) split_nav('move', 'h'), split_nav('move', 'j'), split_nav('move', 'k'), split_nav('move', 'l'), -- Panes { key = "\\", mods="LEADER", action=act{SplitVertical={domain="CurrentPaneDomain"}}}, { key = "|", mods="LEADER|SHIFT", action=act{SplitHorizontal={domain="CurrentPaneDomain"}}}, { key = "w", mods="CTRL|SHIFT", action=act{CloseCurrentPane={confirm=true}}}, { key = "z", mods="LEADER", action=act.TogglePaneZoomState }, -- Tabs { key = 'n', mods = 'CTRL|SHIFT', action=act.SpawnTab 'DefaultDomain'}, { key = "Tab", mods="CTRL", action=act{ActivateTabRelative=-1}}, { key = "Tab", mods="CTRL|SHIFT", action=act{ActivateTabRelative=1}}, -- Workspaces { key = 's', mods = 'LEADER', action = act.ShowLauncherArgs { flags = 'WORKSPACES' }}, { key = '$', mods = 'LEADER|SHIFT', action = act.PromptInputLine { description = 'Enter new name for workspace', action = wezterm.action_callback(function(window, pane, line) if line then wezterm.mux.rename_workspace(wezterm.mux.get_active_workspace(), line) end end), }}, -- Quick Select (Grab URLs/Hashes) { key = 'f', mods = 'LEADER', action = act.QuickSelectArgs { label = 'open url', patterns = { 'https?://\\S+' }, action = wezterm.action_callback(function(window, pane) local url = window:get_selection_text_for_pane(pane) wezterm.open_with(url) end), }, }, } -- Bind number keys to tabs for i = 1, 9 do table.insert(config.keys, { key = tostring(i), mods = 'CTRL', action = act.ActivateTab(i - 1), }) end -- Mouse Bindings config.mouse_bindings = { { event = { Down = { streak = 3, button = 'Left' } }, action = act.SelectTextAtMouseCursor 'SemanticZone', mods = 'NONE', }, } -- Hyperlink rules config.hyperlink_rules = wezterm.default_hyperlink_rules() table.insert(config.hyperlink_rules, { regex = [=[(\b[A-Za-z]:\\[^\s:"']+\b)]=], format = 'file://$1', }) return config