#[cfg(test)]mod syntax_map_tests; use crate::{Grammar, InjectionConfig, Language, LanguageId, LanguageRegistry};use collections::HashMap;use futures::FutureExt;use parking_lot::Mutex;use std::{ borrow::Cow, cmp::{self, Ordering, Reverse}, collections::BinaryHeap, fmt, iter, ops::{Deref, DerefMut, Range}, sync::Arc,};use sum_tree::{Bias, SeekTarget, SumTree};use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint};use tree_sitter::{Node, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatches, Tree}; use super::PARSER; static QUERY_CURSORS: Mutex<Vec<QueryCursor>> = Mutex::new(vec![]); #[derive(Default)]pub struct SyntaxMap { snapshot: SyntaxSnapshot, language_registry: Option<Arc<LanguageRegistry>>,} #[derive(Clone, Default)]pub struct SyntaxSnapshot { layers: SumTree<SyntaxLayerEntry>, parsed_version: clock::Global, interpolated_version: clock::Global, language_registry_version: usize,} #[derive(Default)]pub struct SyntaxMapCaptures<'a> { layers: Vec<SyntaxMapCapturesLayer<'a>>, active_layer_count: usize, grammars: Vec<&'a Grammar>,} #[derive(Default)]pub struct SyntaxMapMatches<'a> { layers: Vec<SyntaxMapMatchesLayer<'a>>, active_layer_count: usize, grammars: Vec<&'a Grammar>,} #[derive(Debug)]pub struct SyntaxMapCapture<'a> { pub depth: usize, pub node: Node<'a>, pub index: u32, pub grammar_index: usize,} #[derive(Debug)]pub struct SyntaxMapMatch<'a> { pub depth: usize, pub pattern_index: usize, pub captures: &'a [QueryCapture<'a>], pub grammar_index: usize,} struct SyntaxMapCapturesLayer<'a> { depth: usize, captures: QueryCaptures<'a, 'a, TextProvider<'a>, &'a [u8]>, next_capture: Option<QueryCapture<'a>>, grammar_index: usize, _query_cursor: QueryCursorHandle,} struct SyntaxMapMatchesLayer<'a> { depth: usize, next_pattern_index: usize, next_captures: Vec<QueryCapture<'a>>, has_next: bool, matches: QueryMatches<'a, 'a, TextProvider<'a>, &'a [u8]>, grammar_index: usize, _query_cursor: QueryCursorHandle,} #[derive(Clone)]struct SyntaxLayerEntry { depth: usize, range: Range<Anchor>, content: SyntaxLayerContent,} #[derive(Clone)]enum SyntaxLayerContent { Parsed { tree: tree_sitter::Tree, language: Arc<Language>, }, Pending { language_name: Arc<str>, },} impl SyntaxLayerContent { fn language_id(&self) -> Option<LanguageId> { match self { SyntaxLayerContent::Parsed { language, .. } => Some(language.id), SyntaxLayerContent::Pending { .. } => None, } } fn tree(&self) -> Option<&Tree> { match self { SyntaxLayerContent::Parsed { tree, .. } => Some(tree), SyntaxLayerContent::Pending { .. } => None, } }} /// A layer of syntax highlighting, corresponding to a single syntax/// tree in a particular language.#[derive(Debug)]pub struct SyntaxLayer<'a> { /// The language for this layer. pub language: &'a Arc<Language>, depth: usize, tree: &'a Tree, offset: (usize, tree_sitter::Point),} /// A layer of syntax highlighting. Like [SyntaxLayer], but holding/// owned data instead of references.#[derive(Clone)]pub struct OwnedSyntaxLayer { /// The language for this layer. pub language: Arc<Language>, tree: tree_sitter::Tree, offset: (usize, tree_sitter::Point),} #[derive(Debug, Clone)]struct SyntaxLayerSummary { min_depth: usize, max_depth: usize, range: Range<Anchor>, last_layer_range: Range<Anchor>, last_layer_language: Option<LanguageId>, contains_unknown_injections: bool,} #[derive(Clone, Debug)]struct SyntaxLayerPosition { depth: usize, range: Range<Anchor>, language: Option<LanguageId>,} #[derive(Clone, Debug)]struct ChangeStartPosition { depth: usize, position: Anchor,} #[derive(Clone, Debug)]struct SyntaxLayerPositionBeforeChange { position: SyntaxLayerPosition, change: ChangeStartPosition,} struct ParseStep { depth: usize, language: ParseStepLanguage, range: Range<Anchor>, included_ranges: Vec<tree_sitter::Range>, mode: ParseMode,} #[derive(Debug)]enum ParseStepLanguage { Loaded { language: Arc<Language> }, Pending { name: Arc<str> },} impl ParseStepLanguage { fn id(&self) -> Option<LanguageId> { match self { ParseStepLanguage::Loaded { language } => Some(language.id), ParseStepLanguage::Pending { .. } => None, } }} enum ParseMode { Single, Combined { parent_layer_range: Range<usize>, parent_layer_changed_ranges: Vec<Range<usize>>, },} #[derive(Debug, PartialEq, Eq)]struct ChangedRegion { depth: usize, range: Range<Anchor>,} #[derive(Default)]struct ChangeRegionSet(Vec<ChangedRegion>); struct TextProvider<'a>(&'a Rope); struct ByteChunks<'a>(text::Chunks<'a>); struct QueryCursorHandle(Option<QueryCursor>); impl SyntaxMap { pub fn new() -> Self { Self::default() } pub fn set_language_registry(&mut self, registry: Arc<LanguageRegistry>) { self.language_registry = Some(registry); } pub fn snapshot(&self) -> SyntaxSnapshot { self.snapshot.clone() } pub fn language_registry(&self) -> Option<Arc<LanguageRegistry>> { self.language_registry.clone() } pub fn interpolate(&mut self, text: &BufferSnapshot) { self.snapshot.interpolate(text); } #[cfg(test)] pub fn reparse(&mut self, language: Arc<Language>, text: &BufferSnapshot) { self.snapshot .reparse(text, self.language_registry.clone(), language); } pub fn did_parse(&mut self, snapshot: SyntaxSnapshot) { self.snapshot = snapshot; } pub fn clear(&mut self) { self.snapshot = SyntaxSnapshot::default(); }} impl SyntaxSnapshot { pub fn is_empty(&self) -> bool { self.layers.is_empty() } fn interpolate(&mut self, text: &BufferSnapshot) { let edits = text .anchored_edits_since::<(usize, Point)>(&self.interpolated_version) .collect::<Vec<_>>(); self.interpolated_version = text.version().clone(); if edits.is_empty() { return; } let mut layers = SumTree::new(); let mut first_edit_ix_for_depth = 0; let mut prev_depth = 0; let mut cursor = self.layers.cursor::<SyntaxLayerSummary>(); cursor.next(text); 'outer: loop { let depth = cursor.end(text).max_depth; if depth > prev_depth { first_edit_ix_for_depth = 0; prev_depth = depth; } // Preserve any layers at this depth that precede the first edit. if let Some((_, edit_range)) = edits.get(first_edit_ix_for_depth) { let target = ChangeStartPosition { depth, position: edit_range.start, }; if target.cmp(cursor.start(), text).is_gt() { let slice = cursor.slice(&target, Bias::Left, text); layers.append(slice, text); } } // If this layer follows all of the edits, then preserve it and any // subsequent layers at this same depth. else if cursor.item().is_some() { let slice = cursor.slice( &SyntaxLayerPosition { depth: depth + 1, range: Anchor::MIN..Anchor::MAX, language: None, }, Bias::Left, text, ); layers.append(slice, text); continue; }; let Some(layer) = cursor.item() else { break }; let (start_byte, start_point) = layer.range.start.summary::<(usize, Point)>(text); // Ignore edits that end before the start of this layer, and don't consider them // for any subsequent layers at this same depth. loop { let Some((_, edit_range)) = edits.get(first_edit_ix_for_depth) else { continue 'outer; }; if edit_range.end.cmp(&layer.range.start, text).is_le() { first_edit_ix_for_depth += 1; } else { break; } } let mut layer = layer.clone(); if let SyntaxLayerContent::Parsed { tree, .. } = &mut layer.content { for (edit, edit_range) in &edits[first_edit_ix_for_depth..] { // Ignore any edits that follow this layer. if edit_range.start.cmp(&layer.range.end, text).is_ge() { break; } // Apply any edits that intersect this layer to the layer's syntax tree. let tree_edit = if edit_range.start.cmp(&layer.range.start, text).is_ge() { tree_sitter::InputEdit { start_byte: edit.new.start.0 - start_byte, old_end_byte: edit.new.start.0 - start_byte + (edit.old.end.0 - edit.old.start.0), new_end_byte: edit.new.end.0 - start_byte, start_position: (edit.new.start.1 - start_point).to_ts_point(), old_end_position: (edit.new.start.1 - start_point + (edit.old.end.1 - edit.old.start.1)) .to_ts_point(), new_end_position: (edit.new.end.1 - start_point).to_ts_point(), } } else { let node = tree.root_node(); tree_sitter::InputEdit { start_byte: 0, old_end_byte: node.end_byte(), new_end_byte: 0, start_position: Default::default(), old_end_position: node.end_position(), new_end_position: Default::default(), } }; tree.edit(&tree_edit); } debug_assert!( tree.root_node().end_byte() <= text.len(), "tree's size {}, is larger than text size {}", tree.root_node().end_byte(), text.len(), ); } layers.push(layer, text); cursor.next(text); } layers.append(cursor.suffix(text), text); drop(cursor); self.layers = layers; } pub fn reparse( &mut self, text: &BufferSnapshot, registry: Option<Arc<LanguageRegistry>>, root_language: Arc<Language>, ) { let edit_ranges = text .edits_since::<usize>(&self.parsed_version) .map(|edit| edit.new) .collect::<Vec<_>>(); self.reparse_with_ranges(text, root_language.clone(), edit_ranges, registry.as_ref()); if let Some(registry) = registry { if registry.version() != self.language_registry_version { let mut resolved_injection_ranges = Vec::new(); let mut cursor = self .layers .filter::<_, ()>(|summary| summary.contains_unknown_injections); cursor.next(text); while let Some(layer) = cursor.item() { let SyntaxLayerContent::Pending { language_name } = &layer.content else { unreachable!() }; if registry .language_for_name_or_extension(language_name) .now_or_never() .and_then(|language| language.ok()) .is_some() { resolved_injection_ranges.push(layer.range.to_offset(text)); } cursor.next(text); } drop(cursor); if !resolved_injection_ranges.is_empty() { self.reparse_with_ranges( text, root_language, resolved_injection_ranges, Some(®istry), ); } self.language_registry_version = registry.version(); } } } fn reparse_with_ranges( &mut self, text: &BufferSnapshot, root_language: Arc<Language>, invalidated_ranges: Vec<Range<usize>>, registry: Option<&Arc<LanguageRegistry>>, ) { log::trace!("reparse. invalidated ranges:{:?}", invalidated_ranges); let max_depth = self.layers.summary().max_depth; let mut cursor = self.layers.cursor::<SyntaxLayerSummary>(); cursor.next(text); let mut layers = SumTree::new(); let mut changed_regions = ChangeRegionSet::default(); let mut queue = BinaryHeap::new(); let mut combined_injection_ranges = HashMap::default(); queue.push(ParseStep { depth: 0, language: ParseStepLanguage::Loaded { language: root_language, }, included_ranges: vec![tree_sitter::Range { start_byte: 0, end_byte: text.len(), start_point: Point::zero().to_ts_point(), end_point: text.max_point().to_ts_point(), }], range: Anchor::MIN..Anchor::MAX, mode: ParseMode::Single, }); loop { let step = queue.pop(); let position = if let Some(step) = &step { SyntaxLayerPosition { depth: step.depth, range: step.range.clone(), language: step.language.id(), } } else { SyntaxLayerPosition { depth: max_depth + 1, range: Anchor::MAX..Anchor::MAX, language: None, } }; let mut done = cursor.item().is_none(); while !done && position.cmp(&cursor.end(text), text).is_gt() { done = true; let bounded_position = SyntaxLayerPositionBeforeChange { position: position.clone(), change: changed_regions.start_position(), }; if bounded_position.cmp(cursor.start(), text).is_gt() { let slice = cursor.slice(&bounded_position, Bias::Left, text); if !slice.is_empty() { layers.append(slice, text); if changed_regions.prune(cursor.end(text), text) { done = false; } } } while position.cmp(&cursor.end(text), text).is_gt() { let Some(layer) = cursor.item() else { break }; if changed_regions.intersects(layer, text) { if let SyntaxLayerContent::Parsed { language, .. } = &layer.content { log::trace!( "discard layer. language:{}, range:{:?}. changed_regions:{:?}", language.name(), LogAnchorRange(&layer.range, text), LogChangedRegions(&changed_regions, text),Lines 1–500 of 1817. Load more
#[cfg(test)] mod syntax_map_tests; use crate::{Grammar, InjectionConfig, Language, LanguageId, LanguageRegistry}; use collections::HashMap; use futures::FutureExt; use parking_lot::Mutex; use std::{ borrow::Cow, cmp::{self, Ordering, Reverse}, collections::BinaryHeap, fmt, iter, ops::{Deref, DerefMut, Range}, sync::Arc, }; use sum_tree::{Bias, SeekTarget, SumTree}; use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint}; use tree_sitter::{Node, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatches, Tree}; use super::PARSER; static QUERY_CURSORS: Mutex<Vec<QueryCursor>> = Mutex::new(vec![]); #[derive(Default)] pub struct SyntaxMap { snapshot: SyntaxSnapshot, language_registry: Option<Arc<LanguageRegistry>>, } #[derive(Clone, Default)] pub struct SyntaxSnapshot { layers: SumTree<SyntaxLayerEntry>, parsed_version: clock::Global, interpolated_version: clock::Global, language_registry_version: usize, } #[derive(Default)] pub struct SyntaxMapCaptures<'a> { layers: Vec<SyntaxMapCapturesLayer<'a>>, active_layer_count: usize, grammars: Vec<&'a Grammar>, } #[derive(Default)] pub struct SyntaxMapMatches<'a> { layers: Vec<SyntaxMapMatchesLayer<'a>>, active_layer_count: usize, grammars: Vec<&'a Grammar>, } #[derive(Debug)] pub struct SyntaxMapCapture<'a> { pub depth: usize, pub node: Node<'a>, pub index: u32, pub grammar_index: usize, } #[derive(Debug)] pub struct SyntaxMapMatch<'a> { pub depth: usize, pub pattern_index: usize, pub captures: &'a [QueryCapture<'a>], pub grammar_index: usize, } struct SyntaxMapCapturesLayer<'a> { depth: usize, captures: QueryCaptures<'a, 'a, TextProvider<'a>, &'a [u8]>, next_capture: Option<QueryCapture<'a>>, grammar_index: usize, _query_cursor: QueryCursorHandle, } struct SyntaxMapMatchesLayer<'a> { depth: usize, next_pattern_index: usize, next_captures: Vec<QueryCapture<'a>>, has_next: bool, matches: QueryMatches<'a, 'a, TextProvider<'a>, &'a [u8]>, grammar_index: usize, _query_cursor: QueryCursorHandle, } #[derive(Clone)] struct SyntaxLayerEntry { depth: usize, range: Range<Anchor>, content: SyntaxLayerContent, } #[derive(Clone)] enum SyntaxLayerContent { Parsed { tree: tree_sitter::Tree, language: Arc<Language>, }, Pending { language_name: Arc<str>, }, } impl SyntaxLayerContent { fn language_id(&self) -> Option<LanguageId> { match self { SyntaxLayerContent::Parsed { language, .. } => Some(language.id), SyntaxLayerContent::Pending { .. } => None, } } fn tree(&self) -> Option<&Tree> { match self { SyntaxLayerContent::Parsed { tree, .. } => Some(tree), SyntaxLayerContent::Pending { .. } => None, } } } /// A layer of syntax highlighting, corresponding to a single syntax /// tree in a particular language. #[derive(Debug)] pub struct SyntaxLayer<'a> { /// The language for this layer. pub language: &'a Arc<Language>, depth: usize, tree: &'a Tree, offset: (usize, tree_sitter::Point), } /// A layer of syntax highlighting. Like [SyntaxLayer], but holding /// owned data instead of references. #[derive(Clone)] pub struct OwnedSyntaxLayer { /// The language for this layer. pub language: Arc<Language>, tree: tree_sitter::Tree, offset: (usize, tree_sitter::Point), } #[derive(Debug, Clone)] struct SyntaxLayerSummary { min_depth: usize, max_depth: usize, range: Range<Anchor>, last_layer_range: Range<Anchor>, last_layer_language: Option<LanguageId>, contains_unknown_injections: bool, } #[derive(Clone, Debug)] struct SyntaxLayerPosition { depth: usize, range: Range<Anchor>, language: Option<LanguageId>, } #[derive(Clone, Debug)] struct ChangeStartPosition { depth: usize, position: Anchor, } #[derive(Clone, Debug)] struct SyntaxLayerPositionBeforeChange { position: SyntaxLayerPosition, change: ChangeStartPosition, } struct ParseStep { depth: usize, language: ParseStepLanguage, range: Range<Anchor>, included_ranges: Vec<tree_sitter::Range>, mode: ParseMode, } #[derive(Debug)] enum ParseStepLanguage { Loaded { language: Arc<Language> }, Pending { name: Arc<str> }, } impl ParseStepLanguage { fn id(&self) -> Option<LanguageId> { match self { ParseStepLanguage::Loaded { language } => Some(language.id), ParseStepLanguage::Pending { .. } => None, } } } enum ParseMode { Single, Combined { parent_layer_range: Range<usize>, parent_layer_changed_ranges: Vec<Range<usize>>, }, } #[derive(Debug, PartialEq, Eq)] struct ChangedRegion { depth: usize, range: Range<Anchor>, } #[derive(Default)] struct ChangeRegionSet(Vec<ChangedRegion>); struct TextProvider<'a>(&'a Rope); struct ByteChunks<'a>(text::Chunks<'a>); struct QueryCursorHandle(Option<QueryCursor>); impl SyntaxMap { pub fn new() -> Self { Self::default() } pub fn set_language_registry(&mut self, registry: Arc<LanguageRegistry>) { self.language_registry = Some(registry); } pub fn snapshot(&self) -> SyntaxSnapshot { self.snapshot.clone() } pub fn language_registry(&self) -> Option<Arc<LanguageRegistry>> { self.language_registry.clone() } pub fn interpolate(&mut self, text: &BufferSnapshot) { self.snapshot.interpolate(text); } #[cfg(test)] pub fn reparse(&mut self, language: Arc<Language>, text: &BufferSnapshot) { self.snapshot .reparse(text, self.language_registry.clone(), language); } pub fn did_parse(&mut self, snapshot: SyntaxSnapshot) { self.snapshot = snapshot; } pub fn clear(&mut self) { self.snapshot = SyntaxSnapshot::default(); } } impl SyntaxSnapshot { pub fn is_empty(&self) -> bool { self.layers.is_empty() } fn interpolate(&mut self, text: &BufferSnapshot) { let edits = text .anchored_edits_since::<(usize, Point)>(&self.interpolated_version) .collect::<Vec<_>>(); self.interpolated_version = text.version().clone(); if edits.is_empty() { return; } let mut layers = SumTree::new(); let mut first_edit_ix_for_depth = 0; let mut prev_depth = 0; let mut cursor = self.layers.cursor::<SyntaxLayerSummary>(); cursor.next(text); 'outer: loop { let depth = cursor.end(text).max_depth; if depth > prev_depth { first_edit_ix_for_depth = 0; prev_depth = depth; } // Preserve any layers at this depth that precede the first edit. if let Some((_, edit_range)) = edits.get(first_edit_ix_for_depth) { let target = ChangeStartPosition { depth, position: edit_range.start, }; if target.cmp(cursor.start(), text).is_gt() { let slice = cursor.slice(&target, Bias::Left, text); layers.append(slice, text); } } // If this layer follows all of the edits, then preserve it and any // subsequent layers at this same depth. else if cursor.item().is_some() { let slice = cursor.slice( &SyntaxLayerPosition { depth: depth + 1, range: Anchor::MIN..Anchor::MAX, language: None, }, Bias::Left, text, ); layers.append(slice, text); continue; }; let Some(layer) = cursor.item() else { break }; let (start_byte, start_point) = layer.range.start.summary::<(usize, Point)>(text); // Ignore edits that end before the start of this layer, and don't consider them // for any subsequent layers at this same depth. loop { let Some((_, edit_range)) = edits.get(first_edit_ix_for_depth) else { continue 'outer; }; if edit_range.end.cmp(&layer.range.start, text).is_le() { first_edit_ix_for_depth += 1; } else { break; } } let mut layer = layer.clone(); if let SyntaxLayerContent::Parsed { tree, .. } = &mut layer.content { for (edit, edit_range) in &edits[first_edit_ix_for_depth..] { // Ignore any edits that follow this layer. if edit_range.start.cmp(&layer.range.end, text).is_ge() { break; } // Apply any edits that intersect this layer to the layer's syntax tree. let tree_edit = if edit_range.start.cmp(&layer.range.start, text).is_ge() { tree_sitter::InputEdit { start_byte: edit.new.start.0 - start_byte, old_end_byte: edit.new.start.0 - start_byte + (edit.old.end.0 - edit.old.start.0), new_end_byte: edit.new.end.0 - start_byte, start_position: (edit.new.start.1 - start_point).to_ts_point(), old_end_position: (edit.new.start.1 - start_point + (edit.old.end.1 - edit.old.start.1)) .to_ts_point(), new_end_position: (edit.new.end.1 - start_point).to_ts_point(), } } else { let node = tree.root_node(); tree_sitter::InputEdit { start_byte: 0, old_end_byte: node.end_byte(), new_end_byte: 0, start_position: Default::default(), old_end_position: node.end_position(), new_end_position: Default::default(), } }; tree.edit(&tree_edit); } debug_assert!( tree.root_node().end_byte() <= text.len(), "tree's size {}, is larger than text size {}", tree.root_node().end_byte(), text.len(), ); } layers.push(layer, text); cursor.next(text); } layers.append(cursor.suffix(text), text); drop(cursor); self.layers = layers; } pub fn reparse( &mut self, text: &BufferSnapshot, registry: Option<Arc<LanguageRegistry>>, root_language: Arc<Language>, ) { let edit_ranges = text .edits_since::<usize>(&self.parsed_version) .map(|edit| edit.new) .collect::<Vec<_>>(); self.reparse_with_ranges(text, root_language.clone(), edit_ranges, registry.as_ref()); if let Some(registry) = registry { if registry.version() != self.language_registry_version { let mut resolved_injection_ranges = Vec::new(); let mut cursor = self .layers .filter::<_, ()>(|summary| summary.contains_unknown_injections); cursor.next(text); while let Some(layer) = cursor.item() { let SyntaxLayerContent::Pending { language_name } = &layer.content else { unreachable!() }; if registry .language_for_name_or_extension(language_name) .now_or_never() .and_then(|language| language.ok()) .is_some() { resolved_injection_ranges.push(layer.range.to_offset(text)); } cursor.next(text); } drop(cursor); if !resolved_injection_ranges.is_empty() { self.reparse_with_ranges( text, root_language, resolved_injection_ranges, Some(®istry), ); } self.language_registry_version = registry.version(); } } } fn reparse_with_ranges( &mut self, text: &BufferSnapshot, root_language: Arc<Language>, invalidated_ranges: Vec<Range<usize>>, registry: Option<&Arc<LanguageRegistry>>, ) { log::trace!("reparse. invalidated ranges:{:?}", invalidated_ranges); let max_depth = self.layers.summary().max_depth; let mut cursor = self.layers.cursor::<SyntaxLayerSummary>(); cursor.next(text); let mut layers = SumTree::new(); let mut changed_regions = ChangeRegionSet::default(); let mut queue = BinaryHeap::new(); let mut combined_injection_ranges = HashMap::default(); queue.push(ParseStep { depth: 0, language: ParseStepLanguage::Loaded { language: root_language, }, included_ranges: vec![tree_sitter::Range { start_byte: 0, end_byte: text.len(), start_point: Point::zero().to_ts_point(), end_point: text.max_point().to_ts_point(), }], range: Anchor::MIN..Anchor::MAX, mode: ParseMode::Single, }); loop { let step = queue.pop(); let position = if let Some(step) = &step { SyntaxLayerPosition { depth: step.depth, range: step.range.clone(), language: step.language.id(), } } else { SyntaxLayerPosition { depth: max_depth + 1, range: Anchor::MAX..Anchor::MAX, language: None, } }; let mut done = cursor.item().is_none(); while !done && position.cmp(&cursor.end(text), text).is_gt() { done = true; let bounded_position = SyntaxLayerPositionBeforeChange { position: position.clone(), change: changed_regions.start_position(), }; if bounded_position.cmp(cursor.start(), text).is_gt() { let slice = cursor.slice(&bounded_position, Bias::Left, text); if !slice.is_empty() { layers.append(slice, text); if changed_regions.prune(cursor.end(text), text) { done = false; } } } while position.cmp(&cursor.end(text), text).is_gt() { let Some(layer) = cursor.item() else { break }; if changed_regions.intersects(layer, text) { if let SyntaxLayerContent::Parsed { language, .. } = &layer.content { log::trace!( "discard layer. language:{}, range:{:?}. changed_regions:{:?}", language.name(), LogAnchorRange(&layer.range, text), LogChangedRegions(&changed_regions, text),