diff --git a/include/tree_sitter/runtime.h b/include/tree_sitter/runtime.h index 5ee8b2e7..a1989fa9 100644 --- a/include/tree_sitter/runtime.h +++ b/include/tree_sitter/runtime.h @@ -34,8 +34,10 @@ typedef struct { } TSPoint; typedef struct { - TSPoint start; - TSPoint end; + TSPoint start_point; + TSPoint end_point; + uint32_t start_byte; + uint32_t end_byte; } TSRange; typedef struct { diff --git a/src/runtime/get_changed_ranges.c b/src/runtime/get_changed_ranges.c index d46bf704..f83e0493 100644 --- a/src/runtime/get_changed_ranges.c +++ b/src/runtime/get_changed_ranges.c @@ -9,17 +9,18 @@ typedef Array(TSRange) RangeArray; -static void range_array_add(RangeArray *results, TSPoint start, TSPoint end) { +static void range_array_add(RangeArray *results, Length start, Length end) { if (results->size > 0) { TSRange *last_range = array_back(results); - if (point_lte(start, last_range->end)) { - last_range->end = end; + if (start.bytes <= last_range->end_byte) { + last_range->end_byte = end.bytes; + last_range->end_point = end.extent; return; } } - if (point_lt(start, end)) { - TSRange range = { start, end }; + if (start.bytes < end.bytes) { + TSRange range = { start.extent, end.extent, start.bytes, end.bytes }; array_push(results, range); } } @@ -272,10 +273,10 @@ unsigned ts_subtree_get_changed_ranges(const Subtree *old_tree, const Subtree *n Length position = iterator_start_position(&old_iter); Length next_position = iterator_start_position(&new_iter); if (position.bytes < next_position.bytes) { - range_array_add(&results, position.extent, next_position.extent); + range_array_add(&results, position, next_position); position = next_position; } else if (position.bytes > next_position.bytes) { - range_array_add(&results, next_position.extent, position.extent); + range_array_add(&results, next_position, position); next_position = position; } @@ -343,7 +344,7 @@ unsigned ts_subtree_get_changed_ranges(const Subtree *old_tree, const Subtree *n ); #endif - range_array_add(&results, position.extent, next_position.extent); + range_array_add(&results, position, next_position); } position = next_position; diff --git a/test/helpers/point_helpers.cc b/test/helpers/point_helpers.cc index 40dd67fd..fd6d8bb1 100644 --- a/test/helpers/point_helpers.cc +++ b/test/helpers/point_helpers.cc @@ -11,7 +11,12 @@ bool operator==(const TSPoint &left, const TSPoint &right) { } bool operator==(const TSRange &left, const TSRange &right) { - return left.start == right.start && left.end == right.end; + return ( + left.start_byte == right.start_byte && + left.end_byte == right.end_byte && + left.start_point == right.start_point && + left.end_point == right.end_point + ); } bool operator==(const Length &left, const Length &right) { @@ -34,7 +39,7 @@ std::ostream &operator<<(std::ostream &stream, const TSPoint &point) { } std::ostream &operator<<(std::ostream &stream, const TSRange &range) { - return stream << "{" << range.start << ", " << range.end << "}"; + return stream << "{" << range.start_point << ", " << range.end_point << "}"; } ostream &operator<<(ostream &stream, const Length &length) { diff --git a/test/helpers/scope_sequence.cc b/test/helpers/scope_sequence.cc index 8851f0c4..1121b80e 100644 --- a/test/helpers/scope_sequence.cc +++ b/test/helpers/scope_sequence.cc @@ -73,7 +73,7 @@ void verify_changed_ranges(const ScopeSequence &old_sequence, const ScopeSequenc bool found_containing_range = false; for (size_t j = 0; j < range_count; j++) { TSRange range = ranges[j]; - if (range.start <= current_position && current_position <= range.end) { + if (range.start_point <= current_position && current_position <= range.end_point) { found_containing_range = true; break; } diff --git a/test/runtime/tree_test.cc b/test/runtime/tree_test.cc index b599f568..d703cd60 100644 --- a/test/runtime/tree_test.cc +++ b/test/runtime/tree_test.cc @@ -131,16 +131,22 @@ describe("Tree", [&]() { return result; }; + auto range_for_text = [&](string start_text, string end_text) { + return TSRange { + point(0, input->content.find(start_text)), + point(0, input->content.find(end_text)), + static_cast(input->content.find(start_text)), + static_cast(input->content.find(end_text)), + }; + }; + it("reports changes when one token has been updated", [&]() { // Replace `null` with `nothing` auto ranges = get_changed_ranges_for_edit([&]() { return input->replace(input->content.find("ull"), 1, "othing"); }); AssertThat(ranges, Equals(vector({ - TSRange{ - point(0, input->content.find("nothing")), - point(0, input->content.find("}")) - }, + range_for_text("nothing", "}"), }))); // Replace `nothing` with `null` again @@ -148,10 +154,7 @@ describe("Tree", [&]() { return input->undo(); }); AssertThat(ranges, Equals(vector({ - TSRange{ - point(0, input->content.find("null")), - point(0, input->content.find("}")) - }, + range_for_text("null", "}"), }))); }); @@ -192,10 +195,7 @@ describe("Tree", [&]() { return input->replace(input->content.find("}"), 0, ", b: false"); }); AssertThat(ranges, Equals(vector({ - TSRange{ - point(0, input->content.find(",")), - point(0, input->content.find("}")) - }, + range_for_text(",", "}"), }))); // Add a third key-value pair in between the first two @@ -209,10 +209,7 @@ describe("Tree", [&]() { "(pair (property_identifier) (false)))))" ); AssertThat(ranges, Equals(vector({ - TSRange{ - point(0, input->content.find(", c")), - point(0, input->content.find(", b")) - }, + range_for_text(", c", ", b"), }))); // Delete the middle pair. @@ -247,10 +244,7 @@ describe("Tree", [&]() { "(pair (property_identifier) (binary_expression (identifier) (null))))))" ); AssertThat(ranges, Equals(vector({ - TSRange{ - point(0, input->content.find("b ===")), - point(0, input->content.find("}")) - }, + range_for_text("b ===", "}"), }))); }); });