-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.tmux.conf
More file actions
357 lines (292 loc) · 17.4 KB
/
Copy path.tmux.conf
File metadata and controls
357 lines (292 loc) · 17.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# Plugins
#
set -g @plugin 'tmux-plugins/tpm'
### https://github.com/tmux-plugins/tmux-sessionist
# - prefix + C - prompt for creating a new session by name.
# - prefix + X - kill current session without detaching tmux.
# - prefix + S - switches to the last session.
# The same as built-in prefix + L that everyone seems to override with some other binding.
# - prefix + @ - promote current pane into a new session.
# Analogous to how prefix + ! breaks current pane to a new window.
set -g @plugin 'tmux-plugins/tmux-sessionist'
### https://github.com/tmux-plugins/tmux-resurrect
# This plugin goes to great lengths to save and restore all the details from your tmux environment.
#
# Key bindings
#
# - prefix + Ctrl-s - save
# - prefix + Ctrl-r - restore
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-yank' # Copy to the system clipboard in tmux.
set -g @plugin 'tmux-plugins/tmux-pain-control'
set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @plugin 'tmux-plugins/tmux-open'
set -g @plugin 'tmux-plugins/tmux-copycat'
set -g @plugin "aless3/tmux-click-copy"
set -g @plugin 'jaclu/tmux-mouse-swipe'
set -g @plugin 'eduwass/tmux-palette'
set -g @fuzzback-finder 'fzf'
set -g @fuzzback-bind '/'
set -g @fuzzback-fzf-colors 'fg:#D8DEE9,bg:#2E3440,hl:#BF616A,fg+:#D8DEE9,bg+:#2E3440,hl+:#BF616A,info:#81A1C1,prompt:#81A1C1,pointer:#BF616A,marker:#EBCB8B,spinner:#5E81AC,header:#5E81AC,border:#81A1C1'
# Continuum
#
set -g @continuum-restore 'on'
set -g @continuum-boot 'off'
set -g @continuum-boot-options 'kitty'
# Theme
#
set -g @plugin 'arcticicestudio/nord-tmux'
set -g status-left-length 60
set -g status-left '#[fg=#2E3440,bg=#81A1C1,nobold] #S #[fg=#81A1C1,bg=#3B4252,nobold]#[default]'
# Bindings
#
# Shared helper to switch layout to English; safe to run even if im-select is missing.
set -g @switch_to_english_cmd "command -v im-select >/dev/null 2>&1 && im-select com.apple.keylayout.ABC >/dev/null 2>&1 || true"
# Keep the prefix window open roughly as long as tmux's default prefix-timeout (1s).
set -g @english_layout_prefix_timeout 1.5
# Disable tmux's built-in prefix handler so we can run our own hook.
set-option -g prefix None
unbind-key C-b
unbind-key C-a
# Pressing prefix twice still sends a literal Ctrl+A to the pane.
unbind-key -T prefix C-a
bind-key -T prefix C-a send-keys C-a
# Custom prefix handler: switch to English and temporarily enter the prefix table.
bind-key -n C-a run-shell "#{@switch_to_english_cmd}" \;\
switch-client -T prefix \;\
run-shell -b "sleep #{@english_layout_prefix_timeout} && tmux switch-client -c '#{client_name}' -T root >/dev/null 2>&1 || true"
# Allow triggering the prefix from copy mode tables as well.
bind-key -T copy-mode C-a send-keys -X cancel \;\
run-shell "#{@switch_to_english_cmd}" \;\
switch-client -T prefix \;\
run-shell -b "sleep #{@english_layout_prefix_timeout} && tmux switch-client -c '#{client_name}' -T root >/dev/null 2>&1 || true"
bind-key -T copy-mode-vi C-a send-keys -X cancel \;\
run-shell "#{@switch_to_english_cmd}" \;\
switch-client -T prefix \;\
run-shell -b "sleep #{@english_layout_prefix_timeout} && tmux switch-client -c '#{client_name}' -T root >/dev/null 2>&1 || true"
bind-key -T copy-mode C-d send-keys -X cancel
bind-key -T copy-mode-vi C-d send-keys -X cancel
# Ctrl-a r to reload this config
unbind r
bind r source-file ~/.tmux.conf \; display "Reloaded ~/.tmux.conf"
bind к source-file ~/.tmux.conf \; display "Reloaded ~/.tmux.conf"
set -g automatic-rename on
set -g automatic-rename-format '#(/Users/tim/dev/dotfiles/tmux/pane-app-name.sh "#{pane_current_command}" "#{pane_pid}" "#{pane_tty}" "#{pane_current_path}")'
# <Prefix> X for killing a session
bind-key X kill-session
# When creating a new window or pane, automatically change to the directory of
# the current window or pane. Switching back to English right before prompts
# avoids typing the window name in the wrong layout.
bind c run-shell "#{@switch_to_english_cmd}" \;\
new-window -c "#{pane_current_path}"
bind '=' split-window -c "#{pane_current_path}"
bind Enter split-window -h -c "#{pane_current_path}"
# Settings
#
set-option -g status-position top
set-option -g renumber-windows on
set -g base-index 1
# Command prompt settings (VI style for prompt, VI for copy-mode)
set -g status-keys vi
# Alt+Backspace deletes a word in tmux prompts (rename-window, command-prompt, etc.)
# Root-table binding is for panes; vi-edit handles the status/command prompt.
bind-key -n M-BSpace send-keys C-w
bind-key -T vi-edit M-BSpace send-keys -X delete-word
set-environment -g TMPDIR "$HOME/tmp"
set-option -g default-shell /opt/homebrew/bin/fish
set-option -g set-clipboard on
set -g mouse on
# Handle mouse clicks in normal mode:
# Trigger on MouseUp to ensure correct pane evaluation.
# - If pane is already active, pass the click directly to the application (e.g., for Neovim cursor positioning).
# - If pane is not active, select it and then pass the click.
bind-key -n MouseUp1Pane if-shell -F '#{==:#{pane_id},#{mouse_pane}}' 'send-keys -M' 'select-pane -t= ; send-keys -M'
setw -g aggressive-resize on
set -g @scroll-speed-num-lines-per-scroll "1"
# This is required for vim colors to work correctly when ssh-ing to one server,
# running tmux on it, and then in one pane ssh-ing to a different server. If
# this is not set, that latter pane will not have proper colors in vim.
set -g allow-passthrough on
set -ga update-environment TERM
set -ga update-environment TERM_PROGRAM
set -g terminal-features 'xterm-kitty:passthrough:clipboard:ccolour:cstyle:focus:title:RGB'
set -g default-terminal "xterm-kitty"
set -ga terminal-overrides ",xterm-kitty:Tc"
# set -g default-terminal "screen-256color"
# set -as terminal-features ",xterm-256color:RGB"
# функциональные клавиши с модификаторами (F1–F12 + Ctrl/Alt/Shift)
set -g extended-keys on
set -g extended-keys-format csi-u
# Apparently helps with nvim compatibility; not sure why this is needed
# Disabled: causes [O and [I characters to appear when switching windows
# Modern nvim versions work fine without this option
set -g focus-events off
# Helps with hitting escape key lag in vim
set -sg escape-time 0 # or maybe 10
# bigger history size
set -g history-limit 100000
# status messages displayed for this many milliseconds
set -g display-time 4000
# update status every this many seconds
set -g status-interval 5
# Move current window to specific index
# - Prefix + i → Insert before index (shift others)
unbind i
unbind v
bind i command-prompt -p "Insert before:" "move-window -b -t ':%1'"
# Move current window to specific index
# - Prefix + u → Swap with index (exchange positions)
unbind u
bind u command-prompt -p "Swap with:" "swap-window -t ':%1'"
# Move current pane to chosen window
# - Prefix + m → Move to index (split 50/50)
unbind m
bind m command-prompt -p "Move to:" "join-pane -h -l 50% -t ':%1'"
# Pull pane from another window into current one
# - Prefix + M → Pull from index (split 50/50)
unbind M
bind M command-prompt -p "Pull from:" "join-pane -h -l 50% -s ':%1' -t :."
# Bind F1..F12 (sent from kitty)
# Cmd+t → kitty sends F1, so switch to English before creating the new window.
bind-key -n F1 run-shell "#{@switch_to_english_cmd}" \;\
new-window -c "#{pane_current_path}"
bind-key -n F2 kill-pane
bind-key -n F3 kill-window
bind-key -n F4 split-window -h -c "#{pane_current_path}"
bind-key -n F5 resize-pane -Z \; if-shell -F '#{window_zoomed_flag}' 'run-shell -b :' 'select-pane -l'
bind-key -n F6 command-prompt -I '#W' 'rename-window -- "%%"'
# Popup shell via kitty cmd+f / cmd+alt+f passthrough (F7/F8)
set -g @popup_gc_script "/Users/tim/dev/dotfiles/tmux/popup-session-gc.sh"
bind-key -n F7 if-shell -F '#{m:_popup*,#{session_name}}' 'detach-client' 'run-shell "/Users/tim/dev/dotfiles/tmux/popup-shell.sh persistent \"#{window_id}\" \"#{pane_current_path}\""'
bind-key -n F8 if-shell -F '#{m:_popup*,#{session_name}}' 'detach-client' 'run-shell "/Users/tim/dev/dotfiles/tmux/popup-shell.sh ephemeral \"#{window_id}\" \"#{pane_current_path}\""'
# Notes popup via kitty cmd+b passthrough (F3). Inside the popup, save before detaching.
bind-key -n F3 if-shell -F '#{==:#{@popup_label},notes}' 'send-keys Escape ":wa" Enter ; detach-client' 'run-shell "/Users/tim/dev/dotfiles/tmux/notes-popup.sh \"#{window_id}\" \"#{pane_current_path}\""'
bind-key f if-shell -F '#{m:_popup*,#{session_name}}' 'run-shell "/Users/tim/dev/dotfiles/tmux/popup-promote-window.sh"' ''
bind-key F if-shell -F '#{m:_popup*,#{session_name}}' 'detach-client' 'run-shell "/Users/tim/dev/dotfiles/tmux/popup-shell.sh ephemeral \"#{window_id}\" \"#{pane_current_path}\""'
set-hook -g window-unlinked 'run-shell -b "#{@popup_gc_script}"'
set-hook -g session-closed 'run-shell -b "#{@popup_gc_script}"'
run-shell -b "#{@popup_gc_script}"
bind-key -n F9 previous-window
bind-key -n F10 next-window
# Cycle sessions while skipping popup/utility sessions.
bind-key ( run-shell "/Users/tim/dev/dotfiles/tmux/session-cycle.sh prev"
bind-key ) run-shell "/Users/tim/dev/dotfiles/tmux/session-cycle.sh next"
bind-key -n F11 run-shell "~/.tmux/plugins/tmux-copycat/scripts/copycat_search.sh"
bind-key -n F12 run-shell "~/.tmux/plugins/tmux-copycat/scripts/copycat_mode_start.sh '(https?://|git@|git://|ssh://|ftp://|file:///)[[:alnum:]?=%/_.:,;~ @!#$&()*+-]*|opencode -s ses_[A-Za-z0-9]+|omp --resume[= ][[:alnum:]_./:-]+'"
# TPM
run '~/.tmux/plugins/tpm/tpm'
# remove unwanted pain-control binds
unbind |
unbind -
unbind \\
unbind _
# keep this line after run '~/.tmux/plugins/tpm/tpm'
set -g status-right ''
set -g status-left '#[fg=black,bg=blue,bold] #S #[fg=blue,bg=black,nobold,noitalics,nounderscore]'
# tmux 3.7+ needs fill/width for a full-width prompt; tmux 3.6 rejects those attrs.
if-shell -F '#{m:3.7*,#{version}}' "set -g message-style 'bg=brightblack,fg=cyan,fill=brightblack,width=100%'" "set -g message-style 'bg=brightblack,fg=cyan'"
if-shell -F '#{m:3.7*,#{version}}' "set -g message-command-style 'bg=brightblack,fg=cyan,fill=brightblack,width=100%'" "set -g message-command-style 'bg=brightblack,fg=cyan'"
# Nord theme sets fg/bg inside the format, so bell fg must be conditional here.
set -g window-status-bell-style 'fg=#A3BE8C,bold'
set -g window-status-format '#{?window_bell_flag,#[fg=black]#[bg=brightblack],#[fg=black]#[bg=brightblack]}#[nobold,noitalics,nounderscore] #{?window_bell_flag,#[fg=#A3BE8C]#[bg=brightblack],#[fg=white]#[bg=brightblack]}#I #{?window_bell_flag,#[fg=#A3BE8C]#[bg=brightblack],#[fg=white]#[bg=brightblack]}#[nobold,noitalics,nounderscore] #{?window_bell_flag,#[fg=#A3BE8C]#[bg=brightblack],#[fg=white]#[bg=brightblack]}#W #F #{?window_bell_flag,#[fg=brightblack]#[bg=black],#[fg=brightblack]#[bg=black]}#[nobold,noitalics,nounderscore]'
set -g window-status-current-format '#{?window_bell_flag,#[fg=black]#[bg=cyan],#[fg=black]#[bg=cyan]}#[nobold,noitalics,nounderscore] #{?window_bell_flag,#[fg=#A3BE8C]#[bg=cyan],#[fg=black]#[bg=cyan]}#I #{?window_bell_flag,#[fg=#A3BE8C]#[bg=cyan],#[fg=black]#[bg=cyan]}#[nobold,noitalics,nounderscore] #{?window_bell_flag,#[fg=#A3BE8C]#[bg=cyan],#[fg=black]#[bg=cyan]}#W #F #{?window_bell_flag,#[fg=cyan]#[bg=black],#[fg=cyan]#[bg=black]}#[nobold,noitalics,nounderscore]'
unbind-key g
bind-key g if-shell -F '#{m:_popup*,#{session_name}}' 'run-shell "/Users/tim/dev/dotfiles/tmux/popup-promote-split.sh"' ''
unbind-key G
bind-key G if-shell -F '#{m:_popup*,#{session_name}}' 'run-shell "/Users/tim/dev/dotfiles/tmux/popup-promote-split.sh horizontal"' ''
# Use vim keybindings for navigating copy mode
setw -g mode-keys vi
bind -T copy-mode-vi WheelUpPane send -N 1 -X scroll-up
bind -T copy-mode-vi WheelDownPane send -N 1 -X scroll-down
# Copy mode bindings
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi м send-keys -X begin-selection
bind-key -T copy-mode-vi y send-keys -X copy-pipe-no-clear "pbcopy"
bind-key -T copy-mode-vi н send-keys -X copy-pipe-no-clear "pbcopy"
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "pbcopy"
# Mouse selection copies and stays in copy mode
unbind-key -T copy-mode-vi MouseDragEnd1Pane
# Override plugin bindings - must be after TPM
# Rebind copycat search to <prefix>+?
unbind-key -T prefix ?
bind-key -T prefix ? run-shell "~/.tmux/plugins/tmux-copycat/scripts/copycat_search.sh"
# TmuxAI in a normal pane (no popup)
unbind-key -T prefix a
bind-key -T prefix a split-window -v -p 35 -c "#{pane_current_path}" "~/dev/dotfiles/tmuxai/tmuxai-wrapper.sh"
bind-key -T prefix \; send-keys "/prepare fish" Enter
# Workmux
unbind-key -T prefix e
unbind-key -T prefix b
unbind-key -T prefix B
unbind-key -T prefix w
unbind-key -T prefix W
bind-key -T prefix e run-shell "/opt/homebrew/bin/workmux sidebar"
bind-key -T prefix E select-layout -E
bind-key -T prefix b choose-tree -Zw
bind-key -T prefix w display-popup -E -w 100% -h 100% -b none -S "fg=#81A1C1" "/opt/homebrew/bin/workmux dashboard -s"
bind-key -T prefix W display-popup -E -w 100% -h 100% -b none -S "fg=#81A1C1" "/opt/homebrew/bin/workmux dashboard"
bind-key -T prefix у run-shell "/opt/homebrew/bin/workmux sidebar"
bind-key -T prefix У select-layout -E
bind-key -T prefix и choose-tree -Zw
bind-key -T prefix ц display-popup -E -w 100% -h 100% -b none -S "fg=#81A1C1" "/opt/homebrew/bin/workmux dashboard -s"
bind-key -T prefix Ц display-popup -E -w 100% -h 100% -b none -S "fg=#81A1C1" "/opt/homebrew/bin/workmux dashboard"
bind-key -n M-Tab run-shell '/opt/homebrew/bin/workmux sidebar next >/dev/null 2>&1 || { /opt/homebrew/bin/workmux sidebar >/dev/null 2>&1 && sleep 0.15 && /opt/homebrew/bin/workmux sidebar next >/dev/null 2>&1; } || true'
bind-key -n M-S-Tab run-shell '/opt/homebrew/bin/workmux sidebar prev >/dev/null 2>&1 || { /opt/homebrew/bin/workmux sidebar >/dev/null 2>&1 && sleep 0.15 && /opt/homebrew/bin/workmux sidebar prev >/dev/null 2>&1; } || true'
bind-key -n M-BTab run-shell '/opt/homebrew/bin/workmux sidebar prev >/dev/null 2>&1 || { /opt/homebrew/bin/workmux sidebar >/dev/null 2>&1 && sleep 0.15 && /opt/homebrew/bin/workmux sidebar prev >/dev/null 2>&1; } || true'
bind-key L run-shell "workmux last-done"
# Fuzzback with fzf-only border: keep only preview separator.
unbind-key -T prefix /
bind-key -T prefix / run-shell -b 'FZF_DEFAULT_OPTS="${FZF_DEFAULT_OPTS:+$FZF_DEFAULT_OPTS }--border=none --preview-window=right:60%:nowrap:border-left" ~/.tmux/plugins/tmux-fuzzback/scripts/fuzzback.sh'
bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-no-clear "pbcopy"
# Click to focus pane even when current pane is in copy-mode
# Also clear any pending selection on click when target pane is in copy mode
unbind-key -T copy-mode-vi MouseDown1Pane
bind-key -T copy-mode-vi MouseDown1Pane select-pane -t= \; if-shell -F "#{pane_in_mode}" "send-keys -X clear-selection"
# Allow clicking on status line tabs to switch windows while in copy mode
bind-key -T copy-mode-vi MouseDown1Status select-window -t=
bind-key -T copy-mode-vi MouseDown3Status select-window -t=
bind-key -T copy-mode-vi MouseUp2Status kill-window -t=
bind-key -T copy-mode-vi MouseUp1StatusLeft run-shell -b "/Users/tim/dev/dotfiles/tmux/sesh-fzf-picker.sh"
# Ensure clicks on status line switch windows outside copy mode as well
unbind-key -n MouseDown1Status
unbind-key -n MouseDown3Status
unbind-key -n MouseUp1Status
unbind-key -n MouseUp3Status
unbind-key -n MouseDrag1Status
bind-key -n MouseDown1Status select-window -t=
bind-key -n MouseDown3Status select-window -t=
bind-key -n MouseUp1Status select-window -t=
bind-key -n MouseUp3Status select-window -t=
bind-key -n MouseDrag1Status select-window -t=
bind-key -n MouseUp1StatusLeft run-shell -b "/Users/tim/dev/dotfiles/tmux/sesh-fzf-picker.sh"
# Middle mouse button on status line closes window (like browser tabs)
bind-key -n MouseUp2Status kill-window -t=
bind-key -T copy-mode-vi q if-shell -F "#{selection_active}" 'send-keys -X copy-pipe-and-cancel "pbcopy"' 'send-keys -X cancel'
bind-key -T copy-mode-vi й if-shell -F "#{selection_active}" 'send-keys -X copy-pipe-and-cancel "pbcopy"' 'send-keys -X cancel'
bind-key -T copy-mode-vi i send-keys -X clear-selection
bind-key -T copy-mode-vi ш send-keys -X clear-selection
bind-key -T copy-mode-vi a send-keys -X cancel
bind-key -T copy-mode-vi ф send-keys -X cancel
bind-key -T copy-mode-vi p send-keys -X cancel \; paste-buffer
bind-key -T copy-mode-vi з send-keys -X cancel \; paste-buffer
bind-key -T copy-mode-vi C-v send-keys -X cancel \; paste-buffer
# Select all in copy mode with cmd+a (Shift+F1 passthrough from kitty)
bind-key -T copy-mode-vi F1 send-keys -X history-top \; send-keys -X begin-selection \; send-keys -X history-bottom
bind-key -T root S-F1 copy-mode \; send-keys -X history-top \; send-keys -X begin-selection \; send-keys -X history-bottom
bind-key -T copy-mode-vi S-F1 send-keys -X history-top \; send-keys -X begin-selection \; send-keys -X history-bottom
# Selection highlighting color (Nord theme)
set -g mode-style "fg=#2E3440,bg=#a3be8c"
# Leader + v for copy-mode (same as [)
unbind-key -T prefix v
unbind-key -T prefix V
bind-key -T prefix v copy-mode
# sesh
unbind-key s
unbind-key S
bind-key "s" run-shell -b "/Users/tim/dev/dotfiles/tmux/sesh-fzf-picker.sh"
bind-key "S" run-shell -b "/Users/tim/dev/dotfiles/tmux/popup-sesh-fzf-picker.sh"
# Command palette
unbind-key p
bind-key p run-shell "~/.tmux/plugins/tmux-palette/bin/tmux-palette.sh"
# Remove SSH vars from tmux global environment to prevent Plannotator issues
# set -g update-environment "DISPLAY KRB5CCNAME SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID WINDOWID XAUTHORITY"