js-graphql-intellij-plugin
js-graphql-intellij-plugin copied to clipboard
Cursor lands at weird position after pressing Enter
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``;
Any updates on this?
@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 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 Thanks for the hint, that looks like a perfect fit.
@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?
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.