@defun treesit-node-child node n &optional named
This function returns the @var{n}'th child of @var{node}. If
@var{named} is non-@code{nil}, it counts only named nodes
-(@pxref{tree-sitter named node, named node}). For example, in a node
-that represents a string @code{"text"}, there are three children
-nodes: the opening quote @code{"}, the string text @code{text}, and
-the closing quote @code{"}. Among these nodes, the first child is the
-opening quote @code{"}, and the first named child is the string text.
+(@pxref{tree-sitter named node, named node}).
+
+For example, in a node that represents a string @code{"text"}, there
+are three children nodes: the opening quote @code{"}, the string text
+@code{text}, and the closing quote @code{"}. Among these nodes, the
+first child is the opening quote @code{"}, and the first named child
+is the string text.
+
+This function returns @code{nil} if there is no @var{n}'th child.
+@var{n} could be negative, e.g., -1 represents the last child.
@end defun
@defun treesit-node-children node &optional named
@defun treesit-node-field-name-for-child node n
This function returns the field name of the @var{n}'th child of
-@var{node}.
+@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 child. And @var{n}
+could be negative, e.g., -1 represents the last child.
@end defun
@defun treesit-child-count node &optional named
Ftreesit_node_child, Streesit_node_child, 2, 3, 0,
doc: /* Return the Nth child of NODE.
-Return nil if there is no Nth child. If NAMED is non-nil, look for named
-child only. NAMED defaults to nil. If NODE is nil, return nil. */)
+Return nil if there is no Nth child. If NAMED is non-nil, look for
+named child only. NAMED defaults to nil. If NODE is nil, return
+nil.
+
+N could be negative, e.g., -1 represents the last child. */)
(Lisp_Object node, Lisp_Object n, Lisp_Object named)
{
if (NILP (node)) return Qnil;
treesit_check_node (node);
- treesit_check_positive_integer (n);
+ CHECK_INTEGER (n);
EMACS_INT idx = XFIXNUM (n);
- if (idx > UINT32_MAX)
- xsignal1 (Qargs_out_of_range, n);
+
treesit_initialize ();
TSNode treesit_node = XTS_NODE (node)->node;
TSNode child;
+
+ /* Process negative index. */
+ if (idx < 0)
+ {
+ if (NILP (named))
+ idx = ts_node_child_count (treesit_node) + idx;
+ else
+ idx = ts_node_named_child_count (treesit_node) + idx;
+ }
+ if (idx < 0)
+ return Qnil;
+ if (idx > UINT32_MAX)
+ xsignal1 (Qargs_out_of_range, n);
+
if (NILP (named))
child = ts_node_child (treesit_node, (uint32_t) idx);
else
doc: /* Return the field name of the Nth child of NODE.
Return nil if there's no Nth child, or if it has no field.
-If NODE is nil, return nil. */)
+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. */)
(Lisp_Object node, Lisp_Object n)
{
if (NILP (node))
return Qnil;
treesit_check_node (node);
- treesit_check_positive_integer (n);
+ CHECK_INTEGER (n);
EMACS_INT idx = XFIXNUM (n);
- if (idx > UINT32_MAX)
- xsignal1 (Qargs_out_of_range, n);
treesit_initialize ();
TSNode treesit_node = XTS_NODE (node)->node;
+
+ /* Process negative index. */
+ if (idx < 0)
+ idx = ts_node_child_count (treesit_node) + idx;
+ if (idx < 0)
+ return Qnil;
+ if (idx > UINT32_MAX)
+ xsignal1 (Qargs_out_of_range, n);
+
const char *name
= ts_node_field_name_for_child (treesit_node, (uint32_t) idx);