diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElement.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElement.java index e22a4114beed..6075e2dcacf2 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElement.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,9 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementPresentation; import com.intellij.codeInsight.lookup.RealLookupElementPresentation; import com.intellij.codeInsight.template.TemplateManager; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.awt.event.KeyEvent; @@ -30,15 +32,17 @@ import java.awt.event.KeyEvent; public class LiveTemplateLookupElement extends LookupElement { private final String myPrefix; private final TemplateImpl myTemplate; + private final String myLookupString; public final boolean sudden; private final boolean myWorthShowingInAutoPopup; public LiveTemplateLookupElement(TemplateImpl template, boolean sudden) { - this(template, sudden, false); + this(template, null, sudden, false); } - public LiveTemplateLookupElement(TemplateImpl template, boolean sudden, boolean worthShowingInAutoPopup) { + public LiveTemplateLookupElement(TemplateImpl template, @Nullable String lookupString, boolean sudden, boolean worthShowingInAutoPopup) { this.sudden = sudden; + myLookupString = lookupString; myPrefix = template.getKey(); myTemplate = template; myWorthShowingInAutoPopup = worthShowingInAutoPopup; @@ -56,6 +60,7 @@ public class LiveTemplateLookupElement extends LookupElement { @Override public void renderElement(LookupElementPresentation presentation) { super.renderElement(presentation); + presentation.setItemText(StringUtil.notNullize(myLookupString, myPrefix)); if (sudden) { presentation.setItemTextBold(true); if (!presentation.isReal() || !((RealLookupElementPresentation)presentation).isLookupSelectionTouched()) { @@ -71,7 +76,6 @@ public class LiveTemplateLookupElement extends LookupElement { } } else { presentation.setTypeText(myTemplate.getDescription()); - } } diff --git a/platform/platform-resources-en/src/messages/XmlBundle.properties b/platform/platform-resources-en/src/messages/XmlBundle.properties index c635cb19e5cb..e477ec05cb92 100644 --- a/platform/platform-resources-en/src/messages/XmlBundle.properties +++ b/platform/platform-resources-en/src/messages/XmlBundle.properties @@ -238,6 +238,7 @@ zen.coding.title=Emmet (XML Zen Coding) emmet.configuration.title=Emmet (Zen Coding) emmet.enable.label=&Enable XML Emmet emmet.enable.bem.filter=Enable &BEM filter by default +emmet.enable.preview=Enable &abbreviation preview emmet.expand.abbreviation.with=Expand &abbreviation with zen.coding.enter.abbreviation.dialog.label=Please enter an abbreviation zen.coding.incorrect.abbreviation.error=Incorrect abbreviation diff --git a/xml/impl/src/com/intellij/application/options/emmet/EmmetOptions.java b/xml/impl/src/com/intellij/application/options/emmet/EmmetOptions.java index 01f0e5d84428..f0b5fb30d6fb 100644 --- a/xml/impl/src/com/intellij/application/options/emmet/EmmetOptions.java +++ b/xml/impl/src/com/intellij/application/options/emmet/EmmetOptions.java @@ -44,6 +44,7 @@ public class EmmetOptions implements PersistentStateComponent, Exp private int myEmmetExpandShortcut = WebEditorOptions.getInstance().getZenCodingExpandShortcut(); private boolean myFuzzySearchEnabled = true; private boolean myAutoInsertCssPrefixedEnabled = true; + private boolean myPreviewEnabled = false; @NotNull private Map prefixes = ContainerUtil.newHashMap(); @@ -64,6 +65,14 @@ public class EmmetOptions implements PersistentStateComponent, Exp return myEmmetExpandShortcut; } + public boolean isPreviewEnabled() { + return myPreviewEnabled; + } + + public void setPreviewEnabled(boolean previewEnabled) { + myPreviewEnabled = previewEnabled; + } + public boolean isEmmetEnabled() { return myEmmetEnabled; } diff --git a/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.form b/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.form index 378f1062072f..0c8dec3afcac 100644 --- a/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.form +++ b/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.form @@ -8,7 +8,7 @@ - + @@ -35,6 +35,14 @@ + + + + + + + + diff --git a/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.java b/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.java index 07091343ba3a..babbfc1d3046 100644 --- a/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.java +++ b/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.java @@ -34,6 +34,7 @@ public class XmlEmmetConfigurable implements UnnamedConfigurable, Disposable, Co private JBCheckBox myEnableBEMFilterJBCheckBox; private JPanel myPanel; private JBCheckBox myEnableEmmetJBCheckBox; + private JBCheckBox myEnablePreviewJBCheckBox; public XmlEmmetConfigurable() { myEnableEmmetJBCheckBox.addActionListener(new ActionListener() { @@ -41,6 +42,7 @@ public class XmlEmmetConfigurable implements UnnamedConfigurable, Disposable, Co public void actionPerformed(ActionEvent e) { boolean selected = myEnableEmmetJBCheckBox.isSelected(); myEnableBEMFilterJBCheckBox.setEnabled(selected); + myEnablePreviewJBCheckBox.setEnabled(selected); } }); } @@ -59,6 +61,7 @@ public class XmlEmmetConfigurable implements UnnamedConfigurable, Disposable, Co public boolean isModified() { EmmetOptions emmetOptions = EmmetOptions.getInstance(); return emmetOptions.isEmmetEnabled() != myEnableEmmetJBCheckBox.isSelected() || + emmetOptions.isPreviewEnabled() != myEnablePreviewJBCheckBox.isSelected() || emmetOptions.isBemFilterEnabledByDefault() != myEnableBEMFilterJBCheckBox.isSelected(); } @@ -68,6 +71,7 @@ public class XmlEmmetConfigurable implements UnnamedConfigurable, Disposable, Co EmmetOptions emmetOptions = EmmetOptions.getInstance(); emmetOptions.setEmmetEnabled(myEnableEmmetJBCheckBox.isSelected()); emmetOptions.setBemFilterEnabledByDefault(myEnableBEMFilterJBCheckBox.isSelected()); + emmetOptions.setPreviewEnabled(myEnablePreviewJBCheckBox.isSelected()); } @Override @@ -76,6 +80,8 @@ public class XmlEmmetConfigurable implements UnnamedConfigurable, Disposable, Co myEnableEmmetJBCheckBox.setSelected(emmetOptions.isEmmetEnabled()); myEnableBEMFilterJBCheckBox.setEnabled(emmetOptions.isEmmetEnabled()); myEnableBEMFilterJBCheckBox.setSelected(emmetOptions.isBemFilterEnabledByDefault()); + myEnablePreviewJBCheckBox.setEnabled(emmetOptions.isEmmetEnabled()); + myEnablePreviewJBCheckBox.setSelected(emmetOptions.isPreviewEnabled()); } @Override diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java index 49ca11297004..3722f4cd8559 100644 --- a/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java +++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import com.intellij.codeInsight.lookup.InsertHandlerDecorator; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.lookup.LookupElementDecorator; +import com.intellij.codeInsight.template.emmet.completion.XmlEmmetAbbreviationCompletionProvider; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.lang.ASTNode; import com.intellij.openapi.actionSystem.IdeActions; @@ -79,6 +80,7 @@ public class XmlCompletionContributor extends CompletionContributor { }; public XmlCompletionContributor() { + extend(CompletionType.BASIC, psiElement().inside(XmlPatterns.xmlFile()), new XmlEmmetAbbreviationCompletionProvider()); extend(CompletionType.BASIC, psiElement().inside(XmlPatterns.xmlAttributeValue()), new CompletionProvider() { diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java index 6fc27d723a62..fae7045b91d2 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java @@ -44,6 +44,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -66,8 +67,9 @@ public class ZenCodingTemplate implements CustomLiveTemplate { @Nullable public static ZenCodingNode parse(@NotNull String text, - @NotNull CustomTemplateCallback callback, - @NotNull ZenCodingGenerator generator, @Nullable String surroundedText) { + @NotNull CustomTemplateCallback callback, + @NotNull ZenCodingGenerator generator, + @Nullable String surroundedText) { List tokens = new EmmetLexer().lex(text); if (tokens == null) { return null; @@ -99,7 +101,7 @@ public class ZenCodingTemplate implements CustomLiveTemplate { public void expand(String key, @NotNull CustomTemplateCallback callback) { ZenCodingGenerator defaultGenerator = findApplicableDefaultGenerator(callback.getContext(), false); assert defaultGenerator != null; - expand(key, callback, null, defaultGenerator); + expand(key, callback, null, defaultGenerator, Collections.emptyList(), true); } @Nullable @@ -154,18 +156,17 @@ public class ZenCodingTemplate implements CustomLiveTemplate { } - public static void expand(String key, - @NotNull CustomTemplateCallback callback, - String surroundedText, - @NotNull ZenCodingGenerator defaultGenerator) { - ZenCodingNode node = parse(key, callback, defaultGenerator, surroundedText); + public static void expand(@NotNull String key, @NotNull CustomTemplateCallback callback, @Nullable String surroundedText, + @NotNull ZenCodingGenerator defaultGenerator, + @NotNull Collection extraFilters, + boolean expandPrimitiveAbbreviations) { + final ZenCodingNode node = parse(key, callback, defaultGenerator, surroundedText); if (node == null) { return; } if (surroundedText == null) { if (node instanceof TemplateNode) { - if (key.equals(((TemplateNode)node).getTemplateToken().getKey()) && - callback.findApplicableTemplates(key).size() > 1) { + if (key.equals(((TemplateNode)node).getTemplateToken().getKey()) && callback.findApplicableTemplates(key).size() > 1) { callback.startTemplate(); return; } @@ -176,15 +177,16 @@ public class ZenCodingTemplate implements CustomLiveTemplate { PsiElement context = callback.getContext(); ZenCodingGenerator generator = findApplicableGenerator(node, context, false); List filters = getFilters(node, context); + filters.addAll(extraFilters); - expand(node, generator, filters, surroundedText, callback); + expand(node, generator, filters, surroundedText, callback, expandPrimitiveAbbreviations); } private static void expand(ZenCodingNode node, ZenCodingGenerator generator, List filters, String surroundedText, - CustomTemplateCallback callback) { + CustomTemplateCallback callback, boolean expandPrimitiveAbbreviations) { if (surroundedText != null) { surroundedText = surroundedText.trim(); } @@ -192,6 +194,12 @@ public class ZenCodingTemplate implements CustomLiveTemplate { GenerationNode fakeParentNode = new GenerationNode(TemplateToken.EMPTY_TEMPLATE_TOKEN, -1, 1, surroundedText, true, null); node.expand(-1, 1, surroundedText, callback, true, fakeParentNode); + if (!expandPrimitiveAbbreviations) { + if (isPrimitiveNode(node)) { + return; + } + } + List genNodes = fakeParentNode.getChildren(); LiveTemplateBuilder builder = new LiveTemplateBuilder(); int end = -1; @@ -248,6 +256,16 @@ public class ZenCodingTemplate implements CustomLiveTemplate { }); } + private static boolean isPrimitiveNode(@NotNull ZenCodingNode node) { + if (node instanceof TemplateNode) { + final TemplateToken token = ((TemplateNode)node).getTemplateToken(); + if (token != null && token.getAttribute2Value().isEmpty()) { + return true; + } + } + return false; + } + public void wrap(final String selection, @NotNull final CustomTemplateCallback callback) { InputValidatorEx validator = new InputValidatorEx() { public String getErrorText(String inputString) { @@ -289,9 +307,7 @@ public class ZenCodingTemplate implements CustomLiveTemplate { return applicableGenerator != null && applicableGenerator.isEnabled(); } - public static void doWrap(final String selection, - final String abbreviation, - final CustomTemplateCallback callback) { + public static void doWrap(final String selection, final String abbreviation, final CustomTemplateCallback callback) { final ZenCodingGenerator defaultGenerator = findApplicableDefaultGenerator(callback.getContext(), true); assert defaultGenerator != null; ApplicationManager.getApplication().runWriteAction(new Runnable() { @@ -308,7 +324,7 @@ public class ZenCodingTemplate implements CustomLiveTemplate { EditorModificationUtil.deleteSelectedText(callback.getEditor()); PsiDocumentManager.getInstance(callback.getProject()).commitAllDocuments(); - expand(node, generator, filters, selection, callback); + expand(node, generator, filters, selection, callback, true); } }, CodeInsightBundle.message("insert.code.template.command"), null); } diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/completion/EmmetAbbreviationCompletionProvider.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/completion/EmmetAbbreviationCompletionProvider.java new file mode 100644 index 000000000000..b0528125f8b5 --- /dev/null +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/completion/EmmetAbbreviationCompletionProvider.java @@ -0,0 +1,101 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.template.emmet.completion; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.template.CustomTemplateCallback; +import com.intellij.codeInsight.template.Template; +import com.intellij.codeInsight.template.TemplateEditingListener; +import com.intellij.codeInsight.template.emmet.ZenCodingTemplate; +import com.intellij.codeInsight.template.emmet.filters.SingleLineEmmetFilter; +import com.intellij.codeInsight.template.emmet.generators.ZenCodingGenerator; +import com.intellij.codeInsight.template.impl.LiveTemplateCompletionContributor; +import com.intellij.codeInsight.template.impl.LiveTemplateLookupElement; +import com.intellij.codeInsight.template.impl.TemplateImpl; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.util.Ref; +import com.intellij.patterns.StandardPatterns; +import com.intellij.psi.PsiFile; +import com.intellij.util.ProcessingContext; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.Map; + +/** + * User: zolotov + * Date: 8/9/13 + */ +abstract public class EmmetAbbreviationCompletionProvider extends CompletionProvider { + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + if (!isAvailable(parameters)) { + return; + } + + final PsiFile file = parameters.getPosition().getContainingFile(); + final Editor editor = parameters.getEditor(); + + final String completionPrefix = result.getPrefixMatcher().getPrefix(); + final String templatePrefix = LiveTemplateCompletionContributor.findLiveTemplatePrefix(file, editor, completionPrefix); + + if (LiveTemplateCompletionContributor.findApplicableTemplate(file, parameters.getOffset(), templatePrefix) != null) { + // exclude perfect matches with existing templates because LiveTemplateCompletionContributor handles it + result.restartCompletionOnPrefixChange(StandardPatterns.string().startsWith(templatePrefix)); + return; + } + + final Ref generatedTemplate = new Ref(); + final CustomTemplateCallback callback = new CustomTemplateCallback(editor, file, false) { + @Override + public void deleteTemplateKey(String key) { + } + + @Override + public void startTemplate(Template template, Map predefinedValues, TemplateEditingListener listener) { + if (template instanceof TemplateImpl && !((TemplateImpl)template).isDeactivated()) { + generatedTemplate.set((TemplateImpl)template); + } + } + }; + + final Collection extraFilters = ContainerUtil.newLinkedList(new SingleLineEmmetFilter()); + ZenCodingTemplate.expand(templatePrefix, callback, null, getGenerator(), extraFilters, false); + if (!generatedTemplate.isNull()) { + result = result.withPrefixMatcher(templatePrefix); + final TemplateImpl template = generatedTemplate.get(); + template.setKey(templatePrefix); + template.setDescription(template.getTemplateText()); + result.addElement(createLookupElement(template)); + result.restartCompletionOnPrefixChange(StandardPatterns.string().startsWith(templatePrefix)); + } + } + + protected LiveTemplateLookupElement createLookupElement(TemplateImpl template) { + return new LiveTemplateLookupElement(template, null, true, true); + } + + protected abstract ZenCodingGenerator getGenerator(); + + protected boolean isAvailable(CompletionParameters parameters) { + return parameters.getInvocationCount() == 0; + } +} diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/completion/XmlEmmetAbbreviationCompletionProvider.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/completion/XmlEmmetAbbreviationCompletionProvider.java new file mode 100644 index 000000000000..c2a55beb9b58 --- /dev/null +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/completion/XmlEmmetAbbreviationCompletionProvider.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.template.emmet.completion; + +import com.intellij.application.options.emmet.EmmetOptions; +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.template.emmet.generators.XmlZenCodingGeneratorImpl; +import com.intellij.codeInsight.template.emmet.generators.ZenCodingGenerator; +import com.intellij.codeInsight.template.impl.LiveTemplateLookupElement; +import com.intellij.codeInsight.template.impl.TemplateImpl; + +/** + * User: zolotov + * Date: 8/9/13 + */ +public class XmlEmmetAbbreviationCompletionProvider extends EmmetAbbreviationCompletionProvider { + @Override + protected boolean isAvailable(CompletionParameters parameters) { + final EmmetOptions emmetOptions = EmmetOptions.getInstance(); + return super.isAvailable(parameters) && emmetOptions.isEmmetEnabled() && emmetOptions.isPreviewEnabled(); + } + + @Override + protected LiveTemplateLookupElement createLookupElement(final TemplateImpl template) { + final String description = template.getDescription(); + template.setDescription(null); + return new LiveTemplateLookupElement(template, description, false, true); + } + + @Override + protected ZenCodingGenerator getGenerator() { + return XmlZenCodingGeneratorImpl.INSTANCE; + } +} diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGeneratorImpl.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGeneratorImpl.java index 0fc0c6971e1f..2725700318d0 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGeneratorImpl.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGeneratorImpl.java @@ -119,7 +119,7 @@ public class XmlZenCodingGeneratorImpl extends XmlZenCodingGenerator { } } }); - PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); + final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); for (final SmartPsiElementPointer pointer : tagToClose) { final XmlTag tag = pointer.getElement(); if (tag != null) { @@ -133,13 +133,13 @@ public class XmlZenCodingGeneratorImpl extends XmlZenCodingGenerator { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { document.replaceString(offset, tag.getTextRange().getEndOffset(), "/>"); + documentManager.commitDocument(document); } }); } } } } - documentManager.commitAllDocuments(); } private static boolean isTagClosed(@NotNull XmlTag tag) { 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 c7ff99fac640..d48f9e263a03 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 @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,6 @@ 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; @@ -272,23 +271,19 @@ public class GenerationNode extends UserDataHolderBase { assert template != null; final XmlFile xmlFile = token.getFile(); - XmlDocument document = xmlFile.getDocument(); - if (document != null) { - final XmlTag tag = document.getRootTag(); + PsiFileFactory fileFactory = PsiFileFactory.getInstance(xmlFile.getProject()); + XmlFile dummyFile = (XmlFile)fileFactory.createFileFromText("dummy.xml", StdFileTypes.XML, xmlFile.getText()); + + final XmlTag tag = dummyFile.getRootTag(); + if (tag != null) { for (Pair pair : attr2value) { if (Strings.isNullOrEmpty(pair.second)) { template.addVariable(pair.first, "", "", true); } } - if (tag != null) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - XmlTag tag1 = hasChildren ? expandEmptyTagIfNeccessary(tag) : tag; - setAttributeValues(tag1, attr2value); - token.setFile((XmlFile)tag1.getContainingFile()); - } - }); - } + XmlTag tag1 = hasChildren ? expandEmptyTagIfNeccessary(tag) : tag; + setAttributeValues(tag1, attr2value); + token.setFile((XmlFile)tag1.getContainingFile()); } ZenCodingGenerator zenCodingGenerator = generator != null ? generator : XmlZenCodingGeneratorImpl.INSTANCE; template = zenCodingGenerator.generateTemplate(token, hasChildren, callback.getContext()); diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/TemplateNode.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/TemplateNode.java index 25cccee7b969..38ba9efe2d18 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/TemplateNode.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/TemplateNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,6 +65,7 @@ public class TemplateNode extends ZenCodingNode { TemplateImpl template = myGenerator.createTemplateByKey(newTemplateKey); if (template != null) { + template.setDeactivated(true); newTemplateToken.setTemplate(template, callback); templateToken = newTemplateToken; }