microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
162.33k stars 28.59k forks source link

[php] Provide HTML tag matching/language service support #2915

Closed adred closed 6 years ago

adred commented 8 years ago

I don't know if it's just me but there's no support for HTML tag matching. If I click on div, every instance of div are highlighted instead of the closing </div>, which is a PITA.

alexdima commented 8 years ago

@adred Maybe you are on an old version?

image

adred commented 8 years ago

screen shot 2016-02-12 at 11 15 17 am

OS X Yosemite. The same behaviour in Ubuntu 14.04. VS Code version is 0.10.8

sorinpopescu commented 8 years ago

I have the same issue - http://prntscr.com/bnfaym

LouWii commented 8 years ago

👍

nunosousa-dev commented 8 years ago

Any update on this? I have the same issue.

giancarlo88 commented 7 years ago

I'm also having the same issue.

Lazerproof commented 7 years ago

Same here

naumanahmed19 commented 7 years ago

same here for .blade.php

aga5tya commented 7 years ago

Issue still persists on latest update, on twig and php files atleast, would love to hear if there is any progress? @alexandrudima

alexjose commented 7 years ago

+1

vasanth833 commented 7 years ago

+1

rgfx commented 7 years ago

+1

robcaa commented 7 years ago

+1

moufeed commented 7 years ago

+1

cbrostrom commented 7 years ago

+1

bunkaisatori commented 7 years ago

+1, I kindly ask to add this feature.

BrunoQuaresma commented 7 years ago

+1

ales-k commented 7 years ago

+1

druellan commented 7 years ago

Seems to match the keyword, not the pair. It is matching even the comments:

2016-12-09_09h47_34

ghost commented 7 years ago

+1

rschalch commented 7 years ago

+1

aga5tya commented 7 years ago

@alexandrudima @aeschli, Is there any progress on this issue, would be helpful if someone could point me in a direction to check the progress. Thank you for all your contributions.

charanjits commented 7 years ago

Any updates? Still facing the same issue with the latest release also v1.8.0...

vs code - tag close start highlight issue

krisbulman commented 7 years ago

Changing the colour between the connecting line of the selected tag or an additional line in the margin would be ideal. Here is how webstorm looks in this scenario:

closing-highlight

AlexPoirier1 commented 7 years ago

+1 here! I've been looking for an extension to do this until I found out it supposed to be built-in

ava-cassiopeia commented 7 years ago

+1 still seeing this in 1.8.1

Kiricon commented 7 years ago

+1

blvd-studio commented 7 years ago

+1

neeravp commented 7 years ago

+1
This is a much required feature for php / laravel developers to embrace VS Code. Most of the time the view or html is being written in .php or .blade.php file as far as PHP developers are concerned.
VS Code is a promising tool, needs a little help from the team to make more Laravel/PHP devs try and embrace it.

andrewmartin commented 7 years ago

+1

Hugocorp974 commented 7 years ago

It's deal breaker ! Come on Dev Team, we need this feature...

+1

therawk commented 7 years ago

Need this

+1

ghost commented 7 years ago

+1

rahulv3a commented 7 years ago

+1

axdyng commented 7 years ago

+1

guilhermebrunoreis commented 7 years ago

+1

neuotq commented 7 years ago

+1 Or maybe there is an extention for it?

ben-styling commented 7 years ago

+1

chrisjimallen commented 7 years ago

+1

amit-coditas commented 7 years ago

i guess we have to deal with it, someone know of a extension that helps timebeing.

guilhermebrunoreis commented 7 years ago

for a while i'm using a different file associations settings, like below:

"files.associations": {
    "*.tpl": "php",
    "*.php": "html"
},

With this, the editor will recognize the php as a html file, and then we can see the tag matching.

AlexPoirier1 commented 7 years ago

@aeschli It is not only for PHP. It does not work for any JSX file or JSX syntax in a .js file either. It would be a nice feature considering how React is becoming (already is) very popular. image

kjetilsg commented 7 years ago

I have the same issue with the Pyramid Web Framework built with Python.

@guilhermebrunoreis solution worked for me by changing user settings to

"files.associations": { "*.pt": "html" },

rifaldhiaw commented 7 years ago

Thanks @kjetilsg

I got this worked too on blade.

"files.associations": { "*.blade.php": "html" }

ankitrg commented 7 years ago

Can anyone point me how can I help/contribute towards this feature? By the amount of time it has taken to provide such a basic feature mean the team must be busy. I would love to contribute if someone can guide me. Thanks.

afdallah commented 7 years ago

+1

chrisjimallen commented 7 years ago

@rifaldhiaw @kjetilsg changing the file suffixes like that will disable any native intellisense it may have had before though right? So changing .php to act like .html will disable any .php support it had previously. Correct me if I'm wrong.

tonypee commented 7 years ago

+1

mousetraps commented 7 years ago

@ankitrg

Can anyone point me how can I help/contribute towards this feature? By the amount of time it has taken to provide such a basic feature mean the team must be busy. I would love to contribute if someone can guide me. Thanks.

