Configuration

wtmux reads ~/.wtmux.conf (or ~/.tmux.conf as fallback). It supports a subset of tmux configuration syntax.

Note: After editing the config, run wtmux reload-config or source-file from the command prompt to re-read it without restarting the server.

See the Default Bindings reference for every built-in prefix, root, mouse, custom-table, and copy-mode binding and the exact override precedence.

Declarative DSC configuration

wtmux also ships a DSC v3 command resource for declarative global option management. The resource type is Shmuelie.WTmux/Options; it invokes wtmux dsc get, wtmux dsc test, and wtmux dsc set with JSON over standard input, so the same option names and values accepted by wtmux set-option -g are used in WinGet Configuration or DSC v3.

Example configuration.dsc.yaml:

$schema: https://aka.ms/configuration-dsc-schema/0.2
properties:
  resources:
    - resource: Shmuelie.WTmux/Options
      id: wtmux-options
      directives:
        description: Configure wtmux global options
      settings:
        options:
          prefix: C-a
          mouse: 'on'
          status-position: bottom
          history-limit: 50000

The DSC resource talks to the per-user wtmux server and starts it if needed. test is idempotent: it reports _inDesiredState: true when the running server already has the desired option values and false when applying set would change them.

Example

# Change prefix key to Ctrl+A
set -g prefix C-a

# Default shell with arguments
set -g default-shell pwsh
set -g default-shell-arg -NoLogo

# Window numbering starts at 1
set -g base-index 1

# Add a command alias
set -g command-alias sp=split-window -h

# Enable mouse support
set -g mouse on

# Terminal settings
set -g default-terminal "screen-256color"
set -g history-limit 50000
set -g set-titles on
set -g set-titles-string '#S:#I:#W'
set -g clock-mode-style 24
set -g clock-mode-colour green
set -g automatic-rename on
set -g destroy-unattached off
set -g display-time 4000

# Activity, bell, and silence monitoring
set -g monitor-activity on
set -g monitor-bell on
set -g monitor-silence 60
set -g activity-action other
set -g bell-action any
set -g silence-action other
set -g visual-activity on
set -g visual-bell both
set -g visual-silence on

# Environment for new panes
set-environment -g WT_SESSION_MODE dev
set-environment -g -u NO_COLOR

# Status bar customization
set -g status-position bottom
set -g status-interval 5
set -g status-left '#{prefix_highlight} [#S] '
set -g status-right '%a %Y-%m-%d %H:%M'
set -g status-style fg=white,bg=black
set -g window-status-current-format ' #I:#W#F '
set -g window-status-format ' #I:#W#F '

# Custom key bindings
bind | split-window -h       # Vertical split with |
bind - split-window          # Horizontal split with -
bind h select-pane -L        # Vim-style pane navigation
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
bind H resize-pane -L 5       # Vim-style pane resize (5 cells)
bind J resize-pane -D 5
bind K resize-pane -U 5
bind L resize-pane -R 5
unbind %                     # Remove default binding

# Include another config file
source-file ~/.wtmux.local.conf

# Run a PowerShell script during config loading
run 'Write-Output "set -g status-right $(Get-Date -Format HH:mm)"'

# Conditionally apply config based on a shell command's exit status
if-shell 'if (Get-Command git -ErrorAction SilentlyContinue) { exit 0 } else { exit 1 }' 'set -g status-left " git "'

Terminal title

set -g set-titles on lets wtmux update the host terminal window title while attached. It is disabled by default; when disabled, wtmux leaves the host title unchanged except for restoring the original title on detach.

set -g set-titles-string <format> controls the title text. The default is #S:#I:#W (session name, window index, and window name). The format uses the same variables and time escapes as the status bar, including #P/#{pane_index}, #T/#{pane_title}, #H/#{host}, and #{host_short}. Runtime changes through wtmux set-option -g set-titles ... or wtmux set-option -g set-titles-string ... repaint attached clients and update the title immediately.

Mouse support

set -g mouse on enables mouse support (it is disabled by default). When enabled:

  • Scroll wheel scrolls the active pane's scrollback. Scrolling up automatically enters copy mode so you can browse history; scrolling down returns toward the live view. When the active pane is running a full-screen application such as less that requested application cursor keys, entered the alternate screen, or hid the cursor for full-screen input, but did not request mouse tracking, wheel input is translated to that application's Up/Down cursor keys instead.
  • Left-click selects the pane under the cursor.
  • Right-click pastes the most recent paste buffer into the pane under the cursor.
  • Left-button drag over a pane enters copy mode, selects text from the press cell to the current cell, and releasing copies the selection to the paste buffer and clipboard.
  • Drag a pane border, or a cell immediately beside it, to resize the split.
  • Mouse events are passed through to full-screen applications that request mouse tracking (for example editors), so their own mouse handling keeps working.

