js-graphql-intellij-plugin icon indicating copy to clipboard operation
js-graphql-intellij-plugin copied to clipboard

Cursor lands at weird position after pressing Enter

Open dandv opened this issue 4 years ago • 6 comments

Version and Environment Details

Operation system: Ubuntu 18.04

IDE name and version: WebStorm 2020.1, see all debug info in this YouTrack ticket

Plugin version: 2.4.0

import GqlMod from '@graphql-modules/core'; const { GraphQLModule } = GqlMod;  // TODO: https://github.com/Urigo/graphql-modules/issues/1066

// Here's the bug: press Enter at the end of this line
export const Module = gql``;

Webstorm lands cursor at WEIRD line position

dandv avatar Apr 14 '20 18:04 dandv

Any updates on this?

dandv avatar May 28 '20 21:05 dandv

@denofevil Tagging you for assistance. The cause has something to do with how the plugin wraps the built-in JS/TS formatter blocks.

I'm doing this to format the GraphQL inside tagged template literals. Without this wrapping, my testing shows that IntelliJ doesn't apply the GraphQL formatter inside injected GraphQL language fragments.

If I return false from the following, the issue goes away, but IntellIJ then no longer indents and formats the GraphQL inside the gql tagged template literal:

https://github.com/jimkyndemeyer/js-graphql-intellij-plugin/blob/ca9b670f706d84e9a30c9503c9ea0a9fcd50edfb/src/main/com/intellij/lang/jsgraphql/ide/formatter/javascript/GraphQLInjectedFormattingModelBuilder.java#L67-L80

The wrapper block is added at https://github.com/jimkyndemeyer/js-graphql-intellij-plugin/blob/ca9b670f706d84e9a30c9503c9ea0a9fcd50edfb/src/main/com/intellij/lang/jsgraphql/ide/formatter/javascript/GraphQLInjectedFormattingModelBuilder.java#L47

I realize this approach might not the be the best way to achieve injected formatting, and I recall this having broken before when the IntelliJ JavaScript tooling made updates to their PSI.

Is there a better "platform" way of achieving formatting inside injected fragments? If not, can you point me in the direction of a fix?

Thanks.

jimkyndemeyer avatar May 30 '20 09:05 jimkyndemeyer

@jimkyndemeyer Hi! You can directly pass information to the js element that we need to re-format injection. It is implemented e.g. for Angular in-place templates.

It can be done by settings

JSFormattableInjectionUtil.setReformattableInjection(context, language);

for the injection host.

See the AngularInjector implementation for more information

anstarovoyt avatar Jun 02 '20 12:06 anstarovoyt

@anstarovoyt Thanks for the hint, that looks like a perfect fit.

jimkyndemeyer avatar Jun 02 '20 18:06 jimkyndemeyer

@anstarovoyt

I've added

JSFormattableInjectionUtil.setReformattableInjection(template, GraphQLLanguage.INSTANCE);

At the line after https://github.com/jimkyndemeyer/js-graphql-intellij-plugin/blob/d83dad8bc30b528b6cc9928408ea7e77df6b16bb/src/main/com/intellij/lang/jsgraphql/ide/injection/javascript/GraphQLTemplateFragmentLanguageInjector.java#L38

This formats as expected, causing the creation of GraphQLBlocks via the normal GraphQL formatter.

Unfortunately, the GraphQL formatter is no longer called when there are JS/TS expressions in the template. I've located the cause to be a limitation in JSFormattableInjectionUtil#isFormattableHost:

return host.isPhysical() && host instanceof JSStringTemplateExpression && ((JSStringTemplateExpression)host).getArguments().length == 0;

In essence, this means that the following common example is not formatted due the use of ${variable}:

const variable = 'hello';
export const query = gql`
    {
        foo(var: ${variable}) {
            nested
        }
    }
`;

Not counting this current bug, the existing formatter code in this plugin does support this, because the grammar includes support for these ${} placeholders, and a valid GraphQL PSI tree is produced for the formatter to work on.

I now recall having run into this limitation during the initial implementation, and it looks like I worked around it in: https://github.com/jimkyndemeyer/js-graphql-intellij-plugin/blob/d83dad8bc30b528b6cc9928408ea7e77df6b16bb/src/main/com/intellij/lang/jsgraphql/ide/formatter/javascript/GraphQLInjectedLanguageBlockBuilder.java#L34-L53

Based on this, it's unclear to me what the best next step is. Any ideas?

jimkyndemeyer avatar Jun 03 '20 07:06 jimkyndemeyer

I'm making some changes to improve injections handling in the Intellij IDEA platform right now, I hope they will be available in 2020.3.

vepanimas avatar Sep 01 '20 18:09 vepanimas