aboutsummaryrefslogtreecommitdiff
path: root/helix-core/src/syntax.rs
diff options
context:
space:
mode:
authorBlaž Hrastnik2020-09-28 16:01:27 +0000
committerBlaž Hrastnik2020-09-28 16:01:27 +0000
commit36e7e2133fe1d472600cfd935b8046b8d50146c2 (patch)
tree887eb91b778bce0ec4a07d3a3c41cb53376579fb /helix-core/src/syntax.rs
parent3020077da8efbf914a9cb0a2cbb50362d339a39a (diff)
Split selection on regex, fix InputEdit generation.
Diffstat (limited to 'helix-core/src/syntax.rs')
-rw-r--r--helix-core/src/syntax.rs48
1 files changed, 39 insertions, 9 deletions
diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs
index 9b09bb58..3d85ff25 100644
--- a/helix-core/src/syntax.rs
+++ b/helix-core/src/syntax.rs
@@ -188,9 +188,19 @@ impl Syntax {
syntax
}
- pub fn update(&mut self, source: &Rope, changeset: &ChangeSet) -> Result<(), Error> {
- self.root_layer
- .update(&mut self.parser, &self.config, source, changeset)
+ pub fn update(
+ &mut self,
+ old_source: &Rope,
+ source: &Rope,
+ changeset: &ChangeSet,
+ ) -> Result<(), Error> {
+ self.root_layer.update(
+ &mut self.parser,
+ &self.config,
+ old_source,
+ source,
+ changeset,
+ )
// TODO: deal with injections and update them too
}
@@ -385,7 +395,7 @@ impl LanguageLayer {
}
pub(crate) fn generate_edits(
- text: &RopeSlice,
+ old_text: &RopeSlice,
changeset: &ChangeSet,
) -> Vec<tree_sitter::InputEdit> {
use Operation::*;
@@ -399,7 +409,7 @@ impl LanguageLayer {
// TODO; this is a lot easier with Change instead of Operation.
fn point_at_pos(text: &RopeSlice, pos: usize) -> (usize, Point) {
- let byte = text.char_to_byte(pos);
+ let byte = text.char_to_byte(pos); // <- attempted to index past end
let line = text.char_to_line(pos);
let line_start_byte = text.line_to_byte(line);
let col = byte - line_start_byte;
@@ -437,8 +447,8 @@ impl LanguageLayer {
new_pos += len;
}
Delete(_) => {
- let (start_byte, start_position) = point_at_pos(&text, old_pos);
- let (old_end_byte, old_end_position) = point_at_pos(&text, old_end);
+ let (start_byte, start_position) = point_at_pos(&old_text, old_pos);
+ let (old_end_byte, old_end_position) = point_at_pos(&old_text, old_end);
// TODO: Position also needs to be byte based...
// let byte = char_to_byte(old_pos)
@@ -475,7 +485,7 @@ impl LanguageLayer {
};
}
Insert(s) => {
- let (start_byte, start_position) = point_at_pos(&text, old_pos);
+ let (start_byte, start_position) = point_at_pos(&old_text, old_pos);
let ins = s.chars().count();
@@ -501,6 +511,7 @@ impl LanguageLayer {
&mut self,
parser: &mut Parser,
config: &HighlightConfiguration,
+ old_source: &Rope,
source: &Rope,
changeset: &ChangeSet,
) -> Result<(), Error> {
@@ -508,7 +519,7 @@ impl LanguageLayer {
return Ok(());
}
- let edits = Self::generate_edits(&source.slice(..), changeset);
+ let edits = Self::generate_edits(&old_source.slice(..), changeset);
// Notify the tree about all the changes
for edit in edits {
@@ -1530,4 +1541,23 @@ fn test_input_edits() {
}
]
);
+
+ // Testing with the official example from tree-sitter
+ let mut state = State::new("fn test() {}".into());
+ let transaction = Transaction::change(&state, vec![(8, 8, Some("a: u32".into()))].into_iter());
+ let edits = LanguageLayer::generate_edits(&state.doc.slice(..), &transaction.changes);
+ transaction.apply(&mut state);
+
+ assert_eq!(state.doc(), "fn test(a: u32) {}");
+ assert_eq!(
+ edits,
+ &[InputEdit {
+ start_byte: 8,
+ old_end_byte: 8,
+ new_end_byte: 14,
+ start_position: Point { row: 0, column: 8 },
+ old_end_position: Point { row: 0, column: 8 },
+ new_end_position: Point { row: 0, column: 14 }
+ }]
+ );
}