InjectedLanguage formatting: computeSpacing


I'm injection a custom language into YAML. For the custom language  I have created a formatter which works fine when the language is not injected but resides in its own file. When injected, everything works as expected except for the getSpacing method. This is called with the 2 child blocks which are now no longer the blocks of the custom language but:

YamlInjectedLanguageBlockWrapper a private inner class of YamlInjectedLanguageBlockBuilder.

The Spacing is calculated with  SpacingBuilder.getSpacing(@NotNull Block parent, @Nullable Block child1, @NotNull Block child2) for which I've created a whole set of patterns to calculate the spacing. The problem is that the blocks are now wrapped so none of the patterns match. I can see from the debugger that the YamlInjectedLanguageBlockWrapper contains a reference to the wrapped block but since it's all in private inner classes there is no nice way for me to access this runtime. I have it working with reflection but I would prefer to have some public interface available to perform the unwrapping.

Any ideas / suggetions?

Official comment

Hm, in my understanding `SpacingBuilder.getSpacing` should be called from inside the `Block.getSpacing` implementation of your custom language, when it performs the "formatting" of the injected file, and only after that it will be wrapped by `YamlInjectedLanguageBlockWrapper` which actually delegates the getSpacing to the `origin`. Thus your custom language should know nothing about `YamlInjectedLanguageBlockWrapper`.

Technically we of course can introduce kind of public interface `WrappedBlock` but it will be good if you provide more information on why it happen that you formatter formats the yaml file instead of injected file or maybe share your sources if it is possible

Hi Nicolay,

I've created a branch for you here: If you take a look at the only commit on that branch you can see the test that I've added that will show that the formatting is not applied on the injected language (ODT) when hosted by the YAML language (OMT). 

If you uncomment the code in ODTFormattingSpacing you can see that the unwrap makes it work.

Just to be clear, you are right in the sense that it is delegated to the origin Block getSpacing, but the provided child1 and child2 blocks are wrapped instead of the original blocks.


Thank you! It seems that it is a bug and `YamlInjectedLanguageBlockWrapper#getSpacing` should pass `original`-s of blocks to `original`. I've created a IDEA-286525 YAML: Injected blocks are not properly reformatted because of incorrect `getSpaces` delegation issue. Hope the fix will be avaiable in the next release. Thank you for reporting!


Thanks Nicolay


Please sign in to leave a comment.