elisp-tree-sitter
elisp-tree-sitter copied to clipboard
Integration with imenu
A simplistic imenu-create-index-function
can look like this:
(defun tree-sitter-rust-imenu-index-function ()
(thread-last (tree-sitter-query [(function_item (identifier) @function)])
(seq-map (lambda (capture)
(pcase-let ((`(_ . ,node) capture))
(cons (ts-node-text node)
(ts-node-start-position node)))))))
A more substantial implementation can use ts-query-matches
to capture nested structures.
Hi! I was playing around with this to try and see what kind of imenu integration I can get going, but I am getting a (wrong-type-argument user-ptrp nil)
when running a test function, with the following stacktrace:
ts-make-query(nil [(function_item (identifier) @name)])
tree-sitter-query([(function_item (identifier) @name)])
(seq-map #'(lambda (capture) (let* ((x474 (car capture)) (x475 (cdr capture))) (let ((node x475)) (progn (print ts-node-text node) (cons (ts-node-text node) (ts-node-start-position node)))))) (tree-sitter-query [(function_item (identifier) @name)]))
(save-current-buffer (set-buffer (current-buffer)) (seq-map #'(lambda (capture) (let* ((x474 (car capture)) (x475 (cdr capture))) (let ((node x475)) (progn (print ts-node-text node) (cons ... ...))))) (tree-sitter-query [(function_item (identifier) @name)])))
ts-identifiers()
It seems that the error is coming from within the Rust module? So I am not sure how I should go about to debug.
For reference, this is what the function I'm testing looks like:
(defun ts-identifiers()
(interactive)
(with-current-buffer (current-buffer)
(seq-map (lambda (capture)
(pcase-let ((`(_ . ,node) capture))
(print ts-node-text node)
(cons (ts-node-text node) (ts-node-start-position node))))
(tree-sitter-query [(function_item (identifier) @name)])))
)
This line ts-make-query(nil [(function_item (identifier) @name)])
means that tree-sitter-language
was nil when tree-sitter-query
called ts-make-query .
It probably means tree-sitter-mode
was not turned on in that buffer.
Also note that tree-sitter-query
is more like a debugging aid currently. It creates a new query object every time. You'd better off create a query object once, and use ts-query-matches
or ts-query-captures
instead.
I see. Got it working again, thanks! Will start experimenting and move towards using tree-query-matches
to get imenu integration working.
I'm interested in implementing this. Do you have any tips for how to approach it? I was thinking maybe reusing the queries we use for highlighting (in emacs-tree-sitter/tree-sitter-langs
) or adding a new file in the same place for imenu queries.
Imenu support would be really great
@DamienCassou See #199. It's still at the draft stage and I'm not sure what the best approach moving forward should be :/.
I still haven't looked into #199 in details, but like @mohkale noted in that issue, I think arbitrary recursion is the single biggest challenge, specifically capturing the full paths of all nested items, not just the leaf identifiers. Queries alone are probably not expressive enough, so some sort of principled extension would be needed. On that front, I think it's worth exploring the newly introduced stack graphs, and the related graph DSL:
(function_definition
name: (identifier) @name) @function
{
node @function.def
attr (@function.def) kind = "definition"
attr (@function.def) symbol = @name
edge @function.containing_scope -> @function.def
}
I went through associated StrangeLoop talk. @dcreager illustrated the concepts very well.
Hi! Is there any update on this feature? Thanks :)