.tmux.conf 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. set -g mouse on
  2. set -g base-index 1
  3. setw -g pane-base-index 1
  4. set -g history-limit 50000
  5. set -s escape-time 0
  6. set -g focus-events on
  7. set -g extended-keys on
  8. set -g display-time 4000
  9. set -g status-interval 5
  10. setw -g aggressive-resize on
  11. set -g status-keys emacs
  12. # Status bar as a tab bar
  13. set -g status-position bottom
  14. set -g status-style 'bg=colour235 fg=colour7'
  15. set -g status-left ' '
  16. # prefix-highlight (native #{client_prefix} — no plugin needed) + copy/sync indicators.
  17. # Indicators prepend to status-right so [+] [d] stay flush-right (mouse math intact).
  18. set -g status-right '#{?client_prefix,#[bg=colour3#,fg=colour235#,bold] ^B #[default] ,}#{?#{==:#{pane_mode},copy-mode},#[bg=colour2#,fg=colour235#,bold] COPY #[default] ,}#{?pane_synchronized,#[bg=colour1#,fg=colour15#,bold] SYNC #[default] ,} [+] [d] '
  19. # Tab label = the app's pane title (Claude Code sets a good one);
  20. # falls back to the running command for bare shells (where pane_title == hostname).
  21. # #{E:...} forces the stored format in @wtitle to expand. Replaces #W to dodge the
  22. # window-name pollution (apps leak junk like "2.1.156" into the window NAME).
  23. # @wtitle = full (feeds Ghostty title), @wtab = truncated (feeds status-bar tabs).
  24. set -g @wtitle '#{?#{||:#{==:#{pane_title},},#{==:#{pane_title},#{host}}},#{pane_current_command},#{pane_title}}'
  25. set -g @wtab '#{?#{||:#{==:#{pane_title},},#{==:#{pane_title},#{host}}},#{pane_current_command},#{=/24/…:pane_title}}'
  26. # Forward the active pane's title to the outer terminal (Ghostty tab/window title)
  27. set -g set-titles on
  28. set -g set-titles-string '#{E:@wtitle}'
  29. # Tab: index:(NpZ) title — pane count + zoom flag prefixed in parens, only when split.
  30. setw -g window-status-format ' #I:#{?#{>:#{window_panes},1},(#{window_panes}p#{?window_zoomed_flag,Z,}) ,}#{E:@wtab} '
  31. setw -g window-status-current-format ' #I:#{?#{>:#{window_panes},1},(#{window_panes}p#{?window_zoomed_flag,Z,}) ,}#{E:@wtab} '
  32. setw -g window-status-current-style 'bg=colour4 fg=colour15 bold'
  33. set -g pane-border-status top
  34. # Click [+] to create new tab, [d] to detach
  35. bind -n MouseDown1StatusRight run-shell -b '\
  36. x="#{mouse_x}"; \
  37. w=$(tmux display-message -p "#{window_width}"); \
  38. pos=$((w - x)); \
  39. if [ "$pos" -ge 0 ] && [ "$pos" -le 3 ]; then \
  40. tmux detach-client; \
  41. elif [ "$pos" -ge 4 ] && [ "$pos" -le 8 ]; then \
  42. tmux new-window; \
  43. fi'
  44. # Close tab: just type exit (or Ctrl-d) in the shell
  45. # Window management menu (prefix + w)
  46. bind w display-menu -T "Windows" \
  47. "New Window" n "new-window" \
  48. "Kill Window" k "kill-window" \
  49. "Next Window" l "next-window" \
  50. "Prev Window" h "previous-window" \
  51. "" \
  52. "Horizontal Split" - "split-window -v" \
  53. "Vertical Split" | "split-window -h" \
  54. "" \
  55. "Kill Pane" x "kill-pane" \
  56. "Zoom Pane" z "resize-pane -Z" \
  57. "" \
  58. "Choose Session" s "choose-tree -s"
  59. bind-key -n M-w new-window
  60. # Navigation hierarchy (no prefix), shared with Zed where possible:
  61. # Shift+arrow -> tabs/windows (flat, left/right only)
  62. # Ctrl+Shift+arrow -> panes (the 2D grid). Same chord in Zed.
  63. # Modified arrows arrive as legacy CSI 1;6 sequences, so tmux parses C-S-Left
  64. # natively -- no user-keys translation needed. Never use Cmd here: Ghostty
  65. # owns it and never forwards it to tmux.
  66. # -r lets you hold/repeat within repeat-time.
  67. bind-key -n -r S-Left previous-window
  68. bind-key -n -r S-Right next-window
  69. bind-key -n -r C-S-Left select-pane -L
  70. bind-key -n -r C-S-Right select-pane -R
  71. bind-key -n -r C-S-Up select-pane -U
  72. bind-key -n -r C-S-Down select-pane -D
  73. # Fork Claude Code session into a new window
  74. bind R source-file ~/.tmux.conf \; display "Reloaded"
  75. bind f run-shell 'T="Fork ($(date "+%a %H:%M"))"; tmux new-window -a -n "$T" "claude --dangerously-skip-permissions --resume --fork-session"; tmux select-pane -T "$T"'
  76. # >>> tmux-claude-status >>>
  77. source-file /Users/tom/.claude/tmux-claude-status.conf
  78. # <<< tmux-claude-status <<<