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

treesitter config: query_file_ignore #15260

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

MunifTanjim
Copy link
Contributor

@MunifTanjim MunifTanjim commented Aug 3, 2021

resolves #15244

Description

  • Introduces vim.treesitter.config method. It is used for updating configuration options for treesitter.
  • Introduces treesitter configuration option: query_file_ignore

Usage

Usage: vim.treesitter.config(options, scope)

Treesitter config can be set for these:

  • for any language
  • for a specific language
  • for a specific buffer

set config for a specific buffer

vim.treesitter.config({
  query_file_ignore = {},
}, 0)

set config for a specific language

vim.treesitter.config({
  query_file_ignore = {},
}, "lua")

set config for any language

vim.treesitter.config({
  query_file_ignore = {},
})

Usage: config query_file_ignore

Lua string pattern: https://www.lua.org/pil/20.2.html

Ignore all query files from a specific plugin:

vim.treesitter.config({
  query_file_ignore = { "/nvim%-treesitter/" },
}, "lua")

Ignore specific query file from a specific plugin:

vim.treesitter.config({
  query_file_ignore = { "/nvim%-treesitter/.+/indents.scm" },
}, "lua")

Ignore all query files from all plugins:

vim.treesitter.config({
  query_file_ignore = { ".+" },
}, "lua")

Add/Remove a specific ignore file pattern:

vim.treesitter.config({
  query_file_ignore = function(patterns)
    table.insert(patterns, "/nvim%-treesitter/") -- or filter it out to remove
    return patterns
  end,
}, "lua")

Clear all ignore file patterns:

vim.treesitter.config({
  query_file_ignore = {},
}, "lua")
-- or
vim.treesitter.config({
  query_file_ignore = function(patterns)
    return nil
  end,
}, "lua")

@gpanders
Copy link
Member

gpanders commented Aug 3, 2021

Is there a way to re-enable a query file after it's been ignored? I can see that being useful for e.g. debugging or to allow easy toggling of certain query files.

@MunifTanjim
Copy link
Contributor Author

MunifTanjim commented Aug 4, 2021

Is there a way to re-enable a query file after it's been ignored? I can see that being useful for e.g. debugging or to allow easy toggling of certain query files.

We can go with one of these three alternatives.


ignore_query_files(lang: string, patterns: string[] | fn | nil)

If patterns is array of string string[], set it as ignore patterns.

If patterns is function fn, it takes the current ignore patterns and returns the next ignore patterns. So user can add more patterns to it or remove some.

Pros:

  • Flexible API
  • Can be called multiple times (from different places)

Cons:

  • Might not seem so friendly for some people (?)

Or, same functionality as the above example, but more explicit API:

ignore_query_files(lang: string, patterns: string[], action?: 'replace' | 'add' | 'remove' = 'replace')

Based on the value of action (defaults to 'replace'), patterns will be added to the current list, removed from it or replace it.

Props:

  • More verbose than the previous example (can go under cons too, depends on the people)
  • Flexible API
  • Can be called multiple times (from different places)

Cons:

  • No way to read the current value of ignore patterns.

Or go with a restricted set API that always replaces the current list:

ignore_query_files(lang: string, patterns: string[] | nil)

Pros

  • Simplest implementation

Cons

  • Since it always replaces the value, calling multiple times (from different places) might break things.
  • No way to read the current value of ignore patterns.

@vigoux you made a comment earlier (now deleted) which suggested the third example here.

@gpanders

Now that the pros and cons are laid out, what do you guys think we should go with?

Or maybe there are some even simpler ways to acheive this?

@MunifTanjim MunifTanjim force-pushed the feat-treesitter-ignore-query-paths branch 3 times, most recently from a0a5db0 to 075b253 Compare August 4, 2021 17:05
@MunifTanjim MunifTanjim changed the title feat: add vim.treesitter.ignore_query_files [RDY] feat: add vim.treesitter.ignore_query_files Aug 4, 2021
@MunifTanjim MunifTanjim marked this pull request as ready for review August 4, 2021 17:07
@MunifTanjim MunifTanjim force-pushed the feat-treesitter-ignore-query-paths branch 2 times, most recently from a0538cb to 9b9aa1b Compare August 6, 2021 18:10
runtime/lua/vim/treesitter/query.lua Outdated Show resolved Hide resolved
runtime/lua/vim/treesitter/query.lua Outdated Show resolved Hide resolved
@MunifTanjim MunifTanjim force-pushed the feat-treesitter-ignore-query-paths branch 2 times, most recently from 616a017 to fa34401 Compare August 10, 2021 13:55
@vigoux
Copy link
Member

