boolean (List<? super Block> result, final ASTNode injectionHost, Wrap wrap, Alignment alignment, Indent indent) { Ref<Integer> lastInjectionEndOffset = new Ref<>(0); final PsiLanguageInjectionHost.InjectedPsiVisitor injectedPsiVisitor = (injectedPsi, places) -> { if (places.isEmpty() || (places.size() != 1 && !supportsMultipleFragments())) { return; } PsiLanguageInjectionHost.Shred firstShred = places.get(0); PsiLanguageInjectionHost.Shred lastShred = places.get(places.size() - 1); PsiLanguageInjectionHost shredHost = firstShred.getHost(); if (shredHost == null) { return; } for (PsiLanguageInjectionHost.Shred place : places) { if (place.getHost() != shredHost) return; } TextRange injectionRange = new TextRange(firstShred.getRangeInsideHost().getStartOffset(), lastShred.getRangeInsideHost().getEndOffset()); ASTNode node = shredHost.getNode(); if (node == null || !injectionHost.getTextRange().contains(injectionRange.shiftRight(node.getStartOffset()))) { return; } if (node != injectionHost) { int shift = 0; boolean canProcess = false; for (ASTNode n = injectionHost.getTreeParent(), prev = injectionHost; n != null; prev = n, n = n.getTreeParent()) { shift += n.getStartOffset() - prev.getStartOffset(); if (n == node) { injectionRange = injectionRange.shiftRight(shift); canProcess = true; break; } } if (!canProcess) { return; } } String childText; if (injectionHost.getTextLength() == injectionRange.getEndOffset() && injectionRange.getStartOffset() == 0 || canProcessFragment((childText = injectionHost.getText()).substring(0, injectionRange.getStartOffset()), injectionHost) && canProcessFragment(childText.substring(injectionRange.getEndOffset()), injectionHost)) { // inject language block final Language childLanguage = injectedPsi.getLanguage(); final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(childLanguage, injectionHost.getPsi()); if (builder != null) { final int startOffset = injectionRange.getStartOffset(); final int endOffset = injectionRange.getEndOffset(); TextRange range = injectionHost.getTextRange(); final int prefixLength = firstShred.getPrefix().length(); final int suffixLength = lastShred.getSuffix().length(); int childOffset = range.getStartOffset(); if (lastInjectionEndOffset.get() < startOffset) { result.add(createBlock(injectionHost, wrap, alignment, indent, new TextRange(lastInjectionEndOffset.get(), startOffset))); } addInjectedLanguageBlocks(result, injectedPsi, indent, childOffset + startOffset, new TextRange(prefixLength, injectedPsi.getTextLength() - suffixLength), places); lastInjectionEndOffset.set(endOffset); } } }; final PsiElement injectionHostPsi = injectionHost.getPsi(); PsiFile containingFile = injectionHostPsi.getContainingFile(); InjectedLanguageManager.getInstance(containingFile.getProject()) .enumerateEx(injectionHostPsi, containingFile, true, injectedPsiVisitor); if (lastInjectionEndOffset.get() > 0) { if (lastInjectionEndOffset.get() < injectionHost.getTextLength()) { result.add(createBlock(injectionHost, wrap, alignment, indent, new TextRange(lastInjectionEndOffset.get(), injectionHost.getTextLength()))); } return true; } return false; }