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