本站截图背后那份 ~/.tmux.conf:为小屏幕、代码助手,以及手机和电脑同时挂着的场景调过。
撰写于
tmux 默认是给台式机用的:只挂一个客户端,键盘上的修饰键随手就够,程序也只输出文字。放到手机上,这几条没有一条成立:屏幕小,往往还有一台笔记本同时挂着,而里面跑的越来越多是代码助手,它讲的是颜色、图片和 Shift+Enter,这些在原装 tmux 下都活不下来。
这就是我们真正在跑的那份文件,不是入门模板:本站所有 tmux 截图都是透过它拍的。整份拷走,或者只挑你要的部分,每一行都带注释说明它换来了什么,下面几节则解释那些不太显然的取舍。
##### 终端能力 ##### # 终端类型 + 24 位真彩色:没有 RGB,渐变会有色带 set -g default-terminal "tmux-256color" set -as terminal-features ",*:RGB" # 内嵌图片(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 ##### 配色:只用 ANSI 16 色 + 透明背景,自动跟随终端的 ##### ##### 明暗主题 ##### # 诀窍:状态栏里绝不写死 RGB。bg=default 让终端背景透过来, # colour0-15 取自终端自己的调色板,终端在明暗之间切换时, # tmux 会跟着一起换。 # 状态栏放在顶部,避开底部 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 # 窗口列表:当前窗口用蓝底块,其它灰色;响铃(!)红色, # 有活动(#)黄色 # reverse 让文字取终端背景色,浅色主题下是深色字, # 深色主题下是浅色字,自己会适应 setw -g window-status-format " #I #W#{?window_flags,#{window_flags}, } " setw -g window-status-style "fg=colour8" setw -g window-status-current-format " #I #W " setw -g window-status-current-style "fg=colour4,bold,reverse" setw -g window-status-bell-style "fg=colour1,bold" setw -g window-status-activity-style "fg=colour3" # 窗格边框、消息、复制模式的选中样式 set -g pane-border-style "fg=colour8" set -g pane-active-border-style "fg=colour4" set -g message-style "fg=colour4,bold,bg=default" set -g mode-style "bg=colour4,fg=colour0" set -g display-panes-colour colour8 set -g display-panes-active-colour colour4 setw -g clock-mode-colour colour4 ##### 快捷键 ##### 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 开始选择,y 复制(经 OSC 52 送到手机/本机剪贴板) bind -T copy-mode-vi v send -X begin-selection bind -T copy-mode-vi y send -X copy-selection-and-cancel # 前缀键 + 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"
复用器夹在程序和 Term 之间,而原装的它对「放什么过去」相当保守。allow-passthrough on 才能让内嵌图片显示出来:sixel、kitty graphics 和 imgcat 都是以转义序列送达的,否则会被 tmux 吞掉。terminal-features ",*:RGB" 恢复24 位色,没有它,TUI 里的渐变全是色带。而 set-clipboard on 才让复制模式里按 y 直接进手机剪贴板,走 OSC 52,服务器上不用装任何辅助程序。
三行 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 里谁还在想、谁在等你的地方。
大多数 tmux 主题把十六进制颜色写死,所以终端一在明暗之间切换就不对劲了。这一份从不指定调色板以外的颜色:bg=default 让 Term 自己的背景透过状态栏,所有颜色都是 colour0–colour15,取自你在 App 里选的那套主题。
结果就是一条会自己换主题的状态栏。在 Term 里换主题,或者让它跟着系统进深色模式,tmux 在同一次重绘里就跟上了,不用重载配置,也不用再维护第二套配色。当前窗口上的 reverse 对文字用的是同一招:它拿终端背景色当字色,于是浅底深字还是深底浅字,它自己会算。
这里每一条绑定都在省掉一次组合键或一次跨键盘的移动。| 和 - 按它们长的样子分屏。前缀键 + hjkl 在窗格间移动,完全不用碰方向键。前缀键 + t 在当前窗格上弹出一个临时小终端(这是手机上对「我要跑一条命令,但不想打乱代码助手的布局」的答案),exit 就关。
切窗口是 tmux 里最频繁的操作,在手机上也最贵:前缀键再加一个数字,是两层组合。bind -n 把前缀键整个去掉,而 Term 的按键栏有一个粘滞 alt,于是它就变成两次点击。
分屏和新建窗口那几条绑定上的 -c "#{pane_current_path}",让新窗格开在你已经在的那个目录里。没有它,每次分屏都从 $HOME 开始,而你在手机键盘上要打的第一样东西就是一长串 cd。
~/.tmux.conf:不是手机上。tmux 在会话运行的那一端读它。前缀键 + r 重载即可。tmux source-file ~/.tmux.conf
中间那步看着和重载绑定重复,其实不是:前缀键 + r 没法完成第一次加载。这个绑定要等文件被读过才存在,而 tmux 服务端是在启动时读配置的,第一次的时候,那还早于文件存在。于是唯一不能用快捷键完成的重载,恰恰是把这个快捷键装上的那一次。另外注意 source-file 是 tmux 的命令而不是 shell 的:所以在这里要在前面加 tmux,而在配置文件里则不用。
还有两件事得先确认,否则怎么改都不生效:这份配置需要 tmux 3.4 或更新的版本,更老的版本启动时只会报一句「unknown option」,那条设置就静默失效了,用 tmux -V 看一下你装的是哪个。另外在 Debian 与 Ubuntu 上,第一行选用的 tmux-256color 这条 terminfo 描述并不随 tmux 一起装,而是在 ncurses-term 包里,记得一并装上。
延伸阅读: 在手机上用 tmux · SSH 自动恢复 · 常见问题