use crate::Editor; use gpui::{Task as AsyncTask, WindowContext}; use project::Location; use task::{TaskContext, TaskVariables, VariableName}; use text::{ToOffset, ToPoint}; use workspace::Workspace; fn task_context_with_editor( editor: &mut Editor, cx: &mut WindowContext<'_>, ) -> AsyncTask> { let Some(project) = editor.project.clone() else { return AsyncTask::ready(None); }; let (selection, buffer, editor_snapshot) = { let selection = editor.selections.newest_adjusted(cx); let Some((buffer, _, _)) = editor .buffer() .read(cx) .point_to_buffer_offset(selection.start, cx) else { return AsyncTask::ready(None); }; let snapshot = editor.snapshot(cx); (selection, buffer, snapshot) }; let selection_range = selection.range(); let start = editor_snapshot .display_snapshot .buffer_snapshot .anchor_after(selection_range.start) .text_anchor; let end = editor_snapshot .display_snapshot .buffer_snapshot .anchor_after(selection_range.end) .text_anchor; let location = Location { buffer, range: start..end, }; let captured_variables = { let mut variables = TaskVariables::default(); let buffer = location.buffer.read(cx); let buffer_id = buffer.remote_id(); let snapshot = buffer.snapshot(); let starting_point = location.range.start.to_point(&snapshot); let starting_offset = starting_point.to_offset(&snapshot); for (_, tasks) in editor .tasks .range((buffer_id, 0)..(buffer_id, starting_point.row + 1)) { if !tasks .context_range .contains(&crate::BufferOffset(starting_offset)) { continue; } for (capture_name, value) in tasks.extra_variables.iter() { variables.insert( VariableName::Custom(capture_name.to_owned().into()), value.clone(), ); } } variables }; project.update(cx, |project, cx| { project.task_store().update(cx, |task_store, cx| { task_store.task_context_for_location(captured_variables, location, cx) }) }) } pub fn task_context(workspace: &Workspace, cx: &mut WindowContext<'_>) -> AsyncTask { let Some(editor) = workspace .active_item(cx) .and_then(|item| item.act_as::(cx)) else { return AsyncTask::ready(TaskContext::default()); }; editor.update(cx, |editor, cx| { let context_task = task_context_with_editor(editor, cx); cx.background_executor() .spawn(async move { context_task.await.unwrap_or_default() }) }) }