mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-03 04:21:28 -08:00
Add treesit thing-at-point functions
* lisp/treesit.el (treesit--thing-sibling): (treesit--thing-prev): (treesit--thing-next): (treesit--thing-at): New functions.
This commit is contained in:
parent
0db75b80e1
commit
3ad06ed4f0
1 changed files with 71 additions and 0 deletions
|
|
@ -2427,6 +2427,77 @@ which see; it can also be a predicate."
|
|||
(treesit-parent-until cursor iter-pred)))
|
||||
result))
|
||||
|
||||
(defun treesit--thing-sibling (pos thing prev)
|
||||
"Return the next or previous THING at POS.
|
||||
|
||||
If PREV is non-nil, return the previous THING. It's guaranteed
|
||||
that returned previous sibling's end <= POS, and returned next
|
||||
sibling's beginning >= POS.
|
||||
|
||||
Return nil if no THING can be found. THING should be a thing
|
||||
defined in `treesit-thing-settings', or a predicate as described
|
||||
in `treesit-thing-settings'."
|
||||
(let* ((cursor (treesit-node-at pos))
|
||||
(pos-pred (if prev
|
||||
(lambda (n) (<= (treesit-node-end n) pos))
|
||||
(lambda (n) (>= (treesit-node-start n) pos))))
|
||||
(iter-pred (lambda (node)
|
||||
(and (treesit-node-match-p node thing t)
|
||||
(funcall pos-pred node))))
|
||||
(sibling nil))
|
||||
(when cursor
|
||||
;; Find the node just before/after POS to start searching.
|
||||
(save-excursion
|
||||
(while (and cursor (not (funcall pos-pred cursor)))
|
||||
(setq cursor (treesit-search-forward-goto
|
||||
cursor "" prev prev t))))
|
||||
;; Keep searching until we run out of candidates or found a
|
||||
;; return value.
|
||||
(while (and cursor
|
||||
(funcall pos-pred cursor)
|
||||
(null sibling))
|
||||
(setq sibling (treesit-node-top-level cursor iter-pred t))
|
||||
(setq cursor (treesit-search-forward cursor thing prev prev)))
|
||||
sibling)))
|
||||
|
||||
(defun treesit--thing-prev (pos thing)
|
||||
"Return the previous THING at POS.
|
||||
|
||||
The returned node, if non-nil, must be before POS, i.e., its end
|
||||
<= POS.
|
||||
|
||||
THING should be a thing defined in `treesit-thing-settings', or a
|
||||
predicate as described in `treesit-thing-settings'."
|
||||
(treesit--thing-sibling pos thing t))
|
||||
|
||||
(defun treesit--thing-next (pos thing)
|
||||
"Return the next THING at POS.
|
||||
|
||||
The returned node, if non-nil, must be after POS, i.e., its
|
||||
start >= POS.
|
||||
|
||||
THING should be a thing defined in `treesit-thing-settings', or a
|
||||
predicate as described in `treesit-thing-settings'."
|
||||
(treesit--thing-sibling pos thing nil))
|
||||
|
||||
(defun treesit--thing-at (pos thing &optional strict)
|
||||
"Return the smallest THING enclosing POS.
|
||||
|
||||
The returned node, if non-nil, must enclose POS, i.e., its start
|
||||
<= POS, its end > POS. If STRICT is non-nil, the returned node's
|
||||
start must < POS rather than <= POS.
|
||||
|
||||
THING should be a thing defined in `treesit-thing-settings', or
|
||||
it can be a predicate described in `treesit-thing-settings'."
|
||||
(let* ((cursor (treesit-node-at pos))
|
||||
(iter-pred (lambda (node)
|
||||
(and (treesit-node-match-p node thing t)
|
||||
(if strict
|
||||
(< (treesit-node-start node) pos)
|
||||
(<= (treesit-node-start node) pos))
|
||||
(< pos (treesit-node-end node))))))
|
||||
(treesit-parent-until cursor iter-pred t)))
|
||||
|
||||
;; The basic idea for nested defun navigation is that we first try to
|
||||
;; move across sibling defuns in the same level, if no more siblings
|
||||
;; exist, we move to parents's beg/end, rinse and repeat. We never
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue