summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuan Fu <casouri@gmail.com>2022-11-25 18:50:26 -0800
committerYuan Fu <casouri@gmail.com>2022-11-25 19:00:22 -0800
commit0369dcacf30aff6d4f733872058fa2446330fd02 (patch)
treed8d8cc56a4801bed293d23c48ce97e8562df014d
parent4ffca85f1eefea5adc96efc276acfae4d737aa17 (diff)
downloademacs-0369dcacf30aff6d4f733872058fa2446330fd02.tar.gz
Fix tree-sitter assertion error (bug#59574)
* src/treesit.c (treesit_sync_visible_region): Initialize visible_beg/end when tree is NULL.
-rw-r--r--src/treesit.c24
1 files 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);