Sublime Forum

PHP / HTML sublime-syntax scope removal

#1

I am trying to remove the text.html.basic that appears when I hit CTRL + ALT + SHIFT + P in the interior PHP tags (<?php ?>). It should appear everything from that list without this one. that should be seen only in the bottom like on the second picture.

YAML CODE (PHP.sublime-syntax)

%YAML 1.2
---
name: PHP
version: 2
file_extensions:
  - php
  - php3
  - php4
  - php5
  - php7
  - phps
  - phpt
  - phtml
first_line_match: '^(#!.*[^-]php[0-9]?|<\?php)\b'
scope: embedding.php
contexts:
  main:
    - match: ''
      push: scope:text.html.basic
      with_prototype:
        - match: <\?(?i:php|=)?(?![^?]*\?>)
          scope: punctuation.section.embedded.begin.php
          push:
            - meta_scope: meta.embedded.block.php
            - meta_content_scope: source.php
            - include: php-end-tag-pop
            - include: scope:source.php
        - match: <\?(?i:php|=)?
          scope: punctuation.section.embedded.begin.php
          push:
            - meta_scope: meta.embedded.line.php
            - meta_content_scope: source.php
            - include: php-end-tag-pop
            - include: scope:source.php

  php-end-tag-pop:
    - match: (\?>)(\s*\n)?
      captures:
        1: punctuation.section.embedded.end.php
        2: meta.html-newline-after-php.php
      pop: 1

PHP%201

0 Likes

#2

pushing directly into a scope always includes its scope. If that’s not desired, an intermediate (in this case anonymous) context is needed, which includes the final context scope:text.html.basic.

...
    - match: ''
      push:
        - include: scope:text.html.basic
      with_prototype:
...

An alternative approach can be found at

1 Like

#3

It worked well for PHP but for html text.html.basic disappeared, leaving it with embedding.php.

0 Likes

#4

But you wanted to have it removed? Can you explain in more detail what you’re trying to achieve?

0 Likes

#5

Yes in the interior of PHP tags ONLY (first picture). It got removed also on the HTML side (second picture), remaining embedding.php. Should had been only in interior of the PHP tags only.

0 Likes

#6

PHP is basically a scripting language which expands any kind of template (HTML, CSS, maybe some crazy guy also may expand JS).

So the toplevel scope is HTML and PHP is the embedded script. To avoid any confusion mensioned PR merges embedding.php text.html.basic to text.html.php. It is common practise to use text.html meta.embedding source to scope embedded script languages which interpreted convert the template into a real html page.

No need to remove text.html.php then.

A plugin can always use a selector like text.html - source to exclude those embedded parts.

0 Likes

#7

I actually think that it’s HTML in PHP, not PHP in HTML. Thus, source.php shouldn’t under text.html.basic scope. There are some HTML snippets, which targets text.html and forget to exclude source.php, accidentally appears in source.php and that makes no sense.

1 Like

#8

That is correct. HTML snippets should appear only in herodoc constructions or in string.quote.

0 Likes

#9

It should probably be implemented like this then. But as <?php ...?> for php code, I am not sure which point of view is finally technical correct.

Basically all PHP files are just templates piped through php interpreter which evaluates everything between <?php ... ?> and outputs the resulting HTML (ignoring any kind of caching for simpicity here). This is IMHO very much the way any other templating engine works as well. If there was no such<?php...?>` in a php-file output would match input (just HTML).

I don’t decline “HTML in PHP” to be the more familiar working with or thinking about PHP.

0 Likes

#10

0 Likes

#11

I added clear_scopes and managed to remove the text.html.basic only from PHP side. Managed to do what I wanted like this:

%YAML 1.2
---
name: PHP
version: 2
file_extensions:
  - php
  - php3
  - php4
  - php5
  - php7
  - phps
  - phpt
  - phtml
first_line_match: '^(#!.*[^-]php[0-9]?|<\?php)\b'
scope: source.php
contexts:
  main:
    - match: ''
      push: scope:text.html.basic
        #- include: scope:text.html.basic
        #- include: embedded-html
      with_prototype:
        - match: <\?(?i:php|=)?(?![^?]*\?>)
          scope: punctuation.section.embedded.begin.php
          push:
            - clear_scopes: true
            - meta_scope: meta.embedded.block.php
            - meta_content_scope: source.php
            - include: php-end-tag-pop
            - include: scope:source.php
        - match: <\?(?i:php|=)?
          scope: punctuation.section.embedded.begin.php
          push:
            - meta_scope: meta.embedded.line.php
            - meta_content_scope: source.php
            - include: php-end-tag-pop
            - include: scope:source.php

  php-end-tag-pop:
    - match: (\?>)(\s*\n)?
      captures:
        1: punctuation.section.embedded.end.php
        2: meta.html-newline-after-php.php
      pop: 1
1 Like

#12

You forget to add it for the

        - match: <\?(?i:php|=)?
          scope: punctuation.section.embedded.begin.php
          push:
            - meta_scope: meta.embedded.line.php
            - meta_content_scope: source.php
            - include: php-end-tag-pop
            - include: scope:source.php

part btw.


That clear scope may cause other issue like

<div class="test <?= $foo ?>"></div>
//         ^^^^^^^^^^^^^^^^^^ string.quoted.double.html

no longer pass. So I guess it’s good to keep it “missing” for one-line PHP :slight_smile:…

0 Likes