aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuan Fu2023-01-08 19:05:19 -0800
committerYuan Fu2023-01-08 21:22:06 -0800
commitef87c75566018b546e56f64f66f665ebfd8da305 (patch)
tree97626b79212932d503077e5d7c9d73c3d0b6ec1e
parent1238fa8e49bdb12db66d856dcb4b192db5d026ff (diff)
downloademacs-ef87c75566018b546e56f64f66f665ebfd8da305.tar.gz
emacs-ef87c75566018b546e56f64f66f665ebfd8da305.zip
Make sure NODE is not the root node in tree-sitter indent (bug#60602)
There are two possible ways to solve the problem raised in the bug report: either make sure NODE is never the root (so that parent is never nil), or allow parent to be nil. If we go with the latter, a lot of matcher and anchor functions need change (they need to guard against a null parent). I tried it, and needing to check for null parent is pretty annoying. In comparison, if NODE is never the root, it is very convenient for the user, and it doesn't complicate the rule that much (and it's rather intuitive, people usually don't think of the case where NODE is the root node). So that's what I choose. * doc/lispref/modes.texi (Parser-based Indentation): Update manual. * lisp/treesit.el (treesit-indent-function): Update docstring. (treesit--indent-1): Make sure NODE is not the root.
-rw-r--r--doc/lispref/modes.texi8
-rw-r--r--lisp/treesit.el13
2 files changed, 12 insertions, 9 deletions
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index b2dd294ea28..ff372edb3ff 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -4936,10 +4936,10 @@ Each @var{matcher} or @var{anchor} is a function that takes three
4936arguments: @var{node}, @var{parent}, and @var{bol}. The argument 4936arguments: @var{node}, @var{parent}, and @var{bol}. The argument
4937@var{bol} is the buffer position whose indentation is required: the 4937@var{bol} is the buffer position whose indentation is required: the
4938position of the first non-whitespace character after the beginning of 4938position of the first non-whitespace character after the beginning of
4939the line. The argument @var{node} is the largest (highest-in-tree) 4939the line. The argument @var{node} is the largest node that starts at
4940node that starts at that position; and @var{parent} is the parent of 4940that position (and is not a root node); and @var{parent} is the parent
4941@var{node}. However, when that position is in a whitespace or inside 4941of @var{node}. However, when that position is in a whitespace or
4942a multi-line string, no node can start at that position, so 4942inside a multi-line string, no node can start at that position, so
4943@var{node} is @code{nil}. In that case, @var{parent} would be the 4943@var{node} is @code{nil}. In that case, @var{parent} would be the
4944smallest node that spans that position. 4944smallest node that spans that position.
4945 4945
diff --git a/lisp/treesit.el b/lisp/treesit.el
index 7205e43916d..e53d5d53bd0 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -1341,10 +1341,10 @@ and returns
1341 (ANCHOR . OFFSET). 1341 (ANCHOR . OFFSET).
1342 1342
1343BOL is the position of the beginning of the line; NODE is the 1343BOL is the position of the beginning of the line; NODE is the
1344\"largest\" node that starts at BOL; PARENT is its parent; ANCHOR 1344\"largest\" node that starts at BOL (and isn't a root node);
1345is a point (not a node), and OFFSET is a number. Emacs finds the 1345PARENT is its parent; ANCHOR is a point (not a node), and OFFSET
1346column of ANCHOR and adds OFFSET to it as the final indentation 1346is a number. Emacs finds the column of ANCHOR and adds OFFSET to
1347of the current line.") 1347it as the final indentation of the current line.")
1348 1348
1349(defun treesit--indent-1 () 1349(defun treesit--indent-1 ()
1350 "Indent the current line. 1350 "Indent the current line.
@@ -1362,10 +1362,13 @@ Return (ANCHOR . OFFSET). This function is used by
1362 ((treesit-language-at (point)) 1362 ((treesit-language-at (point))
1363 (treesit-node-at bol (treesit-language-at (point)))) 1363 (treesit-node-at bol (treesit-language-at (point))))
1364 (t (treesit-node-at bol)))) 1364 (t (treesit-node-at bol))))
1365 (root (treesit-parser-root-node
1366 (treesit-node-parser smallest-node)))
1365 (node (treesit-parent-while 1367 (node (treesit-parent-while
1366 smallest-node 1368 smallest-node
1367 (lambda (node) 1369 (lambda (node)
1368 (eq bol (treesit-node-start node)))))) 1370 (and (eq bol (treesit-node-start node))
1371 (not (treesit-node-eq node root)))))))
1369 (let* 1372 (let*
1370 ((parser (if smallest-node 1373 ((parser (if smallest-node
1371 (treesit-node-parser smallest-node) 1374 (treesit-node-parser smallest-node)