自定义命令

通过在项目根目录或 ~/.config/cmux/ 中添加 cmux.json 文件来定义自定义命令和工作区布局。命令将显示在命令面板中。

文件位置

cmux 在两个地方查找配置:

  • 按项目: ./cmux.json位于项目目录中,优先级更高
  • 全局: ~/.config/cmux/cmux.json适用于所有项目,补充本地未定义的命令
本地命令会覆盖同名的全局命令。

更改会自动生效 — 无需重启。

架构

cmux.json 文件包含一个 commands 数组。每个命令要么是简单的 shell 命令,要么是完整的工作区定义:

cmux.json
{
  "commands": [
    {
      "name": "Start Dev",
      "keywords": ["dev", "start"],
      "workspace": { ... }
    },
    {
      "name": "Run Tests",
      "command": "npm test",
      "confirm": true
    }
  ]
}

简单命令

简单命令在当前聚焦的终端中运行 shell 命令:

cmux.json
{
  "commands": [
    {
      "name": "Run Tests",
      "keywords": ["test", "check"],
      "command": "npm test",
      "confirm": true
    }
  ]
}

字段

  • name在命令面板中显示(必填)
  • description可选描述
  • keywords命令面板的额外搜索词
  • command在聚焦终端中运行的 shell 命令
  • confirm运行前显示确认对话框

简单命令在当前聚焦终端的工作目录中运行。如果命令依赖于项目相对路径,请在前面加上 cd "$(git rev-parse --show-toplevel)" && 以从仓库根目录运行,或使用 cd /your/path && 指定任意目录。

工作区命令

工作区命令会创建一个新工作区,具有自定义的分屏、终端和浏览器面板布局:

cmux.json
{
  "commands": [
    {
      "name": "Dev Environment",
      "keywords": ["dev", "fullstack"],
      "restart": "confirm",
      "workspace": {
        "name": "Dev",
        "cwd": ".",
        "layout": {
          "direction": "horizontal",
          "split": 0.5,
          "children": [
            {
              "pane": {
                "surfaces": [
                  {
                    "type": "terminal",
                    "name": "Frontend",
                    "command": "npm run dev",
                    "focus": true
                  }
                ]
              }
            },
            {
              "pane": {
                "surfaces": [
                  {
                    "type": "terminal",
                    "name": "Backend",
                    "command": "cargo watch -x run",
                    "cwd": "./server",
                    "env": { "RUST_LOG": "debug" }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  ]
}

工作区字段

  • name工作区标签页名称(默认为命令名称)
  • cwd工作区的工作目录
  • color工作区标签页颜色
  • layout定义分屏和面板的布局树

重启行为

控制当同名工作区已存在时的行为:

  • "ignore"切换到现有工作区(默认)
  • "recreate"无需询问直接关闭并重新创建
  • "confirm"重新创建前询问用户

布局树

布局树使用递归分割节点定义面板的排列方式:

分割节点

将空间分割为两个子节点:

  • direction"horizontal" "vertical"
  • split分割线位置,从 0.1 到 0.9(默认 0.5)
  • children恰好两个子节点(分割或面板)

面板节点

包含一个或多个 surface(面板内标签页)的叶节点。

Surface 定义

面板中的每个 surface 可以是终端或浏览器:

  • type"terminal" "browser"
  • name自定义标签页标题
  • command创建时自动运行的 shell 命令(仅限终端)
  • cwd此 surface 的工作目录
  • env以键值对形式表示的环境变量
  • url要打开的 URL(仅限浏览器)
  • focus创建后聚焦此 surface

工作目录解析

  • . 省略工作区工作目录
  • ./subdir相对于工作区工作目录
  • ~/path展开到主目录
  • 绝对路径按原样使用

完整示例

cmux.json
{
  "commands": [
    {
      "name": "Web Dev",
      "description": "Docs site with live preview",
      "keywords": ["web", "docs", "next", "frontend"],
      "restart": "confirm",
      "workspace": {
        "name": "Web Dev",
        "cwd": "./web",
        "color": "#3b82f6",
        "layout": {
          "direction": "horizontal",
          "split": 0.5,
          "children": [
            {
              "pane": {
                "surfaces": [
                  {
                    "type": "terminal",
                    "name": "Next.js",
                    "command": "npm run dev",
                    "focus": true
                  }
                ]
              }
            },
            {
              "direction": "vertical",
              "split": 0.6,
              "children": [
                {
                  "pane": {
                    "surfaces": [
                      {
                        "type": "browser",
                        "name": "Preview",
                        "url": "http://localhost:3777"
                      }
                    ]
                  }
                },
                {
                  "pane": {
                    "surfaces": [
                      {
                        "type": "terminal",
                        "name": "Shell",
                        "env": { "NODE_ENV": "development" }
                      }
                    ]
                  }
                }
              ]
            }
          ]
        }
      }
    },
    {
      "name": "Debug Log",
      "description": "Tail the debug event log from the running dev app",
      "keywords": ["log", "debug", "tail", "events"],
      "restart": "ignore",
      "workspace": {
        "name": "Debug Log",
        "layout": {
          "direction": "horizontal",
          "split": 0.5,
          "children": [
            {
              "pane": {
                "surfaces": [
                  {
                    "type": "terminal",
                    "name": "Events",
                    "command": "tail -f /tmp/cmux-debug.log",
                    "focus": true
                  }
                ]
              }
            },
            {
              "pane": {
                "surfaces": [
                  {
                    "type": "terminal",
                    "name": "Shell"
                  }
                ]
              }
            }
          ]
        }
      }
    },
    {
      "name": "Setup",
      "description": "Initialize submodules and build dependencies",
      "keywords": ["setup", "init", "install"],
      "command": "./scripts/setup.sh",
      "confirm": true
    },
    {
      "name": "Reload",
      "description": "Build and launch the debug app tagged to the current branch",
      "keywords": ["reload", "build", "run", "launch"],
      "command": "./scripts/reload.sh --tag $(git branch --show-current)"
    },
    {
      "name": "Run Unit Tests",
      "keywords": ["test", "unit"],
      "command": "./scripts/test-unit.sh",
      "confirm": true
    }
  ]
}