diff --git a/include/tree_sitter/runtime.h b/include/tree_sitter/runtime.h index 00d8e7c4..69334ad0 100644 --- a/include/tree_sitter/runtime.h +++ b/include/tree_sitter/runtime.h @@ -104,6 +104,7 @@ void ts_document_set_language(TSDocument *, const TSLanguage *); TSInput ts_document_input(TSDocument *); void ts_document_set_input(TSDocument *, TSInput); void ts_document_set_input_string(TSDocument *, const char *); +void ts_document_set_input_string_with_length(TSDocument *, const char *, uint32_t); TSLogger ts_document_logger(const TSDocument *); void ts_document_set_logger(TSDocument *, TSLogger); void ts_document_print_debugging_graphs(TSDocument *, bool); diff --git a/spec/runtime/document_spec.cc b/spec/runtime/document_spec.cc index 52e65ffb..f80419dc 100644 --- a/spec/runtime/document_spec.cc +++ b/spec/runtime/document_spec.cc @@ -116,6 +116,17 @@ describe("Document", [&]() { AssertThat(spy_input->strings_read, Equals(vector({" [null, 2" }))); }); + it("allows setting input string with length", [&]() { + const char content[] = { '1' }; + ts_document_set_input_string_with_length(document, content, 1); + ts_document_parse(document); + TSNode new_root = ts_document_root_node(document); + AssertThat(ts_node_end_char(new_root), Equals(1)); + assert_node_string_equals( + new_root, + "(number)"); + }); + it("reads from the new input correctly when the old input was blank", [&]() { ts_document_set_input_string(document, ""); ts_document_parse(document); diff --git a/src/runtime/document.c b/src/runtime/document.c index 8c1eb779..ff09610d 100644 --- a/src/runtime/document.c +++ b/src/runtime/document.c @@ -77,6 +77,15 @@ void ts_document_set_input_string(TSDocument *self, const char *text) { } } +void ts_document_set_input_string_with_length(TSDocument *self, const char *text, uint32_t length) { + ts_document_invalidate(self); + TSInput input = ts_string_input_make_with_length(text, length); + ts_document_set_input(self, input); + if (input.payload) { + self->owns_input = true; + } +} + void ts_document_edit(TSDocument *self, TSInputEdit edit) { if (!self->tree) return; diff --git a/src/runtime/string_input.c b/src/runtime/string_input.c index 713a272d..3b951a10 100644 --- a/src/runtime/string_input.c +++ b/src/runtime/string_input.c @@ -27,13 +27,17 @@ int ts_string_input_seek(void *payload, uint32_t character, uint32_t byte) { } TSInput ts_string_input_make(const char *string) { + return ts_string_input_make_with_length(string, strlen(string)); +} + +TSInput ts_string_input_make_with_length(const char *string, uint32_t length) { TSStringInput *input = ts_malloc(sizeof(TSStringInput)); if (!input) goto error; input->string = string; input->position = 0; - input->length = strlen(string); + input->length = length; return (TSInput){ .payload = input, .read = ts_string_input_read, diff --git a/src/runtime/string_input.h b/src/runtime/string_input.h index fe5e4b1f..c96cd416 100644 --- a/src/runtime/string_input.h +++ b/src/runtime/string_input.h @@ -8,6 +8,7 @@ extern "C" { #include "tree_sitter/runtime.h" TSInput ts_string_input_make(const char *); +TSInput ts_string_input_make_with_length(const char *, uint32_t); #ifdef __cplusplus }