入门 Zed Industries 2026-09-14 17:42:19 · 0 阅读

第8章 Zed 第8章:执行命令任务详解

Zed 支持通过内置的终端来启动(并重新运行)命令并输出结果。这些命令可以读取一部分有限的 Zed 状态信息(比如当前正在编辑的文件路径,或选中的文本)。

[
  {
    "label": "示例任务",
    "command": "for i in {1..5}; do echo \"Hello $i/5\"; sleep 1; done",
    //"args": [],
    // 命令的环境变量覆盖,将附加到来自设置文件的终端环境中。
    "env": { "foo": "bar" },
    // 生成命令时的当前工作目录,默认为当前项目根目录。
    //"cwd": "/path/to/working/directory",
    // 是否使用新的终端标签页(而非复用现有的)来生成进程,默认为 `false`。
    "use_new_terminal": false,
    // 是否允许运行相同任务的多个实例,还是等待现有实例完成,默认为 `false`。
    "allow_concurrent_runs": false,
    // 命令启动后,如何处理终端面板和标签页:
    // * `always` — 始终显示任务面板,并聚焦其中的相应标签页(默认)
    // * `no_focus` — 始终显示任务面板,添加任务标签页但不聚焦
    // * `never` — 不改变焦点,但在其面板中添加/复用任务标签页
    "reveal": "always",
    // 命令结束后,如何处理终端面板和标签页:
    // * `never` — 命令结束时不执行任何操作(默认)
    // * `always` — 始终隐藏终端标签页,若其是该面板中最后一个标签页则同时隐藏面板
    // * `on_success` — 仅在任务成功时隐藏终端标签页,其他行为类似 `always`
    "hide": "never",
    // 在终端中运行任务时使用的 Shell。
    // 可取以下三种值:
    // 1. (默认) 使用 /etc/passwd 中系统默认终端配置
    //      "shell": "system"
    // 2. 指定程序:
    //      "shell": {
    //        "program": "sh"
    //      }
    // 3. 带参数的程序:
    //     "shell": {
    //         "with_arguments": {
    //           "program": "/bin/bash",
    //           "args": ["--login"]
    //         }
    //     }
    "shell": "system",
    // 是否在生成的任务输出中显示任务行,默认为 `true`。
    "show_summary": true,
    // 是否在生成的任务输出中显示命令行,默认为 `true`。
    "show_command": true,
    // 运行任务前保存哪些已编辑缓冲区:
    // * `all` — 保存所有已编辑缓冲区
    // * `current` — 仅保存当前活动缓冲区
    // * `none` — 不保存任何缓冲区
    "save": "none"
    // 表示内联可运行指示器的标签,或用于一次性生成多个任务。
    // "tags": []
  }
]