With mouse support off, the scroll wheel is handled by your host terminal (for example, Windows Terminal scrolls its own window).

Session cleanup

set -g destroy-unattached on destroys a session when its last attached client detaches, switches away, or disconnects because the terminal tab/process exits. It is disabled by default (off), so unattached sessions persist as before. The option is runtime-settable globally with wtmux set-option -g destroy-unattached on|off or per session with wtmux set-option [-t target] destroy-unattached on|off.

Detached sessions created before any client attaches are not destroyed immediately; cleanup only happens after an attached-client count transitions from at least one to zero. This avoids racing new-session -d creation with a later attach.

Mouse bindings

Mouse actions are bindable with bind -n <mouse-key> <command>, using tmux-style named mouse keys. The event name combines an action, an optional button number (1 = left, 2 = middle, 3 = right), and a location (Pane or Status):

# Rebind the wheel, left-click, and right-click (built-in defaults under `mouse on`)
bind -n WheelUpPane    copy-mode
bind -n MouseDown1Pane select-pane
bind -n MouseDown3Pane paste-buffer

# Middle-click a pane to open a new window
bind -n MouseDown2Pane new-window

# Remove a default mouse binding
unbind -n WheelUpPane

Recognized actions are WheelUp, WheelDown, MouseDown<n>, MouseUp<n>, MouseDrag<n>, and MouseDragEnd<n>. When mouse on is set, WheelUpPane/WheelDownPane (scrollback), MouseDown1Pane (select pane), and MouseDown3Pane (paste buffer) have built-in defaults that a bind/unbind -n overrides. An explicit wheel binding or unbind also takes precedence over alternate-screen wheel-to-arrow translation.

Root key bindings