In order to achieve this, we'll likely want to include HTML as an embedded language. Improving our PHP+HTML experience will certainly be a priority in the coming months, and while I can't get to this immediately, I'm happy to share some preliminary thoughts and provide some quick pointers for those interested in investigating it further.

Dissecting the built-in HTML language extension

A good example to look at is the built-in HTML language service, which embeds CSS and JavaScript. https://github.com/Microsoft/vscode/blob/master/extensions/html/client/src/htmlMain.ts#L47

A quick search reveals that the initializationOptions.embeddedLanguages is first used in the server initialize function, which is the main entrypoint the the language server: https://github.com/Microsoft/vscode/blob/master/extensions/html/server/src/htmlServerMain.ts#L52

The initialize function calls getLanguageModes as one of its first steps, which is defined here: https://github.com/Microsoft/vscode/blob/master/extensions/html/server/src/modes/languageModes.ts#L53

getLanguageModes returns an object of type LanguageModes which includes a bunch of methods that map between the positions / language IDs, and the LanguageMode: https://github.com/Microsoft/vscode/blob/master/extensions/html/server/src/modes/languageModes.ts#L38-L46

This helps use know which language server to ask (CSS, JS, or HTML) for requests like document highlighting (which is the feature described in this thread): https://github.com/Microsoft/vscode/blob/master/extensions/html/server/src/htmlServerMain.ts#L209-L216

What's LanguageMode? https://github.com/Microsoft/vscode/blob/master/extensions/html/server/src/modes/languageModes.ts#L19-L36

LanguageMode is an interface that gets implemented by each of the individual languages supported in the language service. It basically maps a language-specific ID (see getId()) to the language-specific feature implementations:

Now so far, this has all been plumbing - the actual logic for the HTML-specific features lives in vscode-html-languageservice, which gets pulled in as an npm module.

Applying this to PHP

For PHP, we'll probably want to do something similar from the built-in PHP extension (at a high level, we want to have some way to distinguish between which language mode we're in, map that language mode to the corresponding feature implementation, and provide any other relevant context). PHP entrypoint here: https://github.com/Microsoft/vscode/blob/master/extensions/php/src/phpMain.ts

For tag matching in particular, we care about getDocumentHighlight: https://github.com/Microsoft/vscode-html-languageservice/blob/9ea1db325b7bb9c54f7e5fbb8c4a8474df150e7a/src/services/htmlHighlighting.ts#L11-L29

Now, one of the critical questions I glossed over when describing the HTML support above is "how do we actually differentiate between regions?" This is where things get a little trickier if you don't have a full lexer/scanner implementation because if you take the absolute simplest approach - e.g. simply look for the first start-tag, and the first end-tags, there are all sorts of edge cases like:

So now we also need to account for heredoc, nowdoc, command expressions, comments, strings, template strings, etc. and any combination thereof.

The TextMate grammar (which is responsible for syntax highlighting) defines these rules, but we don't currently have a way to simply piggyback on this functionality from a language service, so we would either need to grit our teeth, and write it ourselves, or use an implementation that's already out there. Probably the easiest thing to do is use PHP's built-in tokenizer, token_get_all (see PHP validation logic for how we currently invoke PHP from the extension). T_INLINE_HTML will refer to all text outside of PHP, which is exactly what we want to know.

And of course, token_get_all doesn't return positions, so we'd have to calculate those ourselves while iterating through the loop. E.g. we currently do this in the new PHP parser: https://github.com/Microsoft/tolerant-php-parser/blob/master/src/PhpTokenizer.php#L75

Now that we have php and non-php blocks, we can start looking into tag matching.

Now let's take a simple example:

<html>
</html>
<?php
echo `hello world`;

This could conceivably get split up into two regions:

<!-- HTML region -->
<html>
</html>
/* PHP region */
<?php
echo `hello world`;

The HTML region could then get sent through for the HTML language service to find the document highlights. #winning

But wait. PHP is a templating language. Which means that you can also do stuff like this:

<html>
<?php ?>
</html>

Now our exclusive document regions don't work so cleanly anymore because we get three of them:

If we pass region 1 in alone, then we won't get proper highlights if the end tag lives in region 2 (the same is also true of the PHP code, where for instance a block's close brace can appear after an inline HTML block). So instead of sending in the regions alone to the language services, we actually need to replace everything in the middle of the regions with whitespace to generate the virtual document, which is exactly what the HTML language extension does: https://github.com/Microsoft/vscode/blob/master/extensions/html/server/src/modes/embeddedSupport.ts#L198

To be continued...

Anyways, hope you enjoyed that not-so-quick braindump of some of the considerations with this feature and potential places to start. Note that this is just one way of thinking about the problem, and there are also other approaches we could take. Additionally, I suspect it might be possible to simplify things for this feature in particular, but for now that's left as an exercise to the reader because it's getting late here in Seattle, and as much as I love you all, I also love sleep :wink:

cc @aeschli, @rebornix, @felixfbecker

felixfbecker commented 7 years ago

@mousetraps I think this should be added to LSP. The language server already has an AST, so it knows the exact ranges where other languages are embedded