Skip to content

Instantly share code, notes, and snippets.

@inchoate
Created March 27, 2026 20:44
Show Gist options
  • Select an option

  • Save inchoate/f4b0a319348b84e89b1e46fcd2d9c9bf to your computer and use it in GitHub Desktop.

Select an option

Save inchoate/f4b0a319348b84e89b1e46fcd2d9c9bf to your computer and use it in GitHub Desktop.
My current .tmux.conf
# ╔══════════════════════════════════════════════════════════════════╗
# ║ tmux.conf — Ghostty + Claude Code + Neovim ║
# ║ OSC 52 clipboard · vi copy mode · session persistence ║
# ╚══════════════════════════════════════════════════════════════════╝
# ── Terminal & Color ──────────────────────────────────────────────
# Ghostty supports true color and undercurl natively.
# We set tmux-256color as the base, then add Ghostty-specific
# capabilities: RGB (true color), styled underlines, overlines.
set -g default-terminal "tmux-256color"
set -as terminal-features ",xterm-ghostty:RGB:usstyle:overline"
# ── General ───────────────────────────────────────────────────────
set -g mouse on
set -g history-limit 50000
set -g focus-events on
# Window/pane numbering starts at 1 (matches keyboard layout)
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
# Longer display time for pane numbers and messages
set -g display-time 2000
set -g display-panes-time 2000
# ── Keyboard ──────────────────────────────────────────────────────
# Low escape-time is critical for vim/neovim — prevents lag after
# pressing Escape. 10ms is aggressive but fine for local sessions.
set -s escape-time 10
# Extended keys: forward Shift+Enter, Ctrl+;, etc. to applications.
# "always" is required because Claude Code doesn't request the kitty
# keyboard protocol, so the default "on" silently drops these.
set -s extended-keys always
set -as terminal-features 'xterm*:extkeys'
# ── Clipboard (OSC 52) ───────────────────────────────────────────
# Strategy: let tmux send OSC 52 sequences → Ghostty writes to the
# macOS system clipboard. No pbcopy needed, works over SSH too.
#
# set-clipboard on — tmux copies to its buffer AND sends OSC 52
# allow-passthrough — lets OSC 52 (and image protocols) pass
# through to Ghostty. Required for Claude
# Code image paste.
set -s set-clipboard on
set -g allow-passthrough on
# ── Copy Mode (vi) ───────────────────────────────────────────────
setw -g mode-keys vi
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-selection-and-cancel
bind -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-selection-and-cancel
# ── Navigation ────────────────────────────────────────────────────
# Pane select: prefix + h/j/k/l
# Pane resize: prefix + H/J/K/L (repeatable)
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5
# ── Window Splits ─────────────────────────────────────────────────
# Open new panes and windows in the current working directory.
bind '"' split-window -v -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
bind c new-window -c "#{pane_current_path}"
# ── Window Naming ─────────────────────────────────────────────────
# Auto-rename to the current directory basename, or the running
# command if it isn't the shell. e.g. ~/src/my-project → "my-project"
setw -g automatic-rename on
set -g automatic-rename-format \
'#{?#{==:#{pane_current_command},zsh},#{b:pane_current_path},#{pane_current_command}}'
# ── Claude Code ───────────────────────────────────────────────────
# prefix + V : paste a clipboard image into Claude Code
# (workaround for Cmd+V image paste not working in tmux)
bind V run-shell "~/.local/bin/tmux-paste-image"
# prefix + y : Claude Code popup (80% of screen)
# Each working directory gets its own persistent session
# named claude-<hash>. Reopen to resume where you left off.
bind -r y run-shell '\
SESSION="claude-$(echo #{pane_current_path} | md5 -q | cut -c1-8)"; \
tmux has-session -t "$SESSION" 2>/dev/null || \
tmux new-session -d -s "$SESSION" -c "#{pane_current_path}" "claude"; \
tmux display-popup -w80% -h80% -E "tmux attach-session -t $SESSION"'
# prefix + C-c : claude-tmux TUI for managing multiple Claude sessions
bind C-c display-popup -E -w 80% -h 80% "$HOME/.cargo/bin/claude-tmux"
# ── Status Bar ────────────────────────────────────────────────────
# Minimal, low-distraction status line. Dark background with muted
# text; active window highlighted.
set -g status-position bottom
set -g status-interval 5
set -g status-style "bg=#1a1b26,fg=#565f89"
# Left: session name
set -g status-left-length 30
set -g status-left "#[fg=#7aa2f7,bold] #S #[fg=#3b4261]│ "
# Right: directory · time
set -g status-right-length 60
set -g status-right "#[fg=#565f89]#{b:pane_current_path} #[fg=#3b4261]│ #[fg=#565f89]%H:%M "
# Window tabs
set -g window-status-format " #I:#W "
set -g window-status-current-format "#[fg=#c0caf5,bg=#292e42,bold] #I:#W "
set -g window-status-separator ""
# Pane borders
set -g pane-border-style "fg=#3b4261"
set -g pane-active-border-style "fg=#7aa2f7"
# Messages & command prompt
set -g message-style "bg=#292e42,fg=#c0caf5"
set -g mode-style "bg=#292e42,fg=#c0caf5"
# ── Session Persistence ──────────────────────────────────────────
# Requires TPM (Tmux Plugin Manager). Install once:
# git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
#
# Then press prefix + I inside tmux to install the plugins below.
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
# Auto-save every 10 minutes, auto-restore on tmux start
set -g @continuum-restore 'on'
set -g @continuum-save-interval '10'
# Resurrect: also capture pane contents for better restore fidelity
set -g @resurrect-capture-pane-contents 'on'
# Initialize TPM — must be the very last line
run '~/.tmux/plugins/tpm/tpm'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment