@@ -9,6 +9,7 @@ use crate::{
9pub use helix_syntax::get_language;
9pub use helix_syntax::get_language;
11use arc_swap::ArcSwap;
11use arc_swap::ArcSwap;
12+use slotmap::{DefaultKey as LayerId, HopSlotMap};
14 borrow::Cow,
15 borrow::Cow,
@@ -388,9 +389,9 @@ thread_local! {
389#[derive(Debug)]
390#[derive(Debug)]
390pub struct Syntax {
391pub struct Syntax {
391− config: Arc<HighlightConfiguration>,
392+ layers: HopSlotMap<LayerId, LanguageLayer>,
393− root_layer: LanguageLayer,
394+ loader: Arc<Loader>,
396fn byte_range_to_str(range: std::ops::Range<usize>, source: RopeSlice) -> Cow<str> {
397fn byte_range_to_str(range: std::ops::Range<usize>, source: RopeSlice) -> Cow<str> {
@@ -400,38 +401,36 @@ fn byte_range_to_str(range: std::ops::Range<usize>, source: RopeSlice) -> Cow<st
402impl Syntax {
403impl Syntax {
403− // buffer, grammar, config, grammars, sync_timeout?
405− /*language: Lang,*/ source: &Rope,
406− config: Arc<HighlightConfiguration>,
404+ pub fn new(source: &Rope, config: Arc<HighlightConfiguration>, loader: Arc<Loader>) -> Self {
408− let root_layer = LanguageLayer { tree: None };
405+ let root_layer = LanguageLayer {
409+ ranges: vec![Range {
411+ end_byte: usize::MAX,
412+ start_point: Point::new(0, 0),
413+ end_point: Point::new(usize::MAX, usize::MAX),
410 // track markers of injections
417 // track markers of injections
411 // track scope_descriptor: a Vec of scopes for item in tree
418 // track scope_descriptor: a Vec of scopes for item in tree
420+ let mut layers = HopSlotMap::default();
421+ let root = layers.insert(root_layer);
413 let mut syntax = Self {
423 let mut syntax = Self {
414 // grammar,
424 // grammar,
416− root_layer,
426+ layers,
419− // update root layer
430+ syntax
420− PARSER.with(|ts_parser| {
431+ .update(source, source, &ChangeSet::new(&source))
421− // TODO: handle the returned `Result` properly.
432+ .unwrap();
422− let _ = syntax.root_layer.parse(
433+
423− &mut ts_parser.borrow_mut(),
429− end_byte: usize::MAX,
430− start_point: Point::new(0, 0),
431− end_point: Point::new(usize::MAX, usize::MAX),
@@ -441,30 +440,197 @@ impl Syntax {
441 source: &Rope,
440 source: &Rope,
442 changeset: &ChangeSet,
441 changeset: &ChangeSet,
443 ) -> Result<(), Error> {
442 ) -> Result<(), Error> {
443+ use std::collections::VecDeque;
444+ let mut queue = VecDeque::new();
445+ // let source = source.slice(..);
446+ let injection_callback = |language: &str| {
448+ .language_configuration_for_injection_string(language)
449+ .and_then(|language_config| {
450+ // TODO: get these theme.scopes from somewhere, probably make them settable on Loader
460+ "punctuation.bracket",
461+ "punctuation.delimiter",
469+ "variable.parameter",
471+ language_config.highlight_config(
474+ .map(|scope| scope.to_string())
475+ .collect::<Vec<_>>(),
480+ queue.push_back(self.root);
482+ // HAXX: for now, clear all layers except root so they get re-parsed
483+ self.layers.retain(|id, _| id == self.root);
485+ // Workaround for Syntax::new() with empty changeset
486+ if !changeset.is_empty() {
487+ // TODO: do this in a recursive way
488+ // Notify the tree about all the changes
489+ let edits = generate_edits(old_source.slice(..), changeset);
490+ let tree = self.layers[self.root].tree.as_mut().unwrap();
491+ for edit in edits.iter().rev() {
492+ // apply the edits in reverse. If we applied them in order then edit 1 would disrupt
493+ // the positioning of edit 2
444 PARSER.with(|ts_parser| {
498 PARSER.with(|ts_parser| {
445− self.root_layer.update(
446− &mut ts_parser.borrow_mut(),
499+ let ts_parser = &mut ts_parser.borrow_mut();
447− &self.config,
500+ let mut cursor = ts_parser.cursors.pop().unwrap_or_else(QueryCursor::new);
448− old_source,
501+ // TODO: might need to set cursor range
503+ while let Some(layer_id) = queue.pop_front() {
504+ // Re-parse the tree.
505+ self.layers[layer_id].parse(ts_parser, source)?;
507+ let source = source.slice(..);
508+ let layer = &self.layers[layer_id];
510+ // Process injections.
511+ let matches = cursor.matches(
512+ &layer.config.injections_query,
513+ layer.tree().root_node(),
449− source,
514+ RopeProvider(source),
516+ let mut injections = Vec::new();
517+ for mat in matches {
518+ let (language_name, content_node, include_children) = injection_for_match(
520+ &layer.config.injections_query,
525+ // Explicitly remove this match so that none of its other captures will remain
526+ // in the stream of captures.
527+ mat.remove(); // TODO: is this still necessary?
529+ // If a language is found with the given name, then add a new language layer
530+ // to the highlighted document.
531+ if let (Some(language_name), Some(content_node)) = (language_name, content_node)
533+ if let Some(config) = (injection_callback)(&language_name) {
535+ intersect_ranges(&layer.ranges, &[content_node], include_children);
537+ if !ranges.is_empty() {
538+ log::info!("{} {:?}", language_name, ranges);
539+ injections.push((config, ranges));
454− // TODO: deal with injections and update them too
545+ // Process combined injections.
546+ if let Some(combined_injections_query) = &layer.config.combined_injections_query {
547+ let mut injections_by_pattern_index =
548+ vec![(None, Vec::new(), false); combined_injections_query.pattern_count()];
549+ let matches = cursor.matches(
550+ combined_injections_query,
551+ layer.tree().root_node(),
552+ RopeProvider(source),
554+ for mat in matches {
555+ let entry = &mut injections_by_pattern_index[mat.pattern_index];
556+ let (language_name, content_node, include_children) = injection_for_match(
558+ combined_injections_query,
562+ if language_name.is_some() {
563+ entry.0 = language_name;
565+ if let Some(content_node) = content_node {
566+ entry.1.push(content_node);
568+ entry.2 = include_children;
570+ for (lang_name, content_nodes, includes_children) in injections_by_pattern_index
572+ if let (Some(lang_name), false) = (lang_name, content_nodes.is_empty()) {
573+ if let Some(config) = (injection_callback)(&lang_name) {
574+ let ranges = intersect_ranges(
579+ if !ranges.is_empty() {
580+ injections.push((config, ranges));
587+ let depth = layer.depth + 1;
588+ // TODO: can't inline this since matches borrows self.layers
589+ for (config, ranges) in injections {
590+ let layer_id = self.layers.insert(LanguageLayer {
596+ queue.push_back(layer_id);
600+ // Return the cursor back in the pool.
601+ ts_parser.cursors.push(cursor);
603+ Ok(()) // so we can use the try operator
457 // fn buffer_changed -> call layer.update(range, new_text) on root layer and then all marker layers
609 // fn buffer_changed -> call layer.update(range, new_text) on root layer and then all marker layers
459 // call this on transaction.apply() -> buffer_changed(changes)
610 // call this on transaction.apply() -> buffer_changed(changes)
461− // fn parse(language, old_tree, ranges)
463 pub fn tree(&self) -> &Tree {
612 pub fn tree(&self) -> &Tree {
464− self.root_layer.tree()
613+ self.layers[self.root].tree()
617+ // injections: Vec<(Tree, Range marker)>
619+ // handle updates that go over a part of the layer by truncating them to start/end appropriately
621+ // injections tracked by marker:
622+ // if marker areas match it's fine and update
623+ // if not found add new layer
624+ // if length 0 then area got removed, clean up the layer
467− // <!--update_for_injection(grammar)-->
626+ // layer update:
627+ // if range.len = 0 then remove the layer
628+ // for change in changes { tree.edit(change) }
629+ // tree = parser.parse(.., tree, ..)
630+ // calculate affected range and update injections
631+ // injection update:
632+ // look for existing injections
633+ // if present, range = (first injection start, last injection end)
469 // Highlighting
635 // Highlighting
@@ -474,61 +640,76 @@ impl Syntax {
474 source: RopeSlice<'a>,
640 source: RopeSlice<'a>,
475 range: Option<std::ops::Range<usize>>,
641 range: Option<std::ops::Range<usize>>,
476 cancellation_flag: Option<&'a AtomicUsize>,
642 cancellation_flag: Option<&'a AtomicUsize>,
477− injection_callback: impl FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a,
478 ) -> impl Iterator<Item = Result<HighlightEvent, Error>> + 'a {
643 ) -> impl Iterator<Item = Result<HighlightEvent, Error>> + 'a {
644+ let mut layers = self
648+ // Reuse a cursor from the pool if available.
649+ let mut cursor = PARSER.with(|ts_parser| {
650+ let highlighter = &mut ts_parser.borrow_mut();
651+ highlighter.cursors.pop().unwrap_or_else(QueryCursor::new)
479− // The `captures` iterator borrows the `Tree` and the `QueryCursor`, which
654+ // The `captures` iterator borrows the `Tree` and the `QueryCursor`, which
480− // prevents them from being moved. But both of these values are really just
655+ // prevents them from being moved. But both of these values are really just
481− // pointers, so it's actually ok to move them.
656+ // pointers, so it's actually ok to move them.
482−
657+ let cursor_ref =
483− // reuse a cursor from the pool if possible
658+ unsafe { mem::transmute::<_, &'static mut QueryCursor>(&mut cursor) };
484− let mut cursor = PARSER.with(|ts_parser| {
659+
485− let highlighter = &mut ts_parser.borrow_mut();
660+ // if reusing cursors & no range this resets to whole range
486− highlighter.cursors.pop().unwrap_or_else(QueryCursor::new)
661+ // TODO: handle intersect (range & layer.range)
662+ // cursor_ref.set_byte_range(range.clone().unwrap_or(0..usize::MAX));
663+ cursor_ref.set_byte_range(0..usize::MAX);
665+ let captures = cursor_ref
667+ &layer.config.query,
668+ layer.tree().root_node(),
669+ RopeProvider(source),
673+ HighlightIterLayer {
674+ highlight_end_stack: Vec::new(),
675+ scope_stack: vec![LocalScope {
677+ range: 0..usize::MAX,
678+ local_defs: Vec::new(),
683+ config: layer.config.as_ref(), // TODO: just reuse
684+ depth: layer.depth, // TODO: just reuse
685+ ranges: layer.ranges.clone(),
688+ .collect::<Vec<_>>();
692+ // HAXX: arrange layers by byte range, with deeper layers positioned first
693+ layers.sort_by_key(|layer| {
695+ layer.ranges.first().cloned(),
696+ std::cmp::Reverse(layer.depth),
488− let tree_ref = self.tree();
489− let cursor_ref = unsafe { mem::transmute::<_, &'static mut QueryCursor>(&mut cursor) };
490− let query_ref = &self.config.query;
491− let config_ref = self.config.as_ref();
493− // if reusing cursors & no range this resets to whole range
494− cursor_ref.set_byte_range(range.clone().unwrap_or(0..usize::MAX));
496− let captures = cursor_ref
497− .captures(query_ref, tree_ref.root_node(), RopeProvider(source))
500− // manually craft the root layer based on the existing tree
501− let layer = HighlightIterLayer {
502− highlight_end_stack: Vec::new(),
503− scope_stack: vec![LocalScope {
505− range: 0..usize::MAX,
506− local_defs: Vec::new(),
513− ranges: vec![Range {
515− end_byte: usize::MAX,
516− start_point: Point::new(0, 0),
517− end_point: Point::new(usize::MAX, usize::MAX),
521 let mut result = HighlightIter {
700 let mut result = HighlightIter {
523 byte_offset: range.map_or(0, |r| r.start), // TODO: simplify
702 byte_offset: range.map_or(0, |r| r.start), // TODO: simplify
525 cancellation_flag,
703 cancellation_flag,
526 iter_count: 0,
704 iter_count: 0,
527− layers: vec![layer],
705+ layers,
528 next_event: None,
706 next_event: None,
529 last_highlight_range: None,
707 last_highlight_range: None,
531 result.sort_layers();
709 result.sort_layers();
710+ for layer in &result.layers {
711+ log::info!("> {:?} {:?}", layer.depth, layer.ranges); // <- for some reason layers are reversed here
534 // on_tokenize
715 // on_tokenize
@@ -556,234 +737,155 @@ impl Syntax {
556pub struct LanguageLayer {
737pub struct LanguageLayer {
558 // grammar
739 // grammar
559− // depth
740+ pub config: Arc<HighlightConfiguration>,
560 pub(crate) tree: Option<Tree>,
741 pub(crate) tree: Option<Tree>,
742+ pub ranges: Vec<Range>,
563impl LanguageLayer {
746impl LanguageLayer {
564− // pub fn new() -> Self {
565− // Self { tree: None }
568 pub fn tree(&self) -> &Tree {
747 pub fn tree(&self) -> &Tree {
569 // TODO: no unwrap
748 // TODO: no unwrap
570 self.tree.as_ref().unwrap()
749 self.tree.as_ref().unwrap()
575− ts_parser: &mut TsParser,
752+ fn parse(&mut self, ts_parser: &mut TsParser, source: &Rope) -> Result<(), Error> {
576− config: &HighlightConfiguration,
580− ) -> Result<(), Error> {
581− if ts_parser.parser.set_included_ranges(&ranges).is_ok() {
753+ ts_parser.parser.set_included_ranges(&self.ranges).unwrap();
582− ts_parser
755+ ts_parser
584− .set_language(config.language)
757+ .set_language(self.config.language)
585− .map_err(|_| Error::InvalidLanguage)?;
758+ .map_err(|_| Error::InvalidLanguage)?;
587− // unsafe { syntax.parser.set_cancellation_flag(cancellation_flag) };
760+ // unsafe { syntax.parser.set_cancellation_flag(cancellation_flag) };
588− let tree = ts_parser
761+ let tree = ts_parser
590− .parse_with(
763+ .parse_with(
591− &mut |byte, _| {
764+ &mut |byte, _| {
592− if byte <= source.len_bytes() {
765+ if byte <= source.len_bytes() {
593− let (chunk, start_byte, _, _) = source.chunk_at_byte(byte);
766+ let (chunk, start_byte, _, _) = source.chunk_at_byte(byte);
594− chunk[byte - start_byte..].as_bytes()
767+ chunk[byte - start_byte..].as_bytes()
595− } else {
768+ } else {
596− // out of range
769+ // out of range
600− self.tree.as_ref(),
773+ self.tree.as_ref(),
602− .ok_or(Error::Cancelled)?;
775+ .ok_or(Error::Cancelled)?;
603−
776+ // unsafe { ts_parser.parser.set_cancellation_flag(None) };
604− self.tree = Some(tree)
777+ self.tree = Some(tree);
609− pub(crate) fn generate_edits(
782+pub(crate) fn generate_edits(
610− old_text: RopeSlice,
783+ old_text: RopeSlice,
611− changeset: &ChangeSet,
784+ changeset: &ChangeSet,
612− ) -> Vec<tree_sitter::InputEdit> {
785+) -> Vec<tree_sitter::InputEdit> {
613− use Operation::*;
786+ use Operation::*;
614− let mut old_pos = 0;
787+ let mut old_pos = 0;
616− let mut edits = Vec::new();
789+ let mut edits = Vec::new();
618− let mut iter = changeset.changes.iter().peekable();
791+ let mut iter = changeset.changes.iter().peekable();
620− // TODO; this is a lot easier with Change instead of Operation.
793+ // TODO; this is a lot easier with Change instead of Operation.
622− fn point_at_pos(text: RopeSlice, pos: usize) -> (usize, Point) {
795+ fn point_at_pos(text: RopeSlice, pos: usize) -> (usize, Point) {
623− let byte = text.char_to_byte(pos); // <- attempted to index past end
796+ let byte = text.char_to_byte(pos); // <- attempted to index past end
624− let line = text.char_to_line(pos);
797+ let line = text.char_to_line(pos);
625− let line_start_byte = text.line_to_byte(line);
798+ let line_start_byte = text.line_to_byte(line);
626− let col = byte - line_start_byte;
799+ let col = byte - line_start_byte;
628− (byte, Point::new(line, col))
801+ (byte, Point::new(line, col))
631− fn traverse(point: Point, text: &Tendril) -> Point {
804+ fn traverse(point: Point, text: &Tendril) -> Point {
632− let Point {
805+ let Point {
633− mut row,
806+ mut row,
634− mut column,
807+ mut column,
635− } = point;
808+ } = point;
637− // TODO: there should be a better way here.
810+ // TODO: there should be a better way here.
638− let mut chars = text.chars().peekable();
811+ let mut chars = text.chars().peekable();
639− while let Some(ch) = chars.next() {
812+ while let Some(ch) = chars.next() {
640− if char_is_line_ending(ch) && !(ch == '\r' && chars.peek() == Some(&'\n')) {
813+ if char_is_line_ending(ch) && !(ch == '\r' && chars.peek() == Some(&'\n')) {
641− row += 1;
814+ row += 1;
642− column = 0;
815+ column = 0;
643− } else {
816+ } else {
644− column += 1;
817+ column += 1;
647− Point { row, column }
820+ Point { row, column }
650− while let Some(change) = iter.next() {
823+ while let Some(change) = iter.next() {
651− let len = match change {
824+ let len = match change {
652− Delete(i) | Retain(i) => *i,
825+ Delete(i) | Retain(i) => *i,
653− Insert(_) => 0,
826+ Insert(_) => 0,
655− let mut old_end = old_pos + len;
828+ let mut old_end = old_pos + len;
833+ let (start_byte, start_position) = point_at_pos(old_text, old_pos);
834+ let (old_end_byte, old_end_position) = point_at_pos(old_text, old_end);
836+ // TODO: Position also needs to be byte based...
837+ // let byte = char_to_byte(old_pos)
838+ // let line = char_to_line(old_pos)
839+ // let line_start_byte = line_to_byte()
840+ // Position::new(line, line_start_byte - byte)
843+ edits.push(tree_sitter::InputEdit {
844+ start_byte, // old_pos to byte
845+ old_end_byte, // old_end to byte
846+ new_end_byte: start_byte, // old_pos to byte
847+ start_position, // old pos to coords
848+ old_end_position, // old_end to coords
849+ new_end_position: start_position, // old pos to coords
853+ let (start_byte, start_position) = point_at_pos(old_text, old_pos);
657− match change {
855+ // a subsequent delete means a replace, consume it
658− Retain(_) => {}
856+ if let Some(Delete(len)) = iter.peek() {
659− Delete(_) => {
857+ old_end = old_pos + len;
660− let (start_byte, start_position) = point_at_pos(old_text, old_pos);
661 let (old_end_byte, old_end_position) = point_at_pos(old_text, old_end);
858 let (old_end_byte, old_end_position) = point_at_pos(old_text, old_end);
663− // TODO: Position also needs to be byte based...
860+ iter.next();
664− // let byte = char_to_byte(old_pos)
665− // let line = char_to_line(old_pos)
666− // let line_start_byte = line_to_byte()
667− // Position::new(line, line_start_byte - byte)
669− // deletion
862+ // replacement
670 edits.push(tree_sitter::InputEdit {
863 edits.push(tree_sitter::InputEdit {
671− start_byte, // old_pos to byte
864+ start_byte, // old_pos to byte
672− old_end_byte, // old_end to byte
865+ old_end_byte, // old_end to byte
673− new_end_byte: start_byte, // old_pos to byte
866+ new_end_byte: start_byte + s.len(), // old_pos to byte + s.len()
674− start_position, // old pos to coords
867+ start_position, // old pos to coords
675− old_end_position, // old_end to coords
868+ old_end_position, // old_end to coords
676− new_end_position: start_position, // old pos to coords
869+ new_end_position: traverse(start_position, s), // old pos + chars, newlines matter too (iter over)
873+ edits.push(tree_sitter::InputEdit {
874+ start_byte, // old_pos to byte
875+ old_end_byte: start_byte, // same
876+ new_end_byte: start_byte + s.len(), // old_pos + s.len()
877+ start_position, // old pos to coords
878+ old_end_position: start_position, // same
879+ new_end_position: traverse(start_position, s), // old pos + chars, newlines matter too (iter over)
680− let (start_byte, start_position) = point_at_pos(old_text, old_pos);
682− // a subsequent delete means a replace, consume it
683− if let Some(Delete(len)) = iter.peek() {
684− old_end = old_pos + len;
685− let (old_end_byte, old_end_position) = point_at_pos(old_text, old_end);
690− edits.push(tree_sitter::InputEdit {
691− start_byte, // old_pos to byte
692− old_end_byte, // old_end to byte
693− new_end_byte: start_byte + s.len(), // old_pos to byte + s.len()
694− start_position, // old pos to coords
695− old_end_position, // old_end to coords
696− new_end_position: traverse(start_position, s), // old pos + chars, newlines matter too (iter over)
700− edits.push(tree_sitter::InputEdit {
701− start_byte, // old_pos to byte
702− old_end_byte: start_byte, // same
703− new_end_byte: start_byte + s.len(), // old_pos + s.len()
704− start_position, // old pos to coords
705− old_end_position: start_position, // same
706− new_end_position: traverse(start_position, s), // old pos + chars, newlines matter too (iter over)
718− ts_parser: &mut TsParser,
719− config: &HighlightConfiguration,
722− changeset: &ChangeSet,
723− ) -> Result<(), Error> {
724− if changeset.is_empty() {
727−
884+ old_pos = old_end;
728− let edits = Self::generate_edits(old_source.slice(..), changeset);
730− // Notify the tree about all the changes
731− for edit in edits.iter().rev() {
732− // apply the edits in reverse. If we applied them in order then edit 1 would disrupt
733− // the positioning of edit 2
734− self.tree.as_mut().unwrap().edit(edit);
742− // TODO: what to do about this range on update
745− end_byte: usize::MAX,
746− start_point: Point::new(0, 0),
747− end_point: Point::new(usize::MAX, usize::MAX),
752− // fn highlight_iter() -> same as Mode but for this layer. Mode composits these
753− // fn buffer_changed
755− // fn update_injections()
758−// -- refactored from tree-sitter-highlight to be able to retain state
759−// TODO: add seek() to iter
761−// problem: any time a layer is updated it must update it's injections on the parent (potentially
762−// removing some from use)
763−// can't modify to vec and exist in it at the same time since that would violate borrows
764−// maybe we can do with an arena
765−// maybe just caching on the top layer and nevermind the injections for now?
768−// layers: Vec<Box<Layer>> to prevent memory moves when vec is modified
770−// injections tracked by marker:
771−// if marker areas match it's fine and update
772−// if not found add new layer
773−// if length 0 then area got removed, clean up the layer
776−// if range.len = 0 then remove the layer
777−// for change in changes { tree.edit(change) }
778−// tree = parser.parse(.., tree, ..)
779−// calculate affected range and update injections
781−// look for existing injections
782−// if present, range = (first injection start, last injection end)
784−// For now cheat and just throw out non-root layers if they exist. This should still improve
785−// parsing in majority of cases.
787use std::sync::atomic::{AtomicUsize, Ordering};
889use std::sync::atomic::{AtomicUsize, Ordering};
788use std::{iter, mem, ops, str, usize};
890use std::{iter, mem, ops, str, usize};
789use tree_sitter::{
891use tree_sitter::{
@@ -820,8 +922,8 @@ pub enum HighlightEvent {
820pub struct HighlightConfiguration {
922pub struct HighlightConfiguration {
821 pub language: Grammar,
923 pub language: Grammar,
822 pub query: Query,
924 pub query: Query,
925+ injections_query: Query,
823 combined_injections_query: Option<Query>,
926 combined_injections_query: Option<Query>,
824− locals_pattern_index: usize,
825 highlights_pattern_index: usize,
927 highlights_pattern_index: usize,
826 highlight_indices: ArcSwap<Vec<Option<Highlight>>>,
928 highlight_indices: ArcSwap<Vec<Option<Highlight>>>,
827 non_local_variable_patterns: Vec<bool>,
929 non_local_variable_patterns: Vec<bool>,
@@ -848,13 +950,9 @@ struct LocalScope<'a> {
850#[derive(Debug)]
952#[derive(Debug)]
851−struct HighlightIter<'a, F>
953+struct HighlightIter<'a> {
853− F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a,
855 source: RopeSlice<'a>,
954 source: RopeSlice<'a>,
856 byte_offset: usize,
955 byte_offset: usize,
857− injection_callback: F,
858 cancellation_flag: Option<&'a AtomicUsize>,
956 cancellation_flag: Option<&'a AtomicUsize>,
859 layers: Vec<HighlightIterLayer<'a>>,
957 layers: Vec<HighlightIterLayer<'a>>,
860 iter_count: usize,
958 iter_count: usize,
@@ -894,8 +992,8 @@ struct HighlightIterLayer<'a> {
894 config: &'a HighlightConfiguration,
992 config: &'a HighlightConfiguration,
895 highlight_end_stack: Vec<usize>,
993 highlight_end_stack: Vec<usize>,
896 scope_stack: Vec<LocalScope<'a>>,
994 scope_stack: Vec<LocalScope<'a>>,
898 depth: usize,
995 depth: usize,
996+ ranges: Vec<Range>, // TEMP
901impl<'a> fmt::Debug for HighlightIterLayer<'a> {
999impl<'a> fmt::Debug for HighlightIterLayer<'a> {
@@ -927,38 +1025,32 @@ impl HighlightConfiguration {
927 ) -> Result<Self, QueryError> {
1025 ) -> Result<Self, QueryError> {
928 // Concatenate the query strings, keeping track of the start offset of each section.
1026 // Concatenate the query strings, keeping track of the start offset of each section.
929 let mut query_source = String::new();
1027 let mut query_source = String::new();
930− query_source.push_str(injection_query);
931− let locals_query_offset = query_source.len();
932 query_source.push_str(locals_query);
1028 query_source.push_str(locals_query);
933 let highlights_query_offset = query_source.len();
1029 let highlights_query_offset = query_source.len();
934 query_source.push_str(highlights_query);
1030 query_source.push_str(highlights_query);
936 // Construct a single query by concatenating the three query strings, but record the
1032 // Construct a single query by concatenating the three query strings, but record the
937 // range of pattern indices that belong to each individual string.
1033 // range of pattern indices that belong to each individual string.
938− let mut query = Query::new(language, &query_source)?;
1034+ let query = Query::new(language, &query_source)?;
939− let mut locals_pattern_index = 0;
940 let mut highlights_pattern_index = 0;
1035 let mut highlights_pattern_index = 0;
941 for i in 0..(query.pattern_count()) {
1036 for i in 0..(query.pattern_count()) {
942 let pattern_offset = query.start_byte_for_pattern(i);
1037 let pattern_offset = query.start_byte_for_pattern(i);
943 if pattern_offset < highlights_query_offset {
1038 if pattern_offset < highlights_query_offset {
944− if pattern_offset < highlights_query_offset {
945− highlights_pattern_index += 1;
1039+ highlights_pattern_index += 1;
947− if pattern_offset < locals_query_offset {
948− locals_pattern_index += 1;
1043+ let mut injections_query = Query::new(language, injection_query)?;
953 // Construct a separate query just for dealing with the 'combined injections'.
1045 // Construct a separate query just for dealing with the 'combined injections'.
954 // Disable the combined injection patterns in the main query.
1046 // Disable the combined injection patterns in the main query.
955 let mut combined_injections_query = Query::new(language, injection_query)?;
1047 let mut combined_injections_query = Query::new(language, injection_query)?;
956 let mut has_combined_queries = false;
1048 let mut has_combined_queries = false;
957− for pattern_index in 0..locals_pattern_index {
1049+ for pattern_index in 0..injections_query.pattern_count() {
958− let settings = query.property_settings(pattern_index);
1050+ let settings = injections_query.property_settings(pattern_index);
959 if settings.iter().any(|s| &*s.key == "injection.combined") {
1051 if settings.iter().any(|s| &*s.key == "injection.combined") {
960 has_combined_queries = true;
1052 has_combined_queries = true;
961− query.disable_pattern(pattern_index);
1053+ injections_query.disable_pattern(pattern_index);
962 } else {
1054 } else {
963 combined_injections_query.disable_pattern(pattern_index);
1055 combined_injections_query.disable_pattern(pattern_index);
@@ -990,8 +1082,6 @@ impl HighlightConfiguration {
990 for (i, name) in query.capture_names().iter().enumerate() {
1082 for (i, name) in query.capture_names().iter().enumerate() {
991 let i = Some(i as u32);
1083 let i = Some(i as u32);
992 match name.as_str() {
1084 match name.as_str() {
993− "injection.content" => injection_content_capture_index = i,
994− "injection.language" => injection_language_capture_index = i,
995 "local.definition" => local_def_capture_index = i,
1085 "local.definition" => local_def_capture_index = i,
996 "local.definition-value" => local_def_value_capture_index = i,
1086 "local.definition-value" => local_def_value_capture_index = i,
997 "local.reference" => local_ref_capture_index = i,
1087 "local.reference" => local_ref_capture_index = i,
@@ -1000,12 +1090,21 @@ impl HighlightConfiguration {
1093+ for (i, name) in injections_query.capture_names().iter().enumerate() {
1094+ let i = Some(i as u32);
1095+ match name.as_str() {
1096+ "injection.content" => injection_content_capture_index = i,
1097+ "injection.language" => injection_language_capture_index = i,
1003 let highlight_indices = ArcSwap::from_pointee(vec![None; query.capture_names().len()]);
1102 let highlight_indices = ArcSwap::from_pointee(vec![None; query.capture_names().len()]);
1004 Ok(Self {
1103 Ok(Self {
1005 language,
1104 language,
1007 combined_injections_query,
1107 combined_injections_query,
1008− locals_pattern_index,
1009 highlights_pattern_index,
1108 highlights_pattern_index,
1010 highlight_indices,
1109 highlight_indices,
1011 non_local_variable_patterns,
1110 non_local_variable_patterns,
@@ -1070,238 +1169,6 @@ impl HighlightConfiguration {
1072impl<'a> HighlightIterLayer<'a> {
1171impl<'a> HighlightIterLayer<'a> {
1073− /// Create a new 'layer' of highlighting for this document.
1075− /// In the even that the new layer contains "combined injections" (injections where multiple
1076− /// disjoint ranges are parsed as one syntax tree), these will be eagerly processed and
1077− /// added to the returned vector.
1078− fn new<F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a>(
1079− source: RopeSlice<'a>,
1080− cancellation_flag: Option<&'a AtomicUsize>,
1081− injection_callback: &mut F,
1082− mut config: &'a HighlightConfiguration,
1084− mut ranges: Vec<Range>,
1085− ) -> Result<Vec<Self>, Error> {
1086− let mut result = Vec::with_capacity(1);
1087− let mut queue = Vec::new();
1089− // --> Tree parsing part
1091− PARSER.with(|ts_parser| {
1092− let highlighter = &mut ts_parser.borrow_mut();
1094− if highlighter.parser.set_included_ranges(&ranges).is_ok() {
1097− .set_language(config.language)
1098− .map_err(|_| Error::InvalidLanguage)?;
1100− unsafe { highlighter.parser.set_cancellation_flag(cancellation_flag) };
1101− let tree = highlighter
1105− if byte <= source.len_bytes() {
1106− let (chunk, start_byte, _, _) = source.chunk_at_byte(byte);
1107− chunk[byte - start_byte..].as_bytes()
1115− .ok_or(Error::Cancelled)?;
1116− unsafe { highlighter.parser.set_cancellation_flag(None) };
1117− let mut cursor = highlighter.cursors.pop().unwrap_or_else(QueryCursor::new);
1119− // Process combined injections.
1120− if let Some(combined_injections_query) = &config.combined_injections_query {
1121− let mut injections_by_pattern_index = vec![
1122− (None, Vec::new(), false);
1123− combined_injections_query
1126− let matches = cursor.matches(
1127− combined_injections_query,
1129− RopeProvider(source),
1131− for mat in matches {
1132− let entry = &mut injections_by_pattern_index[mat.pattern_index];
1133− let (language_name, content_node, include_children) =
1134− injection_for_match(
1136− combined_injections_query,
1140− if language_name.is_some() {
1141− entry.0 = language_name;
1143− if let Some(content_node) = content_node {
1144− entry.1.push(content_node);
1146− entry.2 = include_children;
1148− for (lang_name, content_nodes, includes_children) in
1149− injections_by_pattern_index
1151− if let (Some(lang_name), false) = (lang_name, content_nodes.is_empty())
1153− if let Some(next_config) = (injection_callback)(&lang_name) {
1154− let ranges = Self::intersect_ranges(
1159− if !ranges.is_empty() {
1160− queue.push((next_config, depth + 1, ranges));
1167− // --> Highlighting query part
1169− // The `captures` iterator borrows the `Tree` and the `QueryCursor`, which
1170− // prevents them from being moved. But both of these values are really just
1171− // pointers, so it's actually ok to move them.
1172− let tree_ref = unsafe { mem::transmute::<_, &'static Tree>(&tree) };
1174− unsafe { mem::transmute::<_, &'static mut QueryCursor>(&mut cursor) };
1175− let captures = cursor_ref
1176− .captures(&config.query, tree_ref.root_node(), RopeProvider(source))
1179− result.push(HighlightIterLayer {
1180− highlight_end_stack: Vec::new(),
1181− scope_stack: vec![LocalScope {
1183− range: 0..usize::MAX,
1184− local_defs: Vec::new(),
1195− Ok(()) // so we can use the try operator
1198− if queue.is_empty() {
1202− let (next_config, next_depth, next_ranges) = queue.remove(0);
1203− config = next_config;
1204− depth = next_depth;
1205− ranges = next_ranges;
1211− // Compute the ranges that should be included when parsing an injection.
1212− // This takes into account three things:
1213− // * `parent_ranges` - The ranges must all fall within the *current* layer's ranges.
1214− // * `nodes` - Every injection takes place within a set of nodes. The injection ranges
1215− // are the ranges of those nodes.
1216− // * `includes_children` - For some injections, the content nodes' children should be
1217− // excluded from the nested document, so that only the content nodes' *own* content
1218− // is reparsed. For other injections, the content nodes' entire ranges should be
1219− // reparsed, including the ranges of their children.
1220− fn intersect_ranges(
1221− parent_ranges: &[Range],
1223− includes_children: bool,
1225− let mut cursor = nodes[0].walk();
1226− let mut result = Vec::new();
1227− let mut parent_range_iter = parent_ranges.iter();
1228− let mut parent_range = parent_range_iter
1230− .expect("Layers should only be constructed with non-empty ranges vectors");
1231− for node in nodes.iter() {
1232− let mut preceding_range = Range {
1234− start_point: Point::new(0, 0),
1235− end_byte: node.start_byte(),
1236− end_point: node.start_position(),
1238− let following_range = Range {
1239− start_byte: node.end_byte(),
1240− start_point: node.end_position(),
1241− end_byte: usize::MAX,
1242− end_point: Point::new(usize::MAX, usize::MAX),
1245− for excluded_range in node
1246− .children(&mut cursor)
1247− .filter_map(|child| {
1248− if includes_children {
1251− Some(child.range())
1254− .chain([following_range].iter().cloned())
1256− let mut range = Range {
1257− start_byte: preceding_range.end_byte,
1258− start_point: preceding_range.end_point,
1259− end_byte: excluded_range.start_byte,
1260− end_point: excluded_range.start_point,
1262− preceding_range = excluded_range;
1264− if range.end_byte < parent_range.start_byte {
1268− while parent_range.start_byte <= range.end_byte {
1269− if parent_range.end_byte > range.start_byte {
1270− if range.start_byte < parent_range.start_byte {
1271− range.start_byte = parent_range.start_byte;
1272− range.start_point = parent_range.start_point;
1275− if parent_range.end_byte < range.end_byte {
1276− if range.start_byte < parent_range.end_byte {
1277− result.push(Range {
1278− start_byte: range.start_byte,
1279− start_point: range.start_point,
1280− end_byte: parent_range.end_byte,
1281− end_point: parent_range.end_point,
1284− range.start_byte = parent_range.end_byte;
1285− range.start_point = parent_range.end_point;
1287− if range.start_byte < range.end_byte {
1288− result.push(range);
1294− if let Some(next_range) = parent_range_iter.next() {
1295− parent_range = next_range;
1305 // First, sort scope boundaries by their byte offset in the document. At a
1172 // First, sort scope boundaries by their byte offset in the document. At a
1306 // given position, emit scope endings before scope beginnings. Finally, emit
1173 // given position, emit scope endings before scope beginnings. Finally, emit
1307 // scope boundaries from deeper layers first.
1174 // scope boundaries from deeper layers first.
@@ -1327,10 +1194,101 @@ impl<'a> HighlightIterLayer<'a> {
1197+// Compute the ranges that should be included when parsing an injection.
1198+// This takes into account three things:
1199+// * `parent_ranges` - The ranges must all fall within the *current* layer's ranges.
1200+// * `nodes` - Every injection takes place within a set of nodes. The injection ranges
1201+// are the ranges of those nodes.
1202+// * `includes_children` - For some injections, the content nodes' children should be
1203+// excluded from the nested document, so that only the content nodes' *own* content
1204+// is reparsed. For other injections, the content nodes' entire ranges should be
1205+// reparsed, including the ranges of their children.
1206+fn intersect_ranges(
1207+ parent_ranges: &[Range],
1209+ includes_children: bool,
1211+ let mut cursor = nodes[0].walk();
1212+ let mut result = Vec::new();
1213+ let mut parent_range_iter = parent_ranges.iter();
1214+ let mut parent_range = parent_range_iter
1216+ .expect("Layers should only be constructed with non-empty ranges vectors");
1217+ for node in nodes.iter() {
1218+ let mut preceding_range = Range {
1220+ start_point: Point::new(0, 0),
1221+ end_byte: node.start_byte(),
1222+ end_point: node.start_position(),
1224+ let following_range = Range {
1225+ start_byte: node.end_byte(),
1226+ start_point: node.end_position(),
1227+ end_byte: usize::MAX,
1228+ end_point: Point::new(usize::MAX, usize::MAX),
1231+ for excluded_range in node
1232+ .children(&mut cursor)
1233+ .filter_map(|child| {
1234+ if includes_children {
1237+ Some(child.range())
1240+ .chain([following_range].iter().cloned())
1242+ let mut range = Range {
1243+ start_byte: preceding_range.end_byte,
1244+ start_point: preceding_range.end_point,
1245+ end_byte: excluded_range.start_byte,
1246+ end_point: excluded_range.start_point,
1248+ preceding_range = excluded_range;
1250+ if range.end_byte < parent_range.start_byte {
1254+ while parent_range.start_byte <= range.end_byte {
1255+ if parent_range.end_byte > range.start_byte {
1256+ if range.start_byte < parent_range.start_byte {
1257+ range.start_byte = parent_range.start_byte;
1258+ range.start_point = parent_range.start_point;
1261+ if parent_range.end_byte < range.end_byte {
1262+ if range.start_byte < parent_range.end_byte {
1263+ result.push(Range {
1264+ start_byte: range.start_byte,
1265+ start_point: range.start_point,
1266+ end_byte: parent_range.end_byte,
1267+ end_point: parent_range.end_point,
1270+ range.start_byte = parent_range.end_byte;
1271+ range.start_point = parent_range.end_point;
1273+ if range.start_byte < range.end_byte {
1274+ result.push(range);
1280+ if let Some(next_range) = parent_range_iter.next() {
1281+ parent_range = next_range;
1330−impl<'a, F> HighlightIter<'a, F>
1291+impl<'a> HighlightIter<'a> {
1332− F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a,
1334 fn emit_event(
1292 fn emit_event(
1335 &mut self,
1293 &mut self,
1336 offset: usize,
1294 offset: usize,
@@ -1361,6 +1319,12 @@ where
1362 continue;
1320 continue;
1323+ let layer = self.layers.remove(i + 1);
1324+ PARSER.with(|ts_parser| {
1325+ let highlighter = &mut ts_parser.borrow_mut();
1326+ highlighter.cursors.push(layer.cursor);
@@ -1377,30 +1341,9 @@ where
1381− fn insert_layer(&mut self, mut layer: HighlightIterLayer<'a>) {
1382− if let Some(sort_key) = layer.sort_key() {
1384− while i < self.layers.len() {
1385− if let Some(sort_key_i) = self.layers[i].sort_key() {
1386− if sort_key_i > sort_key {
1387− self.layers.insert(i, layer);
1392− self.layers.remove(i);
1395− self.layers.push(layer);
1400−impl<'a, F> Iterator for HighlightIter<'a, F>
1346+impl<'a> Iterator for HighlightIter<'a> {
1402− F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a,
1404 type Item = Result<HighlightEvent, Error>;
1347 type Item = Result<HighlightEvent, Error>;
1406 fn next(&mut self) -> Option<Self::Item> {
1349 fn next(&mut self) -> Option<Self::Item> {
@@ -1460,55 +1403,12 @@ where
1460 layer.highlight_end_stack.pop();
1403 layer.highlight_end_stack.pop();
1461 return self.emit_event(end_byte, Some(HighlightEvent::HighlightEnd));
1404 return self.emit_event(end_byte, Some(HighlightEvent::HighlightEnd));
1462 } else {
1405 } else {
1463− // return self.emit_event(self.source.len(), None);
1406+ return self.emit_event(self.source.len_bytes(), None);
1467 let (mut match_, capture_index) = layer.captures.next().unwrap();
1409 let (mut match_, capture_index) = layer.captures.next().unwrap();
1468 let mut capture = match_.captures[capture_index];
1410 let mut capture = match_.captures[capture_index];
1470− // If this capture represents an injection, then process the injection.
1471− if match_.pattern_index < layer.config.locals_pattern_index {
1472− let (language_name, content_node, include_children) =
1473− injection_for_match(layer.config, &layer.config.query, &match_, self.source);
1475− // Explicitly remove this match so that none of its other captures will remain
1476− // in the stream of captures.
1479− // If a language is found with the given name, then add a new language layer
1480− // to the highlighted document.
1481− if let (Some(language_name), Some(content_node)) = (language_name, content_node) {
1482− if let Some(config) = (self.injection_callback)(&language_name) {
1483− let ranges = HighlightIterLayer::intersect_ranges(
1484− &self.layers[0].ranges,
1488− if !ranges.is_empty() {
1489− match HighlightIterLayer::new(
1491− self.cancellation_flag,
1492− &mut self.injection_callback,
1494− self.layers[0].depth + 1,
1498− for layer in layers {
1499− self.insert_layer(layer);
1502− Err(e) => return Some(Err(e)),
1508− self.sort_layers();
1512 // Remove from the local scope stack any local scopes that have already ended.
1412 // Remove from the local scope stack any local scopes that have already ended.
1513 while range.start > layer.scope_stack.last().unwrap().range.end {
1413 while range.start > layer.scope_stack.last().unwrap().range.end {
1514 layer.scope_stack.pop();
1414 layer.scope_stack.pop();
@@ -1703,14 +1603,6 @@ fn injection_for_match<'a>(
1703 (language_name, content_node, include_children)
1603 (language_name, content_node, include_children)
1706−// fn shrink_and_clear<T>(vec: &mut Vec<T>, capacity: usize) {
1707−// if vec.len() > capacity {
1708−// vec.truncate(capacity);
1709−// vec.shrink_to_fit();
1714pub struct Merge<I> {
1606pub struct Merge<I> {
1715 iter: I,
1607 iter: I,
1716 spans: Box<dyn Iterator<Item = (usize, std::ops::Range<usize>)>>,
1608 spans: Box<dyn Iterator<Item = (usize, std::ops::Range<usize>)>>,
@@ -1877,6 +1769,8 @@ mod test {
1877 .map(String::from)
1769 .map(String::from)
1878 .collect();
1770 .collect();
1772+ let loader = Loader::new(Configuration { language: vec![] });
1880 let language = get_language(&crate::RUNTIME_DIR, "Rust").unwrap();
1774 let language = get_language(&crate::RUNTIME_DIR, "Rust").unwrap();
1881 let config = HighlightConfiguration::new(
1775 let config = HighlightConfiguration::new(
1882 language,
1776 language,
@@ -1899,7 +1793,7 @@ mod test {
1899 fn main() {}
1793 fn main() {}
1902− let syntax = Syntax::new(&source, Arc::new(config));
1796+ let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader));
1903 let tree = syntax.tree();
1797 let tree = syntax.tree();
1904 let root = tree.root_node();
1798 let root = tree.root_node();
1905 assert_eq!(root.kind(), "source_file");
1799 assert_eq!(root.kind(), "source_file");
@@ -1926,7 +1820,7 @@ mod test {
1927 vec![(6, 11, Some("test".into())), (12, 17, None)].into_iter(),
1821 vec![(6, 11, Some("test".into())), (12, 17, None)].into_iter(),
1929− let edits = LanguageLayer::generate_edits(doc.slice(..), transaction.changes());
1823+ let edits = generate_edits(doc.slice(..), transaction.changes());
1930 // transaction.apply(&mut state);
1824 // transaction.apply(&mut state);
1932 assert_eq!(
1826 assert_eq!(
@@ -1955,7 +1849,7 @@ mod test {
1955 let mut doc = Rope::from("fn test() {}");
1849 let mut doc = Rope::from("fn test() {}");
1956 let transaction =
1850 let transaction =
1957 Transaction::change(&doc, vec![(8, 8, Some("a: u32".into()))].into_iter());
1851 Transaction::change(&doc, vec![(8, 8, Some("a: u32".into()))].into_iter());
1958− let edits = LanguageLayer::generate_edits(doc.slice(..), transaction.changes());
1852+ let edits = generate_edits(doc.slice(..), transaction.changes());
1959 transaction.apply(&mut doc);
1853 transaction.apply(&mut doc);
1961 assert_eq!(doc, "fn test(a: u32) {}");
1855 assert_eq!(doc, "fn test(a: u32) {}");