任务的使用流程主要由两个操作驱动:{#action task::Spawn} 和 {#action task::Rerun}。{#action task::Spawn} 会弹出一个模态框,显示当前文件中可用的所有任务。{#action task::Rerun} 用于重新运行最近启动的任务。你也可以从任务模态框中重新运行任务。

默认情况下,重新运行任务会复用同一个终端(因为 "use_new_terminal": false 是默认值),但会等待上一个任务结束后再开始新的任务(因为 "allow_concurrent_runs": false 是默认值)。

保持 "use_new_terminal": false 并设置 "allow_concurrent_runs": true,即可在重新运行时取消之前的任务。

任务模板

任务可以定义在以下位置:

  • 全局 tasks.json 文件中;此类任务在你操作的所有 Zed 项目中均可用。该文件通常位于 ~/.config/zed/tasks.json。你可以通过 {#action zed::OpenTasks} 操作来编辑它们。
  • 工作区特定的(本地).zed/tasks.json 文件中;此类任务仅在包含该工作区的项目中可用。你可以通过 {#action zed::OpenProjectTasks} 操作来编辑工作区特定的任务。
  • 通过 一次性任务 即时创建。这些任务是项目特定的,不会跨会话持久化。
  • 由语言扩展定义。

变量

Zed 任务的行为与你的 Shell 类似;这意味着你也可以通过类似 Shell 的 $VAR_NAME 语法引用环境变量。为了方便起见,系统还设置了一些额外的环境变量。这些变量允许你从当前编辑器中获取信息并在任务中使用。可用的变量如下:

  • ZED_COLUMN:当前行的列号
  • ZED_ROW:当前行的行号
  • ZED_FILE:当前打开文件的绝对路径(例如 /Users/my-user/path/to/project/src/main.rs
  • ZED_FILENAME:当前打开文件的文件名(例如 main.rs
  • ZED_DIRNAME:当前打开文件的绝对路径,但不包含文件名(例如 /Users/my-user/path/to/project/src
  • ZED_RELATIVE_FILE:当前打开文件的路径,相对于 ZED_WORKTREE_ROOT(如 src/main.rs
  • ZED_RELATIVE_DIR:当前打开文件所在目录的路径,相对于 ZED_WORKTREE_ROOT(如 src
  • ZED_STEM:当前打开文件的主文件名(不含扩展名,如 main
  • ZED_SYMBOL:当前选中的符号,应与面包屑中最后显示的符号一致(如 mod tests > fn test_task_contexts
  • ZED_SELECTED_TEXT:当前选中的文本
  • ZED_LANGUAGE:当前打开缓冲区的语言(如 RustPythonShell Script
  • ZED_WORKTREE_ROOT:当前工作树根目录的绝对路径(如 /Users/my-user/path/to/project
  • ZED_MAIN_GIT_WORKTREE:主 git worktree 工作目录的绝对路径。对于普通检出,它与 ZED_WORKTREE_ROOT 相同;对于关联的 git worktree,则指向原始仓库的工作目录。
  • ZED_CUSTOM_RUST_PACKAGE:(仅限 Rust)$ZED_FILE 源文件所属父包的名称。

在任务中使用变量时,需在变量前加美元符号($):

{
  "label": "echo current file's path",
  "command": "echo $ZED_FILE"
}

还可以使用详细语法,为不可用的变量指定默认值:${ZED_FILE:default_value}

这些环境变量也可以用在任务的 cwdargslabel 字段中。

变量引用

当路径中包含空格或其他特殊字符时,请确保对变量进行正确的转义。

例如,下面这种写法在路径包含空格时会失败:

{
  "label": "stat current file",
  "command": "stat $ZED_FILE"
}

应改用以下写法:

{
  "label": "stat current file",
  "command": "stat",
  "args": ["$ZED_FILE"]
}

或者显式地使用转义引号,例如:

{
  "label": "stat current file",
  "command": "stat \"$ZED_FILE\""
}

基于变量的任务筛选

如果在确定任务列表时变量尚未存在,包含该变量的任务定义会被过滤掉。 例如,只有在存在文本选区时,以下任务才会出现在任务弹窗中:

{
  "label": "selected text",
  "command": "echo \"$ZED_SELECTED_TEXT\""
}

可以为这类变量设置默认值,以确保此类任务始终显示:

{
  "label": "selected text with default",
  "command": "echo \"${ZED_SELECTED_TEXT:no text selected}\""
}

一次性任务

通过 {#action task::Spawn} 打开的同一个任务弹窗支持执行任意类 bash 命令:在弹窗文本框中输入命令,然后按 opt-enter 即可执行。

任务弹窗会在整个会话期间保留这些临时命令,如果这些是最后执行的任务,{#action task::Rerun} 也可以重新运行它们。

你还可以在弹窗中调整当前选中的任务(tab 是默认的键位绑定)。这样做会将该任务的命令放入提示框,随后你可以编辑并将其作为一次性任务执行。

瞬时任务

通过弹窗生成任务时可以使用 cmd 修饰键;这样生成的任务不会增加使用计数(因此它们不会通过 {#action task::Rerun} 重新生成,且在任务弹窗中的排名也不会很高)。 瞬时任务的预期用途是配合持续使用 {#action task::Rerun} 以保持工作流连贯。

更多任务重新运行控制

默认情况下,任务只捕获一次变量到上下文中,并且始终重新运行这个“已解析的任务”。

可以通过给任务设置 "reevaluate_context" 参数来控制此行为:将其设为 true 会强制任务在每次运行前重新评估。

{
  "context": "Workspace",
  "bindings": {
    "alt-t": ["task::Rerun", { "reevaluate_context": true }]
  }
}

为任务配置自定义快捷键

你可以通过为 task::Spawn 添加额外参数来为任务定义自定义快捷键。例如,若想将前述的 echo current file's path 任务绑定到 alt-g,需在 keymap.json 文件中加入以下配置:

{
  "context": "Workspace",
  "bindings": {
    "alt-g": ["task::Spawn", { "task_name": "echo current file's path" }]
  }
}

这些任务还支持指定“target”以控制启动后的任务展示位置。若希望将终端应用启动在中央区域,此功能尤为实用:

// In tasks.json
{
  "label": "start lazygit",
  "command": "lazygit -p $ZED_WORKTREE_ROOT"
}
// In keymap.json
{
  "context": "Workspace",
  "bindings": {
    "alt-g": [
      "task::Spawn",
      { "task_name": "start lazygit", "reveal_target": "center" }
    ]
  }
}

Hooks

除了手动启动,任务还可以通过在任务模板的 hooks 字段中添加钩子,配置为响应特定 Zed 事件自动运行。当事件触发时,匹配该钩子的任务会被解析并启动。

目前支持的 Hook 如下:

  • create_worktree — 在 Zed 创建新的关联 Git worktree 后执行,无论是通过 CLI 还是从worktree 选择器操作均适用。此时启动的任务中,ZED_WORKTREE_ROOT 指向新创建的 worktree,而 ZED_MAIN_GIT_WORKTREE 指向原仓库的工作目录。这一特性非常适合用于复制未跟踪文件(如 .env)或运行针对每个 worktree 的初始化命令。

Hook 任务和手动触发的任务一样,都是从全局和工作区本地的 tasks.json 文件中解析的,多个任务可以注册同一个 hook,触发时全部执行。Hook 任务同样可以使用常规的任务配置字段——cwdenvrevealhide 等——因此你可以控制任务运行时终端界面的显示方式。

[
  {
    "label": "copy .env into new worktree",
    "command": "cp",
    "args": ["$ZED_MAIN_GIT_WORKTREE/.env", "$ZED_WORKTREE_ROOT/.env"],
    "hooks": ["create_worktree"],
    "reveal": "no_focus",
    "hide": "on_success"
  }
]

定义了 hooks 的任务仍然会像其他任务一样出现在任务面板中,因此同一个模板也可以用于手动运行。

自定义 Git 命令

Git Graph 支持在提交的右键菜单中运行自定义 Git 命令任务。 要添加命令,需在全局 tasks.json 文件中定义一个带 git-command 标签的任务(目前不支持工作区本地任务)。 从提交的右键菜单打开时,任务会根据所选提交和仓库进行解析,默认从所选仓库的根目录运行。 右键点击一个 ref 标签(分支、远程 ref 或 tag)会打开 ref 专属的右键菜单,此时任务还会通过 ZED_GIT_REF 额外解析所点击的 ref。

Git Graph 命令任务支持以下 Git 专属的任务变量。 这些变量仅在解析 Git Graph 命令任务时提供。 其他任务变量,如 ZED_FILEZED_SELECTED_TEXTZED_WORKTREE_ROOTZED_MAIN_GIT_WORKTREE,不会提供给 Git Graph 命令任务,除非它们设置了默认值。

  • ZED_GIT_SHA:所选提交的完整 SHA。
  • ZED_GIT_SHA_SHORT:所选提交的短 SHA。
  • ZED_GIT_REPOSITORY_NAME:所选 Git 仓库的名称。
  • ZED_GIT_REPOSITORY_PATH:所选 Git 仓库工作目录的绝对路径。
  • ZED_GIT_REF:所点击的 ref 名称(分支、远程 ref 或标签)。仅当菜单从 ref 标签打开时提供。

示例:

[
  {
    "label": "包含提交 $ZED_GIT_SHA_SHORT 的分支",
    "command": "git",
    "args": ["branch", "-a", "--contains", "$ZED_GIT_SHA"],
    "tags": ["git-command"]
  },
  {
    "label": "检出 $ZED_GIT_REF",
    "command": "git",
    "args": ["checkout", "$ZED_GIT_REF"],
    "tags": ["git-command"]
  }
]

VS Code 任务格式

.vscode/tasks.json 导入 VS Code 任务时,可以省略 label 字段。Zed 会根据任务类型自动生成功能标签:

  • npm 任务npm: <脚本名>(例如 npm: start
  • gulp 任务gulp: <任务名>(例如 gulp: build
  • shell 任务:直接使用 command 字符串(例如 echo hello),如果命令为空则显示 shell
  • 无类型任务Untitled Task

带有自动生成功能标签的任务文件示例:

{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "npm",
      "script": "start"
    },
    {
      "type": "shell",
      "command": "cargo build --release"
    }
  ]
}

这些任务在任务选择器中显示为“npm: start”和“cargo build --release”。你也可以通过提供显式的 label 字段来覆盖自动生成的标签。

将可运行标签绑定到任务模板

Zed 支持通过工作区级和全局 tasks.json 文件覆盖内联可运行指示器的默认操作,优先级如下:

  1. 工作区 tasks.json
  2. 全局 tasks.json
  3. 语言提供的标签绑定(默认)。

要为任务添加标签,请将可运行标签名添加到任务模板的 tags 字段中:

{
  "label": "echo current file's path",
  "command": "echo $ZED_FILE",
  "tags": ["rust-test"]
}

通过这种方式,你可以更改在可运行程序指示器中显示的任务。

绑定到可运行程序的任务快捷键

当拥有一个绑定到可运行程序的任务定义时,你可以使用 代码操作 快速执行它。你可以通过 {#action editor::ToggleCodeActions} 命令或 cmd-. / ctrl-. 快捷键触发这些操作。你的任务会出现在下拉列表的首位。如果该行没有额外的代码操作,任务将立即运行。

运行 Bash 脚本

你可以直接从 Zed 运行 bash 脚本。当你打开一个 .sh.bash 文件时,Zed 会自动检测该脚本为可运行,并将其列入任务选择器中。

要运行 bash 脚本:

  1. 使用 {#kb command_palette::Toggle} 打开命令面板
  2. 搜索 "task" 并选择 task: spawn
  3. 从列表中选择该脚本

Bash 脚本会被标记为 bash-script,允许你在任务配置中对其进行搜索过滤或引用。

如果需要传递参数或自定义执行环境,请在你的 .zed/tasks.json 文件中添加任务配置:

[
  {
    "label": "run my-script.sh with args",
    "command": "./my-script.sh",
    "args": ["--verbose", "--output=results.txt"],
    "tags": ["bash-script"]
  }
]

Shell 初始化

当 Zed 运行任务时,它会在登录 shell(login shell)中启动命令。这确保了在执行任务之前,你的 shell 初始化文件(如 .bash_profile.zshrc 等)已经被加载。

这种机制使任务能够访问你在 shell 配置文件中设置的环境变量、别名和 PATH 修改。如果任务未能找到某个在你的终端中可以正常运行的命令,请检查你的 shell 配置文件是否正确设置。

若要覆盖任务使用的 shell,请配置 terminal.shell 设置项:

{
  "terminal": {
    "shell": {
      "program": "/bin/zsh"
    }
  }
}

完整的 shell 配置选项请参阅 终端配置文档。

评论 (0)