[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/tree-sitter 591759d508 2/7: Make treesit-node-child and fiends a
From: |
Yuan Fu |
Subject: |
feature/tree-sitter 591759d508 2/7: Make treesit-node-child and fiends accept negative index |
Date: |
Sun, 23 Oct 2022 22:07:03 -0400 (EDT) |
branch: feature/tree-sitter
commit 591759d508024a666a863cf918287744e72b1267
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>
Make treesit-node-child and fiends accept negative index
* doc/lispref/parsing.texi (Retrieving Node): Update manual.
* src/treesit.c (Ftreesit_node_child)
(Ftreesit_node_field_name_for_child): Accept and process negative
index.
---
doc/lispref/parsing.texi | 21 +++++++++++++++------
src/treesit.c | 45 ++++++++++++++++++++++++++++++++++++---------
2 files changed, 51 insertions(+), 15 deletions(-)
diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi
index e26090be1d..3a19b1b7ca 100644
--- a/doc/lispref/parsing.texi
+++ b/doc/lispref/parsing.texi
@@ -567,11 +567,16 @@ This function returns the immediate parent of @var{node}.
@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
@@ -880,7 +885,11 @@ of @var{node} as a child of its parent.
@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
diff --git a/src/treesit.c b/src/treesit.c
index b0e7d0e211..3ac0a0c7b2 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -1529,20 +1529,36 @@ DEFUN ("treesit-node-child",
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
@@ -1606,19 +1622,30 @@ DEFUN ("treesit-node-field-name-for-child",
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);
- feature/tree-sitter updated (3114eb8078 -> 6203b9db34), Yuan Fu, 2022/10/23
- feature/tree-sitter 6203b9db34 7/7: * lisp/treesit.el (treesit-node-at): Remove argument LARGEST., Yuan Fu, 2022/10/23
- feature/tree-sitter 524d10c86b 3/7: Make treesit-node-at return the last leaf node at EOB, Yuan Fu, 2022/10/23
- feature/tree-sitter 6cf2a9c55d 4/7: Make treesit-search-forward-goto accept a NODE argument, Yuan Fu, 2022/10/23
- feature/tree-sitter c120b0ebdb 5/7: Fix treesit-beginning/end-of-defun, Yuan Fu, 2022/10/23
- feature/tree-sitter e45d8dbeea 1/7: ; * lisp/treesit.el (treesit-range-functions): Fix typo., Yuan Fu, 2022/10/23
- feature/tree-sitter 591759d508 2/7: Make treesit-node-child and fiends accept negative index,
Yuan Fu <=
- feature/tree-sitter 1787e651d3 6/7: * lisp/treesit.el (treesit-parser-range-on): New function., Yuan Fu, 2022/10/23