on master help sign in
do not reparse unmodified injections (#4146)
commit543d75da23425bb3f2c7208dfa4d56bc9031ce67 authorPascal Kuthe <pascal.kuthe@semimod.de> dateTue 11 Oct 2022, 08:48 (4 years ago) parentb58899b
3 files changed+54−21
Cargo.lock+1 helix-core/Cargo.toml+1 helix-core/src/syntax.rs+52−21
Cargo.lock+1
@@ -388,6 +388,7 @@ name = "helix-core"
388388version = "0.6.0"
389389dependencies = [
390390 "arc-swap",
391+ "bitflags",
391392 "chrono",
392393 "encoding_rs",
393394 "etcetera",
helix-core/Cargo.toml+1
@@ -29,6 +29,7 @@ tree-sitter = "0.20"
2929once_cell = "1.15"
3030arc-swap = "1"
3131regex = "1"
32+bitflags = "1.3"
3233
3334log = "0.4"
3435serde = { version = "1.0", features = ["derive"] }
helix-core/src/syntax.rs+52−21
@@ -8,13 +8,15 @@ use crate::{
88};
99
1010use arc_swap::{ArcSwap, Guard};
11+use bitflags::bitflags;
1112use slotmap::{DefaultKey as LayerId, HopSlotMap};
1213
1314use std::{
1415 borrow::Cow,
1516 cell::RefCell,
16− collections::{HashMap, HashSet, VecDeque},
17+ collections::{HashMap, VecDeque},
1718 fmt,
19+ mem::replace,
1820 path::Path,
1921 str::FromStr,
2022 sync::Arc,
@@ -594,6 +596,7 @@ impl Syntax {
594596 tree: None,
595597 config,
596598 depth: 0,
599+ flags: LayerUpdateFlags::empty(),
597600 ranges: vec![Range {
598601 start_byte: 0,
599602 end_byte: usize::MAX,
@@ -656,9 +659,10 @@ impl Syntax {
656659 }
657660 }
658661
659− for layer in &mut self.layers.values_mut() {
662+ for layer in self.layers.values_mut() {
660663 // The root layer always covers the whole range (0..usize::MAX)
661664 if layer.depth == 0 {
665+ layer.flags = LayerUpdateFlags::MODIFIED;
662666 continue;
663667 }
664668
@@ -689,6 +693,8 @@ impl Syntax {
689693 edit.new_end_position,
690694 point_sub(range.end_point, edit.old_end_position),
691695 );
696+
697+ layer.flags |= LayerUpdateFlags::MOVED;
692698 }
693699 // if the edit starts in the space before and extends into the range
694700 else if edit.start_byte < range.start_byte {
@@ -703,11 +709,13 @@ impl Syntax {
703709 edit.new_end_position,
704710 point_sub(range.end_point, edit.old_end_position),
705711 );
712+ layer.flags = LayerUpdateFlags::MODIFIED;
706713 }
707714 // If the edit is an insertion at the start of the tree, shift
708715 else if edit.start_byte == range.start_byte && is_pure_insertion {
709716 range.start_byte = edit.new_end_byte;
710717 range.start_point = edit.new_end_position;
718+ layer.flags |= LayerUpdateFlags::MOVED;
711719 } else {
712720 range.end_byte = range
713721 .end_byte
@@ -717,6 +725,7 @@ impl Syntax {
717725 edit.new_end_position,
718726 point_sub(range.end_point, edit.old_end_position),
719727 );
728+ layer.flags = LayerUpdateFlags::MODIFIED;
720729 }
721730 }
722731 }
@@ -731,27 +740,33 @@ impl Syntax {
731740
732741 let source_slice = source.slice(..);
733742
734− let mut touched = HashSet::new();
735−
736− // TODO: we should be able to avoid editing & parsing layers with ranges earlier in the document before the edit
737−
738743 while let Some(layer_id) = queue.pop_front() {
739− // Mark the layer as touched
740− touched.insert(layer_id);
741−
742744 let layer = &mut self.layers[layer_id];
743745
746+ // Mark the layer as touched
747+ layer.flags |= LayerUpdateFlags::TOUCHED;
748+
744749 // If a tree already exists, notify it of changes.
745750 if let Some(tree) = &mut layer.tree {
746− for edit in edits.iter().rev() {
747− // Apply the edits in reverse.
748− // If we applied them in order then edit 1 would disrupt the positioning of edit 2.
749− tree.edit(edit);
751+ if layer
752+ .flags
753+ .intersects(LayerUpdateFlags::MODIFIED | LayerUpdateFlags::MOVED)
754+ {
755+ for edit in edits.iter().rev() {
756+ // Apply the edits in reverse.
757+ // If we applied them in order then edit 1 would disrupt the positioning of edit 2.
758+ tree.edit(edit);
759+ }
750760 }
751− }
752761
753− // Re-parse the tree.
754− layer.parse(&mut ts_parser.parser, source)?;
762+ if layer.flags.contains(LayerUpdateFlags::MODIFIED) {
763+ // Re-parse the tree.
764+ layer.parse(&mut ts_parser.parser, source)?;
765+ }
766+ } else {
767+ // always parse if this layer has never been parsed before
768+ layer.parse(&mut ts_parser.parser, source)?;
769+ }
755770
756771 // Switch to an immutable borrow.
757772 let layer = &self.layers[layer_id];
@@ -855,6 +870,8 @@ impl Syntax {
855870 config,
856871 depth,
857872 ranges,
873+ // set the modified flag to ensure the layer is parsed
874+ flags: LayerUpdateFlags::empty(),
858875 })
859876 });
860877
@@ -868,8 +885,11 @@ impl Syntax {
868885 // Return the cursor back in the pool.
869886 ts_parser.cursors.push(cursor);
870887
871− // Remove all untouched layers
872− self.layers.retain(|id, _| touched.contains(&id));
888+ // Reset all `LayerUpdateFlags` and remove all untouched layers
889+ self.layers.retain(|_, layer| {
890+ replace(&mut layer.flags, LayerUpdateFlags::empty())
891+ .contains(LayerUpdateFlags::TOUCHED)
892+ });
873893
874894 Ok(())
875895 })
@@ -968,6 +988,16 @@ impl Syntax {
968988 // TODO: Folding
969989}
970990
991+bitflags! {
992+ /// Flags that track the status of a layer
993+ /// in the `Sytaxn::update` function
994+ struct LayerUpdateFlags : u32{
995+ const MODIFIED = 0b001;
996+ const MOVED = 0b010;
997+ const TOUCHED = 0b100;
998+ }
999+}
1000+
9711001#[derive(Debug)]
9721002pub struct LanguageLayer {
9731003 // mode
@@ -975,7 +1005,8 @@ pub struct LanguageLayer {
9751005 pub config: Arc<HighlightConfiguration>,
9761006 pub(crate) tree: Option<Tree>,
9771007 pub ranges: Vec<Range>,
978− pub depth: usize,
1008+ pub depth: u32,
1009+ flags: LayerUpdateFlags,
9791010}
9801011
9811012impl LanguageLayer {
@@ -1191,7 +1222,7 @@ struct HighlightIter<'a> {
11911222 layers: Vec<HighlightIterLayer<'a>>,
11921223 iter_count: usize,
11931224 next_event: Option<HighlightEvent>,
1194− last_highlight_range: Option<(usize, usize, usize)>,
1225+ last_highlight_range: Option<(usize, usize, u32)>,
11951226}
11961227
11971228// Adapter to convert rope chunks to bytes
@@ -1224,7 +1255,7 @@ struct HighlightIterLayer<'a> {
12241255 config: &'a HighlightConfiguration,
12251256 highlight_end_stack: Vec<usize>,
12261257 scope_stack: Vec<LocalScope<'a>>,
1227− depth: usize,
1258+ depth: u32,
12281259 ranges: &'a [Range],
12291260}
12301261