To make the syntax tree easier to analyze, many language grammars
assign @dfn{field names} to child nodes (@pxref{tree-sitter node field
name, field name}). For example, a @code{function_definition} node
-could have a @code{declarator} node and a @code{body} node.
+could have a @code{declarator} child and a @code{body} child.
@defun treesit-node-child-by-field-name node field-name
This function finds the child of @var{node} whose field name is
(@pxref{tree-sitter named node, named node}).
@end defun
+@heading Convenience functions
+
+@defun treesit-node-enclosed-p smaller larger &optional strict
+This function returns non-@code{nil} if @var{smaller} is enclosed in
+@var{larger}. @var{smaller} and @var{larger} can be either a cons
+@code{(@var{beg} . @var{end})} or a node.
+
+Return non-@code{nil} if @var{larger}'s start <= @var{smaller}'s start
+and @var{larger}'s end <= @var{smaller}'s end.
+
+If @var{strict} is @code{t}, compare with < rather than <=.
+
+If @var{strict} is @code{partial}, consider @var{larger} encloses
+@var{smaller} when at least one side is strictly enclosing.
+@end defun
+
@node Pattern Matching
@section Pattern Matching Tree-sitter Nodes
@cindex pattern matching with tree-sitter nodes
(treesit-node-prev-sibling node named)))))))
node)
+(defun treesit-node-enclosed-p (smaller larger &optional strict)
+ "Return non-nil if SMALLER is enclosed in LARGER.
+SMALLER and LARGER can be either (BEG . END) or a node.
+
+Return non-nil if LARGER's start <= SMALLER's start and LARGER's
+end <= SMALLER's end.
+
+If STRICT is t, compare with < rather than <=.
+
+If STRICT is \\='partial, consider LARGER encloses SMALLER when
+at least one side is strictly enclosing."
+ (unless (and (or (consp larger) (treesit-node-p larger))
+ (or (consp smaller) (treesit-node-p smaller)))
+ (signal 'wrong-type-argument '((or cons treesit-node))))
+ (let ((larger-start (if (consp larger)
+ (car larger)
+ (treesit-node-start larger)))
+ (larger-end (if (consp larger)
+ (cdr larger)
+ (treesit-node-end larger)))
+ (smaller-start (if (consp smaller)
+ (car smaller)
+ (treesit-node-start smaller)))
+ (smaller-end (if (consp smaller)
+ (cdr smaller)
+ (treesit-node-end smaller))))
+ (pcase strict
+ ('t (and (< larger-start smaller-start)
+ (< smaller-end larger-end)))
+ ('partial (and (or (not (eq larger-start smaller-start))
+ (not (eq larger-end smaller-end)))
+ (<= larger-start smaller-start
+ smaller-end larger-end)))
+ (_ (<= larger-start smaller-start smaller-end larger-end)))))
+
;;; Query API supplement
(defun treesit-query-string (string query language)
(define-short-documentation-group treesit
-
"Parsers"
(treesit-parser-create
:no-eval (treesit-parser-create 'c)
(treesit-node-check
:no-eval (treesit-node-check node 'named)
:eg-result t)
-
+ (treesit-node-enclosed-p
+ :no-eval (treesit-node-enclosed-p node1 node2)
+ :no-eval (treesit-node-enclosed-p node1 '(12 . 18)))
(treesit-node-field-name-for-child
:no-eval (treesit-node-field-name-for-child node)
;; `treesit-node-eq'.
(should (treesit-node-eq root-node root-node))
(should (not (treesit-node-eq root-node doc-node)))
+ ;; `treesit-node-enclosed-p'
+ (should (treesit-node-enclosed-p '(1 . 3) '(1 . 4)))
+ (should (treesit-node-enclosed-p '(1 . 3) '(1 . 3)))
+ (should (not (treesit-node-enclosed-p '(1 . 3) '(1 . 4) t)))
+ (should (treesit-node-enclosed-p '(1 . 3) '(1 . 4) 'partial))
+ (should (treesit-node-enclosed-p '(2 . 3) '(1 . 4) t))
+ (should (treesit-node-enclosed-p object-node root-node))
;; Further test for `treesit-node-check'.
(treesit-parser-delete parser)