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