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

POC #28, #34, #33 #50

Closed
wants to merge 1 commit into from
Closed

POC #28, #34, #33 #50

wants to merge 1 commit into from

Conversation

EmranMR
Copy link
Owner

@EmranMR EmranMR commented Jan 8, 2024

Hi @calebdw following on from our discussion on #33.

As much as I love your solution, which is a common sense and more semantic, things are a bit more convoluted for Nova (maybe zed as well?).

For those editors at the moment, it is not possible, for extensions or users to access the built-in parsers html/query/injections.scm , in fact I requested this from Panic on the forum back in August when you posted your alpineJS snippet on the "Discussions", which I found pretty cool for NeoVim.

no way of knowing without copying a lot of the html parser

However this POC shows how these can be implemented as first party as a work around, without actually using any duplication from tree-sitter-html:

The following is what is implemented in the POC:

  1. parser picks up alpine attributes
  2. injections.scm is adjusted to inject JS inside the quotes

At the moment, the only problem, with this POC is the painting, which is easily fixed.

Highlighting fix using highlights.scm & few touch ups for the grammar.js:

  1. create a nodes to capture for the alpine attribute & "
  2. Painting quotes as "attribute quotes"
  3. Painting alpine attributes as "attributes"

Both of which can be fixed in two lines in highlights.scm, here is a hypothetical example for Nova.

(attribute_name) @attribute
(quotes) @tag.attribute.value.delimiter ;not sure what this is for neovim

Can I please have your opinion on this, as you are quite experienced with tree-sitter and of course as a NeoVim user.

  1. I could just define the grammars, and commit to main, then NVim users just copy and paste stubs to highlights.scm and injections.scm inside their tree-sitter-blade copy
  2. Branching out from main for Nova, and maintain two parallel branches, merging the future features as added to the Nova branch (absolutely not my favourite because of the development overhead)!

I personally like option 1, because it makes my life easy. I will try to bundle all those issues into one release, with users of the parser having to just copy and paste the stubs provided into two files once and for all. It is sort of future proof as well, everything encapsulated and maintained inside tree-sitter-blade.

@calebdw
Copy link
Contributor

calebdw commented Jan 9, 2024

@EmranMR,

Maybe you should just switch to the dark side and give Neovim a try 😉?

Extending queries

First I took a look at your feature request and the following is not true:

In Neovim you can just extend the html injections, and add your own on the top it. Of course that editor is very customisable, and requires each user getting their hands dirty, changing the queries in the tree-sitter-html folder manually.

I want to point out that the extended queries live in the neovim runtime path (for me that is ~/.config/nvim/after/queries/html/injections.scm which of course is mapped to my dotfile repo, everything in the after dir is loaded after everything else) so the user does not have to manually edit the queries shipped by the parser

The primary method that Neovim users manage their treesitter parsers is through the nvim-treesitter plugin which supports many parsers out of the box and ships with queries for the parsers. Along the same lines, if I want to add to or override these queries I would do so by adding a query in my runtime path and would not go manually edit the installed files.

Thoughts on POC

You can certainly do this, but I don't particularly care for it and would not recommend it as it's really just a dirty workaround.

Some counter arguments to consider are:

  1. This would match any text that resembles an Alpine directive even if it's not Alpine. E.g.,
    <div>
        x-foo="bar"
    </div>
    is not Alpine but it would still get parsed as an Alpine directive. Granted that scenario might be rare in the wild but the
    point still remains.
  2. The parser would produce an AST that is essentially just a blob of nodes instead of structured tree:
    (text)
    (alpine_js)
    (text)
  3. It would be nigh impossible to use this approach to parse @foo and :bar attributes and inject other languages into them because:
    • back to 1), it only makes sense to parse {@,:}foo if it's in an html element
    • context matters: :foo is injected with php in blade components (<x-foo :bar="$this" />) and js otherwise
  4. same thing for the ::foo escaped attribute, it is only valid inside blade components

Response to your solutions

Branching out from main for Nova, and maintain two parallel branches, merging the future features as added to the Nova branch (absolutely not my favourite because of the development overhead)!

Obviously a long lived parallel branch like that is rarely a good idea, but why couldn't you just PR the features to Nova that you would like to see? I don't see why they wouldn't be happy with the contributions.

Possible solutions

This is tricky because there's so many different technologies thrown together, but below are some possible solutions to consider (in no particular order, and some of them might not even be feasible---I'm just spit-balling):

  1. Create a separate Nova plugin from the blade plugin that just extends the html queries and injects the different languages in
  2. Create a PR to Nova to allow users to add their own custom queries
  3. Rewrite this blade parser to extend from the html parser which would then give us all of the element and attribute grammar for free (similar to js and typescript). Then it would be relatively easy to add nodes for blade components and livewire components (could take a look at the Vue grammer which does something similar).

@EmranMR
Copy link
Owner Author

EmranMR commented Jan 9, 2024

@calebdw I would love to just migrate to NeoVim, but I tried to set it up over the holidays and failed miserably haha!

Thanks for the thorough comment! As you pointed out, the specificity, with your solution, is a big winner. I am just going to leave this for now and try to push Panic as you suggested. Unfortunately they do not accept PRs, and refuse to open source the built-in parser for security reasons...

I want to point out that the extended queries live in the neovim runtime path (for me that is ~/.config/nvim/after/queries/html/injections.scm which of course is mapped to my dotfile repo, everything in the after dir is loaded after everything else) so the user does not have to manually edit the queries shipped by the parser

I will also add this to the forum as a correction, as I was not aware of the ins and outs. This is a pretty cool feature by NVim, indeed!

3 Rewrite this blade parser to extend from the html parser which would then give us all of the element and attribute grammar for free (similar to js and typescript). Then it would be relatively easy to add nodes for blade components and livewire components (could take a look at the Vue grammer which does something similar).

This is actually an interesting proposal, and I might just experiment with this, however I would certainly not use it for those issues as your solution would elegantly suffice. Simplicity is always the way forward!

@EmranMR EmranMR closed this Jan 9, 2024
@calebdw
Copy link
Contributor

calebdw commented Jan 10, 2024

I would love to just migrate to NeoVim, but I tried to set it up over the holidays and failed miserably haha!

I'm sorry to hear that! kickstart.nvim is a great place to start your own personal config. ThePrimeagen also has a lot of good videos on his vim channel.

Unfortunately they do not accept PRs, and refuse to open source the built-in parser for security reasons...

That is unfortunate, but I don't really buy their claim about "security implications of those contributions"---there's plenty of frameworks (e.g., Laravel) and numerous editors that operate just fine in open source. Nova looks to be a paid product so I suspect they are protecting their interests on that front...but anyways.

This is actually an interesting proposal, and I might just experiment with this

This is something that I've been thinking about for a while and haven't had a chance to play with it. The other benefit here is that the html injection queries that I wrote could be shipped along with the queries for this parser as they would be extended from the html parsers.

@calebdw
Copy link
Contributor

calebdw commented Mar 4, 2024

@EmranMR, just wanted to let you know that a new and improved kickstart.nvim video just dropped in case you're interested:

https://www.youtube.com/watch?v=m8C0Cq9Uv9o

@EmranMR
Copy link
Owner Author

EmranMR commented Mar 4, 2024

@calebdw Ah fantastic, I have also been trying out the rust based Helix Editor, past few weeks, seems an interesting approach! Of course nothing will be as feature rich as Nvim I think atm!

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

Successfully merging this pull request may close these issues.

2 participants