@@ -80,28 +80,38 @@ BEG and END are the begin and end of the text to be changed."
80
80
(setq tree-sitter--start-point (ts--point-from-position beg)
81
81
tree-sitter--old-end-point (ts--point-from-position end))))
82
82
83
- ; ;; TODO XXX: The doc says that `after-change-functions' can be called multiple times, with
84
- ; ;; different regions enclosed in the region passed to `before-change-functions' . Therefore what we
85
- ; ;; are doing may be a bit too naive. Several questions to investigate:
83
+ ; ;; TODO: How do we batch *after* hooks to re-parse only once? Maybe using
84
+ ; ;; `run-with-idle-timer' with 0-second timeout?
86
85
; ;;
87
- ; ;; 1. Are the *after* regions recorded all at once, or one after another? Are they disjointed
88
- ; ;; (would imply the former)?.
89
- ; ;;
90
- ; ;; 2. Are the *after* regions recorded at the same time as the *before* region? If not, how can the
91
- ; ;; latter possibly enclose the former, e.g. in case of inserting a bunch of text?
92
- ; ;;
93
- ; ;; 3. How do we batch *after* hooks to re-parse only once? Maybe using `run-with-idle-timer' with
94
- ; ;; 0-second timeout?
95
- ; ;;
96
- ; ;; 4. What's the deal with several primitives calling `after-change-functions' *zero* or more
97
- ; ;; times? Does that mean we can't rely on this hook at all?
98
- (defun tree-sitter--after-change (_beg end _length )
86
+ ; ;; XXX: Figure out how to detect whether it was a text-property-only change.
87
+ ; ;; There's no point in reparsing in these situations.
88
+ (defun tree-sitter--after-change (beg end length )
99
89
" Update relevant editing states and reparse the buffer (incrementally).
100
90
Installed on `after-change-functions' .
101
91
102
92
END is the end of the changed text."
103
- (setq tree-sitter--new-end-byte (position-bytes end)
104
- tree-sitter--new-end-point (ts-point-from-position end))
93
+ (ts--save-context
94
+ (setq tree-sitter--start-byte (position-bytes beg)
95
+ tree-sitter--start-point (ts--point-from-position beg)
96
+ tree-sitter--new-end-byte (position-bytes end)
97
+ tree-sitter--new-end-point (ts--point-from-position end))
98
+ ; ; The enclosing region passed to `before-change-functions' can be inexact,
99
+ ; ; which can be larger than the actual changes. One example is
100
+ ; ; `upcase-initials-region' . Therefore, we need to compute the exact change
101
+ ; ; here. XXX: This is sometimes incorrect, because `ts--point-from-position'
102
+ ; ; and `position-bytes' here look at other text in the same region, not the
103
+ ; ; changed text. TODO FIX: Either figure out how we can get the exact
104
+ ; ; old-end, or make `ts_tree_edit' accept position ranges.
105
+ (let ((old-end (+ beg length )))
106
+ ; ; XXX: Additionally, in case of a deletion at the end of the buffer,
107
+ ; ; trying to compute the old-end position/byte is impossible, because the
108
+ ; ; text is already gone. When that happens, use the old-end previously
109
+ ; ; recorded in `before-change-functions' .
110
+ (setq tree-sitter--old-end-point (or (ignore-errors
111
+ (ts--point-from-position old-end))
112
+ tree-sitter--old-end-point)
113
+ tree-sitter--old-end-byte (or (position-bytes old-end)
114
+ tree-sitter--old-end-byte))))
105
115
(when tree-sitter-tree
106
116
(ts-edit-tree tree-sitter-tree
107
117
tree-sitter--start-byte
0 commit comments