Skip to content

Latest commit

History

History
672 lines (481 loc) 路 17.2 KB

File metadata and controls

672 lines (481 loc) 路 17.2 KB

Scripting & Automation

psmux supports tmux-compatible commands for scripting and automation.

Window & Pane Control

# Create a new window
psmux new-window

# Split panes
psmux split-window -v          # Split vertically (top/bottom)
psmux split-window -h          # Split horizontally (side by side)

# Navigate panes
psmux select-pane -U           # Select pane above
psmux select-pane -D           # Select pane below
psmux select-pane -L           # Select pane to the left
psmux select-pane -R           # Select pane to the right

# Navigate windows
psmux select-window -t 1       # Select window by index (default base-index is 1)
psmux next-window              # Go to next window
psmux previous-window          # Go to previous window
psmux last-window              # Go to last active window

# Kill panes and windows
psmux kill-pane
psmux kill-window
psmux kill-session

Sending Keys

# Send text directly
psmux send-keys "ls -la" Enter

# Send keys literally (no parsing)
psmux send-keys -l "literal text"

# Paste mode (legacy compatibility)
psmux send-keys -p

# Repeat a key N times
psmux send-keys -N 5 Up

# Send copy mode command
psmux send-keys -X copy-mode-up

# Special keys supported:
# Enter, Tab, Escape, Space, Backspace
# Up, Down, Left, Right, Home, End
# PageUp, PageDown, Delete, Insert
# F1-F12, C-a through C-z (Ctrl+key)

Pane Information

# List all panes in current window
psmux list-panes

# List all windows
psmux list-windows

# Capture pane content
psmux capture-pane

# Display formatted message with variables
psmux display-message "#S:#I:#W"   # Session:Window Index:Window Name

Paste Buffers

# Set paste buffer content
psmux set-buffer "text to paste"

# Paste buffer to active pane
psmux paste-buffer

# List all buffers
psmux list-buffers

# Show buffer content
psmux show-buffer

# Delete buffer
psmux delete-buffer

# Interactive buffer chooser (enter=paste, d=delete, esc=close)
psmux choose-buffer

# Named buffers (separate from anonymous stack)
psmux set-buffer -b mydata "key=value"
psmux show-buffer -b mydata
psmux paste-buffer -b mydata
psmux delete-buffer -b mydata

# Clear command prompt history
psmux clear-prompt-history

Pane Layout

# Resize panes
psmux resize-pane -U 5         # Resize up by 5
psmux resize-pane -D 5         # Resize down by 5
psmux resize-pane -L 10        # Resize left by 10
psmux resize-pane -R 10        # Resize right by 10

# Swap panes
psmux swap-pane -U             # Swap with pane above
psmux swap-pane -D             # Swap with pane below

# Rotate panes in window
psmux rotate-window

# Toggle pane zoom
psmux zoom-pane

Pane Titles

Programs running inside a pane can set the title via OSC escape sequences. PowerShell 7 does this automatically with the current working directory. See pane-titles.md for full details on how pane titles work, how to control them, and how different shells behave.

# Set a title on the active pane
psmux select-pane -T "my build pane"

# Set pane title on a specific pane
psmux select-pane -t %3 -T "logs"

# Set per-pane style (foreground/background color override)
psmux select-pane -P "bg=default,fg=blue"

# Display pane title using format variables
psmux display-message "#{pane_title}"

Enable pane-border-format and pane-border-status in your config to see titles on pane borders:

set -g pane-border-status top
set -g pane-border-format " #{pane_index}: #{pane_title} "

Popups

# Open a popup running a command
psmux display-popup "Get-Process"

# Set width and height (absolute or percentage)
psmux display-popup -w 80% -h 50% "htop"

# Set the starting directory
psmux display-popup -d "C:\Projects" -w 100 -h 30

# Close popup on command exit (default behavior, -E inverts it)
psmux display-popup -E "git log --oneline -20"

# Keep popup open after command finishes
psmux display-popup -K "echo done"

Menus

