Created
September 19, 2025 17:54
-
-
Save aserper/24350ba2a89b7801bcff272b8ddf89a1 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| local wezterm = require("wezterm") | |
| local act = wezterm.action | |
| local mux = wezterm.mux | |
| local config = wezterm.config_builder() | |
| -- Session Management Plugin | |
| local workspace_switcher = wezterm.plugin.require("https://github.com/MLFlexer/smart_workspace_switcher.wezterm") | |
| workspace_switcher.zoxide_path = "/usr/bin/zoxide" | |
| -- Font configuration (exactly matching ghostty config) | |
| config.font = wezterm.font("CaskaydiaMono Nerd Font") | |
| config.font_size = 12 | |
| config.harfbuzz_features = { "liga", "calt" } | |
| config.font_rules = { | |
| { | |
| intensity = "Bold", | |
| font = wezterm.font("CaskaydiaMono Nerd Font", { weight = "Bold" }), | |
| }, | |
| { | |
| italic = true, | |
| font = wezterm.font("CaskaydiaMono Nerd Font", { style = "Italic" }), | |
| }, | |
| { | |
| intensity = "Bold", | |
| italic = true, | |
| font = wezterm.font("CaskaydiaMono Nerd Font", { weight = "Bold", style = "Italic" }), | |
| }, | |
| } | |
| config.cell_width = 1.0 | |
| config.line_height = 1.1 | |
| config.adjust_window_size_when_changing_font_size = false | |
| -- Font rendering to match ghostty (enhanced) | |
| config.freetype_load_target = "Light" | |
| config.freetype_render_target = "HorizontalLcd" | |
| config.freetype_load_flags = "NO_HINTING" | |
| -- Disable custom rendering that might interfere | |
| config.custom_block_glyphs = false | |
| config.use_cap_height_to_scale_fallback_fonts = false | |
| -- Window configuration | |
| config.window_padding = { | |
| left = 14, | |
| right = 14, | |
| top = 14, | |
| bottom = 14, | |
| } | |
| config.window_decorations = "NONE" | |
| config.enable_wayland = false | |
| config.window_background_opacity = 0.98 | |
| config.text_background_opacity = 1.0 | |
| -- Focus follows mouse (from Ghostty) | |
| config.pane_focus_follows_mouse = true | |
| -- Background blur and visual effects | |
| config.macos_window_background_blur = 20 | |
| config.window_background_gradient = { | |
| orientation = "Vertical", | |
| colors = { | |
| "#1a1b26", | |
| "#16161e", | |
| }, | |
| } | |
| -- Cursor configuration | |
| config.default_cursor_style = "BlinkingUnderline" | |
| config.cursor_blink_rate = 1000 | |
| config.cursor_blink_ease_in = "Constant" | |
| config.cursor_blink_ease_out = "Constant" | |
| -- Tokyo Night theme colors | |
| config.colors = { | |
| foreground = "#a9b1d6", | |
| background = "#1a1b26", | |
| cursor_bg = "#a9b1d6", | |
| cursor_fg = "#1a1b26", | |
| cursor_border = "#a9b1d6", | |
| selection_fg = "#1a1b26", | |
| selection_bg = "#7aa2f7", | |
| scrollbar_thumb = "#444b6a", | |
| split = "#32344a", | |
| ansi = { | |
| "#32344a", -- black | |
| "#f7768e", -- red | |
| "#9ece6a", -- green | |
| "#e0af68", -- yellow | |
| "#7aa2f7", -- blue | |
| "#ad8ee6", -- magenta | |
| "#449dab", -- cyan | |
| "#787c99", -- white | |
| }, | |
| brights = { | |
| "#444b6a", -- bright black | |
| "#ff7a93", -- bright red | |
| "#b9f27c", -- bright green | |
| "#ff9e64", -- bright yellow | |
| "#7da6ff", -- bright blue | |
| "#bb9af7", -- bright magenta | |
| "#0db9d7", -- bright cyan | |
| "#acb0d0", -- bright white | |
| }, | |
| } | |
| -- Enhanced tab bar configuration (blog post style) | |
| config.enable_tab_bar = true | |
| config.use_fancy_tab_bar = false | |
| config.tab_bar_at_bottom = false | |
| config.hide_tab_bar_if_only_one_tab = false | |
| config.show_new_tab_button_in_tab_bar = false | |
| config.tab_max_width = 32 | |
| -- Custom tab styling | |
| config.colors.tab_bar = { | |
| background = "#1a1b26", | |
| active_tab = { | |
| bg_color = "#7aa2f7", | |
| fg_color = "#1a1b26", | |
| intensity = "Bold", | |
| }, | |
| inactive_tab = { | |
| bg_color = "#32344a", | |
| fg_color = "#787c99", | |
| }, | |
| inactive_tab_hover = { | |
| bg_color = "#444b6a", | |
| fg_color = "#a9b1d6", | |
| }, | |
| new_tab = { | |
| bg_color = "#32344a", | |
| fg_color = "#787c99", | |
| }, | |
| new_tab_hover = { | |
| bg_color = "#444b6a", | |
| fg_color = "#a9b1d6", | |
| }, | |
| } | |
| -- Scrollback and scrolling enhancements | |
| config.scrollback_lines = 10000 | |
| config.enable_scroll_bar = true | |
| config.mouse_wheel_scrolls_tabs = false | |
| -- Default shell command to ensure prompt loads properly | |
| config.default_prog = { "/bin/bash", "-l", "-c", "exec bash" } | |
| -- Keybindings | |
| config.keys = { | |
| -- Fullscreen toggle | |
| { key = "F11", action = wezterm.action.ToggleFullScreen }, | |
| -- Tab management | |
| { key = "t", mods = "CTRL|SHIFT", action = wezterm.action.SpawnTab("CurrentPaneDomain") }, | |
| { key = "q", mods = "CTRL|SHIFT", action = wezterm.action.CloseCurrentTab({ confirm = true }) }, | |
| { key = "RightArrow", mods = "CTRL|SHIFT", action = wezterm.action.ActivateTabRelative(1) }, | |
| { key = "LeftArrow", mods = "CTRL|SHIFT", action = wezterm.action.ActivateTabRelative(-1) }, | |
| -- Workspace management | |
| { key = "s", mods = "CTRL|SHIFT", action = workspace_switcher.switch_workspace() }, | |
| { key = "w", mods = "CTRL|SHIFT", action = act.ShowLauncherArgs({ flags = "FUZZY|WORKSPACES" }) }, | |
| { key = "LeftBracket", mods = "CTRL|SHIFT", action = act.SwitchWorkspaceRelative(-1) }, | |
| { key = "RightBracket", mods = "CTRL|SHIFT", action = act.SwitchWorkspaceRelative(1) }, | |
| { key = "d", mods = "CTRL|SHIFT", action = act.SwitchToWorkspace({ name = "default" }) }, | |
| -- Direct tab switching with Alt+Ctrl+number | |
| { key = "1", mods = "ALT|CTRL", action = wezterm.action.ActivateTab(0) }, | |
| { key = "2", mods = "ALT|CTRL", action = wezterm.action.ActivateTab(1) }, | |
| { key = "3", mods = "ALT|CTRL", action = wezterm.action.ActivateTab(2) }, | |
| { key = "4", mods = "ALT|CTRL", action = wezterm.action.ActivateTab(3) }, | |
| { key = "5", mods = "ALT|CTRL", action = wezterm.action.ActivateTab(4) }, | |
| { key = "6", mods = "ALT|CTRL", action = wezterm.action.ActivateTab(5) }, | |
| { key = "7", mods = "ALT|CTRL", action = wezterm.action.ActivateTab(6) }, | |
| { key = "8", mods = "ALT|CTRL", action = wezterm.action.ActivateTab(7) }, | |
| { key = "9", mods = "ALT|CTRL", action = wezterm.action.ActivateTab(8) }, | |
| -- Tmux-style pane splitting (prefix key approach) | |
| { | |
| key = "a", | |
| mods = "CTRL", | |
| action = wezterm.action.ActivateKeyTable({ | |
| name = "tmux_mode", | |
| one_shot = true, | |
| timeout_milliseconds = 1000, | |
| }), | |
| }, | |
| -- Pane navigation | |
| { key = "h", mods = "CTRL|SHIFT", action = wezterm.action.ActivatePaneDirection("Left") }, | |
| { key = "l", mods = "CTRL|SHIFT", action = wezterm.action.ActivatePaneDirection("Right") }, | |
| { key = "k", mods = "CTRL|SHIFT", action = wezterm.action.ActivatePaneDirection("Up") }, | |
| { key = "j", mods = "CTRL|SHIFT", action = wezterm.action.ActivatePaneDirection("Down") }, | |
| -- Search functionality | |
| { key = "f", mods = "CTRL|SHIFT", action = wezterm.action.Search({ CaseInSensitiveString = "" }) }, | |
| -- Command palette | |
| { key = "p", mods = "CTRL|SHIFT", action = wezterm.action.ActivateCommandPalette }, | |
| -- Copy/paste enhancements with popup notification | |
| { | |
| key = "c", | |
| mods = "CTRL|SHIFT", | |
| action = wezterm.action.Multiple({ | |
| wezterm.action.CopyTo("Clipboard"), | |
| wezterm.action.EmitEvent("show-copy-notification"), | |
| }), | |
| }, | |
| { key = "v", mods = "CTRL|SHIFT", action = wezterm.action.PasteFrom("Clipboard") }, | |
| -- Scrolling shortcuts | |
| { key = "PageUp", mods = "SHIFT", action = wezterm.action.ScrollByPage(-1) }, | |
| { key = "PageDown", mods = "SHIFT", action = wezterm.action.ScrollByPage(1) }, | |
| { key = "Home", mods = "SHIFT", action = wezterm.action.ScrollToTop }, | |
| { key = "End", mods = "SHIFT", action = wezterm.action.ScrollToBottom }, | |
| -- Window management | |
| { key = "z", mods = "CTRL|SHIFT", action = wezterm.action.TogglePaneZoomState }, | |
| { key = "=", mods = "CTRL", action = wezterm.action.IncreaseFontSize }, | |
| { key = "-", mods = "CTRL", action = wezterm.action.DecreaseFontSize }, | |
| { key = "0", mods = "CTRL", action = wezterm.action.ResetFontSize }, | |
| -- Pane resizing | |
| { key = "LeftArrow", mods = "CTRL|ALT", action = wezterm.action.AdjustPaneSize({ "Left", 5 }) }, | |
| { key = "RightArrow", mods = "CTRL|ALT", action = wezterm.action.AdjustPaneSize({ "Right", 5 }) }, | |
| { key = "UpArrow", mods = "CTRL|ALT", action = wezterm.action.AdjustPaneSize({ "Up", 5 }) }, | |
| { key = "DownArrow", mods = "CTRL|ALT", action = wezterm.action.AdjustPaneSize({ "Down", 5 }) }, | |
| } | |
| -- Performance optimizations | |
| config.front_end = "OpenGL" | |
| -- Enhanced visual effects | |
| config.inactive_pane_hsb = { | |
| saturation = 0.9, | |
| brightness = 0.85, | |
| } | |
| -- Selection and copy behavior | |
| config.selection_word_boundary = " \t\n{}[]()\"'`" | |
| config.bypass_mouse_reporting_modifiers = "SHIFT" | |
| -- Visual bell instead of audio (subtle) | |
| config.audible_bell = "Disabled" | |
| config.visual_bell = { | |
| fade_in_function = "EaseIn", | |
| fade_in_duration_ms = 75, | |
| fade_out_function = "EaseOut", | |
| fade_out_duration_ms = 75, | |
| } | |
| config.colors.visual_bell = "#444b6a" | |
| -- Oh-my-tmux style key table (prefix mode: Ctrl+A) | |
| config.key_tables = { | |
| tmux_mode = { | |
| -- Split panes (simple keys) | |
| { key = "v", action = wezterm.action.SplitHorizontal({ domain = "CurrentPaneDomain" }) }, -- vertical split (pane to right) | |
| { key = "h", action = wezterm.action.SplitVertical({ domain = "CurrentPaneDomain" }) }, -- horizontal split (pane below) | |
| -- Oh-my-tmux additional split bindings | |
| { key = "-", action = wezterm.action.SplitVertical({ domain = "CurrentPaneDomain" }) }, -- split horizontally (pane below) | |
| { key = "_", action = wezterm.action.SplitHorizontal({ domain = "CurrentPaneDomain" }) }, -- split vertically (pane right) | |
| -- Pane navigation (using arrow keys to avoid conflict with split) | |
| { key = "LeftArrow", action = wezterm.action.ActivatePaneDirection("Left") }, | |
| { key = "DownArrow", action = wezterm.action.ActivatePaneDirection("Down") }, | |
| { key = "UpArrow", action = wezterm.action.ActivatePaneDirection("Up") }, | |
| { key = "RightArrow", action = wezterm.action.ActivatePaneDirection("Right") }, | |
| -- Pane resizing (oh-my-tmux style) | |
| { key = "H", action = wezterm.action.AdjustPaneSize({ "Left", 2 }) }, | |
| { key = "J", action = wezterm.action.AdjustPaneSize({ "Down", 2 }) }, | |
| { key = "K", action = wezterm.action.AdjustPaneSize({ "Up", 2 }) }, | |
| { key = "L", action = wezterm.action.AdjustPaneSize({ "Right", 2 }) }, | |
| -- Pane swapping (oh-my-tmux style) | |
| { key = ">", action = wezterm.action.RotatePanes("Clockwise") }, | |
| { key = "<", action = wezterm.action.RotatePanes("CounterClockwise") }, | |
| -- Maximize current pane (oh-my-tmux +) | |
| { key = "+", action = wezterm.action.TogglePaneZoomState }, | |
| -- Window navigation (oh-my-tmux style) | |
| { key = "h", mods = "CTRL", action = wezterm.action.ActivateTabRelative(-1) }, | |
| { key = "l", mods = "CTRL", action = wezterm.action.ActivateTabRelative(1) }, | |
| { key = "Tab", action = wezterm.action.ActivateLastTab }, | |
| -- Session/window management | |
| { key = "c", mods = "CTRL", action = wezterm.action.SpawnTab("CurrentPaneDomain") }, -- new session (closest to new tab) | |
| { key = "c", action = wezterm.action.SpawnTab("CurrentPaneDomain") }, -- new window (tab) | |
| -- Config reload (oh-my-tmux 'r') | |
| { key = "r", action = wezterm.action.ReloadConfiguration }, | |
| -- Clear screen and history (oh-my-tmux Ctrl+l) | |
| { | |
| key = "l", | |
| mods = "CTRL", | |
| action = wezterm.action.Multiple({ | |
| wezterm.action.SendKey({ key = "l", mods = "CTRL" }), | |
| wezterm.action.ClearScrollback("ScrollbackAndViewport"), | |
| }), | |
| }, | |
| -- Close current pane | |
| { key = "x", action = wezterm.action.CloseCurrentPane({ confirm = true }) }, | |
| -- Pane management | |
| { key = "z", action = wezterm.action.TogglePaneZoomState }, -- toggle zoom (duplicate of +) | |
| { key = "o", action = wezterm.action.ActivatePaneByIndex(0) }, -- cycle through panes | |
| { key = "q", action = wezterm.action.PaneSelect }, -- show pane numbers | |
| { key = "{", action = wezterm.action.RotatePanes("CounterClockwise") }, -- move pane left | |
| { key = "}", action = wezterm.action.RotatePanes("Clockwise") }, -- move pane right | |
| { key = "!", action = wezterm.action.SpawnTab("CurrentPaneDomain") }, -- break pane into new tab | |
| { key = ";", action = wezterm.action.ActivateLastTab }, -- go to last active (using tab as closest equivalent) | |
| -- Exit tmux mode | |
| { key = "Escape", action = "PopKeyTable" }, | |
| { key = "a", mods = "CTRL", action = "PopKeyTable" }, -- double Ctrl+A to exit | |
| }, | |
| } | |
| -- Custom tab title formatting (from blog post) | |
| local function get_current_working_dir(tab) | |
| local current_dir = tab.active_pane and tab.active_pane.current_working_dir or { file_path = "" } | |
| local HOME_DIR = string.format("file://%s", os.getenv("HOME")) | |
| return current_dir.file_path == HOME_DIR and "~" or string.gsub(current_dir.file_path, "(.*[/\\])(.*)", "%2") | |
| end | |
| wezterm.on("format-tab-title", function(tab, tabs, panes, config, hover, max_width) | |
| local has_unseen_output = false | |
| if not tab.is_active then | |
| for _, pane in ipairs(tab.panes) do | |
| if pane.has_unseen_output then | |
| has_unseen_output = true | |
| break | |
| end | |
| end | |
| end | |
| -- Get the window title (what applications set dynamically) | |
| local window_title = tab.active_pane.title or "" | |
| -- Get current working directory | |
| local cwd = get_current_working_dir(tab) | |
| -- Format: [1] app_title (directory) or [1] directory if no title | |
| local title | |
| if window_title and window_title ~= "" and window_title ~= cwd then | |
| title = string.format(" [%s] %s (%s) ", tab.tab_index + 1, window_title, cwd) | |
| else | |
| title = string.format(" [%s] %s ", tab.tab_index + 1, cwd) | |
| end | |
| if has_unseen_output then | |
| return { | |
| { Foreground = { Color = "#bb9af7" } }, -- Tokyo Night purple for unseen output | |
| { Text = title }, | |
| } | |
| end | |
| return { | |
| { Text = title }, | |
| } | |
| end) | |
| -- Startup workspace configuration | |
| wezterm.on("gui-startup", function(cmd) | |
| -- Create a default workspace with the home directory | |
| local home_path = wezterm.home_dir | |
| local tab, pane, window = mux.spawn_window({ | |
| workspace = "default", | |
| cwd = home_path, | |
| }) | |
| mux.set_active_workspace("default") | |
| end) | |
| -- Copy notification popup (simple and clean) | |
| local copy_notification_visible = false | |
| wezterm.on("show-copy-notification", function(window, pane) | |
| copy_notification_visible = true | |
| -- Clear notification after 1 second | |
| wezterm.time.call_after(1.0, function() | |
| copy_notification_visible = false | |
| end) | |
| end) | |
| -- Status handling for notifications, tmux mode, and workspace display | |
| wezterm.on("update-right-status", function(window, pane) | |
| local key_table = window:active_key_table() | |
| if copy_notification_visible then | |
| window:set_right_status(wezterm.format({ | |
| { Background = { Color = "#32344a" } }, | |
| { Foreground = { Color = "#a9b1d6" } }, | |
| { Text = " ✓ COPIED " }, | |
| })) | |
| elseif key_table == "tmux_mode" then | |
| window:set_right_status(wezterm.format({ | |
| { Background = { Color = "#e0af68" } }, | |
| { Foreground = { Color = "#1a1b26" } }, | |
| { Text = " TMUX MODE " }, | |
| })) | |
| else | |
| -- Show current workspace name (including default) | |
| local workspace_name = window:active_workspace() | |
| if workspace_name then | |
| window:set_right_status(wezterm.format({ | |
| { Background = { Color = "#7aa2f7" } }, | |
| { Foreground = { Color = "#1a1b26" } }, | |
| { Text = " " .. workspace_name .. " " }, | |
| })) | |
| else | |
| window:set_right_status("") | |
| end | |
| end | |
| end) | |
| return config |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment