From 37397ecc6dfc9e9c6f45e53823877fabd6a132ef Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Mon, 22 Apr 2024 02:25:18 +0200 Subject: [PATCH] tmp --- helix-syntax/src/injections_tree.rs | 94 +++++++++++++++++++++++++++++ helix-syntax/src/lib.rs | 4 +- 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 helix-syntax/src/injections_tree.rs diff --git a/helix-syntax/src/injections_tree.rs b/helix-syntax/src/injections_tree.rs new file mode 100644 index 000000000..e181a7754 --- /dev/null +++ b/helix-syntax/src/injections_tree.rs @@ -0,0 +1,94 @@ +use core::slice; +use std::iter::Peekable; +use std::sync::Arc; + +use hashbrown::HashMap; +use slotmap::{new_key_type, HopSlotMap, SlotMap}; +use tree_sitter::Tree; + +use crate::parse::LayerUpdateFlags; +use crate::{HighlightConfiguration, RopeProvider}; + +// TODO(perf): replace std::ops::Range with helix_core::Range once added +type Range = std::ops::Range; + +new_key_type! { + /// The default slot map key type. + pub struct LayerId; +} + +#[derive(Debug)] +pub struct LanguageLayer { + pub config: Arc, + pub(crate) parse_tree: Option, + /// internal flags used during parsing to track incremental invalidation + pub(crate) flags: LayerUpdateFlags, + pub(crate) parent: Option, + /// a list of **sorted** non-overlapping injection ranges note that + /// injection ranges are not relative to the start of this layer but the + /// start of the root layer + pub(crate) injection_ranges: Box<[InjectionRange]>, +} + +#[derive(Debug)] +pub(crate) struct InjectionRange { + pub byte_range: Range, + pub layer: LayerId, +} + +impl LanguageLayer { + /// Returns the injection range **within this layers** that contains `idx`. + /// This function will not descend into nested injections + pub(crate) fn injection_at_byte_idx(&self, idx: usize) -> Option<&InjectionRange> { + let i = self + .injection_ranges + .partition_point(|range| range.byte_range.start <= idx); + self.injection_ranges + .get(i) + .filter(|injection| injection.byte_range.end > idx) + } +} + +struct InjectionTree { + layers: SlotMap, + root: LayerId, +} + +impl InjectionTree { + pub fn layer_for_byte_range(&self, start: usize, end: usize) -> LayerId { + let mut cursor = self.root; + loop { + let layer = &self.layers[cursor]; + let Some(start_injection) = layer.injection_at_byte_idx(start) else { + break; + }; + let Some(end_injection) = layer.injection_at_byte_idx(end) else { + break; + }; + if start_injection.layer == end_injection.layer { + cursor = start_injection.layer; + } else { + break; + } + } + cursor + } +} + +struct ActiveInjection<'a> { + injections: Peekable>, + range: InjectionRange, +} + +struct ActiveLayer<'a, State> { + state: State, + /// the query captures just for this layer + layer_captures: Peekable>, +} + +type LayerQueryCaptures<'a> = tree_sitter::QueryCaptures<'a, 'a, RopeProvider<'a>, &'a [u8]>; + +pub struct QueryCaptures<'a> { + active_layers: HashMap>, + active_injections: Vec>, +} diff --git a/helix-syntax/src/lib.rs b/helix-syntax/src/lib.rs index 04a2d27d5..915d8df5b 100644 --- a/helix-syntax/src/lib.rs +++ b/helix-syntax/src/lib.rs @@ -1,5 +1,5 @@ use ::ropey::RopeSlice; -use slotmap::{DefaultKey as LayerId, HopSlotMap}; +use slotmap::{new_key_type, HopSlotMap}; use tree_sitter::{Node, Parser, Point, Query, QueryCursor, Range, Tree}; use std::borrow::Cow; @@ -9,6 +9,7 @@ use std::str; use std::sync::Arc; +use crate::injections_tree::LayerId; use crate::parse::LayerUpdateFlags; pub use crate::config::{read_query, HighlightConfiguration}; @@ -19,6 +20,7 @@ mod config; pub mod highlighter; +mod injections_tree; mod merge; mod parse; mod pretty_print;