# Display an interactive menu
# Format: display-menu [-x x] [-y y] [-T title] name key command ...
psmux display-menu -T "Actions" \
  "New Window" n "new-window" \
  "Split Horizontal" h "split-window -h" \
  "Split Vertical" v "split-window -v" \
  "Close Pane" x "kill-pane"

# Position the menu at specific coordinates
psmux display-menu -x 10 -y 5 -T "Quick" \
  "Zoom" z "resize-pane -Z" \
  "Rename" r "command-prompt -I '#W' 'rename-window %%'"

Session Management

# Check if session exists (exit code 0 = exists)
psmux has-session -t mysession

# Rename session
psmux rename-session newname

# Switch to another session
psmux switch-client -t other-session

# Cycle through sessions
psmux switch-client -n          # Next session
psmux switch-client -p          # Previous session
psmux switch-client -l          # Last (most recently used) session

# Create a session with environment variables
psmux new-session -s work -e "MY_VAR=value"

# Respawn pane (restart shell, or restart with a different command)
psmux respawn-pane
psmux respawn-pane -k           # Kill the current process first
psmux respawn-pane -c /tmp      # Restart in a different directory

Pane Reorganization

# Break the current pane out into a new window
psmux break-pane

# Break a specific pane, keep it in background
psmux break-pane -d -s %3

# Join a pane from another window into the current window
psmux join-pane -s :2           # Bring pane from window 2

# Join horizontally or vertically
psmux join-pane -h -s :2        # Join side by side
psmux join-pane -v -s :3        # Join top/bottom

# Move a pane (same as join-pane)
psmux move-pane -s %5 -t %3

# Find a window by name or content
psmux find-window "search term"

Environment Variables

# Set a global env var (inherited by all new panes)
psmux set-environment -g EDITOR vim

# Set a session-scoped env var
psmux set-environment MY_VAR value

# Unset a global env var
psmux set-environment -gu MY_VAR

# Show all environment variables
psmux show-environment
psmux show-environment -g

Format Variables

The display-message command supports 140+ variables. Common ones include:

Variable Description
#S Session name
#I Window index
#W Window name
#P Pane ID
#T Pane title
#H Hostname
#{pane_current_path} Current working directory of the pane
#{pane_current_command} Foreground process name
#{pane_pid} PID of the pane's shell
#{pane_width} Width of the pane in columns
#{pane_height} Height of the pane in rows
#{pane_active} 1 if this pane is the active pane
#{pane_index} Pane index within the window
#{window_zoomed_flag} 1 if the window has a zoomed pane
#{window_panes} Number of panes in the window
#{window_active} 1 if this is the active window
#{session_windows} Number of windows in the session
#{session_attached} Number of clients attached to the session
#{client_prefix} 1 if the prefix key was pressed
#{client_width} Width of the client terminal
#{client_height} Height of the client terminal

Format Modifiers

# Conditional
psmux display-message -p "#{?window_zoomed_flag,ZOOMED,normal}"

# Comparison
psmux display-message -p "#{==:#{pane_index},0}"

# Regex substitution
psmux display-message -p "#{s/old/new/:pane_title}"

# Basename and dirname
psmux display-message -p "#{b:pane_current_path}"
psmux display-message -p "#{d:pane_current_path}"

# Loop over all windows
psmux display-message -p "#{W:#{window_index}:#{window_name} }"

# Loop over all panes
psmux display-message -p "#{P:#{pane_index} }"

Advanced Commands

# Discover supported commands
psmux list-commands

# Server/session management
psmux kill-server
psmux list-clients
psmux switch-client -t other-session

# Config at runtime
psmux source-file ~/.psmux.conf
psmux show-options
psmux set-option -g status-left "[#S]"

# Layout/history/stream control
psmux next-layout
psmux previous-layout
psmux select-layout tiled         # Apply a specific layout
psmux clear-history
psmux pipe-pane -o "cat > pane.log"

# Hooks (event callbacks) - see Hooks section below for full reference
psmux set-hook -g after-new-window "display-message created"
psmux set-hook -g client-attached "run-shell 'echo attached'"
psmux set-hook -gu after-new-window     # Unset (remove) a hook
psmux show-hooks

