Skip to content

Commit

Permalink
Optimize syntax update to only do partial updates
Browse files Browse the repository at this point in the history
Signed-off-by: Hanif Bin Ariffin <[email protected]>
  • Loading branch information
hbina committed Nov 18, 2023
1 parent c7e0474 commit b33bf76
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
2 changes: 1 addition & 1 deletion lapce-core/src/syntax/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use tree_sitter::Point;

use crate::buffer::rope_text::{RopeText, RopeTextRef};

#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct SyntaxEdit(pub(crate) Vec<tree_sitter::InputEdit>);

impl SyntaxEdit {
Expand Down
39 changes: 35 additions & 4 deletions lapce-core/src/syntax/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,14 +590,33 @@ impl Syntax {
let _ = layers.update(self.rev, new_rev, &new_text, edits);
let tree = layers.try_tree();

let styles = if tree.is_some() {
let (start_offset, end_offset) = match edits {
Some(edits) => (
edits
.iter()
.flat_map(|e| e.0.iter())
.flat_map(|e| [e.start_byte, e.old_end_byte, e.new_end_byte])
.min()
.unwrap_or(0),
edits
.iter()
.flat_map(|e| e.0.iter())
.flat_map(|e| [e.start_byte, e.old_end_byte, e.new_end_byte])
.max()
.unwrap_or(new_text.len()),
),
None => (0usize, new_text.len()),
};

let new_styles = if tree.is_some() {
let mut current_hl: Option<Highlight> = None;
let mut highlights: SpansBuilder<Style> =
SpansBuilder::new(new_text.len());

// TODO: Should we be ignoring highlight errors via flattening them?
for highlight in layers
.highlight_iter(&new_text, Some(0..new_text.len()), None)
for highlight in self
.layers
.highlight_iter(&new_text, Some(start_offset..end_offset), None)
.flatten()
{
match highlight {
Expand Down Expand Up @@ -644,7 +663,19 @@ impl Syntax {
self.rev = new_rev;
self.lens = lens;
self.normal_lines = normal_lines;
self.styles = styles;
self.styles = match (self.styles.as_mut(), new_styles) {
(Some(styles), Some(new_styles)) => {
Some(Arc::new(styles.merge(&new_styles, |a, b| {
if let Some(b) = b {
return b.clone();
}
a.clone()
})))
}
(None, Some(new_styles)) => Some(new_styles),
(Some(styles), None) => Some(styles.clone()),
_ => None,
};
self.text = new_text
}

Expand Down

0 comments on commit b33bf76

Please sign in to comment.