1use crate::Editor;
2
3use collections::HashMap;
4use gpui::{App, Task, Window};
5use lsp::LanguageServerName;
6use project::{Location, project_settings::ProjectSettings};
7use settings::Settings as _;
8use task::{TaskContext, TaskVariables, VariableName};
9use text::{BufferId, ToOffset, ToPoint};
10
11impl Editor {
12 pub fn task_context(&self, window: &mut Window, cx: &mut App) -> Task<Option<TaskContext>> {
13 let Some(project) = self.project.clone() else {
14 return Task::ready(None);
15 };
16 let display_snapshot = self.display_snapshot(cx);
17 let selection = self.selections.newest_adjusted(&display_snapshot);
18 let start = display_snapshot
19 .buffer_snapshot()
20 .anchor_after(selection.start);
21 let end = display_snapshot
22 .buffer_snapshot()
23 .anchor_after(selection.end);
24 let Some((buffer_snapshot, range)) = display_snapshot
25 .buffer_snapshot()
26 .anchor_range_to_buffer_anchor_range(start..end)
27 else {
28 return Task::ready(None);
29 };
30 let Some(buffer) = self.buffer.read(cx).buffer(buffer_snapshot.remote_id()) else {
31 return Task::ready(None);
32 };
33 let location = Location { buffer, range };
34 let captured_variables = {
35 let mut variables = TaskVariables::default();
36 let buffer = location.buffer.read(cx);
37 let buffer_id = buffer.remote_id();
38 let snapshot = buffer.snapshot();
39 let starting_point = location.range.start.to_point(&snapshot);
40 let starting_offset = starting_point.to_offset(&snapshot);
41 for (_, tasks) in self
42 .tasks
43 .range((buffer_id, 0)..(buffer_id, starting_point.row + 1))
44 {
45 if !tasks
46 .context_range
47 .contains(&crate::BufferOffset(starting_offset))
48 {
49 continue;
50 }
51 for (capture_name, value) in tasks.extra_variables.iter() {
52 variables.insert(
53 VariableName::Custom(capture_name.to_owned().into()),
54 value.clone(),
55 );
56 }
57 }
58 variables
59 };
60
61 project.update(cx, |project, cx| {
62 project.task_store().update(cx, |task_store, cx| {
63 task_store.task_context_for_location(captured_variables, location, cx)
64 })
65 })
66 }
67
68 pub fn lsp_task_sources(&self, cx: &App) -> HashMap<LanguageServerName, Vec<BufferId>> {
69 let lsp_settings = &ProjectSettings::get_global(cx).lsp;
70
71 self.buffer()
72 .read(cx)
73 .all_buffers()
74 .into_iter()
75 .filter_map(|buffer| {
76 let lsp_tasks_source = buffer
77 .read(cx)
78 .language()?
79 .context_provider()?
80 .lsp_task_source()?;
81 if lsp_settings
82 .get(&lsp_tasks_source)
83 .is_none_or(|s| s.enable_lsp_tasks)
84 {
85 let buffer_id = buffer.read(cx).remote_id();
86 Some((lsp_tasks_source, buffer_id))
87 } else {
88 None
89 }
90 })
91 .fold(
92 HashMap::default(),
93 |mut acc, (lsp_task_source, buffer_id)| {
94 acc.entry(lsp_task_source)
95 .or_insert_with(Vec::new)
96 .push(buffer_id);
97 acc
98 },
99 )
100 }
101}