vigoux commented Aug 11, 2021

Could you add a little test for this feature ? After that we'll be good to go !

@MunifTanjim MunifTanjim force-pushed the feat-treesitter-ignore-query-paths branch from fa34401 to 67aed82 Compare August 11, 2021 17:18
@MunifTanjim
Copy link
Contributor Author

Could you add a little test for this feature ? After that we'll be good to go !

Added the tests for this method. Since we only have a single query file to play with runtime/queries/c/highlights.scm, that's all I could think of testing... hoping it would be enough 🤞🏼

Copy link
Member

@vigoux vigoux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are going to hate me but : could you run ./scripts/gen_vimdoc.py -t treesitter just to see the look of the generated docs ? I think we handle type information in lua pretty bad.

@MunifTanjim
Copy link
Contributor Author

You are going to hate me but : could you run ./scripts/gen_vimdoc.py -t treesitter just to see the look of the generated docs ? I think we handle type information in lua pretty bad.

😂 no worries... This is what I get:

image

Should I remove the type information?

@vigoux
Copy link
Member

vigoux commented Aug 12, 2021

Hmmmm... @tjdevries do you think we could keep those around until we support type indications in the doc comments ?

@tjdevries
Copy link
Contributor

Whatever makes the docs look good for now is fine with me :)

@MunifTanjim MunifTanjim force-pushed the feat-treesitter-ignore-query-paths branch from 67aed82 to 2b54a51 Compare August 14, 2021 09:22
@MunifTanjim
Copy link
Contributor Author

I've removed the type annotations.

@MunifTanjim MunifTanjim force-pushed the feat-treesitter-ignore-query-paths branch from 2b54a51 to 45a64db Compare August 23, 2021 03:46
@justinmk justinmk changed the title [RDY] feat: add vim.treesitter.ignore_query_files feat: add vim.treesitter.ignore_query_files Aug 27, 2021
@MunifTanjim MunifTanjim force-pushed the feat-treesitter-ignore-query-paths branch from f074d26 to 24493d6 Compare December 18, 2021 06:12
@MunifTanjim MunifTanjim force-pushed the feat-treesitter-ignore-query-paths branch from 24493d6 to 7ff0bc7 Compare January 3, 2022 06:53
@MunifTanjim MunifTanjim force-pushed the feat-treesitter-ignore-query-paths branch from 7ff0bc7 to 5623b3c Compare January 9, 2022 06:38
@clason
Copy link
Member

clason commented Jan 11, 2022

@neovim/treesitter @gpanders

@clason clason added api libnvim, Nvim RPC API needs:discussion For PRs that propose significant changes to some part of the architecture or API labels Jan 11, 2022
@clason clason added this to the 0.7 milestone Jan 11, 2022
@clason
Copy link
Member

clason commented Jan 11, 2022

I think vim.treesitter.config() should

  1. be reserved for global options and
  2. hence take only a single table.

Anything language or buffer specific is better handled through explicit vim.treesitter.set_query (or somesuch) functions; maybe the best approach is extending vim.treesitter.require_language to take an optional dict with an allow list and/or a block list?

Note that for vim.treesitter.highlighter, we already allow passing a {queries = {...}} option to override the queries used for that parsed tree.

@MunifTanjim
Copy link
Contributor Author

MunifTanjim commented Jan 11, 2022

Anything language or buffer specific is better handled through explicit vim.treesitter.set_query (or somesuch) functions;

I actually went with vim.treesitter.ignore_query_files initially, but in the previous discussions (in this PR) @justinmk suggested the vim.treesitter.config approach. Should we revert to that?

maybe the best approach is extending vim.treesitter.require_language to take an optional dict with an allow list and/or a block list?

vim.treesitter.require_language seems to deal with only the parser, not queries. Might not be the right place for it? 🤔

Note that for vim.treesitter.highlighter, we already allow passing a {queries = {...}} option to override the queries used for that parsed tree.

This is not only about highlighting. The use-case goes like this: "I use a plugin that implements a feature using treesitter. They also provide some queries in queries/<lang>/ folder for that feature. But I want to completely ignore those queries for a specific <lang> and write my own queries for it."

@clason
Copy link
Member

clason commented Jan 11, 2022

I actually went with vim.treesitter.ignore_query_files initially, but in the previous discussions (in this PR) @justinmk suggested the vim.treesitter.config approach. Should we revert to that?

No, we should first discuss what kind of API we want to have before implementing anything.

vim.treesitter.require_language seems to deal with only the parser, not queries. Might not be the right place for it? 🤔