# Run shell commands
psmux run-shell "echo hello"           # Output shown in status bar
psmux run-shell -b "long-running.ps1"  # Fire-and-forget (background)

# Conditional execution
psmux if-shell "test -f ~/.psmux.conf" "source-file ~/.psmux.conf"
psmux if-shell -F "#{window_zoomed_flag}" "" "resize-pane -Z"

# User confirmation dialogs
psmux confirm-before -p "Kill this pane? (y/n)" kill-pane

# Wait channels for cross-pane synchronization
psmux wait-for -L mychannel             # Lock a channel
psmux wait-for -S mychannel             # Signal (unlock) a channel
psmux wait-for mychannel                # Wait until channel is signaled

Hooks (Event Callbacks)

Hooks let you run commands automatically when events occur. They are one of the most powerful scripting features in psmux.

Setting Hooks

# Global hook (applies to all sessions)
psmux set-hook -g after-new-window "display-message 'New window created'"

# Session-scoped hook
psmux set-hook after-split-window "select-layout tiled"

# Chain multiple commands in a hook
psmux set-hook -g after-new-session "set -g status-left '[#S] ' \; display-message 'Session ready'"

Available Hook Events

Hook Fires when...
after-new-session A new session is created
after-new-window A new window is created
after-split-window A pane is split
client-attached A client attaches to a session
client-detached A client detaches from a session
after-select-window A different window is selected
after-select-pane A different pane is selected
after-resize-pane A pane is resized
pane-died A pane's process exits
alert-activity Activity detected in a monitored window
alert-silence Silence detected in a monitored window
alert-bell Bell received from a pane
after-kill-pane A pane is killed

Removing Hooks

# Remove a global hook
psmux set-hook -gu after-new-window

# View all active hooks
psmux show-hooks

Important: If you repeatedly call set-hook -g for the same event, psmux appends duplicate entries. Use set-hook -gu to clear the old hook before setting a new one, or check show-hooks to verify no duplicates.

Display Panes

Show numbered overlays on all panes, then type a number to jump to that pane:

# Show pane number overlay (also: Prefix + q)
psmux display-panes

The overlay shows each pane's number according to pane-base-index. Press a number key while the overlay is visible to switch to that pane. The overlay auto-dismisses after display-panes-time milliseconds.

Run Shell

Run an external command and display the output:

# Output appears in the status bar message area
psmux run-shell "echo hello"

# Run in background (fire-and-forget, no output displayed)
psmux run-shell -b "long-running-script.ps1"

# Use format variables in shell commands
psmux run-shell "echo 'Current pane: #{pane_index}'"

Interactive Choosers

# Interactive session/window/pane tree browser
psmux choose-tree

# Show only sessions
psmux choose-tree -s

# Show only windows
psmux choose-tree -w

# Interactive buffer picker (enter=paste, d=delete)
psmux choose-buffer

# Interactive client picker
psmux choose-client

# Interactive options editor
psmux customize-mode

Target Syntax (-t)

psmux supports tmux-style targets:

# Window by index in session
psmux select-window -t work:2

# Window by name in session
psmux select-window -t work:editor

# Specific pane by index
psmux send-keys -t work:2.1 "echo hi" Enter

# Pane by pane id
psmux send-keys -t %3 "pwd" Enter

# Window by window id
psmux select-window -t @4

# Target a specific session
psmux has-session -t mysession

# Session:window.pane full path
psmux send-keys -t dev:0.2 "make build" Enter

Server Namespaces (-L)

Use -L to run multiple isolated psmux servers on the same machine:

# Start a session in a named server namespace
psmux -L work new-session -s dev

# Attach to a session in that namespace
psmux -L work attach -t dev

# Each namespace gets its own server, sessions, and socket
psmux -L personal new-session -s play

Key Binding Management

# Bind a key in the default prefix table
psmux bind-key h split-window -h

# Bind with format variable expansion (-F flag)
psmux bind-key -F M-h "resize-pane -L #{pane_width}"

# Bind with repeat (successive presses within repeat-time don't need prefix)
psmux bind-key -r Left select-pane -L
psmux bind-key -r Right select-pane -R

# Bind in root table (no prefix needed)
psmux bind-key -n M-Left select-pane -L

# Bind in a specific key table
psmux bind-key -T copy-mode-vi y send-keys -X copy-selection

# Unbind a single key
psmux unbind-key h

# Unbind ALL keys (reset to clean slate)
psmux unbind-key -a

# Unbind all keys in a specific key table only
psmux unbind-key -a -T copy-mode-vi
psmux unbind-key -a -T prefix
psmux unbind-key -a -T root
psmux unbind-key -a -T copy-mode

Command Chaining

Chain multiple commands with \; in config files:

# Split and select in one binding
bind-key M-v split-window -v \; select-pane -U

# Create a 3-pane layout
bind-key M-d split-window -h \; split-window -v \; select-pane -t 0

# Conditional chaining
bind-key M-z if-shell -F "#{window_zoomed_flag}" "resize-pane -Z" ""

From the CLI, use \; or quote the command:

psmux split-window -h `; select-pane -L

Querying Lists with Custom Formats

# List all sessions with custom format
psmux list-sessions -F "#{session_name}:#{session_windows}"

# List all windows with custom format
psmux list-windows -F "#{window_index}:#{window_name}:#{window_panes}"

# List all panes across the session (-s flag)
psmux list-panes -s -F "#{window_index}.#{pane_index}: #{pane_current_command} [#{pane_width}x#{pane_height}]"

# List all panes across all sessions (-a flag)
psmux list-panes -a

# Capture pane content to stdout
psmux capture-pane -p -t %0

# Capture with line range (negative = scrollback)
psmux capture-pane -p -S -100 -E -1

# Print a format variable
psmux display-message -p "#{pane_current_path}"

Window and Pane Creation Options

new-window

# Create a window with a name
psmux new-window -n "logs"

# Create a window in the background (don't switch to it)
psmux new-window -d -n "background"

# Create a window in a specific directory
psmux new-window -c "C:\Projects\myapp"

# Create a window running a command
psmux new-window -n "build" -- cargo watch

# Create a window at a specific index
psmux new-window -t 5

When you set a window name with -n, automatic renaming is disabled for that window so the foreground process name does not overwrite your chosen name.

split-window

# Split with percentage size
psmux split-window -v -p 30            # Bottom pane gets 30%
psmux split-window -h -p 70            # Right pane gets 70%

# Split in the current pane's directory
psmux split-window -h -c "#{pane_current_path}"

# Split with a specific command
psmux split-window -v -- python

# Split a specific target pane
psmux split-window -v -t %3

# Split without switching focus
psmux split-window -d -v

new-session

# Create a named session
psmux new-session -s work

# Create in a specific directory
psmux new-session -s project -c "C:\Projects\myapp"

# Create with environment variables
psmux new-session -s dev -e "NODE_ENV=development"

# Create in background (detached)
psmux new-session -d -s background

# Create with an initial command
psmux new-session -s monitor -- htop

# Create a session with a named first window
psmux new-session -s work -n "editor"

Target Syntax

Many commands accept a -t flag to specify which session, window, or pane to act on:

# Target a session by name
psmux switch-client -t mysession

# Target a window by index (within current session)
psmux select-window -t 3

# Target a window in a specific session
psmux select-window -t mysession:2

# Target a pane by ID (absolute, shown with %)
psmux select-pane -t %5

# Target a pane within a window
psmux select-pane -t :2.1             # Window 2, pane 1

# Special targets
psmux select-pane -t +               # Next pane
psmux select-pane -t -               # Previous pane
psmux select-window -t !             # Last (previous) window

Server Namespaces

Run isolated psmux instances using the -L flag. Each namespace gets its own server process with its own sessions:

# Start a session in a named namespace
psmux -L work new-session -s dev

# Attach to a session in that namespace
psmux -L work attach

# List sessions in a namespace
psmux -L work list-sessions

# Default namespace is used when -L is not specified

This is useful for running completely separate psmux environments, for example one for development and one for monitoring.