‹ 指南

我們在用的 tmux 設定

本站截圖背後那份 ~/.tmux.conf:為小螢幕、程式助手,以及手機和電腦同時掛著的情境調過。

撰寫於

為甚麼要設定

tmux 的預設值是為桌上型電腦寫的:只掛一個用戶端,鍵盤上有一整排修飾鍵,執行的程式只輸出文字。放到手機上,這幾條沒有一條成立,螢幕小,往往還有一台手提電腦同時掛著,而裏面跑的越來越多是程式助手,它講的是顏色、圖片和 Shift+Enter,這些在原裝 tmux 下都活不下來。

這就是我們真正在用的那份檔案,不是入門範本:本站所有 tmux 截圖都是透過它拍的。整份拷走,或者只挑你要的部分,每一行都帶註解說明它換來了甚麼,下面幾節則解釋那些不太顯然的取捨。

~/.tmux.conf
##### 終端機能力 #####

# 終端機類型 + 24 位真彩色:沒有 RGB,漸變會有色帶
set  -g default-terminal "tmux-256color"
set -as terminal-features ",*:RGB"

# RGB 告訴的是 tmux:外層終端機支援真彩色;裏面的程式(nvim、bat、fzf、
# delta)要不要送 24 位色,看的是 COLORTERM。tmux 自己從不把這個變數
# 傳進去,所以把它釘死
set-environment -g COLORTERM truecolor

# 內嵌圖片(sixel、kitty、imgcat):否則會被 tmux 丟掉
set  -g allow-passthrough on
set -as terminal-features ",*:sixel"

# 在 tmux 裏複製,直接進手機剪貼簿(OSC 52)
set  -g set-clipboard on

# ……走 mosh 時也一樣。tmux 發這條 OSC 52 時不填目標,發出來是 52;;,
# 而 mosh 只轉發 52;c;,所以沒有這一行,在 tmux 裏複製的內容只會進
# tmux 自己的貼上緩衝區,根本出不了伺服器。%p1 一定要留着:跳過它
# 直接寫 %p2 的寫法能正常載入,然後甚麼都不發
set -ag terminal-overrides ',*:Ms=\E]52;%p1%sc;%p2%s\a'

# 讓 Ctrl+Shift+…、Shift+Enter 之類以 CSI u 形式穿過 tmux
# (Claude Code 靠這個來實現 Shift+Enter 換行)
set  -s extended-keys on
set -as terminal-features ",*:extkeys"
set  -g extended-keys-format csi-u

# 別在 Esc 上等:預設那 500ms 會毀掉 Alt 組合鍵
set -sg escape-time 10

# 焦點事件和滑鼠(在終端機裏按住 Shift 可以本機選取)
set  -g focus-events on
set  -g mouse on

# 把視窗標題轉發出來,終端機 App 才能為分頁命名
set  -g set-titles on
set  -g set-titles-string "tmux · #{pane_title}"

# 捲動回看行數:程式助手輸出很多,給它留夠
set  -g history-limit 100000

##### 手機 / 同時掛著多個用戶端 #####

# 視窗大小跟著「最近活動」的用戶端走:手機和電腦同時掛著時,
# 誰在打字就按誰的螢幕來;小螢幕不會把版面鎖死
set  -g window-size latest
setw -g aggressive-resize on

# 視窗和窗格從 1 開始編號,關掉後自動補號:手機鍵盤上 1 比 0 好按
set  -g base-index 1
setw -g pane-base-index 1
set  -g renumber-windows on

# 關掉目前工作階段時跳到下一個,而不是直接 detach:
# 從手機上重新連線很麻煩
set  -g detach-on-destroy off

# 提示訊息多留一會兒,小螢幕上才來得及看
set  -g display-time 2000
set  -g display-panes-time 2000

##### 程式助手提醒 #####

# Claude Code 這類工具做完會響鈴:不要閃螢幕,
# 只在狀態列那個視窗名上加一個粗體的 !
set  -g bell-action any
set  -g visual-bell off
setw -g monitor-bell on

# 背景視窗有新輸出 -> 狀態列出現 # 標記,
# 一眼就能看出哪個程式助手還在跑、哪個已經停了
setw -g monitor-activity on
set  -g visual-activity off

