diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java index c3556448ecfd..acd047a26d1f 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java @@ -16,8 +16,10 @@ package com.intellij.codeInsight.template.emmet.filters; import com.intellij.codeInsight.template.emmet.nodes.GenerationNode; +import com.intellij.codeInsight.template.emmet.tokens.TemplateToken; import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.lang.xml.XMLLanguage; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; @@ -32,6 +34,12 @@ public class SingleLineEmmetFilter extends ZenCodingFilter { return "s"; } + @NotNull + @Override + public String filterText(@NotNull String text, @NotNull TemplateToken token) { + return StringUtil.replace(text, "\n", ""); + } + @NotNull @Override public GenerationNode filterNode(@NotNull GenerationNode node) { diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/GenerationNode.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/GenerationNode.java index e31b36ccb00b..c7ff99fac640 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/GenerationNode.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/GenerationNode.java @@ -26,8 +26,11 @@ import com.intellij.codeInsight.template.emmet.generators.XmlZenCodingGeneratorI import com.intellij.codeInsight.template.emmet.generators.ZenCodingGenerator; import com.intellij.codeInsight.template.emmet.tokens.TemplateToken; import com.intellij.codeInsight.template.impl.TemplateImpl; +import com.intellij.injected.editor.DocumentWindowImpl; import com.intellij.lang.xml.XMLLanguage; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; @@ -135,23 +138,48 @@ public class GenerationNode extends UserDataHolderBase { boolean insertSurroundedText) { myContainsSurroundedTextMarker = !(insertSurroundedText && myInsertSurroundedTextAtTheEnd); - boolean singleLineFilterEnabled = false; - GenerationNode generationNode = this; + if (generationNode != this) { + return generationNode.generate(callback, generator, Collections.emptyList(), insertSurroundedText); + } + + boolean shouldNotReformatTemplate = false; + boolean oneLineTemplateExpanding = false; for (ZenCodingFilter filter : filters) { generationNode = filter.filterNode(generationNode); if(filter instanceof SingleLineEmmetFilter) { - singleLineFilterEnabled = true; + shouldNotReformatTemplate = true; + oneLineTemplateExpanding = true; } } - if (generationNode != this) { - return generationNode.generate(callback, generator, Collections.emptyList(), insertSurroundedText); + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(callback.getProject()); + String indentStr; + if (callback.isInInjectedFragment()) { + Editor editor = callback.getEditor(); + Document document = editor.getDocument(); + if(document instanceof DocumentWindowImpl && ((DocumentWindowImpl)document).isOneLine()) { + /* + * If document is one-line that in the moment of inserting text, + * new line chars will be filtered (see DocumentWindowImpl#insertString). + * So in this case we should filter text by SingleLineAvoid in order to avoid + * inconsistency of template segments. + */ + oneLineTemplateExpanding = true; + filters.add(new SingleLineEmmetFilter()); + } + indentStr = ""; + } + else if (settings.useTabCharacter(callback.getFileType())) { + indentStr = "\t"; + } + else { + int tabSize = settings.getTabSize(callback.getFileType()); + indentStr = StringUtil.repeatSymbol(' ', tabSize); } LiveTemplateBuilder builder = new LiveTemplateBuilder(); int end = -1; - boolean hasChildren = myChildren.size() > 0; TemplateImpl parentTemplate; @@ -188,26 +216,14 @@ public class GenerationNode extends UserDataHolderBase { } LiveTemplateBuilder.Marker marker = offset < builder.length() ? builder.createMarker(offset) : null; - CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(callback.getProject()); - String indentStr; - if (callback.isInInjectedFragment()) { - indentStr = ""; - } - else if (settings.useTabCharacter(callback.getFileType())) { - indentStr = "\t"; - } - else { - int tabSize = settings.getTabSize(callback.getFileType()); - indentStr = StringUtil.repeatSymbol(' ', tabSize); - } - + //noinspection ForLoopReplaceableByForEach for (int i = 0, myChildrenSize = myChildren.size(); i < myChildrenSize; i++) { GenerationNode child = myChildren.get(i); TemplateImpl childTemplate = child.generate(callback, generator, filters, !myContainsSurroundedTextMarker); boolean blockTag = child.isBlockTag(); - if (!singleLineFilterEnabled && blockTag && !isNewLineBefore(builder.getText(), offset)) { + if (!oneLineTemplateExpanding && blockTag && !isNewLineBefore(builder.getText(), offset)) { builder.insertText(offset, "\n" + indentStr, false); offset += indentStr.length() + 1; } @@ -215,7 +231,7 @@ public class GenerationNode extends UserDataHolderBase { int e = builder.insertTemplate(offset, childTemplate, null); offset = marker != null ? marker.getEndOffset() : builder.length(); - if (!singleLineFilterEnabled && ((blockTag && !isNewLineAfter(builder.getText(), offset)) || myInsertNewLineBetweenNodes)) { + if (!oneLineTemplateExpanding && ((blockTag && !isNewLineAfter(builder.getText(), offset)) || myInsertNewLineBetweenNodes)) { builder.insertText(offset, "\n" + indentStr, false); offset += indentStr.length() + 1; } @@ -224,7 +240,7 @@ public class GenerationNode extends UserDataHolderBase { end = e; } } - if(singleLineFilterEnabled) { + if(shouldNotReformatTemplate) { builder.setIsToReformat(false); } return builder.buildTemplate();