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

Support local queries/predicates #94

Open
jcs090218 opened this issue Jan 5, 2021 · 6 comments
Open

Support local queries/predicates #94

jcs090218 opened this issue Jan 5, 2021 · 6 comments

Comments

@jcs090218
Copy link
Member

jcs090218 commented Jan 5, 2021

The original issue is from #93.

It will be great if this feature is supported!

@woolsweater
Copy link

I assume this means Tree-sitter's Local Variables feature? If so, I would love to see this as well.

Would it need to be implemented in Rust, or can it be done in Lisp? If Lisp, I might be able to take a stab at it.

@ubolonton
Copy link
Collaborator

ubolonton commented Feb 21, 2021

It needs some Rust code to implement the custom predicates, e.g. (.is-not? local).

You can study Tree-sitter's implementation. It queries the whole buffer in a single pass using a combined query (locals + highlight), It doesn't handle changes, so it cannot be applied as-is.

There's also nvim-treesitter's implementation of locals, which also seems to be single-pass and whole-buffer, but does not support highlighting (locals only).

An MVP prototype could do it in 2 passes: The first pass queries (the whole buffer) locals, and provides data for the custom predicates used by the second pass. From there we can start optimizing things.

@theHamsta
Copy link
Contributor

theHamsta commented Feb 22, 2021

We have a implementation of local highlighting (just use is-local?) But it is not used because our current implementation is to slow (mainly wrong data structures and single buffer pass). This is why it isn't used for highlighting at the moment.

Our predicates are custom Lua functions so they can use data from a cached local passes.

EDIT: our local query works like this (is? @variable "parameter") to check whether an identifier is a function parameter (or local variable or function).

@ubolonton
Copy link
Collaborator

We have a implementation of local highlighting (just use is-local?) But it is not used because our current implementation is to slow (mainly wrong data structures and single buffer pass). This is why it isn't used for highlighting at the moment.

I think the reason could be that the query patterns needed to support this require accessing buffer text a lot. Doing that on the whole buffer is slow, unless it's direct access without copying. tree-sitter-hl suffered from the same issue, so we use range restriction query execution (ts_query_cursor_set_byte_range) for highlighting. A similar approach could probably be used for the local pass. (It doesn't work well with sibling patterns, but these are probably uncommon for querying locals.)

Our predicates are custom Lua functions so they can use data from a cached local passes.

How are text edits handled? Are subsequent query executions (after the first full-buffer execution) range-restricted?

Side note: I think eventually it's more desirable for tree-sitter to support some sort of "reactive query execution", maybe by somehow fusing the parser automata and the query automata together, so that incremental parses emit a streams of matches/captures and their retractions. (I don't know if that makes sense. I don't have deep enough knowledge in this area.)

@ubolonton
Copy link
Collaborator

Personally I'm looking at the brute-forcing approach of adding direct no-copy text access to Emacs dynamic modules, which hopefully can eliminate the need for these "clever" optimizations.

@lambdadog
Copy link

Any updates on this issue? I'm working on implementing indentation along the lines of Helix Editor's indent queries and while their custom predicates aren't widely used in the indent queries they actually have in-repo, they are essential in some cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants