Add 'live' property to treesit-node-check (bug#61235)

* doc/lispref/parsing.texi (Accessing Node Information): Document.
* src/treesit.c (treesit_parser_live_p): New function.
(Ftreesit_node_check): Add 'live' property.
* test/src/treesit-tests.el (treesit-node-api): Add tests.
This commit is contained in:
Yuan Fu 2023-02-05 20:22:52 -08:00
parent 56960a6558
commit 5190173696
No known key found for this signature in database
GPG key ID: 56E19BC57664A442
3 changed files with 38 additions and 5 deletions

View file

@ -970,10 +970,15 @@ A node ``has error'' if the text it spans contains a syntax error. It
can be that the node itself has an error, or one of its descendants can be that the node itself has an error, or one of its descendants
has an error. has an error.
@cindex tree-sitter live node
@cindex live node, tree-sitter
A node is ``live'' if its parser is not deleted, and the buffer it
belongs to is live.
@defun treesit-node-check node property @defun treesit-node-check node property
This function checks if @var{node} has the specified @var{property}. This function checks if @var{node} has the specified @var{property}.
@var{property} can be @code{named}, @code{missing}, @code{extra}, @var{property} can be @code{named}, @code{missing}, @code{extra},
@code{outdated}, or @code{has-error}. @code{outdated}, @code{has-error}, or @code{live}.
@end defun @end defun
@defun treesit-node-type node @defun treesit-node-type node

View file

@ -1475,6 +1475,15 @@ This symbol is the one used to create the parser. */)
return XTS_PARSER (parser)->language_symbol; return XTS_PARSER (parser)->language_symbol;
} }
/* Return true if PARSER is not deleted and its buffer is live. */
static bool
treesit_parser_live_p (Lisp_Object parser)
{
CHECK_TS_PARSER (parser);
return ((!XTS_PARSER (parser)->deleted) &&
(!NILP (Fbuffer_live_p (XTS_PARSER (parser)->buffer))));
}
/*** Parser API */ /*** Parser API */
DEFUN ("treesit-parser-root-node", DEFUN ("treesit-parser-root-node",
@ -1908,7 +1917,8 @@ DEFUN ("treesit-node-check",
Ftreesit_node_check, Streesit_node_check, 2, 2, 0, Ftreesit_node_check, Streesit_node_check, 2, 2, 0,
doc: /* Return non-nil if NODE has PROPERTY, nil otherwise. doc: /* Return non-nil if NODE has PROPERTY, nil otherwise.
PROPERTY could be `named', `missing', `extra', `outdated', or `has-error'. PROPERTY could be `named', `missing', `extra', `outdated',
`has-error', or `live'.
Named nodes correspond to named rules in the language definition, Named nodes correspond to named rules in the language definition,
whereas "anonymous" nodes correspond to string literals in the whereas "anonymous" nodes correspond to string literals in the
@ -1924,7 +1934,10 @@ A node is "outdated" if the parser has reparsed at least once after
the node was created. the node was created.
A node "has error" if itself is a syntax error or contains any syntax A node "has error" if itself is a syntax error or contains any syntax
errors. */) errors.
A node is "live" if its parser is not deleted and its buffer is
live. */)
(Lisp_Object node, Lisp_Object property) (Lisp_Object node, Lisp_Object property)
{ {
if (NILP (node)) return Qnil; if (NILP (node)) return Qnil;
@ -1947,9 +1960,11 @@ errors. */)
result = ts_node_is_extra (treesit_node); result = ts_node_is_extra (treesit_node);
else if (EQ (property, Qhas_error)) else if (EQ (property, Qhas_error))
result = ts_node_has_error (treesit_node); result = ts_node_has_error (treesit_node);
else if (EQ (property, Qlive))
result = treesit_parser_live_p (XTS_NODE (node)->parser);
else else
signal_error ("Expecting `named', `missing', `extra', " signal_error ("Expecting `named', `missing', `extra', "
"`outdated', or `has-error', but got", "`outdated', `has-error', or `live', but got",
property); property);
return result ? Qt : Qnil; return result ? Qt : Qnil;
} }
@ -3448,6 +3463,7 @@ syms_of_treesit (void)
DEFSYM (Qextra, "extra"); DEFSYM (Qextra, "extra");
DEFSYM (Qoutdated, "outdated"); DEFSYM (Qoutdated, "outdated");
DEFSYM (Qhas_error, "has-error"); DEFSYM (Qhas_error, "has-error");
DEFSYM (Qlive, "live");
DEFSYM (QCanchor, ":anchor"); DEFSYM (QCanchor, ":anchor");
DEFSYM (QCequal, ":equal"); DEFSYM (QCequal, ":equal");

View file

@ -100,6 +100,7 @@
(should (eq nil (treesit-node-check root-node 'missing))) (should (eq nil (treesit-node-check root-node 'missing)))
(should (eq nil (treesit-node-check root-node 'extra))) (should (eq nil (treesit-node-check root-node 'extra)))
(should (eq nil (treesit-node-check root-node 'has-error))) (should (eq nil (treesit-node-check root-node 'has-error)))
(should (eq t (treesit-node-check root-node 'live)))
;; `treesit-node-child'. ;; `treesit-node-child'.
(setq doc-node (treesit-node-child root-node 0)) (setq doc-node (treesit-node-child root-node 0))
(should (equal "array" (treesit-node-type doc-node))) (should (equal "array" (treesit-node-type doc-node)))
@ -160,7 +161,18 @@
:type 'args-out-of-range) :type 'args-out-of-range)
;; `treesit-node-eq'. ;; `treesit-node-eq'.
(should (treesit-node-eq root-node root-node)) (should (treesit-node-eq root-node root-node))
(should (not (treesit-node-eq root-node doc-node)))))) (should (not (treesit-node-eq root-node doc-node)))
;; Further test for `treesit-node-check'.
(treesit-parser-delete parser)
(should (equal nil (treesit-node-check root-node 'live)))
;; Recreate parser.
(setq parser (treesit-parser-create 'json))
(setq root-node (treesit-parser-root-node
parser))
(should (equal t (treesit-node-check root-node 'live)))
(kill-buffer)
(should (equal nil (treesit-node-check root-node 'live))))))
;;; Indirect buffer ;;; Indirect buffer