##### 配色 #####

# bg=default 讓終端機自己的背景透過來,點綴色(工作階段名稱、前綴提示、
# 活動標記)取自終端機的調色盤。凡是必須在每個掛著的用戶端上都看得清的
# 部分,改用固定的 256 色,它們在任何主題下都長一個樣

# 狀態列放在頂部,避開底部 Claude Code 的輸入框
set  -g status-position top
set  -g status-interval 5
set  -g status-style "bg=default,fg=default"

# 左邊顯示工作階段名稱;右邊只在按住前綴鍵時顯示 ^B 提示
set  -g status-left "#[fg=colour5,bold] #S #[default]"
set  -g status-left-length 20
set  -g status-right "#{?client_prefix,#[fg=colour3 bold]^B ,}"
set  -g status-right-length 20

# 視窗列表:目前視窗是一塊自帶白字的藍底(任何主題下對比度都是 5.8:1),
# 其它視窗用中灰;響鈴(!)紅色,有活動(#)黃色
setw -g window-status-format " #I #W#{?window_flags,#{window_flags}, } "
setw -g window-status-style "fg=colour245"
setw -g window-status-current-format " #I #W "
setw -g window-status-current-style "bg=colour26,fg=colour231,bold"
setw -g window-status-bell-style "fg=colour203,bold"
setw -g window-status-activity-style "fg=colour3"

# 窗格邊框、訊息、複製模式的選取樣式:一種灰,一種藍
set  -g pane-border-style "fg=colour243"
set  -g pane-active-border-style "fg=colour32"
set  -g message-style "fg=colour32,bold,bg=default"
# tmux 自己的指令提示符是一條不透明的黑條:讓它和訊息一個樣
set  -g message-command-style "fg=colour32,bold,bg=default"
set  -g mode-style "bg=colour26,fg=colour231"
set  -g display-panes-colour colour243
set  -g display-panes-active-colour colour32
setw -g clock-mode-colour colour32

##### 快捷鍵 #####

setw -g mode-keys vi

# 分割和新增視窗都繼承目前目錄:不用再 cd 回程式助手做事的地方
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
bind c new-window   -c "#{pane_current_path}"

# Alt+數字直接跳視窗,不用按前綴鍵:手機上少按一次組合鍵
bind -n M-1 select-window -t 1
bind -n M-2 select-window -t 2
bind -n M-3 select-window -t 3
bind -n M-4 select-window -t 4
bind -n M-5 select-window -t 5

# 前綴鍵 + hjkl 在窗格之間移動
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

##### 複製與貼上 #####

# 前綴鍵 + v 也能進複製模式(比 [ 好記)
bind v copy-mode

# 複製模式:v 開始選取,y 複製(經 OSC 52 送到手機/本機剪貼簿),
# Y 複製整行,Ctrl+v 切換矩形選取
bind -T copy-mode-vi v send -X begin-selection
bind -T copy-mode-vi y send -X copy-selection-and-cancel
bind -T copy-mode-vi Y send -X copy-line-and-cancel
bind -T copy-mode-vi C-v send -X rectangle-toggle

# 滑鼠拖選即複製,但留在複製模式的原位:不會跳回底部,
# 可以接著看程式助手的捲動輸出;按 q 退出
bind -T copy-mode-vi MouseDragEnd1Pane send -X copy-selection

# 雙擊複製一個詞,三擊複製一整行。詞的邊界只算空格,
# 所以雙擊就能從程式助手的輸出裏一次拿到完整的檔案路徑或 URL
set -g word-separators " "
# 那個 `run -d0.3` 要留着:進複製模式和複製放在同一條指令裏,
# tmux 的緩衝區有了內容,卻不送 OSC 52,剪貼簿裏甚麼都沒有。
# 用 -H 而不是 -M:-M 會把這次點擊繼續傳下去,選取範圍會越過這個詞
bind -n DoubleClick1Pane copy-mode -H \; send -X select-word \; run -d0.3 \; send -X copy-selection-and-cancel
bind -n TripleClick1Pane copy-mode -H \; send -X select-line \; run -d0.3 \; send -X copy-selection-and-cancel
bind -T copy-mode-vi DoubleClick1Pane send -X select-word \; send -X copy-selection-and-cancel
bind -T copy-mode-vi TripleClick1Pane send -X select-line \; send -X copy-selection-and-cancel

