Built-in tree-sitter-php upgrade request

Hello!

I would really appreciate if Nova updates the built-in tree-sitter-php parser to the latest version for the next release! The split parser PR has been finally accepted and merged into the master branch!

This is extremely beneficial, allowing php_only injections into the specified regions. Up until now this was not possible, for blade, twig and so forth :blush:

Hello Emran,

Apologies for the extreme delay in getting back to you on this. I’ve been focused on Nova 11.x bug fix updates for the past couple of months. I’m refocused toward Nova 12 at this point and have indeed begun updating our built-in grammars for their latest upstream changes. With regard to PHP, I did see that the parser was split into php and php_only.

Not coming from a strong PHP background myself (and having never used Blade or Twig), would you be able to give me some details about what Blade, Twig, et. al. might need?

Our current PHP grammar is obviously built for PHP+HTML, and has direct injections for HTML content. I’m guessing your request is for us to also ship the php_only parser separately as well, such that extensions could take advantage of it for injections of pure PHP (without HTML) within another template language. Is that correct?

Hi @logan !

No problem at all! So, as you pointed correctly, oddly up until recently it was not possible to inject only php due to the way the parser was designed.

As an example for Blade, The file .blade.php is a valid php but instead of using <?php ?> to start the php parsing/completion you could do {{I am php now}} in the regions parsed as HTML.

Now before the release the <?php ?> syntax was the only thing recognised by the tree-sitter-php parser as it was hard-coded :grimacing:.

Also, just to add, the html injection responsibility is passed on to the tree-sitter-php and tree-sitter-blade will be only responsible for injecting php or the php_only based on the context

So for tree-sitter-blade if I did php injection for {{ php_only }}, you would have gotten the content parsed as HTML , and the only way to get the php parsing would be {{<?php xxx ?>}}. With the new release I can easily distinguish where to inject the php or php_only.

Now this a very interesting PR, and with the aim to have minimal overheads for yourself hopefully :crossed_fingers:. I noticed users were able to swap with no bother in NeoVim and so forth, like flicking a switch.

Basically what they have done, is they created a common/ folder that holds the old parser. Then they created two folders php_only and php where the grammar exists, which imports the common-grammar from the common/ and based on the argument decides what to do, bypass the HTML or just parse the PHP .

The tactic is very similar for what they did for typescript and tsx in tree-sitter-typescript!

Possible Update Guide?

I reckon all that is needed from your side is to make the .dylib using the grammar.js in those two folders, then make a simple php_only.xml inside Syntaxes/ folder.

Here is what I did to port / hack my way to get the Laravel Suite Extension correctly parsing php_only inside the tree-sitter-blade using the old messier PR, which was sort of, based on a duplicate strategy rather than using common/

  1. I generated the php-only.dylib. for some odd reason I remember I had an issue with naming/generation and I could only do php-only instead of php_only because of the make file or the way shell script was working from Nova docs. So I manually changed them myself, to get them working by hard coding the parser-name, instead of relying on the automatic repo based name generation. (might not be relevant for the new PR!)
  2. I then created a simple php-only.xml inside Syntaxes/
  3. Then I duplicated the internal php Completions for php … However inside Completions/PHP.xml, I changed the following line, and it all started working fine!
// Completions/PHP.xml
 <syntax>php-only</syntax>

The new version should hopefully be even easier to port!

Ah, awesome. That all makes sense and is pretty simple overall (once you know what happened!), as you mention. Cool, I will keep all of this in mind as I update our PHP support and will look into how we can ship the php_only support via Nova directly as well for our extension devs, and make the completions, et. al “just work” within it from our side to ease developer adoption.

1 Like

Hi @logan, I have noticed in the release notes for Nova 12 that the built in tree-sitters grammars have been updated with the upstream and

  • PHP-HTML: PHP completions should no longer be offered within HTML elements

So has the php-only parser been added to Nova? If so, how could the extension devs access the syntax for injection purposes? Thanks

Hello Emran!

Ah, apologies for the lack of documentation on this at the moment. This should be available as a tree-sitter grammar with the name php_only which you can use with an injection. If you encounter issues using it, let us know!

Hi @logan

Now that the Nova 12 is released, I gave it a shot, and removed all my made up php-only artefacts. But for some odd reason, it does not inject the php_only with the following injections.scm as suggested:

((text) @injection.content
    (#not-has-ancestor? @injection.content "envoy")
    (#set! injection.combined)
    (#set! injection.language php))

((text) @injection.content
    (#has-ancestor? @injection.content "envoy")
    (#set! injection.combined)
    (#set! injection.language shell))


((php_only) @injection.content
    (#set! injection.language php_only))
((parameter) @injection.content
    (#set! injection.language php_only))

here is a photo of the parse tree before and after using the php_only.

BEFORE

AFTER

I tried the internal html/javascript as the injected language, just in case, and it worked out fine. The autocompletion in the SCM shows the php_only as well as one of the options, just not injecting it for some odd reason, any ideas? :thinking:

PS:

In a normal PHP file, with PHP Syntax Nova does not show the php_only for the php content. Please see below.

Thanks
Emran