bind -n <key> <command> also binds a keyboard key to fire without the prefix (tmux's root table), alongside the normal prefix bindings created by bind <key> <command>. -n is an alias for -T root; ordinary bind commands target the prefix table:

bind -n C-o new-window       # Ctrl+O opens a new window without the prefix
bind -T root C-p previous-window

Root key bindings match raw input bytes before the prefix, so bind control or special keys (e.g. C-o) rather than plain letters — a letter binding would also fire when that byte appears inside an escape sequence (such as arrow keys) or pasted text.

Custom key tables

Use bind -T <table> and unbind -T <table> to define named key tables. A binding can enter one with switch-client -T <table>:

bind n switch-client -T navigation
bind -T navigation h select-pane -L
bind -T navigation j select-pane -D
bind -T navigation k select-pane -U
bind -T navigation l select-pane -R
unbind -T navigation q

After prefix n, the next key is looked up in navigation. Custom tables are one-shot: the next key is consumed and the client returns to root whether the key matches or not. A matched binding runs through the normal runtime command path; it may use another switch-client -T to continue a longer sequence. Switching to an undefined or invalid table reports an error.

For this initial key-table slice, switch-client -T must be the only command on its command line. Combining it with ; and server commands is rejected; ordinary all-server command sequences continue to run server-side with their existing ordering and stop-on-error behavior.

This is partial advanced-binding support. Repeatable bind -r behavior, binding notes (bind -N), list-keys, and send-prefix are not implemented.

Configuration options

See the Configuration Options reference for every supported option, accepted values, defaults, and runtime scope.

Conditional Configuration

wtmux evaluates run-shell and if-shell directives while loading the config file.

run-shell

run-shell 'shell-command'
run 'shell-command'          # short alias

Runs shell-command (via pwsh/powershell, falling back to cmd) and feeds each line of its standard output back to the parser as a wtmux command. Only set / setw, bind, and unbind commands are recognized in the output.

if-shell

if-shell [-b] shell-command then-command [else-command]
if [-b] shell-command then-command [else-command]   # short alias

Runs shell-command. If it exits with status 0, then-command is executed as a wtmux command; otherwise the optional else-command runs. then-command and else-command are ordinary config commands (usually quoted) and may be any supported directive, including a nested if-shell or source-file.

# Apply a different prefix when running under an SSH session
if-shell 'if ($env:SSH_CONNECTION) { exit 0 } else { exit 1 }' \
  'set -g prefix C-a' 'set -g prefix C-b'

Supported semantics and notes:

  • The exit status of the shell command determines the branch (0 = success → then-command; non-zero, or a command that fails to launch → else-command).
  • -b (run the command in the background) is accepted for tmux compatibility, but the command is always evaluated synchronously at config load time.
  • Commands are run with a 5-second timeout; a command that times out or cannot be launched is treated as a failure.

Environment

Use set-environment to configure environment variables for panes created after the server loads the config:

set-environment [-g] NAME VALUE
set-environment [-g] -u NAME
show-environment [-g]

Config-time environment changes are global. Runtime set-environment without -g applies to the current session; with -g, it updates the global environment. Configured values override inherited variables, and -u removes a variable from the child process environment. wtmux still sets WTMUX and WTMUX_PANE for each pane.

Format Variables

Status formats (status-left, status-right, window-status-format, window-status-current-format) support tmux-style # variables, #{...} expressions, % time escapes, and inline #[...] style directives.

Variable Description
#S / #{session_name} Session name
#I / #{window_index} Window index
#W / #{window_name} Window name
#F / #{window_flags} Window flags (* current, - last, # activity, ! bell, ~ silence, Z zoomed)
#P / #{pane_index} Pane index
#H / #{host} / #{hostname} Hostname
#{host_short} Hostname before the first dot
#T / #{pane_title} Pane title
#{pane_pid} Pane process ID
#{pane_current_path} Pane working directory, initialized from the launch directory and updated when the shell emits OSC 7 (file://...) or OSC 9;9 cwd reports
#{session_windows} Number of windows in the session
#{window_activity} Last window output time as a Unix timestamp
#{client_prefix} 1 while the prefix key is active; otherwise 0
#{synchronize_panes} / #{pane_synchronized} 1 when synchronize-panes is enabled for the active window; otherwise 0
#{@name} Value of the @name user option, or empty when unset (see User options)
#{prefix_highlight} Prefix key indicator supplied by the built-in prefix-highlight plugin

Format Expressions

Expression Description
#{?condition,yes,no} Conditional text. condition may be a variable or nested expression and is true when it expands to a non-empty value other than 0, false, no, or off.
#{==:left,right} Expands to 1 when the expanded values are equal; otherwise 0.
#{!=:left,right} Expands to 1 when the expanded values differ; otherwise 0.
#{m:pattern,string} Expands to 1 when string matches pattern. * and ? use glob matching; patterns without wildcards use substring matching.
#{s/old/new/:value} Replaces old with new in the expanded value. The delimiter after s can be any character.
#{=<N>:value} Trims the expanded value to N visible columns.
#{p<N>:value} Pads the expanded value with spaces to at least N visible columns.
#{t:value} Formats an expanded timestamp value such as #{t:window_activity}. Unix seconds and parseable date/time strings are accepted.
#{W:body} Expands body once for each window in the current session, with window variables (#I, #W, #F, #{window_activity}) scoped to that window.
#{P:body} Expands body once for each pane in the current window, with pane variables (#P, #T, #{pane_pid}, #{pane_current_path}) scoped to that pane.

Use \, for a literal comma inside conditional or operator arguments. Nested #{...} expressions are supported inside arguments, branches, and loop bodies. Session loop expressions (#{S:...}) are reserved but not populated by the status renderer yet.

Inline Styles

Use #[...] inside a status format to change the style for following text:

set -g status-left '#[fg=green,bold]#S#[default] '
set -g status-right '#[fg=colour220,bg=black] %H:%M #[default]'

Supported style entries are fg=<color>, bg=<color>, bold, dim, reverse, underline, default, and none. #[default] and #[none] reset back to the base status-style/status-fg/status-bg. Inline style escape sequences do not count toward status-line width or truncation.

Time Formats

Format Description Example
%H Hour (24h) 14
%I Hour (12h) 02
%M Minute 35
%S Second 09
%R HH:MM 14:35
%T HH:MM:SS 14:35:09
%p AM/PM PM
%P am/pm pm
%a Day abbreviation Mon
%A Day full name Monday
%d Day of month 07
%e Day (space-padded)  7
%b / %h Month abbreviation Jan
%B Month full name January
%m Month number 01
%Y Year 2026
%j Day of year 042
%k Hour (space-padded 24h) 14
%l Hour (space-padded 12h)  2

Colors

Named colors: red, green, blue, yellow, cyan, magenta, white, black, default

256-color palette: colour0 through colour255 (or color0 through color255). Numeric palette indexes are also accepted.