Function: treesit-node-at
treesit-node-at is a byte-compiled function defined in treesit.el.gz.
Signature
(treesit-node-at POS &optional PARSER-OR-LANG NAMED)
Documentation
Return the leaf node at position POS.
A leaf node is a node that doesn't have any child nodes.
The returned node's span covers POS: the node's beginning is before or at POS, and the node's end is after POS.
If no such node exists, but there's a leaf node which ends at POS, return that node.
Otherwise (e.g., when POS is on whitespace between two leaf nodes), return the first leaf node after POS.
If there is no leaf node after POS, return the first leaf node before POS.
Return nil if no leaf node can be returned. If NAMED is non-nil, only look for named nodes.
If PARSER-OR-LANG is a parser, use that parser; if PARSER-OR-LANG
is a language, find the first parser for that language in the
current buffer, or create one if none exists; If PARSER-OR-LANG
is nil, try to guess the language at POS using treesit-language-at.
If there's a local parser at POS, the local parser takes priority unless PARSER-OR-LANG is a parser, or PARSER-OR-LANG is a language and doesn't match the language of the local parser.
Other relevant functions are documented in the treesit group.
Shortdoc
;; treesit
(treesit-node-at (point))
e.g. => #<treesit-node (identifier) in 179-180>
Source Code
;; Defined in /usr/src/emacs/lisp/treesit.el.gz
(defun treesit-node-at (pos &optional parser-or-lang named)
"Return the leaf node at position POS.
A leaf node is a node that doesn't have any child nodes.
The returned node's span covers POS: the node's beginning is before
or at POS, and the node's end is after POS.
If no such node exists, but there's a leaf node which ends at POS,
return that node.
Otherwise (e.g., when POS is on whitespace between two leaf
nodes), return the first leaf node after POS.
If there is no leaf node after POS, return the first leaf node
before POS.
Return nil if no leaf node can be returned. If NAMED is non-nil,
only look for named nodes.
If PARSER-OR-LANG is a parser, use that parser; if PARSER-OR-LANG
is a language, find the first parser for that language in the
current buffer, or create one if none exists; If PARSER-OR-LANG
is nil, try to guess the language at POS using `treesit-language-at'.
If there's a local parser at POS, the local parser takes priority
unless PARSER-OR-LANG is a parser, or PARSER-OR-LANG is a
language and doesn't match the language of the local parser."
(let* ((root
;; 1. Given a parser, just use the parser's root node.
(cond ((treesit-parser-p parser-or-lang)
(treesit-parser-root-node parser-or-lang))
;; 2. Given a language, try local parser, then global
;; parser.
(parser-or-lang
(let ((parser (car (treesit-parsers-at
pos parser-or-lang))))
(when parser
(treesit-parser-root-node parser))))
;; 3. No given language, try to get a language at point.
;; If we got a language, only use parser of that
;; language, otherwise use any parser we can find. When
;; finding parser, try local parser first, then global
;; parser.
(t
;; LANG can be nil. Use the parser deepest by embed level.
(let ((parser (car (treesit-parsers-at pos))))
(when parser
(treesit-parser-root-node parser))))))
(node root)
(node-before root)
(pos-1 (max (1- pos) (point-min)))
next)
(when node
;; This is very fast so no need for C implementation.
(while (setq next (treesit-node-first-child-for-pos
node pos named))
(setq node next))
;; If POS is at the end of buffer, after all the text, we will
;; end up with NODE = root node. Instead of returning nil,
;; return the last leaf node in the tree for convenience.
(if (treesit-node-eq node root)
(progn
(while (setq next (treesit-node-child node -1 named))
(setq node next))
node)
;; Normal case, where we found a node.
(if (<= (treesit-node-start node) pos)
node
;; So the node we found is completely after POS, try to find
;; a node whose end equals to POS.
(while (setq next (treesit-node-first-child-for-pos
node-before pos-1 named))
(setq node-before next))
(if (eq (treesit-node-end node-before) pos)
node-before
node))))))