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

feat(treesitter): add injections of glsl #1

Merged
merged 2 commits into from
May 13, 2024

Conversation

DanilaMihailov
Copy link
Contributor

@DanilaMihailov DanilaMihailov commented May 10, 2024

Using treesitter language injections add support for inline glsl. Most notably it adds highlights, but actually more than that - for example plugin comment.nvim now comments (gcc) inside shader code using // string. And folding works + any other treesitter magic :)

Added queries in after/queries/lua/injections.scm as said here. And took these from nvim/runtime/queries queries as starting point.

I'am not sure that this really helps anyone, but it looks cool :)

before
Screenshot 2024-05-11 at 01 24 31

after
Screenshot 2024-05-11 at 01 24 44

There is two ways I check if glsl should be injected:

  1. Calls to love.graphics.newShader([[...]])
  2. Any string that starts with #pragma language glsl

There is 2 problems right now:

  1. If plugin is lazy loaded, then you have to :e current file for treesitter to re-highlight injected code.
  2. And you can see that variables in glsl (e.g. time) are highlighted in green, as lua strings. Highlight groups seems ok, but maybe I can fix it somehow

And I think maybe I should update readme. Because at least you need to install glsl parser to see this highlights (:TSInstall glsl)

@S1M0N38 S1M0N38 added the enhancement New feature or request label May 11, 2024
@S1M0N38
Copy link
Owner

S1M0N38 commented May 11, 2024

I'm not familiar with GLSL, but using TreeSitter (TS) to highlight inline languages is valuable. I'll be glad to merge this PR as long as these additions are optional and don't introduce extra dependencies.

It would be great if you could also add a small section to doc/love2d.txt, similar to the LSP section, e.g.:

================================================================================
GLSL                                                             *love2d-glsl*

OpenGL Shading Language (GLSL) is a high-level shading language ...

You can enable TreeSitter support for inline GLSL by ...

Doing so will ...

Just a few sentences explaining:

  • What GLSL is and how it can be used in Love2D
  • How to enable TS support for GLSL (e.g. simply run :TSInstall glsl)
  • Some examples of benefits of using TS (e.g. highlighting and plugins that leverage TS like comment.nvim)

The usage of GLSL may be a bit niche, so I don't want to overload new users with something overly technical. However, I think it's nice to let them know that if they need it, it's pretty simple to set up. So just a small section of around 10-20 lines in the docs should suffice.

@DanilaMihailov
Copy link
Contributor Author

Yeah, this is totally optional. I'm just using treesitter queries (that are included in base nvim) to hint parser that there is another language inside the string. If glsl parser is not installed, then it just should be highlighted as string.

Great idea to add this to help doc, will do it later. Now I am trying to fix the 2 problems I described above. The first problem with weird highlights actually is present in all embedded langs in lua. I checked queries for vim.cmd [[ some vim code ]] and it has same problem. I will create an issue in treesitter.

For second problem, still trying to figure out how to trigger reparsing tree, when plugin loaded. It is a small issue, but would be cool if it worked without additional actions.

And for GLSL, it is just a language used to write shaders. love2D uses its own language, but it is basically glsl syntactically with few changes in variable names. It described here in "Shader Language" section.

@DanilaMihailov
Copy link
Contributor Author

Added docs, tried my best to be succinct, but I am severely limited by my english level. Feel free to correct me :)

Regarding problems:

  1. Highlights are not applied, if plugin loaded lazily
    • Just run :edit inside a buffer, to refresh treesitter parsers
    • Load plugin not lazily and everything will work
    • The problem basically that treesitter loads queries before plugin is loaded and there is seems to be no way to programmatically "refresh" parser. I scoured the source code of nvim, and could not find a way. But gained enough understanding, that I will create a PR that allows to "refresh" parsers.
  2. Some highlights are wrong

So consider this PR ready for merge. I will try to add ability to refresh parsers to nvim and if successful, I will create additional PR that refreshes parsers automatically.

@DanilaMihailov DanilaMihailov marked this pull request as ready for review May 11, 2024 17:35
@S1M0N38 S1M0N38 merged commit bfafe88 into S1M0N38:main May 13, 2024
2 checks passed
@S1M0N38
Copy link
Owner

S1M0N38 commented May 13, 2024

Great work!

  • I have enhanced the English in the GLSL section of the documentation.
  • The Shader is used in the test/game code as an example.
  • I ran the tests locally, and all tests passed.

I like to push v0.2 of the library. Should I wait for the PR about "auto-refresh parser"?

@S1M0N38 S1M0N38 requested review from S1M0N38 and removed request for S1M0N38 May 13, 2024 07:22
@DanilaMihailov
Copy link
Contributor Author

Here is my PR in neovim neovim/neovim#28715 . It needs to be merged in order to make auto refresh work. So I think you should not wait.

Locally I am running nvim compiled on my branch and added this snippet in plugin for auto reload parser

  -- after plugin is loaded check if there is any open lua buffers,
  -- if so, we need to refresh their parsers, so our treesitter queries will work
  for bufnr in vim.iter(vim.api.nvim_list_bufs()) do
    if vim.api.nvim_buf_is_loaded(bufnr) and vim.bo[bufnr].ft == "lua" then
      vim.treesitter.get_parser(bufnr, "lua", { reload = true }) -- reload parser
    end
  end

and it works great. So as soon as my PR in nvim is merged, I will create PR here with this code added somewhere :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants