Wezterm Terminal Emulator

Mar 22, 2024

Emile Perron

Wezterm has been my latest obsession lately. For the longest time, I’ve faced a huge terminal emulator dilemma. How can I (be lazy) and consolidate the development tools that I use?

For context, I write code on multiple machines.

  1. Work laptop - MacOS
  2. Personal laptop - Windows

As you can imagine, the configuration between Macs and Windows are very different, and at times, the tools found native to nix machines are not available on Windows. Terminals are one of them.

Before Wezterm came around, I was using Cmder. Cmder was great! It beat using the native Windows terminal. It is highly customizable and comes with a lot of prepackaged developer tools and integration.

However, what I didn’t like was the constant switch between remembering how to use Cmder after a day of using something entirely different at work.

So why Wezterm? There are plenty of other cross-platform terminal emulation options.

Wezterm stood out to me the most due to several reasons.

  1. I don’t mind marginal speed/performance differences between the latest emulation options (i.e. alacritty, warp, etc).
  2. Cross-platform - Wezterm is available on MacOS, Windows, and Linux.
  3. Supports tabs and windows natively.

Wezterm Panes
Wezterm Panes
Wezterm Workspaces
Wezterm Workspaces

The last point hits home since I am a huge tmux user. Truth be told, I wasn’t ready to give up tmux features yet.

Wezterm is not a direct 1:1 replacement for tmux; however, it does provide a lot of the commonly used features.

So with all of that said, below are some configuration snippets that help customize Wezterm into a more tmux-like experience.

-- Set coloring for inactive panes to be less bright than your active pane
config.inactive_pane_hsb = {
    hue = 0.5,
    saturation = 0.5,
    brightness = 0.6,
}
-- Set main keybinding key to "CTRL + p" with a timeout of 1 second
config.leader = { key='p', mods='CTRL', timeout_milliseconds=1000 }
config.keys = {
    -- Set keybinding to split the current pane horizontally
    -- This is similar to tmux's "CTRL + b" + "|"
    -- pane 1 | pane 2
    {
        key = '|',
        mods = 'LEADER|SHIFT',
        action = wezterm.action { SplitHorizontal={domain='CurrentPaneDomain'} },
    },

    -- Split pane vertically
    -- pane 1
    -- -----
    -- pane 2
    {
        key = '-',
        mods = 'LEADER',
        action = wezterm.action { SplitVertical={domain='CurrentPaneDomain'} },
    },

    -- Switch to new or existing workspace
    -- Similar to when you attach to or switch tmux sessions
    {
        key = 'W',
        mods = 'LEADER|SHIFT',
        action = wezterm.action.PromptInputLine {
            description = wezterm.format {
                { Attribute = { Intensity = 'Bold' } },
                { Foreground = { AnsiColor = 'Fuchsia' } },
                { Text = 'Enter name for new workspace.' },
            },
            action = wezterm.action_callback(function(window, pane, line)
                -- line will be `nil` if they hit escape without entering anything
                -- An empty string if they just hit enter
                -- Or the actual line of text they wrote
                if line then
                    window:perform_action(
                        wezterm.action.SwitchToWorkspace {
                            name = line,
                        },
                        pane
                    )
                end
            end),
        },
    },

    -- Move between panes
    { key = 'h', mods = 'LEADER', action=wezterm.action{ActivatePaneDirection='Left'} },
    { key = 'j', mods = 'LEADER', action=wezterm.action{ActivatePaneDirection='Down'} },
    { key = 'k', mods = 'LEADER', action=wezterm.action{ActivatePaneDirection='Up'} },
    { key = 'l', mods = 'LEADER', action=wezterm.action{ActivatePaneDirection='Right'} },
}
-- Create a status bar on the top right that shows the current workspace and date
wezterm.on('update-right-status', function(window, pane)
    local date = wezterm.strftime '%Y-%m-%d %H:%M:%S'

    -- Make it italic and underlined
    window:set_right_status(wezterm.format {
        { Attribute = { Underline = 'Single' } },
        { Attribute = { Italic = true } },
        { Attribute = { Intensity = 'Bold' } },
        { Foreground = { AnsiColor = 'Fuchsia' } },
        { Text = window:active_workspace() },
        { Text = '   ' },
        { Text = date },
    })
end)

My full configuration file can be found in my dotfile repository.

Yiping Su
Yiping Su
Software Engineer

I am interested in data, software engineering, and the application of computer science concepts in real-world scenarios.

Related