Files
oak-gpui/crates/task/src/lib.rs
T
Piotr OsiewiczandAnthony 2201b9b116 task: Add task contexts (#8675)
This PR supplements tasks with additional environment variables; ideally
we'll be able to write a task like:
`cargo test -p $ZED_CURRENT_PACKAGE -- $ZED_CURRENT_FUNCTION`
- [x] Flesh out multibuffer interactions
- [x] Add ZED_SYMBOL detection based on tree-sitter queries
- [ ] Add release note and demo
- [x] Figure out a solution for rerun dilemma - should `task: rerun`
reevaluate contexts for tasks?

This PR introduced the following variables:
- ZED_COLUMN - current line column
- ZED_ROW - current line row
and the following, which are available for buffers with associated
files:
- ZED_WORKTREE_ROOT - absolute path to the root of the current worktree.
- ZED_FILE - absolute path to the file
- ZED_SYMBOL - currently selected symbol; should match the last symbol
shown in a symbol breadcrumb (e.g. `mod tests > fn test_task_contexts`
should be equal to ZED_SYMBOL of `test_task_contexts`). Note that this
isn't necessarily a test function or a function at all.

Also, you can use them in `cwd` field of definitions (note though that
we're using https://docs.rs/subst/latest/subst/#features for that, so
don't expect a full shell functionality to work); the syntax should
match up with your typical Unix shell.


Release Notes:

- Added task contexts, which are additional environment variables set by
Zed for task execution; task content is dependent on the state of the
editor at the time the task is spawned.

---------

Co-authored-by: Anthony <anthonyeid7@protonmail.com>
2024-03-04 21:04:53 +01:00

76 lines
3.2 KiB
Rust

//! Baseline interface of Tasks in Zed: all tasks in Zed are intended to use those for implementing their own logic.
#![deny(missing_docs)]
pub mod oneshot_source;
pub mod static_source;
use collections::HashMap;
use gpui::ModelContext;
use std::any::Any;
use std::path::{Path, PathBuf};
use std::sync::Arc;
/// Task identifier, unique within the application.
/// Based on it, task reruns and terminal tabs are managed.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TaskId(pub String);
/// Contains all information needed by Zed to spawn a new terminal tab for the given task.
#[derive(Debug, Clone)]
pub struct SpawnInTerminal {
/// Id of the task to use when determining task tab affinity.
pub id: TaskId,
/// Human readable name of the terminal tab.
pub label: String,
/// Executable command to spawn.
pub command: String,
/// Arguments to the command.
pub args: Vec<String>,
/// Current working directory to spawn the command into.
pub cwd: Option<PathBuf>,
/// Env overrides for the command, will be appended to the terminal's environment from the settings.
pub env: HashMap<String, String>,
/// Whether to use a new terminal tab or reuse the existing one to spawn the process.
pub use_new_terminal: bool,
/// Whether to allow multiple instances of the same task to be run, or rather wait for the existing ones to finish.
pub allow_concurrent_runs: bool,
}
/// Keeps track of the file associated with a task and context of tasks execution (i.e. current file or current function)
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct TaskContext {
/// A path to a directory in which the task should be executed.
pub cwd: Option<PathBuf>,
/// Additional environment variables associated with a given task.
pub env: HashMap<String, String>,
}
/// Represents a short lived recipe of a task, whose main purpose
/// is to get spawned.
pub trait Task {
/// Unique identifier of the task to spawn.
fn id(&self) -> &TaskId;
/// Human readable name of the task to display in the UI.
fn name(&self) -> &str;
/// Task's current working directory. If `None`, current project's root will be used.
fn cwd(&self) -> Option<&str>;
/// Sets up everything needed to spawn the task in the given directory (`cwd`).
/// If a task is intended to be spawned in the terminal, it should return the corresponding struct filled with the data necessary.
fn exec(&self, cx: TaskContext) -> Option<SpawnInTerminal>;
}
/// [`Source`] produces tasks that can be scheduled.
///
/// Implementations of this trait could be e.g. [`StaticSource`] that parses tasks from a .json files and provides process templates to be spawned;
/// another one could be a language server providing lenses with tests or build server listing all targets for a given project.
pub trait TaskSource: Any {
/// A way to erase the type of the source, processing and storing them generically.
fn as_any(&mut self) -> &mut dyn Any;
/// Collects all tasks available for scheduling, for the path given.
fn tasks_for_path(
&mut self,
path: Option<&Path>,
cx: &mut ModelContext<Box<dyn TaskSource>>,
) -> Vec<Arc<dyn Task>>;
}