From 4abd55d34047267f9229bdec8a0db6aa2165347d Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 25 Apr 2024 16:46:15 -0700 Subject: [PATCH] Finish collecting data to be able to spawn tasks --- crates/editor/src/editor.rs | 76 +++++++++++++++++-------- crates/editor/src/element.rs | 4 +- crates/language/src/buffer.rs | 28 +++++---- crates/languages/src/rust/runnables.scm | 1 + crates/multi_buffer/src/multi_buffer.rs | 14 ++--- crates/project/src/project_tests.rs | 2 +- crates/project/src/task_inventory.rs | 2 +- 7 files changed, 78 insertions(+), 49 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index dfda457cdaf..be9535af993 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -76,6 +76,7 @@ use inlay_hint_cache::{InlayHintCache, InlaySplice, InvalidationStrategy}; pub use inline_completion_provider::*; pub use items::MAX_TAB_TITLE_LEN; use itertools::Itertools; +use language::Runnable; use language::{ char_kind, language_settings::{self, all_language_settings, InlayHintSettings}, @@ -83,7 +84,7 @@ use language::{ CursorShape, Diagnostic, Documentation, IndentKind, IndentSize, Language, OffsetRangeExt, Point, Selection, SelectionGoal, TransactionId, }; -use task::{RunnableTag, TaskTemplate}; +use task::TaskTemplate; use hover_links::{HoverLink, HoveredLinkState, InlayHighlight}; use lsp::{DiagnosticSeverity, LanguageServerId}; @@ -98,7 +99,8 @@ use ordered_float::OrderedFloat; use parking_lot::{Mutex, RwLock}; use project::project_settings::{GitGutterSetting, ProjectSettings}; use project::{ - CodeAction, Completion, FormatTrigger, Item, Location, Project, ProjectPath, ProjectTransaction, + CodeAction, Completion, FormatTrigger, Item, Location, Project, ProjectPath, + ProjectTransaction, WorktreeId, }; use rand::prelude::*; use rpc::proto::*; @@ -390,6 +392,13 @@ impl Default for ScrollbarMarkerState { } } +struct RunnableTasks { + templates: SmallVec<[TaskTemplate; 1]>, + match_range: Range, // The equivalent of the newest selection, + language: Arc, // For getting a context provider + worktree: Option, +} + /// Zed's primary text input `View`, allowing users to edit a [`MultiBuffer`] /// /// See the [module level documentation](self) for more information. @@ -7440,52 +7449,69 @@ impl Editor { self.select_larger_syntax_node_stack = stack; } - pub fn runnable_display_rows( + fn runnable_display_rows( &self, range: Range, snapshot: &DisplaySnapshot, cx: &WindowContext, - ) -> Vec<(u32, SmallVec<[TaskTemplate; 1]>)> { + ) -> Vec<(u32, RunnableTasks)> { snapshot .buffer_snapshot .runnable_ranges(range) - .filter_map(|(multi_buffer_range, tags)| { - let tasks = self.resolve_runnable_tags(tags, cx); + .filter_map(|(multi_buffer_range, mut runnable)| { + let (tasks, worktree_id) = self.resolve_runnable(&mut runnable, cx); if tasks.is_empty() { return None; } Some(( - dbg!(multi_buffer_range.start.to_display_point(&snapshot).row()), - dbg!(tasks), + multi_buffer_range.start.to_display_point(&snapshot).row(), + RunnableTasks { + templates: tasks, + match_range: multi_buffer_range, + language: runnable.language, + worktree: worktree_id, + }, )) }) .collect() } - fn resolve_runnable_tags( + fn resolve_runnable( &self, - tags: SmallVec<[(task::RunnableTag, Arc); 1]>, + runnable: &mut Runnable, cx: &WindowContext<'_>, - ) -> SmallVec<[TaskTemplate; 1]> { + ) -> (SmallVec<[TaskTemplate; 1]>, Option) { let Some(project) = self.project.as_ref() else { return Default::default(); }; - let inventory = project.read(cx).task_inventory().read(cx); + let (inventory, worktree_id) = project.read_with(cx, |project, cx| { + let worktree_id = project + .buffer_for_id(runnable.buffer) + .and_then(|buffer| buffer.read(cx).file()) + .map(|file| WorktreeId::from_usize(file.worktree_id())); - SmallVec::from_iter( - tags.into_iter() - .flat_map(|(tag, language)| { - let tag = tag.0.clone(); - inventory - .list_tasks(Some(language), None, cx) - .into_iter() - .filter(move |(_, template)| { - template.tags.iter().any(|source_tag| source_tag == &tag) - }) - }) - .sorted_by_key(|(kind, _)| kind.to_owned()) - .map(|(_, template)| template), + (project.task_inventory().clone(), worktree_id) + }); + + let inventory = inventory.read(cx); + let tags = mem::take(&mut runnable.tags); + ( + SmallVec::from_iter( + tags.into_iter() + .flat_map(|tag| { + let tag = tag.0.clone(); + inventory + .list_tasks(Some(runnable.language.clone()), worktree_id, cx) + .into_iter() + .filter(move |(_, template)| { + template.tags.iter().any(|source_tag| source_tag == &tag) + }) + }) + .sorted_by_key(|(kind, _)| kind.to_owned()) + .map(|(_, template)| template), + ), + worktree_id, ) } diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index d1a55dd09d8..3708640ca88 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -15,7 +15,7 @@ use crate::{ CursorShape, DisplayPoint, DocumentHighlightRead, DocumentHighlightWrite, Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle, ExpandExcerpts, GutterDimensions, HalfPageDown, HalfPageUp, HoveredCursor, LineDown, LineUp, OpenExcerpts, PageDown, PageUp, Point, - SelectPhase, Selection, SoftWrap, ToPoint, CURSORS_VISIBLE_FOR, MAX_LINE_LEN, + RunnableTasks, SelectPhase, Selection, SoftWrap, ToPoint, CURSORS_VISIBLE_FOR, MAX_LINE_LEN, }; use anyhow::Result; use collections::{BTreeMap, HashMap}; @@ -1280,7 +1280,7 @@ impl EditorElement { fn layout_test_run_indicators( &self, - test_lines: Vec<(u32, SmallVec<[TaskTemplate; 1]>)>, + test_lines: Vec<(u32, RunnableTasks)>, line_height: Pixels, scroll_pixel_position: gpui::Point, gutter_dimensions: &GutterDimensions, diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index bd65f8baefc..a0cad801723 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -498,6 +498,13 @@ pub enum CharKind { Word, } +/// A runnable is a set of data about a region that could be resolved into a task +pub struct Runnable { + pub tags: SmallVec<[RunnableTag; 1]>, + pub language: Arc, + pub buffer: BufferId, +} + impl Buffer { /// Create a new buffer with the given base text. pub fn local>(base_text: T, cx: &mut ModelContext) -> Self { @@ -2951,8 +2958,7 @@ impl BufferSnapshot { pub fn runnable_ranges( &self, range: Range, - ) -> impl Iterator, SmallVec<[(RunnableTag, Arc); 1]>)> + '_ - { + ) -> impl Iterator, Runnable)> + '_ { let offset_range = range.start.to_offset(self)..range.end.to_offset(self); let mut syntax_matches = self.syntax.matches(offset_range, self, |grammar| { @@ -2970,15 +2976,11 @@ impl BufferSnapshot { .peek() .and_then(|mat| { test_configs[mat.grammar_index].and_then(|test_configs| { - let test_tags = - SmallVec::from_iter(mat.captures.iter().filter_map(|capture| { - Some(( - test_configs.runnable_tags.get(&capture.index).cloned()?, - mat.language.clone(), - )) - })); + let tags = SmallVec::from_iter(mat.captures.iter().filter_map(|capture| { + test_configs.runnable_tags.get(&capture.index).cloned() + })); - if test_tags.is_empty() { + if tags.is_empty() { return None; } @@ -2986,7 +2988,11 @@ impl BufferSnapshot { mat.captures .iter() .find(|capture| capture.index == test_configs.run_capture_ix)?, - test_tags, + Runnable { + tags, + language: mat.language, + buffer: self.remote_id(), + }, )) }) }) diff --git a/crates/languages/src/rust/runnables.scm b/crates/languages/src/rust/runnables.scm index 88e53fe179e..47035bb0b3c 100644 --- a/crates/languages/src/rust/runnables.scm +++ b/crates/languages/src/rust/runnables.scm @@ -1,6 +1,7 @@ ( (attribute_item (attribute) @_attribute (#match? @_attribute ".*test.*")) + . (function_item name: (_) @run) ) @rust-test diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index 6f5b93c2fca..d17f9f58c78 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -13,7 +13,7 @@ use language::{ language_settings::{language_settings, LanguageSettings}, AutoindentMode, Buffer, BufferChunks, BufferSnapshot, Capability, CharKind, Chunk, CursorShape, DiagnosticEntry, File, IndentSize, Language, LanguageScope, OffsetRangeExt, OffsetUtf16, - Outline, OutlineItem, Point, PointUtf16, Selection, TextDimension, ToOffset as _, + Outline, OutlineItem, Point, PointUtf16, Runnable, Selection, TextDimension, ToOffset as _, ToOffsetUtf16 as _, ToPoint as _, ToPointUtf16 as _, TransactionId, Unclipped, }; use smallvec::SmallVec; @@ -31,6 +31,7 @@ use std::{ time::{Duration, Instant}, }; use sum_tree::{Bias, Cursor, SumTree}; +use task::RunnableTag; use text::{ locator::Locator, subscription::{Subscription, Topic}, @@ -3135,12 +3136,7 @@ impl MultiBufferSnapshot { pub fn runnable_ranges( &self, range: Range, - ) -> impl Iterator< - Item = ( - Range, - SmallVec<[(task::RunnableTag, Arc); 1]>, - ), - > + '_ { + ) -> impl Iterator, Runnable)> + '_ { let range = range.start.to_offset(self)..range.end.to_offset(self); self.excerpts_for_range(range.clone()) .flat_map(move |(excerpt, excerpt_offset)| { @@ -3149,13 +3145,13 @@ impl MultiBufferSnapshot { excerpt .buffer .runnable_ranges(excerpt.range.context.clone()) - .map(move |(mut match_range, test_tags)| { + .map(move |(mut match_range, runnable)| { // Re-base onto the excerpts coordinates in the multibuffer match_range.start = excerpt_offset + (match_range.start - excerpt_buffer_start); match_range.end = excerpt_offset + (match_range.end - excerpt_buffer_start); - (match_range, test_tags) + (match_range, runnable) }) .skip_while(move |(match_range, _)| match_range.end < range.start) .take_while(move |(match_range, _)| match_range.start < range.end) diff --git a/crates/project/src/project_tests.rs b/crates/project/src/project_tests.rs index 2b4946d901d..2bd965f3d0b 100644 --- a/crates/project/src/project_tests.rs +++ b/crates/project/src/project_tests.rs @@ -326,7 +326,7 @@ impl TaskSource for TestTaskSource { self } - fn tasks_to_schedule(&self, _: &ModelContext>) -> TaskTemplates { + fn tasks_to_schedule(&self) -> TaskTemplates { self.tasks.clone() } } diff --git a/crates/project/src/task_inventory.rs b/crates/project/src/task_inventory.rs index 603ea06d264..f3da4cefbc2 100644 --- a/crates/project/src/task_inventory.rs +++ b/crates/project/src/task_inventory.rs @@ -430,7 +430,7 @@ mod test_inventory { } impl TaskSource for StaticTestSource { - fn tasks_to_schedule(&self, _cx: &ModelContext>) -> TaskTemplates { + fn tasks_to_schedule(&self) -> TaskTemplates { TaskTemplates( self.tasks .clone()