🔧 在 VS Code 中自动集成 tmux,实现持久会话

发布: (2026年1月19日 GMT+8 18:13)
4 min read
原文: Dev.to

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_PIDTERM_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 作为会话管理器,这种集成可以消除摩擦,显著提升日常工作流。

你是如何在不同项目之间管理终端会话的?

Back to Blog

相关文章

阅读更多 »