tasks.rs

  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(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}