This PR also introduces built-in tasks for Rust and Elixir. Note that this is not a precedent for future PRs to include tasks for more languages; we simply want to find the rough edges with tasks & language integrations before proceeding to task contexts provided by extensions. As is, we'll load tasks for all loaded languages, so in order to get Elixir tasks, you have to open an Elixir buffer first. I think it sort of makes sense (though it's not ideal), as in the future where extensions do provide their own tasks.json, we'd like to limit the # of tasks surfaced to the user to make them as relevant to the project at hand as possible. Release Notes: - Added built-in tasks for Rust and Elixir files.
88 lines
2.1 KiB
Rust
88 lines
2.1 KiB
Rust
//! A source of tasks, based on ad-hoc user command prompt input.
|
|
|
|
use std::sync::Arc;
|
|
|
|
use crate::{
|
|
static_source::RevealStrategy, SpawnInTerminal, Task, TaskContext, TaskId, TaskSource,
|
|
};
|
|
use gpui::{AppContext, Context, Model};
|
|
|
|
/// A storage and source of tasks generated out of user command prompt inputs.
|
|
pub struct OneshotSource {
|
|
tasks: Vec<Arc<dyn Task>>,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
struct OneshotTask {
|
|
id: TaskId,
|
|
}
|
|
|
|
impl OneshotTask {
|
|
fn new(prompt: String) -> Self {
|
|
Self { id: TaskId(prompt) }
|
|
}
|
|
}
|
|
|
|
impl Task for OneshotTask {
|
|
fn id(&self) -> &TaskId {
|
|
&self.id
|
|
}
|
|
|
|
fn name(&self) -> &str {
|
|
&self.id.0
|
|
}
|
|
|
|
fn cwd(&self) -> Option<&str> {
|
|
None
|
|
}
|
|
|
|
fn exec(&self, cx: TaskContext) -> Option<SpawnInTerminal> {
|
|
if self.id().0.is_empty() {
|
|
return None;
|
|
}
|
|
let TaskContext {
|
|
cwd,
|
|
task_variables,
|
|
} = cx;
|
|
Some(SpawnInTerminal {
|
|
id: self.id().clone(),
|
|
label: self.name().to_owned(),
|
|
command: self.id().0.clone(),
|
|
args: vec![],
|
|
cwd,
|
|
env: task_variables.0,
|
|
use_new_terminal: Default::default(),
|
|
allow_concurrent_runs: Default::default(),
|
|
reveal: RevealStrategy::default(),
|
|
})
|
|
}
|
|
}
|
|
|
|
impl OneshotSource {
|
|
/// Initializes the oneshot source, preparing to store user prompts.
|
|
pub fn new(cx: &mut AppContext) -> Model<Box<dyn TaskSource>> {
|
|
cx.new_model(|_| Box::new(Self { tasks: Vec::new() }) as Box<dyn TaskSource>)
|
|
}
|
|
|
|
/// Spawns a certain task based on the user prompt.
|
|
pub fn spawn(&mut self, prompt: String) -> Arc<dyn Task> {
|
|
let ret = Arc::new(OneshotTask::new(prompt));
|
|
self.tasks.push(ret.clone());
|
|
ret
|
|
}
|
|
}
|
|
|
|
impl TaskSource for OneshotSource {
|
|
fn as_any(&mut self) -> &mut dyn std::any::Any {
|
|
self
|
|
}
|
|
|
|
fn tasks_for_path(
|
|
&mut self,
|
|
_path: Option<&std::path::Path>,
|
|
_cx: &mut gpui::ModelContext<Box<dyn TaskSource>>,
|
|
) -> Vec<Arc<dyn Task>> {
|
|
self.tasks.clone()
|
|
}
|
|
}
|