mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 05:51:14 +00:00
Finish collecting data to be able to spawn tasks
This commit is contained in:
parent
8aac108d5a
commit
4abd55d340
7 changed files with 78 additions and 49 deletions
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
},
|
||||
))
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
(
|
||||
(attribute_item (attribute) @_attribute
|
||||
(#match? @_attribute ".*test.*"))
|
||||
.
|
||||
(function_item
|
||||
name: (_) @run)
|
||||
) @rust-test
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue