Finish collecting data to be able to spawn tasks

This commit is contained in:
Mikayla 2024-04-25 16:46:15 -07:00
parent 8aac108d5a
commit 4abd55d340
No known key found for this signature in database
7 changed files with 78 additions and 49 deletions

View file

@ -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<usize>, // The equivalent of the newest selection,
language: Arc<Language>, // For getting a context provider
worktree: Option<WorktreeId>,
}
/// 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<Anchor>,
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<Language>); 1]>,
runnable: &mut Runnable,
cx: &WindowContext<'_>,
) -> SmallVec<[TaskTemplate; 1]> {
) -> (SmallVec<[TaskTemplate; 1]>, Option<WorktreeId>) {
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,
)
}

View file

@ -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<Pixels>,
gutter_dimensions: &GutterDimensions,

View file

@ -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<Language>,
pub buffer: BufferId,
}
impl Buffer {
/// Create a new buffer with the given base text.
pub fn local<T: Into<String>>(base_text: T, cx: &mut ModelContext<Self>) -> Self {
@ -2951,8 +2958,7 @@ impl BufferSnapshot {
pub fn runnable_ranges(
&self,
range: Range<Anchor>,
) -> impl Iterator<Item = (Range<usize>, SmallVec<[(RunnableTag, Arc<Language>); 1]>)> + '_
{
) -> impl Iterator<Item = (Range<usize>, 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(),
},
))
})
})

View file

@ -1,6 +1,7 @@
(
(attribute_item (attribute) @_attribute
(#match? @_attribute ".*test.*"))
.
(function_item
name: (_) @run)
) @rust-test

View file

@ -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<Anchor>,
) -> impl Iterator<
Item = (
Range<usize>,
SmallVec<[(task::RunnableTag, Arc<Language>); 1]>,
),
> + '_ {
) -> impl Iterator<Item = (Range<usize>, 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)

View file

@ -326,7 +326,7 @@ impl TaskSource for TestTaskSource {
self
}
fn tasks_to_schedule(&self, _: &ModelContext<Box<dyn TaskSource>>) -> TaskTemplates {
fn tasks_to_schedule(&self) -> TaskTemplates {
self.tasks.clone()
}
}

View file

@ -430,7 +430,7 @@ mod test_inventory {
}
impl TaskSource for StaticTestSource {
fn tasks_to_schedule(&self, _cx: &ModelContext<Box<dyn TaskSource>>) -> TaskTemplates {
fn tasks_to_schedule(&self) -> TaskTemplates {
TaskTemplates(
self.tasks
.clone()