obsidian/wiki/dotfiles/wezterm-key-tables.md
2026-04-17 12:55:53 +01:00

5 KiB

title aliases tags sources created updated
WezTerm Key Tables (Modal Keybindings)
wezterm-modal-keys
key-table-activation
wezterm-leader-modes
wezterm
keybindings
lua
terminal
modal
raw/Key Tables - Wez's Terminal Emulator.md
2026-04-17 2026-04-17

Overview

Key tables let you define named sets of keybindings that activate on demand — enabling modal keybinding workflows similar to Vim modes. Available since WezTerm 20220408-101518-b908e2dd.

Defined via the key_tables config option; triggered via the ActivateKeyTable action.


How It Works

  1. Define named tables in config.key_tables = { ... }
  2. Bind a trigger key (often prefixed with LEADER) to act.ActivateKeyTable { name = '...' }
  3. WezTerm pushes that table onto its activation stack — keys in that table take effect
  4. Exit the mode via PopKeyTable, timeout, or one_shot = true

Activation Stack

Each WezTerm window maintains a stack of active key tables:

Action Effect
ActivateKeyTable Push a table onto the stack
PopKeyTable Pop the top entry
ClearKeyTableStack Clear entire stack
Config reload Stack is also cleared automatically

Key resolution walks top → bottom of the stack until a match is found (layering behavior added in 20220624-141144-bd1b7c5d).


ActivateKeyTable Options

Field Type Description
name string Name of the key table to activate
one_shot bool If true, table pops after one key press (default: true)
timeout_milliseconds int Auto-pop after N ms of inactivity
replace_current bool Implicitly pop current entry before pushing

Example: Pane Resize & Activation Modes

local wezterm = require 'wezterm'
local act = wezterm.action
local config = {}

-- Show active key table in status bar
wezterm.on('update-right-status', function(window, pane)
  local name = window:active_key_table()
  if name then name = 'TABLE: ' .. name end
  window:set_right_status(name or '')
end)

config.leader = { key = 'Space', mods = 'CTRL|SHIFT' }
config.keys = {
  -- LEADER + r → resize mode (persistent until Escape)
  { key = 'r', mods = 'LEADER',
    action = act.ActivateKeyTable { name = 'resize_pane', one_shot = false } },

  -- LEADER + a → activate-pane mode (auto-exits after 1 second)
  { key = 'a', mods = 'LEADER',
    action = act.ActivateKeyTable { name = 'activate_pane', timeout_milliseconds = 1000 } },
}

config.key_tables = {
  resize_pane = {
    { key = 'LeftArrow',  action = act.AdjustPaneSize { 'Left', 1 } },
    { key = 'h',          action = act.AdjustPaneSize { 'Left', 1 } },
    { key = 'RightArrow', action = act.AdjustPaneSize { 'Right', 1 } },
    { key = 'l',          action = act.AdjustPaneSize { 'Right', 1 } },
    { key = 'UpArrow',    action = act.AdjustPaneSize { 'Up', 1 } },
    { key = 'k',          action = act.AdjustPaneSize { 'Up', 1 } },
    { key = 'DownArrow',  action = act.AdjustPaneSize { 'Down', 1 } },
    { key = 'j',          action = act.AdjustPaneSize { 'Down', 1 } },
    { key = 'Escape',     action = 'PopKeyTable' },
  },
  activate_pane = {
    { key = 'LeftArrow',  action = act.ActivatePaneDirection 'Left' },
    { key = 'h',          action = act.ActivatePaneDirection 'Left' },
    { key = 'RightArrow', action = act.ActivatePaneDirection 'Right' },
    { key = 'l',          action = act.ActivatePaneDirection 'Right' },
    { key = 'UpArrow',    action = act.ActivatePaneDirection 'Up' },
    { key = 'k',          action = act.ActivatePaneDirection 'Up' },
    { key = 'DownArrow',  action = act.ActivatePaneDirection 'Down' },
    { key = 'j',          action = act.ActivatePaneDirection 'Down' },
  },
}
return config

Showing Active Mode in Status Bar

wezterm.on('update-right-status', function(window, pane)
  local name = window:active_key_table()
  window:set_right_status(name and ('TABLE: ' .. name) or '')
end)

Useful for knowing which modal layer is active.


Key Takeaways

  • Key tables = modal keybinding layers, like Vim modes in a terminal
  • one_shot = false keeps the mode active until Escape / PopKeyTable
  • timeout_milliseconds auto-exits modes after inactivity — good for "quick prefix" modes
  • Stack layering (v20220624+) means tables compose rather than replace
  • Config reload clears the stack — useful escape hatch when you get stuck
  • Always show active table in status bar (window:active_key_table()) while developing
  • Pair with config.leader for a two-key prefix workflow without holding many modifiers


Sources

  • raw/Key Tables - Wez's Terminal Emulator.md (clipped from wezterm.org/config/key-tables.html)