task_context.rs

 1use crate::Location;
 2
 3use anyhow::Result;
 4use gpui::AppContext;
 5use task::{static_source::TaskDefinitions, TaskVariables, VariableName};
 6
 7/// Language Contexts are used by Zed tasks to extract information about source file.
 8pub trait ContextProvider: Send + Sync {
 9    fn build_context(&self, _: Location, _: &mut AppContext) -> Result<TaskVariables> {
10        Ok(TaskVariables::default())
11    }
12
13    fn associated_tasks(&self) -> Option<TaskDefinitions> {
14        None
15    }
16}
17
18/// A context provider that finds out what symbol is currently focused in the buffer.
19pub struct SymbolContextProvider;
20
21impl ContextProvider for SymbolContextProvider {
22    fn build_context(
23        &self,
24        location: Location,
25        cx: &mut AppContext,
26    ) -> gpui::Result<TaskVariables> {
27        let symbols = location
28            .buffer
29            .read(cx)
30            .snapshot()
31            .symbols_containing(location.range.start, None);
32        let symbol = symbols.unwrap_or_default().last().map(|symbol| {
33            let range = symbol
34                .name_ranges
35                .last()
36                .cloned()
37                .unwrap_or(0..symbol.text.len());
38            symbol.text[range].to_string()
39        });
40        Ok(TaskVariables::from_iter(
41            Some(VariableName::Symbol).zip(symbol),
42        ))
43    }
44}
45
46/// A ContextProvider that doesn't provide any task variables on it's own, though it has some associated tasks.
47pub struct ContextProviderWithTasks {
48    definitions: TaskDefinitions,
49}
50
51impl ContextProviderWithTasks {
52    pub fn new(definitions: TaskDefinitions) -> Self {
53        Self { definitions }
54    }
55}
56
57impl ContextProvider for ContextProviderWithTasks {
58    fn associated_tasks(&self) -> Option<TaskDefinitions> {
59        Some(self.definitions.clone())
60    }
61
62    fn build_context(&self, location: Location, cx: &mut AppContext) -> Result<TaskVariables> {
63        SymbolContextProvider.build_context(location, cx)
64    }
65}