1use std::sync::Arc;
2
3use gpui::{AppContext, Model};
4use runnable::{Runnable, RunnableId, Source};
5use ui::Context;
6
7pub struct OneshotSource {
8 runnables: Vec<Arc<dyn runnable::Runnable>>,
9}
10
11#[derive(Clone)]
12struct OneshotRunnable {
13 id: RunnableId,
14}
15
16impl OneshotRunnable {
17 fn new(prompt: String) -> Self {
18 Self {
19 id: RunnableId(prompt),
20 }
21 }
22}
23
24impl Runnable for OneshotRunnable {
25 fn id(&self) -> &runnable::RunnableId {
26 &self.id
27 }
28
29 fn name(&self) -> &str {
30 &self.id.0
31 }
32
33 fn cwd(&self) -> Option<&std::path::Path> {
34 None
35 }
36
37 fn exec(&self, cwd: Option<std::path::PathBuf>) -> Option<runnable::SpawnInTerminal> {
38 if self.id().0.is_empty() {
39 return None;
40 }
41 Some(runnable::SpawnInTerminal {
42 id: self.id().clone(),
43 label: self.name().to_owned(),
44 command: self.id().0.clone(),
45 args: vec![],
46 cwd,
47 env: Default::default(),
48 use_new_terminal: Default::default(),
49 allow_concurrent_runs: Default::default(),
50 separate_shell: true,
51 })
52 }
53}
54
55impl OneshotSource {
56 pub fn new(cx: &mut AppContext) -> Model<Box<dyn Source>> {
57 cx.new_model(|_| Box::new(Self { runnables: vec![] }) as Box<dyn Source>)
58 }
59
60 pub fn spawn(&mut self, prompt: String) -> Arc<dyn runnable::Runnable> {
61 let ret = Arc::new(OneshotRunnable::new(prompt));
62 self.runnables.push(ret.clone());
63 ret
64 }
65}
66
67impl Source for OneshotSource {
68 fn as_any(&mut self) -> &mut dyn std::any::Any {
69 self
70 }
71
72 fn runnables_for_path(
73 &mut self,
74 _path: Option<&std::path::Path>,
75 _cx: &mut gpui::ModelContext<Box<dyn Source>>,
76 ) -> Vec<Arc<dyn runnable::Runnable>> {
77 self.runnables.clone()
78 }
79}