diff options
-rw-r--r-- | src/treesit.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/src/treesit.c b/src/treesit.c index 813d4222f98..e226df263c1 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -955,6 +955,11 @@ treesit_call_after_change_functions (TSTree *old_tree, TSTree *new_tree, static void treesit_ensure_parsed (Lisp_Object parser) { + /* Make sure this comes before everything else, see comment + (ref:notifier-inside-ensure-parsed) for more detail. */ + if (!XTS_PARSER (parser)->need_reparse) + return; + struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer); /* Before we parse, catch up with the narrowing situation. */ @@ -963,8 +968,6 @@ treesit_ensure_parsed (Lisp_Object parser) because it might set the flag to true. */ treesit_sync_visible_region (parser); - if (!XTS_PARSER (parser)->need_reparse) - return; TSParser *treesit_parser = XTS_PARSER (parser)->parser; TSTree *tree = XTS_PARSER (parser)->tree; TSInput input = XTS_PARSER (parser)->input; @@ -984,14 +987,20 @@ treesit_ensure_parsed (Lisp_Object parser) xsignal1 (Qtreesit_parse_error, buf); } + XTS_PARSER (parser)->tree = new_tree; + XTS_PARSER (parser)->need_reparse = false; + + /* After-change functions should run at the very end, most crucially + after need_reparse is set to false, this way if the function + calls some tree-sitter function which invokes + treesit_ensure_parsed again, it returns early and do not + recursively call the after change functions again. + (ref:notifier-inside-ensure-parsed) */ if (tree != NULL) { treesit_call_after_change_functions (tree, new_tree, parser); ts_tree_delete (tree); } - - XTS_PARSER (parser)->tree = new_tree; - XTS_PARSER (parser)->need_reparse = false; } /* This is the read function provided to tree-sitter to read from a |