Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration with imenu #19

Open
ubolonton opened this issue Feb 6, 2020 · 8 comments
Open

Integration with imenu #19

ubolonton opened this issue Feb 6, 2020 · 8 comments
Labels
help wanted Extra attention is needed

Comments

@ubolonton
Copy link
Collaborator

ubolonton commented Feb 6, 2020

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.

@ubolonton ubolonton added help wanted Extra attention is needed good first issue Good for newcomers labels Feb 6, 2020
@jakejx
Copy link

jakejx commented Mar 2, 2020

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)])))
    )

@ubolonton
Copy link
Collaborator Author

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.

@jakejx
Copy link

jakejx commented Mar 2, 2020

I see. Got it working again, thanks! Will start experimenting and move towards using tree-query-matches to get imenu integration working.

@ubolonton ubolonton removed the good first issue Good for newcomers label Mar 3, 2020
@ubolonton ubolonton pinned this issue Oct 19, 2020
@mohkale
Copy link

mohkale commented Dec 17, 2021

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.

@DamienCassou
Copy link

Imenu support would be really great

@mohkale
Copy link

mohkale commented Feb 6, 2022

@DamienCassou See #199. It's still at the draft stage and I'm not sure what the best approach moving forward should be :/.

@ubolonton
Copy link
Collaborator Author

ubolonton commented Feb 6, 2022

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.

@lshnmoptim
Copy link

Hi! Is there any update on this feature? Thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

6 participants
@ubolonton @DamienCassou @jakejx @mohkale @lshnmoptim and others