summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuan Fu <casouri@gmail.com>2022-11-25 15:06:55 -0800
committerYuan Fu <casouri@gmail.com>2022-11-25 19:00:22 -0800
commit245366b18a0675dc56d3236895cf0e099385d720 (patch)
tree6cd9b4487ee0aecbc359d5afe01514128af21e3f
parent73c94d5a9f00a98944516d86e4efcf50e20b2d48 (diff)
downloademacs-245366b18a0675dc56d3236895cf0e099385d720.tar.gz
; Add comments in treesit.c and treesit.h
* src/treesit.c * src/treesit.h: Add (and fix) comments.
-rw-r--r--src/treesit.c49
-rw-r--r--src/treesit.h13
2 files changed, 51 insertions, 11 deletions
diff --git a/src/treesit.c b/src/treesit.c
index 3df53f2179d..66fd884efc3 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -707,6 +707,8 @@ treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte,
Lisp_Object lisp_parser = XCAR (parser_list);
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. */
if (tree != NULL)
{
eassert (start_byte <= old_end_byte);
@@ -742,7 +744,7 @@ treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte,
XTS_PARSER (lisp_parser)->timestamp++;
/* VISIBLE_BEG/END records tree-sitter's range of view in
- the buffer. Ee need to adjust them when tree-sitter's
+ the buffer. We need to adjust them when tree-sitter's
view changes. */
ptrdiff_t visi_beg_delta;
if (old_end_byte > new_end_byte)
@@ -765,6 +767,44 @@ treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte,
}
}
+/* Comment (ref:visible-beg-null) So the purpose of visible_beg/end
+ are to keep track of "which part of the buffer does the tree-sitter
+ tree sees", in order to update the tree correctly. Visible_beg/end
+ has two purposes: "clips" buffer changes within them, and translate
+ position in buffer to position in the tree (buf position - visi_beg
+ = tree position).
+
+ Conceptually, visible_beg/end marks the visible region of the
+ buffer when we last reparsed. In between two reparse, we don't
+ really care if the visible region of the buffer changes.
+
+ Right before we reparse, we make tree-sitter's visible region
+ 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_ensure_position_synced) 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).
+
+ In a nutshell, tree-sitter incremental parsing in Emacs looks like:
+
+ treesit_record_change(tree) \
+ treesit_record_change(tree) | user edits buffer
+ ... /
+
+ treesit_ensure_position_synced(tree) \ treesit_ensure_parsed
+ ts_parser_parse(tree) -> tree /
+
+ treesit_record_change(tree) \
+ treesit_record_change(tree) | user edits buffer
+ ... /
+
+ and so on. */
+
/* Make sure PARSER's visible_beg and visible_end are in sync with
BUF_BEGV_BYTE and BUG_ZV_BYTE. When calling this function you must
make sure the current buffer's size is not larger than UINT32_MAX.
@@ -1365,9 +1405,10 @@ treesit_check_range_argument (Lisp_Object ranges)
CHECK_LIST_END (tail, ranges);
}
-/* Generate a list of ranges in Lisp from RANGES. This function
- doesn't take ownership of RANGES. BUFFER is used to convert
- between tree-sitter buffer offset and buffer position. */
+/* Generate a list of ranges in Lisp from RANGES. Assumes tree-sitter
+ tree and the buffer has the same visible region (w.r.t narrowing).
+ This function doesn't take ownership of RANGES. BUFFER is used to
+ convert between tree-sitter buffer offset and buffer position. */
static Lisp_Object
treesit_make_ranges (const TSRange *ranges, uint32_t len,
struct buffer *buffer)
diff --git a/src/treesit.h b/src/treesit.h
index 1473126c5bc..6f6423ff472 100644
--- a/src/treesit.h
+++ b/src/treesit.h
@@ -56,13 +56,12 @@ struct Lisp_TS_Parser
this field to true to force tree-sitter to re-parse. */
bool need_reparse;
/* These two positions record the buffer byte position (1-based) of
- the "visible region" that tree-sitter sees. Unlike markers,
- These two positions do not change as the user inserts and deletes
- text around them. Before re-parse, we move these positions to
- match BUF_BEGV_BYTE and BUF_ZV_BYTE. Note that we don't need to
- synchronize these positions when retrieving them in a function
- that involves a node: if the node is not outdated, these
- positions are synchronized. */
+ the "visible region" that tree-sitter sees. Before re-parse, we
+ move these positions to match BUF_BEGV_BYTE and BUF_ZV_BYTE.
+ Note that we don't need to synchronize these positions when
+ retrieving them in a function that involves a node: if the node
+ is not outdated, these positions are synchronized. See comment
+ (ref:visible-beg-null) in treesit.c for more explanation. */
ptrdiff_t visible_beg;
ptrdiff_t visible_end;
/* This counter is incremented every time a change is made to the