From 0a5615669a4f5d7e2db3c4117f3c2440e9c4cfd5 Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Fri, 17 Feb 2023 14:21:49 -0800 Subject: [PATCH] Don't completely clip into visible range in treesit_record_change (Bug#61369) From min (visible_end, max (visible_beg, new_end_byte)) - visible_beg to max (visible_beg, new_end_byte) - visible_beg * src/treesit.c (treesit_record_change): We don't clip the new end into the visible range anymore. If you think of it, when inserting in a narrowed region, the visible region is always extended to accommodate more text, rather than pushing text at the end to keep the size of the visible region. --- src/treesit.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/treesit.c b/src/treesit.c index cab2f0d5354..08119f149b7 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -770,7 +770,8 @@ treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, treesit_check_parser (lisp_parser); TSTree *tree = XTS_PARSER (lisp_parser)->tree; /* See comment (ref:visible-beg-null) if you wonder why we don't - update visible_beg/end when tree is NULL. */ + update visible_beg/end when tree is NULL. */ + if (tree != NULL) { eassert (start_byte <= old_end_byte); @@ -794,8 +795,14 @@ treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, ptrdiff_t old_end_offset = (min (visible_end, max (visible_beg, old_end_byte)) - visible_beg); - ptrdiff_t new_end_offset = (min (visible_end, - max (visible_beg, new_end_byte)) + /* We don't clip new_end_offset under visible_end, because + inserting in narrowed region always extends the visible + region. If we clip new_end_offset here, and re-add the + clipped "tail" in treesit_sync_visible_region later, + while it is technically equivalent, tree-sitter's + incremental parsing algorithm doesn't seem to like it + (bug#61369). */ + ptrdiff_t new_end_offset = (max (visible_beg, new_end_byte) - visible_beg); eassert (start_offset <= old_end_offset); eassert (start_offset <= new_end_offset); @@ -817,11 +824,13 @@ treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, /* Move forward. */ visi_beg_delta = (old_end_byte < visible_beg ? new_end_byte - old_end_byte : 0); + XTS_PARSER (lisp_parser)->visible_beg = visible_beg + visi_beg_delta; XTS_PARSER (lisp_parser)->visible_end = (visible_end + visi_beg_delta + (new_end_offset - old_end_offset)); + eassert (XTS_PARSER (lisp_parser)->visible_beg >= 0); eassert (XTS_PARSER (lisp_parser)->visible_beg <= XTS_PARSER (lisp_parser)->visible_end); -- 2.39.2