Keybindings

This page covers the terminal key bindings configured in your TermSurf config file with the keybind option. Ghostboard inherits Ghostty’s keybinding system, so the syntax below matches Ghostty. For the full list of actions you can bind, see the Keybind Actions reference.

These are the terminal’s bindings, not the web browser TUI’s. The Web TUI has its own modal, vim-inspired keys for driving the browser; this page does not cover those.

Format

A binding has the form keybind = trigger=action. Set it in your config (see the configuration guide for the file location):

# ~/.config/termsurf/config
keybind = ctrl+z=close_surface
keybind = ctrl+d=new_split:right

Duplicate triggers overwrite earlier ones. Triggers are not unique per prefix — ctrl+a and global:ctrl+a (see Prefixes) overwrite each other.

Triggers

A trigger is a +-separated list of keys and modifiers, for example ctrl+a, ctrl+shift+b, or up.

Modifiers

The valid modifiers (with their aliases) are:

  • shift
  • ctrl (alias control)

  • alt (aliases opt, option)

  • super (aliases cmd, command)

A modifier cannot repeat (ctrl+ctrl+a is invalid), and a trigger may contain only one key (ctrl+a+b is invalid). Modifiers and the key may appear in any order.

Unicode keys vs. physical keys

A single character such as a matches by its unmodified codepoint, which depends on the keyboard layout, and matching is case-insensitive (ctrl+A matches ctrl+a). To match a physical key position regardless of layout, use a W3C key code such as KeyA (a lowercase snake-case form like key_a also works), or the physical: trigger prefix to force physical-key matching. Physical keys always match at higher priority than Unicode codepoints. The special key catch_all matches any key that is not otherwise bound.

Sequences (leader keys)

Join multiple triggers with > to require a sequence — what other software calls a leader key or key chord. There is no limit on the number of steps.

# Press ctrl+a, then n
keybind = ctrl+a>n=new_split:right

TermSurf waits indefinitely for the next key in a sequence (there is no timeout). If you set a sequence as a CLI argument, quote it, because > is special in most shells. Binding a prefix directly (e.g. ctrl+a) unbinds any sequences that started with it.

Actions

An action is either action or action:param (the parameterized form is used when the action takes a value). The full list is in the Keybind Actions reference. A few special actions are worth calling out:

  • ignore — do nothing (black-hole the input).

  • unbind — remove the binding so the key passes through to the program.

  • csi:…, esc:…, text:… — send a CSI sequence, an escape sequence, or a literal string.

The special value keybind = clear removes all bindings set up to that point, including the defaults.

Prefixes

A trigger can be prefixed to change how the binding behaves:

  • all: — apply the binding to every terminal surface, not just the focused one (only affects surface-specific actions).

  • global: — make the binding work system-wide, even when TermSurf is not focused (supported on macOS). It implies all:.

  • unconsumed: — do not consume the input; the encoded key is also sent to the running program. (global: and all: bindings always consume.)

  • performable: — only consume the input if the action actually runs (e.g. copy_to_clipboard with no selection does nothing and passes the key through).

Sequences are not allowed with global: or all: triggers.