Fix treesit-node-field-name and friends (bug#66674)

So turns out ts_node_field_name_for_child takes a named node index,
but we were passing it normal index that counts both named and
anonymous nodes.  That's what makes the field name all wrong in
treesit explorer.

* doc/lispref/parsing.texi:
(Accessing Node Information): Update docstring.
* lisp/treesit.el (treesit-node-index): Add some unrelated comment.
(treesit-node-field-name): Get named node index rather than all node
index.
* src/treesit.c (Ftreesit_node_field_name_for_child): Update
docstring, use ts_node_named_child_count.
This commit is contained in:
Yuan Fu 2023-12-10 16:23:44 -08:00
parent eace9e1122
commit 9874561f39
No known key found for this signature in database
GPG key ID: 56E19BC57664A442
3 changed files with 7 additions and 7 deletions

View file

@ -1015,8 +1015,8 @@ This function returns the field name of the @var{n}'th child of
@var{node}. It returns @code{nil} if there is no @var{n}'th child, or
the @var{n}'th child doesn't have a field name.
Note that @var{n} counts both named and anonymous children, and
@var{n} can be negative, e.g., @minus{}1 represents the last child.
Note that @var{n} counts named nodes only, and @var{n} can be
negative, e.g., @minus{}1 represents the last child.
@end defun
@defun treesit-node-child-count node &optional named

View file

@ -360,6 +360,7 @@ If NAMED is non-nil, collect named child only."
"Return the index of NODE in its parent.
If NAMED is non-nil, count named child only."
(let ((count 0))
;; TODO: Use next-sibling as it's more efficient.
(while (setq node (treesit-node-prev-sibling node named))
(cl-incf count))
count))
@ -367,7 +368,7 @@ If NAMED is non-nil, count named child only."
(defun treesit-node-field-name (node)
"Return the field name of NODE as a child of its parent."
(when-let ((parent (treesit-node-parent node))
(idx (treesit-node-index node)))
(idx (treesit-node-index node t)))
(treesit-node-field-name-for-child parent idx)))
;;; Query API supplement

View file

@ -2015,9 +2015,8 @@ DEFUN ("treesit-node-field-name-for-child",
Return nil if there's no Nth child, or if it has no field.
If NODE is nil, return nil.
N counts all children, i.e., named ones and anonymous ones.
N could be negative, e.g., -1 represents the last child. */)
Note that N counts named nodes only. Also, N could be negative, e.g.,
-1 represents the last child. */)
(Lisp_Object node, Lisp_Object n)
{
if (NILP (node))
@ -2031,7 +2030,7 @@ N could be negative, e.g., -1 represents the last child. */)
/* Process negative index. */
if (idx < 0)
idx = ts_node_child_count (treesit_node) + idx;
idx = ts_node_named_child_count (treesit_node) + idx;
if (idx < 0)
return Qnil;
if (idx > UINT32_MAX)