# tmux

Tessera 原生支持 tmux 的控制模式（`tmux -CC`）：窗口和窗格都是一等的界面
元素，而不是文本透传。它要求服务器上已安装 `tmux`。

## 为什么用 tmux

在由 tmux 支撑的会话中，shell 运行在服务器上。关闭 Tessera、断开 Wi-Fi、
切换到蜂窝网络、让设备休眠 —— 这些都不会终止你的工作。重新连接后，你会回到
离开时的原处。

## 接入

**自动 tmux** 启动模式会接入（或创建）该主机专属的会话，其名称是确定性的
`tessera-XXXXXXXX`，在应用重装后仍然记得。**具名 tmux** 则接入你指定的会话
名。两者都在[主机编辑器](https://bambouville.com/docs/zh-hans/connections/#启动模式)中按主机设置。

确定性的名称意味着，使用同一条主机记录的两台设备会落入*同一个* tmux 会话
—— 这正是让它们之间[接力会话](https://bambouville.com/docs/zh-hans/continuity/)如此顺畅的原因。

如果 tmux 起不来，Tessera 不会让你干等：主机未安装 tmux、tmux 会话启动失败，
或者 dotfiles 在登录时已经 `exec tmux` —— 这些情况都会把你送入一个纯 shell，
并附上说明原因的横幅（“此主机在登录时会自行启动 tmux —— 将该会话作为纯终端
显示”）。参见[连接卡住时](https://bambouville.com/docs/zh-hans/connections/#连接卡住时)。

## 窗口

tmux 窗口按索引顺序以标签形式出现在会话的顶栏中。栏中的 **+** 按钮可以打开
一个新窗口；当标签多到放不下时，一个溢出控件会列出全部窗口。每个标签都带有
关闭控件，窗口可以从 **⌘K** 面板重命名 —— 该名称对接入此会话的所有客户端
都生效。

| 快捷键 | 操作 |
| --- | --- |
| **⌘T** | 新建窗口 |
| **⇧⌘W** | 关闭窗格 / 窗口 |
| **⇧⌘[** / **⇧⌘]** | 上一个 / 下一个窗口 |
| **⌘1** – **⌘9** | 跳转到窗口 1–9 |

## 窗格

窗格是真正的 tmux 窗格，通过控制模式驱动。

| 快捷键 | 操作 |
| --- | --- |
| **⌘D** | 左右分割 |
| **⇧⌘D** | 上下分割 |
| **⌘[** / **⌘]** | 循环切换窗格 |
| **⇧⌘↩** | 缩放 / 取消缩放窗格 |

![Tessera 中的一个 tmux 会话，顶部横排三个窗口标签，下方是左右并排的两个窗格：左侧的 shell 显示 git log 输出，右侧运行着 htop。](https://bambouville.com/docs/assets/img/tmux-panes.png)

*同一个 tmux 窗口中的两个窗格，会话的窗口以标签形式排在上方。每个窗格都有自己的标题栏和关闭控件。*


## 在 iPhone 上

从 iPhone 接入绝不会重排你的布局：分割和缩放状态会保持大屏幕上留下的样子，
手机则通过切换器一次显示一个窗格。参见 [iPhone 上的 Tessera](https://bambouville.com/docs/zh-hans/iphone/)。

## mosh + tmux

在 mosh 下，终端跑在 UDP 上，而 tmux 标签使用第二条 SSH 侧信道。对 mosh 主机
来说，这条侧信道同样承载着[端口转发](https://bambouville.com/docs/zh-hans/port-forwarding/#mosh-与转发) ——
以及[真正的回滚缓冲](https://bambouville.com/docs/zh-hans/mosh/#真正的回滚缓冲)。

## 响铃

正是 tmux 控制模式的这套接线，让 Tessera 能把终端响铃转发到
[通知](https://bambouville.com/docs/zh-hans/notifications/) —— 按窗口区分，并标记出发出响铃的标签。

## 注意事项

- 环境变量和启动脚本片段只在 tmux 会话启动时执行。修改之后，请在服务器上
  结束该会话（`tmux kill-session`），才能应用更改。
- 同时从 Tessera 和另一个客户端接入是可以的，但两个客户端会共用同一批窗口
  —— 这是 tmux 的行为，不是缺陷。当另一个客户端是你自己的 iPhone 或 iPad
  时，Tessera 会妥善处理这种争用 —— 参见
  [取回控制权](https://bambouville.com/docs/zh-hans/continuity/#取回控制权)。
- 如果在大量重绘之后输出看起来卡住了，**⌘R**（iPad）可以强制完整重绘。而
  如果某个会话接入后没有绘制画面，Tessera 会明确说明（“按任意键将其唤醒”）
  —— 你的第一次按键会让屏幕显示出来。
