🔧 在 VS Code 中自动集成 tmux,实现持久会话
Source: Dev.to
🟢 原生方案(显而易见的方案)
VS Code 允许你这样配置终端配置文件:
// "terminal.integrated.profiles.osx": {
// "tmux-shell": {
// "path": "tmux",
// "args": ["new-session", "-A", "-s", "${workspaceFolderBasename}"]
// }
// },
// "terminal.integrated.defaultProfile.osx": "tmux-shell"
此方案的优势
- 一个工作区 → 一个 tmux 会话(通过
-A自动持久化) - 配置简洁、清晰
- 不涉及脚本
对许多使用场景来说,这已经足够且优雅。
🔴 真正的限制
settings.json 不支持条件逻辑。像 ${workspaceFolderBasename} 这样的变量:
- ✅ 会被展开
- ❌ 不能进行转换
- ❌ 不能使用正则表达式
- ❌ 不能进行分组或规范化
将多个文件夹分组到单个会话中
设想你有多个相关项目,想在同一个共享的 tmux 会话中工作,以保留上下文、窗格和布局:
fe-dashboard, fe-admin, be-api, be-auth
使用原生配置时,每个文件夹都会强制创建自己的 tmux 会话,即使它们在概念上属于同一个“工作上下文”。你无法表达类似的规则:
“如果文件夹以
fe-或be-开头,使用work会话”
这在 VS Code 的终端配置中根本无法表示。
🧠 稳健的方案:将逻辑移至 shell
VS Code 会注入诸如 VSCODE_PID 和 TERM_PROGRAM=vscode 的环境变量,这让你能够可靠地检测终端是否由 VS Code 启动。随后,由 shell 决定行为。
使用 fish 的示例:
if set -q VSCODE_PID; or test "$TERM_PROGRAM" = "vscode"
if not set -q TMUX
set -l folder_name (basename (pwd))
if string match -qr "^fe-.*" -- $folder_name
set folder_name "work"
else if string match -qr "^be-.*" -- $folder_name
set folder_name "work"
else
set folder_name "projects"
end
# tmux new-session -A -s $folder_name &>/dev/null
end
end
VS Code 只充当启动器;决策逻辑仍然位于它应在的地方:shell。
🚀 实际收益
- 按意义而非字面文件夹名对项目进行分组
- 关闭 VS Code 后仍可复用 tmux 会话
- 避免会话重复创建
- 保持窗格和布局的持久性
- 无需插件、无须扩展——仅使用 tmux 与标准环境变量
⚠️ 注意事项
- 适用于集成终端,不适用于外部终端。
VSCODE_PID并非正式 API,但多年来一直保持稳定。- 同样的模式同样适用于 bash 或 zsh。
如果你把 VS Code 当作编辑器,却用 tmux 作为会话管理器,这种集成可以消除摩擦,显著提升日常工作流。
你是如何在不同项目之间管理终端会话的?