Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-syntax/src/parse.rs')
-rw-r--r--helix-syntax/src/parse.rs828
1 files changed, 414 insertions, 414 deletions
diff --git a/helix-syntax/src/parse.rs b/helix-syntax/src/parse.rs
index de70f2a1..d2903b07 100644
--- a/helix-syntax/src/parse.rs
+++ b/helix-syntax/src/parse.rs
@@ -1,18 +1,18 @@
-use std::collections::VecDeque;
-use std::mem::replace;
-use std::sync::Arc;
+// use std::collections::VecDeque;
+// use std::mem::replace;
+// use std::sync::Arc;
-use ahash::RandomState;
+// use ahash::RandomState;
use bitflags::bitflags;
-use hashbrown::raw::RawTable;
-use ropey::RopeSlice;
-use tree_sitter::{Node, Parser, Point, QueryCursor, Range};
+// use hashbrown::raw::RawTable;
+// use ropey::RopeSlice;
+// use tree_sitter::{Node, Parser, Point, QueryCursor, Range};
-use crate::ropey::RopeProvider;
-use crate::{
- Error, HighlightConfiguration, IncludedChildren, InjectionLanguageMarker, LanguageLayer,
- Syntax, PARSER, TREE_SITTER_MATCH_LIMIT,
-};
+// use crate::ropey::RopeProvider;
+// use crate::{
+// Error, HighlightConfiguration, IncludedChildren, InjectionLanguageMarker, LanguageLayer,
+// Syntax, PARSER, TREE_SITTER_MATCH_LIMIT,
+// };
bitflags! {
/// Flags that track the status of a layer
@@ -25,405 +25,405 @@ bitflags! {
}
}
-impl Syntax {
- pub fn update(
- &mut self,
- source: RopeSlice,
- edits: Vec<tree_sitter::InputEdit>,
- injection_callback: impl Fn(&InjectionLanguageMarker) -> Option<Arc<HighlightConfiguration>>,
- ) -> Result<(), Error> {
- let mut queue = VecDeque::new();
- queue.push_back(self.root);
-
- // This table allows inverse indexing of `layers`.
- // That is by hashing a `Layer` you can find
- // the `LayerId` of an existing equivalent `Layer` in `layers`.
- //
- // It is used to determine if a new layer exists for an injection
- // or if an existing layer needs to be updated.
- let mut layers_table = RawTable::with_capacity(self.layers.len());
- let layers_hasher = RandomState::new();
- // Use the edits to update all layers markers
- fn point_add(a: Point, b: Point) -> Point {
- if b.row > 0 {
- Point::new(a.row.saturating_add(b.row), b.column)
- } else {
- Point::new(0, a.column.saturating_add(b.column))
- }
- }
- fn point_sub(a: Point, b: Point) -> Point {
- if a.row > b.row {
- Point::new(a.row.saturating_sub(b.row), a.column)
- } else {
- Point::new(0, a.column.saturating_sub(b.column))
- }
- }
-
- for (layer_id, layer) in self.layers.iter_mut() {
- // The root layer always covers the whole range (0..usize::MAX)
- if layer.depth == 0 {
- layer.flags = LayerUpdateFlags::MODIFIED;
- continue;
- }
-
- if !edits.is_empty() {
- for range in &mut layer.ranges {
- // Roughly based on https://github.com/tree-sitter/tree-sitter/blob/ddeaa0c7f534268b35b4f6cb39b52df082754413/lib/src/subtree.c#L691-L720
- for edit in edits.iter().rev() {
- let is_pure_insertion = edit.old_end_byte == edit.start_byte;
-
- // if edit is after range, skip
- if edit.start_byte > range.end_byte {
- // TODO: || (is_noop && edit.start_byte == range.end_byte)
- continue;
- }
-
- // if edit is before range, shift entire range by len
- if edit.old_end_byte < range.start_byte {
- range.start_byte =
- edit.new_end_byte + (range.start_byte - edit.old_end_byte);
- range.start_point = point_add(
- edit.new_end_position,
- point_sub(range.start_point, edit.old_end_position),
- );
-
- range.end_byte = edit
- .new_end_byte
- .saturating_add(range.end_byte - edit.old_end_byte);
- range.end_point = point_add(
- edit.new_end_position,
- point_sub(range.end_point, edit.old_end_position),
- );
-
- layer.flags |= LayerUpdateFlags::MOVED;
- }
- // if the edit starts in the space before and extends into the range
- else if edit.start_byte < range.start_byte {
- range.start_byte = edit.new_end_byte;
- range.start_point = edit.new_end_position;
-
- range.end_byte = range
- .end_byte
- .saturating_sub(edit.old_end_byte)
- .saturating_add(edit.new_end_byte);
- range.end_point = point_add(
- edit.new_end_position,
- point_sub(range.end_point, edit.old_end_position),
- );
- layer.flags = LayerUpdateFlags::MODIFIED;
- }
- // If the edit is an insertion at the start of the tree, shift
- else if edit.start_byte == range.start_byte && is_pure_insertion {
- range.start_byte = edit.new_end_byte;
- range.start_point = edit.new_end_position;
- layer.flags |= LayerUpdateFlags::MOVED;
- } else {
- range.end_byte = range
- .end_byte
- .saturating_sub(edit.old_end_byte)
- .saturating_add(edit.new_end_byte);
- range.end_point = point_add(
- edit.new_end_position,
- point_sub(range.end_point, edit.old_end_position),
- );
- layer.flags = LayerUpdateFlags::MODIFIED;
- }
- }
- }
- }
-
- let hash = layers_hasher.hash_one(layer);
- // Safety: insert_no_grow is unsafe because it assumes that the table
- // has enough capacity to hold additional elements.
- // This is always the case as we reserved enough capacity above.
- unsafe { layers_table.insert_no_grow(hash, layer_id) };
- }
-
- PARSER.with(|ts_parser| {
- let ts_parser = &mut ts_parser.borrow_mut();
- ts_parser.parser.set_timeout_micros(1000 * 500); // half a second is pretty generours
- let mut cursor = ts_parser.cursors.pop().unwrap_or_else(QueryCursor::new);
- // TODO: might need to set cursor range
- cursor.set_byte_range(0..usize::MAX);
- cursor.set_match_limit(TREE_SITTER_MATCH_LIMIT);
-
- let source_slice = source.slice(..);
-
- while let Some(layer_id) = queue.pop_front() {
- let layer = &mut self.layers[layer_id];
-
- // Mark the layer as touched
- layer.flags |= LayerUpdateFlags::TOUCHED;
-
- // If a tree already exists, notify it of changes.
- if let Some(tree) = &mut layer.tree {
- if layer
- .flags
- .intersects(LayerUpdateFlags::MODIFIED | LayerUpdateFlags::MOVED)
- {
- for edit in edits.iter().rev() {
- // Apply the edits in reverse.
- // If we applied them in order then edit 1 would disrupt the positioning of edit 2.
- tree.edit(edit);
- }
- }
-
- if layer.flags.contains(LayerUpdateFlags::MODIFIED) {
- // Re-parse the tree.
- layer.parse(&mut ts_parser.parser, source)?;
- }
- } else {
- // always parse if this layer has never been parsed before
- layer.parse(&mut ts_parser.parser, source)?;
- }
-
- // Switch to an immutable borrow.
- let layer = &self.layers[layer_id];
-
- // Process injections.
- let matches = cursor.matches(
- &layer.config.injections_query,
- layer.tree().root_node(),
- RopeProvider(source_slice),
- );
- let mut combined_injections = vec![
- (None, Vec::new(), IncludedChildren::default());
- layer.config.combined_injections_patterns.len()
- ];
- let mut injections = Vec::new();
- let mut last_injection_end = 0;
- for mat in matches {
- let (injection_capture, content_node, included_children) = layer
- .config
- .injection_for_match(&layer.config.injections_query, &mat, source_slice);
-
- // in case this is a combined injection save it for more processing later
- if let Some(combined_injection_idx) = layer
- .config
- .combined_injections_patterns
- .iter()
- .position(|&pattern| pattern == mat.pattern_index)
- {
- let entry = &mut combined_injections[combined_injection_idx];
- if injection_capture.is_some() {
- entry.0 = injection_capture;
- }
- if let Some(content_node) = content_node {
- if content_node.start_byte() >= last_injection_end {
- entry.1.push(content_node);
- last_injection_end = content_node.end_byte();
- }
- }
- entry.2 = included_children;
- continue;
- }
-
- // Explicitly remove this match so that none of its other captures will remain
- // in the stream of captures.
- mat.remove();
-
- // If a language is found with the given name, then add a new language layer
- // to the highlighted document.
- if let (Some(injection_capture), Some(content_node)) =
- (injection_capture, content_node)
- {
- if let Some(config) = (injection_callback)(&injection_capture) {
- let ranges =
- intersect_ranges(&layer.ranges, &[content_node], included_children);
-
- if !ranges.is_empty() {
- if content_node.start_byte() < last_injection_end {
- continue;
- }
- last_injection_end = content_node.end_byte();
- injections.push((config, ranges));
- }
- }
- }
- }
-
- for (lang_name, content_nodes, included_children) in combined_injections {
- if let (Some(lang_name), false) = (lang_name, content_nodes.is_empty()) {
- if let Some(config) = (injection_callback)(&lang_name) {
- let ranges =
- intersect_ranges(&layer.ranges, &content_nodes, included_children);
- if !ranges.is_empty() {
- injections.push((config, ranges));
- }
- }
- }
- }
-
- let depth = layer.depth + 1;
- // TODO: can't inline this since matches borrows self.layers
- for (config, ranges) in injections {
- let parent = Some(layer_id);
- let new_layer = LanguageLayer {
- tree: None,
- config,
- depth,
- ranges,
- flags: LayerUpdateFlags::empty(),
- parent: None,
- };
-
- // Find an identical existing layer
- let layer = layers_table
- .get(layers_hasher.hash_one(&new_layer), |&it| {
- self.layers[it] == new_layer
- })
- .copied();
-
- // ...or insert a new one.
- let layer_id = layer.unwrap_or_else(|| self.layers.insert(new_layer));
- self.layers[layer_id].parent = parent;
-
- queue.push_back(layer_id);
- }
-
- // TODO: pre-process local scopes at this time, rather than highlight?
- // would solve problems with locals not working across boundaries
- }
-
- // Return the cursor back in the pool.
- ts_parser.cursors.push(cursor);
-
- // Reset all `LayerUpdateFlags` and remove all untouched layers
- self.layers.retain(|_, layer| {
- replace(&mut layer.flags, LayerUpdateFlags::empty())
- .contains(LayerUpdateFlags::TOUCHED)
- });
-
- Ok(())
- })
- }
-}
-
-/// Compute the ranges that should be included when parsing an injection.
-/// This takes into account three things:
-/// * `parent_ranges` - The ranges must all fall within the *current* layer's ranges.
-/// * `nodes` - Every injection takes place within a set of nodes. The injection ranges
-/// are the ranges of those nodes.
-/// * `includes_children` - For some injections, the content nodes' children should be
-/// excluded from the nested document, so that only the content nodes' *own* content
-/// is reparsed. For other injections, the content nodes' entire ranges should be
-/// reparsed, including the ranges of their children.
-fn intersect_ranges(
- parent_ranges: &[Range],
- nodes: &[Node],
- included_children: IncludedChildren,
-) -> Vec<Range> {
- let mut cursor = nodes[0].walk();
- let mut result = Vec::new();
- let mut parent_range_iter = parent_ranges.iter();
- let mut parent_range = parent_range_iter
- .next()
- .expect("Layers should only be constructed with non-empty ranges vectors");
- for node in nodes.iter() {
- let mut preceding_range = Range {
- start_byte: 0,
- start_point: Point::new(0, 0),
- end_byte: node.start_byte(),
- end_point: node.start_position(),
- };
- let following_range = Range {
- start_byte: node.end_byte(),
- start_point: node.end_position(),
- end_byte: usize::MAX,
- end_point: Point::new(usize::MAX, usize::MAX),
- };
-
- for excluded_range in node
- .children(&mut cursor)
- .filter_map(|child| match included_children {
- IncludedChildren::None => Some(child.range()),
- IncludedChildren::All => None,
- IncludedChildren::Unnamed => {
- if child.is_named() {
- Some(child.range())
- } else {
- None
- }
- }
- })
- .chain([following_range].iter().cloned())
- {
- let mut range = Range {
- start_byte: preceding_range.end_byte,
- start_point: preceding_range.end_point,
- end_byte: excluded_range.start_byte,
- end_point: excluded_range.start_point,
- };
- preceding_range = excluded_range;
-
- if range.end_byte < parent_range.start_byte {
- continue;
- }
-
- while parent_range.start_byte <= range.end_byte {
- if parent_range.end_byte > range.start_byte {
- if range.start_byte < parent_range.start_byte {
- range.start_byte = parent_range.start_byte;
- range.start_point = parent_range.start_point;
- }
-
- if parent_range.end_byte < range.end_byte {
- if range.start_byte < parent_range.end_byte {
- result.push(Range {
- start_byte: range.start_byte,
- start_point: range.start_point,
- end_byte: parent_range.end_byte,
- end_point: parent_range.end_point,
- });
- }
- range.start_byte = parent_range.end_byte;
- range.start_point = parent_range.end_point;
- } else {
- if range.start_byte < range.end_byte {
- result.push(range);
- }
- break;
- }
- }
-
- if let Some(next_range) = parent_range_iter.next() {
- parent_range = next_range;
- } else {
- return result;
- }
- }
- }
- }
- result
-}
-
-impl LanguageLayer {
- fn parse(&mut self, parser: &mut Parser, source: RopeSlice) -> Result<(), Error> {
- parser
- .set_included_ranges(&self.ranges)
- .map_err(|_| Error::InvalidRanges)?;
-
- parser
- .set_language(&self.config.language)
- .map_err(|_| Error::InvalidLanguage)?;
-
- // unsafe { syntax.parser.set_cancellation_flag(cancellation_flag) };
- let tree = parser
- .parse_with(
- &mut |byte, _| {
- if byte <= source.len_bytes() {
- let (chunk, start_byte, _, _) = source.chunk_at_byte(byte);
- &chunk.as_bytes()[byte - start_byte..]
- } else {
- // out of range
- &[]
- }
- },
- self.tree.as_ref(),
- )
- .ok_or(Error::Cancelled)?;
- // unsafe { ts_parser.parser.set_cancellation_flag(None) };
- self.tree = Some(tree);
- Ok(())
- }
-}
+// impl Syntax {
+// pub fn update(
+// &mut self,
+// source: RopeSlice,
+// edits: Vec<tree_sitter::InputEdit>,
+// injection_callback: impl Fn(&InjectionLanguageMarker) -> Option<Arc<HighlightConfiguration>>,
+// ) -> Result<(), Error> {
+// let mut queue = VecDeque::new();
+// queue.push_back(self.root);
+
+// // This table allows inverse indexing of `layers`.
+// // That is by hashing a `Layer` you can find
+// // the `LayerId` of an existing equivalent `Layer` in `layers`.
+// //
+// // It is used to determine if a new layer exists for an injection
+// // or if an existing layer needs to be updated.
+// let mut layers_table = RawTable::with_capacity(self.layers.len());
+// let layers_hasher = RandomState::new();
+// // Use the edits to update all layers markers
+// fn point_add(a: Point, b: Point) -> Point {
+// if b.row > 0 {
+// Point::new(a.row.saturating_add(b.row), b.column)
+// } else {
+// Point::new(0, a.column.saturating_add(b.column))
+// }
+// }
+// fn point_sub(a: Point, b: Point) -> Point {
+// if a.row > b.row {
+// Point::new(a.row.saturating_sub(b.row), a.column)
+// } else {
+// Point::new(0, a.column.saturating_sub(b.column))
+// }
+// }
+
+// for (layer_id, layer) in self.layers.iter_mut() {
+// // The root layer always covers the whole range (0..usize::MAX)
+// if layer.depth == 0 {
+// layer.flags = LayerUpdateFlags::MODIFIED;
+// continue;
+// }
+
+// if !edits.is_empty() {
+// for range in &mut layer.ranges {
+// // Roughly based on https://github.com/tree-sitter/tree-sitter/blob/ddeaa0c7f534268b35b4f6cb39b52df082754413/lib/src/subtree.c#L691-L720
+// for edit in edits.iter().rev() {
+// let is_pure_insertion = edit.old_end_byte == edit.start_byte;
+
+// // if edit is after range, skip
+// if edit.start_byte > range.end_byte {
+// // TODO: || (is_noop && edit.start_byte == range.end_byte)
+// continue;
+// }
+
+// // if edit is before range, shift entire range by len
+// if edit.old_end_byte < range.start_byte {
+// range.start_byte =
+// edit.new_end_byte + (range.start_byte - edit.old_end_byte);
+// range.start_point = point_add(
+// edit.new_end_position,
+// point_sub(range.start_point, edit.old_end_position),
+// );
+
+// range.end_byte = edit
+// .new_end_byte
+// .saturating_add(range.end_byte - edit.old_end_byte);
+// range.end_point = point_add(
+// edit.new_end_position,
+// point_sub(range.end_point, edit.old_end_position),
+// );
+
+// layer.flags |= LayerUpdateFlags::MOVED;
+// }
+// // if the edit starts in the space before and extends into the range
+// else if edit.start_byte < range.start_byte {
+// range.start_byte = edit.new_end_byte;
+// range.start_point = edit.new_end_position;
+
+// range.end_byte = range
+// .end_byte
+// .saturating_sub(edit.old_end_byte)
+// .saturating_add(edit.new_end_byte);
+// range.end_point = point_add(
+// edit.new_end_position,
+// point_sub(range.end_point, edit.old_end_position),
+// );
+// layer.flags = LayerUpdateFlags::MODIFIED;
+// }
+// // If the edit is an insertion at the start of the tree, shift
+// else if edit.start_byte == range.start_byte && is_pure_insertion {
+// range.start_byte = edit.new_end_byte;
+// range.start_point = edit.new_end_position;
+// layer.flags |= LayerUpdateFlags::MOVED;
+// } else {
+// range.end_byte = range
+// .end_byte
+// .saturating_sub(edit.old_end_byte)
+// .saturating_add(edit.new_end_byte);
+// range.end_point = point_add(
+// edit.new_end_position,
+// point_sub(range.end_point, edit.old_end_position),
+// );
+// layer.flags = LayerUpdateFlags::MODIFIED;
+// }
+// }
+// }
+// }
+
+// let hash = layers_hasher.hash_one(layer);
+// // Safety: insert_no_grow is unsafe because it assumes that the table
+// // has enough capacity to hold additional elements.
+// // This is always the case as we reserved enough capacity above.
+// unsafe { layers_table.insert_no_grow(hash, layer_id) };
+// }
+
+// PARSER.with(|ts_parser| {
+// let ts_parser = &mut ts_parser.borrow_mut();
+// ts_parser.parser.set_timeout_micros(1000 * 500); // half a second is pretty generours
+// let mut cursor = ts_parser.cursors.pop().unwrap_or_else(QueryCursor::new);
+// // TODO: might need to set cursor range
+// cursor.set_byte_range(0..usize::MAX);
+// cursor.set_match_limit(TREE_SITTER_MATCH_LIMIT);
+
+// let source_slice = source.slice(..);
+
+// while let Some(layer_id) = queue.pop_front() {
+// let layer = &mut self.layers[layer_id];
+
+// // Mark the layer as touched
+// layer.flags |= LayerUpdateFlags::TOUCHED;
+
+// // If a tree already exists, notify it of changes.
+// if let Some(tree) = &mut layer.parse_tree {
+// if layer
+// .flags
+// .intersects(LayerUpdateFlags::MODIFIED | LayerUpdateFlags::MOVED)
+// {
+// for edit in edits.iter().rev() {
+// // Apply the edits in reverse.
+// // If we applied them in order then edit 1 would disrupt the positioning of edit 2.
+// tree.edit(edit);
+// }
+// }
+
+// if layer.flags.contains(LayerUpdateFlags::MODIFIED) {
+// // Re-parse the tree.
+// layer.parse(&mut ts_parser.parser, source)?;
+// }
+// } else {
+// // always parse if this layer has never been parsed before
+// layer.parse(&mut ts_parser.parser, source)?;
+// }
+
+// // Switch to an immutable borrow.
+// let layer = &self.layers[layer_id];
+
+// // Process injections.
+// let matches = cursor.matches(
+// &layer.config.injections_query,
+// layer.tree().root_node(),
+// RopeProvider(source_slice),
+// );
+// let mut combined_injections = vec![
+// (None, Vec::new(), IncludedChildren::default());
+// layer.config.combined_injections_patterns.len()
+// ];
+// let mut injections = Vec::new();
+// let mut last_injection_end = 0;
+// for mat in matches {
+// let (injection_capture, content_node, included_children) = layer
+// .config
+// .injection_for_match(&layer.config.injections_query, &mat, source_slice);
+
+// // in case this is a combined injection save it for more processing later
+// if let Some(combined_injection_idx) = layer
+// .config
+// .combined_injections_patterns
+// .iter()
+// .position(|&pattern| pattern == mat.pattern_index)
+// {
+// let entry = &mut combined_injections[combined_injection_idx];
+// if injection_capture.is_some() {
+// entry.0 = injection_capture;
+// }
+// if let Some(content_node) = content_node {
+// if content_node.start_byte() >= last_injection_end {
+// entry.1.push(content_node);
+// last_injection_end = content_node.end_byte();
+// }
+// }
+// entry.2 = included_children;
+// continue;
+// }
+
+// // Explicitly remove this match so that none of its other captures will remain
+// // in the stream of captures.
+// mat.remove();
+
+// // If a language is found with the given name, then add a new language layer
+// // to the highlighted document.
+// if let (Some(injection_capture), Some(content_node)) =
+// (injection_capture, content_node)
+// {
+// if let Some(config) = (injection_callback)(&injection_capture) {
+// let ranges =
+// intersect_ranges(&layer.ranges, &[content_node], included_children);
+
+// if !ranges.is_empty() {
+// if content_node.start_byte() < last_injection_end {
+// continue;
+// }
+// last_injection_end = content_node.end_byte();
+// injections.push((config, ranges));
+// }
+// }
+// }
+// }
+
+// for (lang_name, content_nodes, included_children) in combined_injections {
+// if let (Some(lang_name), false) = (lang_name, content_nodes.is_empty()) {
+// if let Some(config) = (injection_callback)(&lang_name) {
+// let ranges =
+// intersect_ranges(&layer.ranges, &content_nodes, included_children);
+// if !ranges.is_empty() {
+// injections.push((config, ranges));
+// }
+// }
+// }
+// }
+
+// let depth = layer.depth + 1;
+// // TODO: can't inline this since matches borrows self.layers
+// for (config, ranges) in injections {
+// let parent = Some(layer_id);
+// let new_layer = LanguageLayer {
+// parse_tree: None,
+// config,
+// depth,
+// ranges,
+// flags: LayerUpdateFlags::empty(),
+// parent: None,
+// };
+
+// // Find an identical existing layer
+// let layer = layers_table
+// .get(layers_hasher.hash_one(&new_layer), |&it| {
+// self.layers[it] == new_layer
+// })
+// .copied();
+
+// // ...or insert a new one.
+// let layer_id = layer.unwrap_or_else(|| self.layers.insert(new_layer));
+// self.layers[layer_id].parent = parent;
+
+// queue.push_back(layer_id);
+// }
+
+// // TODO: pre-process local scopes at this time, rather than highlight?
+// // would solve problems with locals not working across boundaries
+// }
+
+// // Return the cursor back in the pool.
+// ts_parser.cursors.push(cursor);
+
+// // Reset all `LayerUpdateFlags` and remove all untouched layers
+// self.layers.retain(|_, layer| {
+// replace(&mut layer.flags, LayerUpdateFlags::empty())
+// .contains(LayerUpdateFlags::TOUCHED)
+// });
+
+// Ok(())
+// })
+// }
+// }
+
+// /// Compute the ranges that should be included when parsing an injection.
+// /// This takes into account three things:
+// /// * `parent_ranges` - The ranges must all fall within the *current* layer's ranges.
+// /// * `nodes` - Every injection takes place within a set of nodes. The injection ranges
+// /// are the ranges of those nodes.
+// /// * `includes_children` - For some injections, the content nodes' children should be
+// /// excluded from the nested document, so that only the content nodes' *own* content
+// /// is reparsed. For other injections, the content nodes' entire ranges should be
+// /// reparsed, including the ranges of their children.
+// fn intersect_ranges(
+// parent_ranges: &[Range],
+// nodes: &[Node],
+// included_children: IncludedChildren,
+// ) -> Vec<Range> {
+// let mut cursor = nodes[0].walk();
+// let mut result = Vec::new();
+// let mut parent_range_iter = parent_ranges.iter();
+// let mut parent_range = parent_range_iter
+// .next()
+// .expect("Layers should only be constructed with non-empty ranges vectors");
+// for node in nodes.iter() {
+// let mut preceding_range = Range {
+// start_byte: 0,
+// start_point: Point::new(0, 0),
+// end_byte: node.start_byte(),
+// end_point: node.start_position(),
+// };
+// let following_range = Range {
+// start_byte: node.end_byte(),
+// start_point: node.end_position(),
+// end_byte: usize::MAX,
+// end_point: Point::new(usize::MAX, usize::MAX),
+// };
+
+// for excluded_range in node
+// .children(&mut cursor)
+// .filter_map(|child| match included_children {
+// IncludedChildren::None => Some(child.range()),
+// IncludedChildren::All => None,
+// IncludedChildren::Unnamed => {
+// if child.is_named() {
+// Some(child.range())
+// } else {
+// None
+// }
+// }
+// })
+// .chain([following_range].iter().cloned())
+// {
+// let mut range = Range {
+// start_byte: preceding_range.end_byte,
+// start_point: preceding_range.end_point,
+// end_byte: excluded_range.start_byte,
+// end_point: excluded_range.start_point,
+// };
+// preceding_range = excluded_range;
+
+// if range.end_byte < parent_range.start_byte {
+// continue;
+// }
+
+// while parent_range.start_byte <= range.end_byte {
+// if parent_range.end_byte > range.start_byte {
+// if range.start_byte < parent_range.start_byte {
+// range.start_byte = parent_range.start_byte;
+// range.start_point = parent_range.start_point;
+// }
+
+// if parent_range.end_byte < range.end_byte {
+// if range.start_byte < parent_range.end_byte {
+// result.push(Range {
+// start_byte: range.start_byte,
+// start_point: range.start_point,
+// end_byte: parent_range.end_byte,
+// end_point: parent_range.end_point,
+// });
+// }
+// range.start_byte = parent_range.end_byte;
+// range.start_point = parent_range.end_point;
+// } else {
+// if range.start_byte < range.end_byte {
+// result.push(range);
+// }
+// break;
+// }
+// }
+
+// if let Some(next_range) = parent_range_iter.next() {
+// parent_range = next_range;
+// } else {
+// return result;
+// }
+// }
+// }
+// }
+// result
+// }
+
+// impl LanguageLayer {
+// fn parse(&mut self, parser: &mut Parser, source: RopeSlice) -> Result<(), Error> {
+// parser
+// .set_included_ranges(&self.ranges)
+// .map_err(|_| Error::InvalidRanges)?;
+
+// parser
+// .set_language(&self.config.language)
+// .map_err(|_| Error::InvalidLanguage)?;
+
+// // unsafe { syntax.parser.set_cancellation_flag(cancellation_flag) };
+// let tree = parser
+// .parse_with(
+// &mut |byte, _| {
+// if byte <= source.len_bytes() {
+// let (chunk, start_byte, _, _) = source.chunk_at_byte(byte);
+// &chunk.as_bytes()[byte - start_byte..]
+// } else {
+// // out of range
+// &[]
+// }
+// },
+// self.parse_tree.as_ref(),
+// )
+// .ok_or(Error::Cancelled)?;
+// // unsafe { ts_parser.parser.set_cancellation_flag(None) };
+// self.parse_tree = Some(tree);
+// Ok(())
+// }
+// }