From 0369dcacf30aff6d4f733872058fa2446330fd02 Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Fri, 25 Nov 2022 18:50:26 -0800 Subject: [PATCH] Fix tree-sitter assertion error (bug#59574) * src/treesit.c (treesit_sync_visible_region): Initialize visible_beg/end when tree is NULL. --- src/treesit.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/treesit.c b/src/treesit.c index d18e77a3531..c910aea1da2 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -782,13 +782,13 @@ treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, matches that of the buffer, and update visible_beg/end. That is, the whole purpose of visible_beg/end (and - treesit_record_change and treesit_sync_visible_region) is to - update the tree (by ts_tree_edit). So if the tree is NULL, we - don't update the tree and there is no need to keep tracking of - them. Only when we already have a tree, do we need to keep track - of position changes and update it correctly, so it can be feed into - ts_parser_parse as the old tree, so that tree-sitter only parses - the changed part (aka incremental). + treesit_record_change and treesit_sync_visible_region) is to update + the tree (by ts_tree_edit). So if the tree is NULL, + visible_beg/end are considered uninitialized. Only when we already + have a tree, do we need to keep track of position changes and + update it correctly, so it can be feed into ts_parser_parse as the + old tree, so that tree-sitter only parses the changed part (aka + incremental). In a nutshell, tree-sitter incremental parsing in Emacs looks like: @@ -815,11 +815,17 @@ static void treesit_sync_visible_region (Lisp_Object parser) { TSTree *tree = XTS_PARSER (parser)->tree; + struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer); + /* If we are setting visible_beg/end for the first time, we can skip + the offset acrobatics and updating the tree below. */ if (tree == NULL) - return; + { + XTS_PARSER (parser)->visible_beg = BUF_BEGV_BYTE (buffer); + XTS_PARSER (parser)->visible_end = BUF_ZV_BYTE (buffer); + return; + } - struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer); ptrdiff_t visible_beg = XTS_PARSER (parser)->visible_beg; ptrdiff_t visible_end = XTS_PARSER (parser)->visible_end; eassert (0 <= visible_beg); -- 2.39.2