oneshot_source.rs

 1//! A source of tasks, based on ad-hoc user command prompt input.
 2
 3use std::sync::Arc;
 4
 5use crate::{SpawnInTerminal, Task, TaskContext, TaskId, TaskSource};
 6use gpui::{AppContext, Context, Model};
 7
 8/// A storage and source of tasks generated out of user command prompt inputs.
 9pub struct OneshotSource {
10    tasks: Vec<Arc<dyn Task>>,
11}
12
13#[derive(Clone)]
14struct OneshotTask {
15    id: TaskId,
16}
17
18impl OneshotTask {
19    fn new(prompt: String) -> Self {
20        Self { id: TaskId(prompt) }
21    }
22}
23
24impl Task for OneshotTask {
25    fn id(&self) -> &TaskId {
26        &self.id
27    }
28
29    fn name(&self) -> &str {
30        &self.id.0
31    }
32
33    fn cwd(&self) -> Option<&str> {
34        None
35    }
36
37    fn exec(&self, cx: TaskContext) -> Option<SpawnInTerminal> {
38        if self.id().0.is_empty() {
39            return None;
40        }
41        let TaskContext { cwd, env } = cx;
42        Some(SpawnInTerminal {
43            id: self.id().clone(),
44            label: self.name().to_owned(),
45            command: self.id().0.clone(),
46            args: vec![],
47            cwd,
48            env,
49            use_new_terminal: Default::default(),
50            allow_concurrent_runs: Default::default(),
51        })
52    }
53}
54
55impl OneshotSource {
56    /// Initializes the oneshot source, preparing to store user prompts.
57    pub fn new(cx: &mut AppContext) -> Model<Box<dyn TaskSource>> {
58        cx.new_model(|_| Box::new(Self { tasks: Vec::new() }) as Box<dyn TaskSource>)
59    }
60
61    /// Spawns a certain task based on the user prompt.
62    pub fn spawn(&mut self, prompt: String) -> Arc<dyn Task> {
63        let ret = Arc::new(OneshotTask::new(prompt));
64        self.tasks.push(ret.clone());
65        ret
66    }
67}
68
69impl TaskSource for OneshotSource {
70    fn as_any(&mut self) -> &mut dyn std::any::Any {
71        self
72    }
73
74    fn tasks_for_path(
75        &mut self,
76        _path: Option<&std::path::Path>,
77        _cx: &mut gpui::ModelContext<Box<dyn TaskSource>>,
78    ) -> Vec<Arc<dyn Task>> {
79        self.tasks.clone()
80    }
81}