tomblachut / svelte-intellij

Svelte components in WebStorm and friends
MIT License
485 stars 38 forks source link

Emmet is not working as expected #19

Closed tobias-kuendig closed 4 years ago

tobias-kuendig commented 5 years ago

Can this be because of this plugin? I'm using Goland.

I haven't found out when exaclty it doesn't work. It never works inside another tag. Sometimes it doesn't even work on the root level.

Changing the File type of .svelte files back to HTML makes everything work as expected again.

emmet

tomblachut commented 5 years ago

Really weird, thanks for raising!

unlocomqx commented 5 years ago

Here's some debug info

In com.intellij.codeInsight.template.emmet.XmlEmmetParser#getDefaultTemplateKey then com.intellij.codeInsight.template.emmet.ZenCodingUtil#isHtml , the language is checked and must be HTML or XML and so on To pass that condition, you need to override getBaseLanguage in SvelteLanguage and return HtmlLanguage.INSTANCE

Even so, emmet fails because it creates the wrong dummy file type (SvelteFile instead of HTML File) This is because it reads the file language (which is SvelteLanguage) and doesn't look for a base language that is HTML So then com.intellij.codeInsight.template.emmet.tokens.TemplateToken#getXmlTag fails to find the XML tag that was added dynamically and null is returned screenshot_16

So basically com.intellij.codeInsight.template.emmet.tokens.TemplateToken#setTemplateText should use the HTML language instead of the file language which it gets through callback.getFile().getLanguage()

Or we should find a way to allow PsiTreeUtil to find an XmlTag inside HTML_FRAGMENT elements

tomblachut commented 5 years ago

@unlocomqx thx to your finding about setTemplateText I managed to do something For example

    <ul>
        {#each assets as {title} (a.id)}
            .header
        {/each}
    </ul>

Is expanded into

    <ul>
        {#each assets as {title} (a.id)}
            <li class=""></li>
        {/each}
    </ul>

So finding a parent works even across Svelte outer fragments which is great. Expanding if blocks etc. still works. Figuring out how to fix complex emmet patterns will be easy enough I hope.

My approach revolves around updating SvelteZenCodingGeneratorImpl

    override fun createParser(tokens: MutableList<ZenCodingToken>?, callback: CustomTemplateCallback, generator: ZenCodingGenerator?, surroundWithTemplate: Boolean): EmmetParser {
        return XmlEmmetParser(tokens, SvelteZenCodingCustomTemplateCallback(callback), generator, surroundWithTemplate)
    }
class SvelteZenCodingCustomTemplateCallback(callback: CustomTemplateCallback) : CustomTemplateCallback(callback.editor, callback.file.viewProvider.getPsi(HTMLLanguage.INSTANCE))

Notice that I overrode PsiFile in callback to always be HTML one.

unlocomqx commented 5 years ago

Brilliant I will try to figure out why it doesn't assign the attribute value correctly

unlocomqx commented 5 years ago

I did some debugging and found that this line gets the Psi File with Svelte Language when cursor is inside a Svelte Fragment TemplateManagerImpl.java:253 PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, myProject);

That file is used to instantiate CustomTemplateCallback in TemplateManagerImpl.java:263 CustomTemplateCallback templateCallback = new CustomTemplateCallback(editor, file);

(is there a way to override that?)

Then a dummy file is created using Svelte Language here GenerationNode.java:274 PsiFile dummyFile = fileFactory.createFileFromText(...

In the next line PsiTreeUtil.findChildOfType can't find the tag and null is returned which prevents entering the if which contains a call to setAttributeValues

Cursor inside SVELTE_FRAGMENT image

Result image

tomblachut commented 5 years ago

In #40 I've changed how whitespace is parsed.

Now it's delegated to HTML side with notable exception of continuous whitespace between Svelte mustaches and first non-whitespace HTML character, it's required for current (bad) implementation of formatter to work.

Anyway that fixed Emmet partially.

image

image

Preview still does not work with the last character in a file. Add one space after Emmet shorthand and everything starts to work. Anyway you can expand shorthand and it works in both cases.

image

Remaining unsolved issue is shorthand directly after Svelte mustache. I suspect this is connected to mentioned whitespace handling and by extension formatter. Edit. No it doesn't. Mustaches live in different PSI, that must be an issue. image

unlocomqx commented 5 years ago

That's great IMO, the edge cases are not severe This one is because the document ends with a SVELTE_FRAGMENT image

image

tomblachut commented 5 years ago

@unlocomqx in branch with lexer fixes document actually ends with XmlToken

unlocomqx commented 5 years ago

I just tested with rework-lexer, it worked correctly image

tomblachut commented 5 years ago

yeah it expands correctly but preview does not work for me as shown in screenshot

unlocomqx commented 5 years ago

Sry for the confusion, how do you get the preview to pop up? is it automatic?

tomblachut commented 5 years ago

No worries. You need to enable it and then it's automatic

image

Actually I find it useless but users can expect it to work

unlocomqx commented 5 years ago

I was able to reproduce, It's not a big deal really but I will try to debug it sometime nonetheless

unlocomqx commented 5 years ago

As I expected, it's the same as this

Then a dummy file is created using Svelte Language here GenerationNode.java:274 PsiFile dummyFile = fileFactory.createFileFromText(...

In the next line PsiTreeUtil.findChildOfType can't find the tag and null is returned which prevents entering the if which contains a call to setAttributeValues