tasks.md

  1# Tasks
  2
  3Zed supports ways to spawn (and rerun) commands using its integrated terminal to output the results. These commands can read a limited subset of Zed state (such as a path to the file currently being edited or selected text).
  4
  5```json
  6[
  7  {
  8    "label": "Example task",
  9    "command": "for i in {1..5}; do echo \"Hello $i/5\"; sleep 1; done",
 10    //"args": [],
 11    // Env overrides for the command, will be appended to the terminal's environment from the settings.
 12    "env": { "foo": "bar" },
 13    // Current working directory to spawn the command into, defaults to current project root.
 14    //"cwd": "/path/to/working/directory",
 15    // Whether to use a new terminal tab or reuse the existing one to spawn the process, defaults to `false`.
 16    "use_new_terminal": false,
 17    // Whether to allow multiple instances of the same task to be run, or rather wait for the existing ones to finish, defaults to `false`.
 18    "allow_concurrent_runs": false,
 19    // What to do with the terminal pane and tab, after the command was started:
 20    // * `always` — always show the terminal pane, add and focus the corresponding task's tab in it (default)
 21    // * `no_focus` — always show the terminal pane, add/reuse the task's tab there, but don't focus it
 22    // * `never` — avoid changing current terminal pane focus, but still add/reuse the task's tab there
 23    "reveal": "always",
 24    // What to do with the terminal pane and tab, after the command had finished:
 25    // * `never` — Do nothing when the command finishes (default)
 26    // * `always` — always hide the terminal tab, hide the pane also if it was the last tab in it
 27    // * `on_success` — hide the terminal tab on task success only, otherwise behaves similar to `always`
 28    "hide": "never",
 29    // Which shell to use when running a task inside the terminal.
 30    // May take 3 values:
 31    // 1. (default) Use the system's default terminal configuration in /etc/passwd
 32    //      "shell": "system"
 33    // 2. A program:
 34    //      "shell": {
 35    //        "program": "sh"
 36    //      }
 37    // 3. A program with arguments:
 38    //     "shell": {
 39    //         "with_arguments": {
 40    //           "program": "/bin/bash",
 41    //           "args": ["--login"]
 42    //         }
 43    //     }
 44    "shell": "system"
 45  }
 46]
 47```
 48
 49There are two actions that drive the workflow of using tasks: `task: spawn` and `task: rerun`
 50`task: spawn` opens a modal with all available tasks in the current file.
 51`task: rerun` reruns the most-recently spawned task. You can also rerun tasks from task modal.
 52
 53By default, rerunning tasks reuses the same terminal (due to the `"use_new_terminal": false` default) but waits for the previous task to finish before start (due to the `"allow_concurrent_runs": false` default).
 54
 55Keep `"use_new_terminal": false` and set `"allow_concurrent_runs": true` to allow cancelling previous tasks on rerun.
 56
 57## Task templates
 58
 59Tasks can be defined:
 60
 61- in global `tasks.json` file; such tasks are available in all Zed projects you work on. This file is usually located in `~/.config/zed/tasks.json`. You can edit them by using `zed: open tasks` action.
 62- in worktree-specific (local) `.zed/tasks.json` file; such tasks are available only when working on a project with that worktree included. You can edit worktree-specific tasks by using `zed: open local tasks`.
 63- on the fly with [oneshot tasks](#oneshot-tasks). These tasks are project-specific and do not persist across sections.
 64- by language extension.
 65
 66## Variables
 67
 68Zed tasks act just like your shell; that also means that you can reference environmental variables via sh-esque `$VAR_NAME` syntax. A couple of additional environmental variables are set for your convenience.
 69These variables allow you to pull information from the current editor and use it in your tasks. The following variables are available:
 70
 71- `ZED_COLUMN`: current line column
 72- `ZED_ROW`: current line row
 73- `ZED_FILE`: absolute path of the currently opened file (e.g. `/Users/my-user/path/to/project/src/main.rs`)
 74- `ZED_FILENAME`: filename of the currently opened file (e.g. `main.rs`)
 75- `ZED_DIRNAME`: absolute path of the currently opened file with file name stripped (e.g. `/Users/my-user/path/to/project/src`)
 76- `ZED_RELATIVE_FILE`: path of the currently opened file, relative to `ZED_WORKTREE_ROOT` (e.g. `src/main.rs`)
 77- `ZED_STEM`: stem (filename without extension) of the currently opened file (e.g. `main`)
 78- `ZED_SYMBOL`: currently selected symbol; should match the last symbol shown in a symbol breadcrumb (e.g. `mod tests > fn test_task_contexts`)
 79- `ZED_SELECTED_TEXT`: currently selected text
 80- `ZED_WORKTREE_ROOT`: absolute path to the root of the current worktree. (e.g. `/Users/my-user/path/to/project`)
 81- `ZED_CUSTOM_RUST_PACKAGE`: (Rust-specific) name of the parent package of $ZED_FILE source file.
 82
 83To use a variable in a task, prefix it with a dollar sign (`$`):
 84
 85```json
 86{
 87  "label": "echo current file's path",
 88  "command": "echo $ZED_FILE"
 89}
 90```
 91
 92You can also use verbose syntax that allows specifying a default if a given variable is not available: `${ZED_FILE:default_value}`
 93
 94These environmental variables can also be used in tasks `cwd`, `args` and `label` fields.
 95
 96## Oneshot tasks
 97
 98The same task modal opened via `task: spawn` supports arbitrary bash-like command execution: type a command inside the modal text field, and use `opt-enter` to spawn it.
 99
100Task modal will persist list of those command for current Zed session, `task: rerun` will also rerun such tasks if they were the last ones spawned.
101
102You can also adjust currently selected task in a modal (`tab` is a default key binding). Doing so will put its command into a prompt that can then be edited & spawned as an oneshot task.
103
104### Ephemeral tasks
105
106You can use cmd modifier when spawning a task via a modal; tasks spawned this way will not have their usage count increased (thus, they will not be respawned with `task: rerun` and they won't be have a high rank in task modal).
107The intended use of ephemeral tasks is to stay in the flow with continuous `task: rerun` usage.
108
109## Custom keybindings for tasks
110
111You can define your own keybindings for your tasks via additional argument to `task::Spawn`. If you wanted to bind the aforementioned `echo current file's path` task to `alt-g`, you would add the following snippet in your [`keymap.json`](./key-bindings.md) file:
112
113```json
114{
115  "context": "Workspace",
116  "bindings": {
117    "alt-g": ["task::Spawn", { "task_name": "echo current file's path" }]
118  }
119}
120```
121
122## Binding runnable tags to task templates
123
124Zed supports overriding default action for inline runnable indicators via workspace-local and global `tasks.json` file with the following precedence hierarchy:
125
1261. Workspace `tasks.json`
1272. Global `tasks.json`
1283. Language-provided tag bindings (default).
129
130To tag a task, add the runnable tag name to `tags` field on task template:
131
132```json
133{
134  "label": "echo current file's path",
135  "command": "echo $ZED_FILE",
136  "tags": ["rust-test"]
137}
138```
139
140In doing so, you can change which task is shown in runnables indicator.