From 9874561f39e62c1c9fada6c2e013f93d9ea65729 Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Sun, 10 Dec 2023 16:23:44 -0800 Subject: [PATCH] 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. --- doc/lispref/parsing.texi | 4 ++-- lisp/treesit.el | 3 ++- src/treesit.c | 7 +++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index 353585f79c7..34eb2826a21 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi @@ -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 diff --git a/lisp/treesit.el b/lisp/treesit.el index 962a6fc3cf8..9dc5d4970b6 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -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 diff --git a/src/treesit.c b/src/treesit.c index 8419452d54a..45de82ec096 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -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) -- 2.39.2