# 前綴鍵 + ] 貼上最近一次複製(tmux 預設);前綴鍵 + P 打開緩衝區清單,
# 貼上更早複製的內容
bind P choose-buffer

# 前綴鍵 + t:彈出一個小終端機跑一次性指令,不打亂程式助手的版面;
# exit 就關
bind t display-popup -E -w 80% -h 75% -d "#{pane_current_path}"

# 前綴鍵 + r:重新載入設定
bind r source-file ~/.tmux.conf \; display "已重新載入 ~/.tmux.conf"

tmux 擋住了終端機的哪些能力

多工器夾在程式和 Term 之間,而原裝的它對「放甚麼過去」相當保守。allow-passthrough on 才能讓內嵌圖片顯示出來:sixel、kitty graphics 和 imgcat 都是以逸出序列送達的,否則會被 tmux 吞掉。terminal-features ",*:RGB" 恢復24 位色,沒有它,TUI 裏的漸變全是色帶。而 set-clipboard on 才讓複製模式裏按 y 直接進手機剪貼簿,走 OSC 52,伺服器上不用裝任何輔助程式。

RGB 只是告訴 tmux 自己:Term 能畫 24 位色。裏面的程式要自己判斷,看的是 COLORTERM,而 tmux 從不把這個變數傳進去:從普通 shell 啟動的伺服端,會讓 nvim、bat、delta 退回 256 色,看起來只是主題發灰,不像出了錯。set-environment -g COLORTERM truecolor 把它釘給之後開的每一個窗格。Term 連上時也會替正在執行的 tmux 伺服端設上它;這一行讓這份設定從任何終端機連過去都一樣對。

三行 extended-keys 是這組裏最新、也最容易漏掉的。它讓 Ctrl+Shift+…、Shift+Enter 這類按鍵以 CSI u 形式穿過去,而不是被壓扁成普通按鍵。Claude Code 用 Shift+Enter 在提示詞裏換行;少了這幾行,這一下會變成普通 Enter,把寫到一半的提示詞直接送出。

set-clipboard 下面那行 terminal-overrides 只為一種組合而存在:在 mosh 工作階段裏跑 tmux。一條 OSC 52 要寫明它指的是哪個剪貼簿,而 tmux 把這個名字留空,發出來是 52;;;mosh 按字面只認 52;c;,於是一條都不轉發,你在 tmux 裏複製的內容落進 tmux 自己的貼上緩衝區就到頭了。這一行把名字釘成 c。格式裏的 %p1 即使取值被丟掉也必須留着:跳過它直接寫 %p2 的版本能正常載入,然後一個位元組都不發。

手機和電腦同時掛著

掛兩個用戶端時,原裝 tmux 會把每個視窗縮到最小的那個用戶端,手機一連上,200 欄的手提電腦就被壓到 56 欄,而且一直保持。window-size latest 改成按最近活動的用戶端來:在手提電腦上打字就用它的螢幕,拿起手機就為手機重排。aggressive-resize 對個別視窗做同樣的事。

detach-on-destroy off 也是同一個道理。關掉工作階段的最後一個窗格,原裝 tmux 會把你丟回對端的 shell:在手機上,這意味著你剛花二十秒建起來的那條連線。跳到下一個工作階段,人就還在裏面。

哪個程式助手還在做事

程式助手做完一輪會響鈴。monitor-bell 開、visual-bell 關,這一下就變成狀態列裏那個視窗名旁邊一個粗體的紅色 !,而不是在你正在看的螢幕上閃一下;monitor-activity 則替任何有輸出的視窗加一個黃色的 #。手機上同一時間只看得見一個視窗,狀態列是唯一能讓你分辨四個 agent 裏誰還在想、誰在等你的地方。

在任何主題下都看得清的狀態列

