Intro to wezterm
WezTerm is a modern, GPU-accelerated terminal emulator with a powerful Lua configuration system. Unlike traditional terminals that rely on static config files, WezTerm lets you “code” your terminal behavior.
Why WezTerm?
- Lua Configuration: Write your settings as code—intuitive if you’re a programmer
- Flexible Keybindings: Define custom shortcuts that fit your workflow
- Pane & Tab Support: Built-in terminal multiplexing without extra tools
- Performance: GPU-accelerated rendering (with software fallback)
- Cross-Platform: Works on Linux, macOS, and Windows
Installation
Debian/Ubuntu
Add the WezTerm repository and install:
sudo apt install wezterm
See the official guide for your specific distribution.
Basic Configuration
WezTerm looks for its config at ~/.wezterm.lua. Here’s a starter setup:
local wezterm = require 'wezterm'
local config = {}
-- Basic Settings
config.color_scheme = 'Tokyo Night'
config.font = wezterm.font 'monospace'
config.font_size = 11.0
-- Tab bar settings
config.use_fancy_tab_bar = false
config.hide_tab_bar_if_only_one_tab = true
-- Performance for older hardware
-- config.front_end = "Software" -- Uncomment if GPU rendering lags
return config
Panes: Splitting Your Terminal
WezTerm includes pane functionality similar to tmux. The default shortcuts use awkward 3-modifier combos, so most users customize them.
Default Split Shortcuts
| Action | Keys |
|---|---|
| Split horizontally (right) | Ctrl + Shift + Alt + % |
| Split vertically (down) | Ctrl + Shift + Alt + " |
| Close pane | Ctrl + Shift + W |
| Zoom/fullscreen pane | Ctrl + Shift + Z |
Recommended Custom Keybindings
Add these to your config.keys table:
config.keys = {
-- Split right
{ key = '|', mods = 'CTRL|SHIFT', action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' } },
-- Split down
{ key = '-', mods = 'CTRL|SHIFT', action = wezterm.action.SplitVertical { domain = 'CurrentPaneDomain' } },
}
Navigating Between Panes
WezTerm has no default arrow-key bindings for pane navigation. Add them manually:
-- Navigate with Alt + arrow keys
{ key = 'LeftArrow', mods = 'ALT', action = wezterm.action.ActivatePaneDirection 'Left' },
{ key = 'RightArrow', mods = 'ALT', action = wezterm.action.ActivatePaneDirection 'Right' },
{ key = 'UpArrow', mods = 'ALT', action = wezterm.action.ActivatePaneDirection 'Up' },
{ key = 'DownArrow', mods = 'ALT', action = wezterm.action.ActivatePaneDirection 'Down' },
For vim users, map Ctrl + h/j/k/l instead:
{ key = 'h', mods = 'CTRL', action = wezterm.action.ActivatePaneDirection 'Left' },
{ key = 'l', mods = 'CTRL', action = wezterm.action.ActivatePaneDirection 'Right' },
{ key = 'k', mods = 'CTRL', action = wezterm.action.ActivatePaneDirection 'Up' },
{ key = 'j', mods = 'CTRL', action = wezterm.action.ActivatePaneDirection 'Down' },
Resizing Panes
Use AdjustPaneSize with directional keys:
-- Resize with Alt + Shift + arrows
{ key = 'LeftArrow', mods = 'ALT|SHIFT', action = wezterm.action.AdjustPaneSize { 'Left', 5 } },
{ key = 'RightArrow', mods = 'ALT|SHIFT', action = wezterm.action.AdjustPaneSize { 'Right', 5 } },
{ key = 'UpArrow', mods = 'ALT|SHIFT', action = wezterm.action.AdjustPaneSize { 'Up', 5 } },
{ key = 'DownArrow', mods = 'ALT|SHIFT', action = wezterm.action.AdjustPaneSize { 'Down', 5 } },
The 5 is the cell count to resize by—adjust as needed.
Using a Leader Key
WezTerm supports a leader key (like tmux’s prefix). Set a modifier that triggers a brief “mode” where single keys execute actions:
config.leader = { key = 'a', mods = 'CTRL', timeout_milliseconds = 1000 }
config.keys = {
{ key = 'v', mods = 'LEADER', action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' } },
{ key = 'h', mods = 'LEADER', action = wezterm.action.SplitVertical { domain = 'CurrentPaneDomain' } },
{ key = 'x', mods = 'LEADER', action = wezterm.action.CloseCurrentPane { confirm = true } },
{ key = 'z', mods = 'LEADER', action = wezterm.action.TogglePaneZoomState },
}
This mirrors tmux muscle memory nicely.
Tabs
| Action | Shortcut |
|---|---|
| New tab | Ctrl + Shift + T |
| Next tab | Ctrl + Tab |
| Previous tab | Ctrl + Shift + Tab |
| Close tab | Ctrl + Shift + W |
Visual Styling
Make the active pane stand out with dimming and border colors:
-- Dim inactive panes
config.inactive_pane_hsb = {
saturation = 0.8,
brightness = 0.5,
}
-- Pane border colors
config.colors = {
pane_border = '#2f334d',
active_pane_border = '#7aa2f7',
}
-- Minimal window decorations
config.window_decorations = "RESIZE"
Note: If dimming causes lag on older hardware, comment out the inactive_pane_hsb section.
Performance on Older Hardware
If WezTerm feels sluggish on older GPUs (like Intel HD 2000), force software rendering:
config.front_end = "Software"
Or try WebGPU first:
config.front_end = "WebGpu"
Why It’s Great for Python Development
- Split Workflow: Run vim in one pane, Python interpreter in another
- Zoom Feature: Maximize the execution pane to read long tracebacks, then toggle back
- Quick Navigation: Use vim-style keys to zip between code and output
- Clean Setup: Everything configured in one Lua file
Complete Starter Config
local wezterm = require 'wezterm'
local config = {}
-- Basic Setup
config.color_scheme = 'Tokyo Night'
config.font = wezterm.font 'monospace'
config.font_size = 11.0
-- Tab bar
config.use_fancy_tab_bar = false
config.hide_tab_bar_if_only_one_tab = true
-- Leader key (Ctrl + a)
config.leader = { key = 'a', mods = 'CTRL', timeout_milliseconds = 1000 }
-- Visual styling
config.inactive_pane_hsb = {
saturation = 0.8,
brightness = 0.5,
}
config.colors = {
pane_border = '#2f334d',
active_pane_border = '#7aa2f7',
}
config.window_decorations = "RESIZE"
-- Keybindings
config.keys = {
-- Leader key shortcuts
{ key = 'v', mods = 'LEADER', action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' } },
{ key = 'h', mods = 'LEADER', action = wezterm.action.SplitVertical { domain = 'CurrentPaneDomain' } },
{ key = 'x', mods = 'LEADER', action = wezterm.action.CloseCurrentPane { confirm = true } },
{ key = 'z', mods = 'LEADER', action = wezterm.action.TogglePaneZoomState },
-- Vim-style navigation
{ key = 'h', mods = 'CTRL', action = wezterm.action.ActivatePaneDirection 'Left' },
{ key = 'l', mods = 'CTRL', action = wezterm.action.ActivatePaneDirection 'Right' },
{ key = 'k', mods = 'CTRL', action = wezterm.action.ActivatePaneDirection 'Up' },
{ key = 'j', mods = 'CTRL', action = wezterm.action.ActivatePaneDirection 'Down' },
-- Resize panes
{ key = 'LeftArrow', mods = 'ALT|SHIFT', action = wezterm.action.AdjustPaneSize { 'Left', 5 } },
{ key = 'RightArrow', mods = 'ALT|SHIFT', action = wezterm.action.AdjustPaneSize { 'Right', 5 } },
{ key = 'UpArrow', mods = 'ALT|SHIFT', action = wezterm.action.AdjustPaneSize { 'Up', 5 } },
{ key = 'DownArrow', mods = 'ALT|SHIFT', action = wezterm.action.AdjustPaneSize { 'Down', 5 } },
}
return config
Quick Reference
| Action | Shortcut |
|---|---|
| Split side-by-side | Ctrl-a then v |
| Split top-and-bottom | Ctrl-a then h |
| Zoom/unzoom pane | Ctrl-a then z |
| Close pane | Ctrl-a then x |
| Move between panes | Ctrl + h/j/k/l |
| Resize panes | Alt + Shift + arrows |
| New tab | Ctrl + Shift + T |