Maybe not (but the parser implies which queries are loaded currently, so it's not unrelated); that's what needs to be discussed.

This is not only about highlighting. The use-case goes like this: "I use a plugin that implements a feature using treesitter. They also provide some queries in queries/<lang>/ folder for that feature. But I want to completely ignore those queries for a specific <lang> and write my own queries for it."

I know; I'm just saying there is already precedent for customizing the queries, and we should keep that pattern in mind. In particular, the use case you describe is not about ignoring (specific) queries but overriding them completely with your custom list. Basically, what your plugin does is implement something on the same level as vim.treesitter.highlight, so it's reasonable to follow a similar pattern.

(In particular, I don't quite see why in this case your plugin couldn't go straight for custom queries <foo>.scm, similarly to indent.scm and fold.scm? It's also important to keep separate Neovim's core treesitter API and the nvim-treesitter infrastructure on top of that.)

@clason
Copy link
Member

clason commented Jan 11, 2022

Let me put it this way: I worry that your proposal acts on the wrong level: queries belong to "modules" (in nvim-treesitter terminology), not to parsers and even less to the global scope. Your use case is valid, but I don't think a global ignore list is the right approach to handle it -- we want finer-grained control. (What if I do want queries from plugins for some modules, like highlight and injections, but not for whatever your plugin does?)

@MunifTanjim
Copy link
Contributor Author

In particular, I don't quite see why in this case your plugin couldn't go straight for custom queries <foo>.scm, similarly to indent.scm and fold.scm?

Hmm... Sorry, the example of the use-case in my previous comment was probably bad. Let me take a step back and describe why I wanted this to begin with:

I was not satisfied with the default lua parser nvim-treesitter comes with (it's not really maintained and was incomplete). And so I wrote one. Now, all the plugin that provides queries for lua is for that default lua parser from nvim-treesitter. So for using this new parser there are two options:

  1. Name it something else than lua (lua-new or whatever) so that I can put queries in queries/lua-new folder. And use that parser for lua language.
  2. Put something in my personal config file that tells neovim to ignore the queries files in queries/lua directories in all those plugins that comes with it. And only load queries for lua from my own queries/lua directory (which includes indent.scm, folds.scm, textobjects.scm and so on).

This PR is for implementing that "something" from Option 2 which I can put in my personal config, e.g.

  vim.treesitter.config({
    query_file_ignore = {
      "nvim-treesitter",
      "nvim-treesitter-textobjects",
      "nvim-treesitter-textsubjects",
      "refactoring.nvim",
    },
  }, "lua")

I think now we're more clear about the use-case I had.

With that being said, I understand if this is something that should not be included in Neovim core or if it's not worth adding the complexity. In that case I'll gladly go with the Option 1.

@clason
Copy link
Member

clason commented Jan 11, 2022

OK, that is indeed a very different problem. Yes, in general option 1 is the correct thing to do (different, incompatible, parsers should not have the same name!); but the real issue here is not with the core tree-sitter API but with nvim-treesitter (installing parsers) -- so I'd recommend simply not installing the default parser and adding yours as a custom parser (as explained in the README) under the same name.

In this case, however, if your Lua parser is indeed better than the current fork in nvim-treesitter, we might wish to switch -- but that is again something handled by nvim-treesitter, so I'd suggest opening an issue there about switching (where we may also want to consider @tjdevries' parser, so it would be good to include a comparison of the three).

@MunifTanjim
Copy link
Contributor Author

My use-case is unblocked by doing it a bit differently. Closing this PR.

Thanks everybody for the discussion! 💜

@theHamsta
Copy link
Member

@MunifTanjim I think this problem is not solved. We should have a way to select the query files

@MunifTanjim
Copy link
Contributor Author

@theHamsta Once the preferred solution is decided in nvim-treesitter/nvim-treesitter#2241, I can open another PR if needed.

@clason clason reopened this Jan 12, 2022
@clason
Copy link
Member

clason commented Jan 12, 2022

I'd like to keep the discussion open, even if the specific code here is probably not going to be merged. The generic question of how to override queries is still valid. (It could also be made into an issue, but for now it's easier to keep the history here.)

@clason clason marked this pull request as draft January 12, 2022 14:32
@bfredl bfredl modified the milestones: 0.9, 0.8 Aug 18, 2022
@justinmk justinmk mentioned this pull request Aug 29, 2022
3 tasks
@clason clason removed this from the 0.8 milestone Oct 1, 2022
@zeertzjq zeertzjq removed api libnvim, Nvim RPC API lua stdlib labels Mar 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs:discussion For PRs that propose significant changes to some part of the architecture or API treesitter
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support ignoring tree-sitter 'queries' for a specific language from specific plugins
9 participants