bg=default 讓 Term 自己的背景透過狀態列,點綴色(工作階段名稱、^B 提示、活動標記)都是調色盤裏的顏色,會跟著 Term 一起換主題。但跟著調色盤走,不等於看得清。調色盤裏的顏色保留的是它的角色,不是亮度:colour8 在每個主題裏都是「亮黑」,在深色主題上就是一片暗灰。目前視窗原來用的 reverse 更是把對比度變成了抽獎:黑底的調色盤上只有 2.2:1,粉彩系的調色盤上又沒問題。手機和電腦同時掛著時,兩邊的調色盤甚至都不一樣。

所以凡是要讀的部分,都改用固定的 256 色,它們在每個終端機裏畫出來都一樣。目前視窗是一塊自帶白字的藍底(colour26 底、colour231 字,任何主題下都是 5.8:1);其它視窗名用一種淺色深色都看得清的中灰;邊框、訊息、指令提示符和時鐘共用一種藍。tmux 3.7 能分辨用戶端是淺色還是深色(#{client_theme}),但前提是終端機回報,而走 mosh 時這份回報永遠到不了,所以這裏沒有任何東西依賴它。

適合拇指的按鍵

這裏每一條綁定都在省掉一次組合鍵或一次跨鍵盤的移動。| 和 - 按它們長的樣子分割。前綴鍵 + hjkl 在窗格間移動,完全不用碰方向鍵。前綴鍵 + t 在目前窗格上彈出一個臨時小終端機(這是手機上對「我要跑一條指令,但不想打亂程式助手的版面」的答案),exit 就關。

Alt+1 … Alt+5,不用前綴鍵

切視窗是 tmux 裏最頻繁的操作,在手機上也最貴:前綴鍵再加一個數字,是兩層組合。bind -n 把前綴鍵整個去掉,而 Term 的按鍵列有一個黏滯 alt,於是它就變成兩次點擊。

就地開出來的分割

分割和新增視窗那幾條綁定上的 -c "#{pane_current_path}",讓新窗格開在你已經在的那個目錄裏。沒有它,每次分割都從 $HOME 開始,而你在手機鍵盤上要打的第一樣東西就是一長串 cd。

複製程式助手的輸出

複製相關的綁定是為了從程式助手印出的東西裏挑內容而調的。雙擊複製一個詞,而 word-separators 只算空格,所以一個「詞」就是一整條檔案路徑或 URL:點一下,不用小心翼翼地拖。三擊拿整行。滑鼠拖選會複製,並且留在複製模式的原位,不會彈回底部,你可以接著往回看捲動輸出;按 q 離開。前綴鍵 + P 打開之前複製過的內容清單。

雙擊和三擊那兩條綁定裏的 run -d0.3 要留着。進複製模式和複製放在同一條指令裏,tmux 的貼上緩衝區有了內容,卻不送 OSC 52,於是複製的東西到不了剪貼簿,不管走哪種連線都一樣。這點延遲讓模式切換先落定,tmux 內建的預設綁定裏也有它,就是這個原因。

怎麼裝上

  1. 把上面這份檔案拷走,存成伺服器上的 ~/.tmux.conf:不是手機上。tmux 在工作階段執行的那一端讀它。
  2. 在 shell 提示符下用下面這條指令載入一次。
  3. 之後每次改完,用 前綴鍵 + r 重新載入即可。
第一次載入,在 shell 裏
tmux source-file ~/.tmux.conf

中間那步看著和重新載入的綁定重複,其實不是:前綴鍵 + r 沒法完成第一次載入。這個綁定要等檔案被讀過才存在,而 tmux 伺服端是在啟動時讀設定的,第一次的時候,那還早於檔案存在。於是唯一不能用快捷鍵完成的重新載入,恰恰是把這個快捷鍵裝上的那一次。另外注意 source-file 是 tmux 的指令而不是 shell 的:所以在這裏要在前面加 tmux,而在設定檔裏則不用。

還有兩件事得先確認,否則怎麼改都不生效:這份設定需要 tmux 3.5 或更新的版本,更舊的版本啟動時只會報一句「unknown option」,那條設定就靜默失效了,用 tmux -V 看一下你裝的是哪個。另外在 Debian 與 Ubuntu 上,第一行選用的 tmux-256color 這條 terminfo 描述並不隨 tmux 一起裝,而是在 ncurses-term 套件裏,記得一併裝上。

延伸閱讀: 在手機上用 tmux · SSH 自動恢復 · 常見問題