Reimplement emmet completion with new CustomLiveTemplate api

This commit is contained in:
Alexander Zolotov
2014-04-10 16:35:08 +04:00
parent c96efa1e90
commit 312acda27e
11 changed files with 134 additions and 156 deletions
@@ -18,13 +18,11 @@ package com.intellij.codeInsight.template.postfix.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.completion.PrefixMatcher;
import com.intellij.codeInsight.template.impl.LiveTemplateCompletionContributor;
import com.intellij.codeInsight.template.postfix.settings.PostfixTemplatesSettings;
import com.intellij.codeInsight.template.postfix.templates.PostfixLiveTemplate;
import com.intellij.codeInsight.template.postfix.templates.PostfixTemplate;
import com.intellij.patterns.StandardPatterns;
import com.intellij.psi.PsiFile;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
@@ -43,17 +41,7 @@ class PostfixTemplatesCompletionProvider extends CompletionProvider<CompletionPa
PostfixLiveTemplate postfixLiveTemplate = getPostfixLiveTemplate(parameters.getOriginalFile(), parameters.getEditor());
if (postfixLiveTemplate != null) {
PsiFile file = parameters.getPosition().getContainingFile();
final CustomTemplateCallback callback = new CustomTemplateCallback(parameters.getEditor(), file, false);
String computedKey = postfixLiveTemplate.computeTemplateKey(callback);
if (computedKey != null) {
PostfixTemplate template = postfixLiveTemplate.getTemplateByKey(computedKey);
if (template != null) {
result = result.withPrefixMatcher(computedKey);
result.addElement(new PostfixTemplateLookupElement(postfixLiveTemplate, template, computedKey, true));
}
}
postfixLiveTemplate.addCompletions(parameters, result.withPrefixMatcher(new MyPrefixMatcher(result.getPrefixMatcher().getPrefix())));
CharSequence documentContent = parameters.getEditor().getDocument().getCharsSequence();
String possibleKey = postfixLiveTemplate.computeTemplateKeyWithoutContextChecking(documentContent, parameters.getOffset());
if (possibleKey != null) {
@@ -75,4 +63,21 @@ class PostfixTemplatesCompletionProvider extends CompletionProvider<CompletionPa
return true;
}
private static class MyPrefixMatcher extends PrefixMatcher {
protected MyPrefixMatcher(String prefix) {
super(prefix);
}
@Override
public boolean prefixMatches(@NotNull String name) {
return name.equalsIgnoreCase(myPrefix);
}
@NotNull
@Override
public PrefixMatcher cloneWithPrefix(@NotNull String prefix) {
return new MyPrefixMatcher(prefix);
}
}
}
@@ -185,7 +185,7 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase {
for (Map.Entry<String, PostfixTemplate> entry : myTemplates.entrySet()) {
PostfixTemplate postfixTemplate = entry.getValue();
if (entry.getKey().startsWith(key) && isApplicationTemplateFunction.value(postfixTemplate)) {
result.put(postfixTemplate.getKey(), new PostfixTemplateLookupElement(this, postfixTemplate, postfixTemplate.getKey(), false));
result.put(postfixTemplate.getKey(), new PostfixTemplateLookupElement(this, postfixTemplate, entry.getKey(), false));
}
}
return result.values();
@@ -15,6 +15,8 @@
*/
package com.intellij.codeInsight.template;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.template.impl.CustomLiveTemplateLookupElement;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiFile;
@@ -40,6 +42,17 @@ abstract public class CustomLiveTemplateBase implements CustomLiveTemplate {
public Collection<? extends CustomLiveTemplateLookupElement> getLookupElements(@NotNull PsiFile file, @NotNull Editor editor, int offset) {
return Collections.emptyList();
}
/**
* Populate completion result set. Used by LiveTemplateCompletionContributor
*/
public void addCompletions(CompletionParameters parameters, CompletionResultSet result) {
String prefix = computeTemplateKeyWithoutContextChecking(new CustomTemplateCallback(parameters.getEditor(), parameters.getOriginalFile(), false));
if (prefix != null) {
result.withPrefixMatcher(result.getPrefixMatcher().cloneWithPrefix(prefix)).addAllElements(
getLookupElements(parameters.getOriginalFile(), parameters.getEditor(), parameters.getOffset()));
}
}
@Nullable
public String computeTemplateKeyWithoutContextChecking(@NotNull CustomTemplateCallback callback) {
@@ -112,7 +112,7 @@ public class ListTemplatesHandler implements CodeInsightActionHandler {
showLookup(lookup, file);
}
public static MultiMap<String, CustomLiveTemplateLookupElement> listApplicableCustomTemplates(@NotNull Editor editor, @NotNull PsiFile file, int offset) {
private static MultiMap<String, CustomLiveTemplateLookupElement> listApplicableCustomTemplates(@NotNull Editor editor, @NotNull PsiFile file, int offset) {
final MultiMap<String, CustomLiveTemplateLookupElement> result = MultiMap.create();
CustomTemplateCallback customTemplateCallback = new CustomTemplateCallback(editor, file, false);
for (CustomLiveTemplate customLiveTemplate : CustomLiveTemplate.EP_NAME.getExtensions()) {
@@ -18,12 +18,12 @@ package com.intellij.codeInsight.template.impl;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.template.CustomLiveTemplate;
import com.intellij.codeInsight.template.CustomLiveTemplateBase;
import com.intellij.codeInsight.template.CustomTemplateCallback;
import com.intellij.codeInsight.template.TemplateContextType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiFile;
@@ -32,13 +32,13 @@ import com.intellij.ui.EditorTextField;
import com.intellij.util.Consumer;
import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import static com.intellij.codeInsight.template.impl.ListTemplatesHandler.listApplicableCustomTemplates;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author peter
@@ -69,18 +69,17 @@ public class LiveTemplateCompletionContributor extends CompletionContributor {
final List<TemplateImpl> templates = listApplicableTemplates(file, offset);
Editor editor = parameters.getEditor();
if (showAllTemplates()) {
final MultiMap<String, CustomLiveTemplateLookupElement> customTemplates = listApplicableCustomTemplates(editor, file, offset);
final Ref<Boolean> templatesShown = Ref.create(false);
final AtomicBoolean templatesShown = new AtomicBoolean(false);
final CompletionResultSet finalResult = result;
result.runRemainingContributors(parameters, new Consumer<CompletionResult>() {
@Override
public void consume(CompletionResult completionResult) {
finalResult.passResult(completionResult);
ensureTemplatesShown(templatesShown, templates, customTemplates, finalResult);
ensureTemplatesShown(templatesShown, templates, parameters, finalResult);
}
});
ensureTemplatesShown(templatesShown, templates, customTemplates, result);
ensureTemplatesShown(templatesShown, templates, parameters, result);
return;
}
@@ -104,20 +103,20 @@ public class LiveTemplateCompletionContributor extends CompletionContributor {
return shouldShowAllTemplates();
}
private static void ensureTemplatesShown(Ref<Boolean> templatesShown,
private static void ensureTemplatesShown(AtomicBoolean templatesShown,
List<TemplateImpl> templates,
MultiMap<String, CustomLiveTemplateLookupElement> customTemplates,
CompletionParameters parameters,
CompletionResultSet result) {
if (!templatesShown.get()) {
templatesShown.set(true);
if (!templatesShown.getAndSet(true)) {
for (final TemplateImpl possible : templates) {
result.addElement(new LiveTemplateLookupElementImpl(possible, false));
}
for (Map.Entry<String, Collection<CustomLiveTemplateLookupElement>> entry : customTemplates.entrySet()) {
Collection<CustomLiveTemplateLookupElement> value = entry.getValue();
if (!value.isEmpty()) {
result.withPrefixMatcher(entry.getKey()).addAllElements(value);
PsiFile file = parameters.getPosition().getContainingFile();
Editor editor = parameters.getEditor();
for (CustomLiveTemplate customLiveTemplate : CustomLiveTemplate.EP_NAME.getExtensions()) {
if (customLiveTemplate instanceof CustomLiveTemplateBase && TemplateManagerImpl.isApplicable(customLiveTemplate, editor, file)) {
((CustomLiveTemplateBase)customLiveTemplate).addCompletions(parameters, result);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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,7 +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.codeInsight.template.emmet.completion.EmmetAbbreviationCompletionProvider;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.actionSystem.IdeActions;
@@ -78,7 +78,7 @@ public class XmlCompletionContributor extends CompletionContributor {
};
public XmlCompletionContributor() {
extend(CompletionType.BASIC, psiElement().inside(XmlPatterns.xmlFile()), new XmlEmmetAbbreviationCompletionProvider());
extend(CompletionType.BASIC, psiElement().inside(XmlPatterns.xmlFile()), new EmmetAbbreviationCompletionProvider());
extend(CompletionType.BASIC,
psiElement().inside(XmlPatterns.xmlAttributeValue()),
new CompletionProvider<CompletionParameters>() {
@@ -17,6 +17,8 @@ package com.intellij.codeInsight.template.emmet;
import com.intellij.application.options.emmet.EmmetOptions;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.template.*;
import com.intellij.codeInsight.template.emmet.filters.SingleLineEmmetFilter;
import com.intellij.codeInsight.template.emmet.filters.ZenCodingFilter;
@@ -26,6 +28,7 @@ import com.intellij.codeInsight.template.emmet.nodes.*;
import com.intellij.codeInsight.template.emmet.tokens.TemplateToken;
import com.intellij.codeInsight.template.emmet.tokens.TextToken;
import com.intellij.codeInsight.template.emmet.tokens.ZenCodingToken;
import com.intellij.codeInsight.template.impl.LiveTemplateCompletionContributor;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import com.intellij.codeInsight.template.impl.TemplateState;
import com.intellij.diagnostic.AttachmentFactory;
@@ -41,9 +44,11 @@ import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.ui.popup.util.PopupUtil;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.patterns.StandardPatterns;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -59,9 +64,7 @@ import java.awt.event.ComponentEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.*;
import java.util.List;
@@ -454,4 +457,47 @@ public class ZenCodingTemplate extends CustomLiveTemplateBase {
public boolean supportsWrapping() {
return true;
}
@Override
public void addCompletions(CompletionParameters parameters, CompletionResultSet result) {
PsiFile file = parameters.getOriginalFile();
int offset = parameters.getOffset();
Editor editor = parameters.getEditor();
ZenCodingGenerator generator = findApplicableDefaultGenerator(CustomTemplateCallback.getContext(file, offset), false);
if (generator != null && generator.hasCompletionItem()) {
final Ref<TemplateImpl> generatedTemplate = new Ref<TemplateImpl>();
final CustomTemplateCallback callback = new CustomTemplateCallback(editor, file, false) {
@Override
public void deleteTemplateKey(String key) {
}
@Override
public void startTemplate(Template template, Map<String, String> predefinedValues, TemplateEditingListener listener) {
if (template instanceof TemplateImpl && !((TemplateImpl)template).isDeactivated()) {
generatedTemplate.set((TemplateImpl)template);
}
}
};
String templatePrefix = computeTemplateKeyWithoutContextChecking(callback);
if (templatePrefix != null) {
if (LiveTemplateCompletionContributor.findApplicableTemplate(file, offset, templatePrefix) == null) {
// exclude perfect matches with existing templates because LiveTemplateCompletionContributor handles it
final Collection<SingleLineEmmetFilter> extraFilters = ContainerUtil.newLinkedList(new SingleLineEmmetFilter());
expand(templatePrefix, callback, null, generator, extraFilters, false);
if (!generatedTemplate.isNull()) {
final TemplateImpl template = generatedTemplate.get();
template.setKey(templatePrefix);
template.setDescription(template.getTemplateText());
CompletionResultSet resultSet = result.withPrefixMatcher(result.getPrefixMatcher().cloneWithPrefix(templatePrefix));
resultSet.restartCompletionOnPrefixChange(StandardPatterns.string().startsWith(templatePrefix));
resultSet.addElement(generator.createLookupElement(this, template));
}
}
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -18,93 +18,31 @@ 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.*;
import com.intellij.codeInsight.template.CustomLiveTemplate;
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.CustomLiveTemplateLookupElement;
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<CompletionParameters> {
public class EmmetAbbreviationCompletionProvider extends CompletionProvider<CompletionParameters> {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters,
ProcessingContext context,
@NotNull CompletionResultSet result) {
if (!isAvailable(parameters)) {
return;
}
final ZenCodingGenerator generator = getGenerator();
if (!generator.isMyContext(parameters.getPosition(), false) || !generator.isAppliedByDefault(parameters.getPosition())) {
if (LiveTemplateCompletionContributor.shouldShowAllTemplates() || !parameters.isAutoPopup()) {
/**
* covered with {@link com.intellij.codeInsight.template.impl.LiveTemplateCompletionContributor}
*/
return;
}
ZenCodingTemplate zenCodingTemplate = CustomLiveTemplate.EP_NAME.findExtension(ZenCodingTemplate.class);
if (zenCodingTemplate == null) {
return;
if (zenCodingTemplate != null) {
zenCodingTemplate.addCompletions(parameters, result);
}
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<TemplateImpl> generatedTemplate = new Ref<TemplateImpl>();
final CustomTemplateCallback callback = new CustomTemplateCallback(editor, file, false) {
@Override
public void deleteTemplateKey(String key) {
}
@Override
public void startTemplate(Template template, Map<String, String> predefinedValues, TemplateEditingListener listener) {
if (template instanceof TemplateImpl && !((TemplateImpl)template).isDeactivated()) {
generatedTemplate.set((TemplateImpl)template);
}
}
};
final Collection<SingleLineEmmetFilter> extraFilters = ContainerUtil.newLinkedList(new SingleLineEmmetFilter());
ZenCodingTemplate.expand(templatePrefix, callback, null, generator, extraFilters, false);
if (!generatedTemplate.isNull()) {
result = result.withPrefixMatcher(templatePrefix);
final TemplateImpl template = generatedTemplate.get();
template.setKey(templatePrefix);
template.setDescription(template.getTemplateText());
result.addElement(createLookupElement(zenCodingTemplate, template));
result.restartCompletionOnPrefixChange(StandardPatterns.string().startsWith(templatePrefix));
}
}
protected LiveTemplateLookupElement createLookupElement(@NotNull CustomLiveTemplateBase customLiveTemplate, @NotNull TemplateImpl template) {
return new CustomLiveTemplateLookupElement(customLiveTemplate, template.getKey(), template.getKey(), template.getDescription(), true, true);
}
protected abstract ZenCodingGenerator getGenerator();
protected boolean isAvailable(CompletionParameters parameters) {
return parameters.getInvocationCount() == 0;
}
}
@@ -1,44 +0,0 @@
/*
* 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.CustomLiveTemplateBase;
import com.intellij.codeInsight.template.emmet.generators.XmlZenCodingGeneratorImpl;
import com.intellij.codeInsight.template.emmet.generators.ZenCodingGenerator;
import com.intellij.codeInsight.template.impl.CustomLiveTemplateLookupElement;
import com.intellij.codeInsight.template.impl.LiveTemplateLookupElement;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import org.jetbrains.annotations.NotNull;
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(@NotNull CustomLiveTemplateBase customLiveTemplate, @NotNull final TemplateImpl template) {
return new CustomLiveTemplateLookupElement(customLiveTemplate, template.getKey(), template.getDescription(), "", false, true);
}
@Override
protected ZenCodingGenerator getGenerator() {
return XmlZenCodingGeneratorImpl.INSTANCE;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -15,7 +15,10 @@
*/
package com.intellij.codeInsight.template.emmet.generators;
import com.intellij.application.options.emmet.EmmetOptions;
import com.intellij.codeInsight.template.CustomLiveTemplateBase;
import com.intellij.codeInsight.template.emmet.tokens.TemplateToken;
import com.intellij.codeInsight.template.impl.CustomLiveTemplateLookupElement;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
@@ -76,4 +79,16 @@ public abstract class XmlZenCodingGenerator extends ZenCodingGenerator {
int totalIterations, @Nullable String surroundedText);
public abstract boolean isMyContext(@NotNull PsiElement context, boolean wrapping);
@Override
public CustomLiveTemplateLookupElement createLookupElement(@NotNull CustomLiveTemplateBase customLiveTemplate,
@NotNull final TemplateImpl template) {
return new CustomLiveTemplateLookupElement(customLiveTemplate, template.getKey(), template.getDescription(), "", false, true);
}
@Override
public boolean hasCompletionItem() {
EmmetOptions emmetOptions = EmmetOptions.getInstance();
return emmetOptions.isEmmetEnabled() && emmetOptions.isPreviewEnabled();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -15,12 +15,14 @@
*/
package com.intellij.codeInsight.template.emmet.generators;
import com.intellij.codeInsight.template.CustomLiveTemplateBase;
import com.intellij.codeInsight.template.CustomTemplateCallback;
import com.intellij.codeInsight.template.emmet.EmmetParser;
import com.intellij.codeInsight.template.emmet.XmlEmmetParser;
import com.intellij.codeInsight.template.emmet.ZenCodingTemplate;
import com.intellij.codeInsight.template.emmet.tokens.TemplateToken;
import com.intellij.codeInsight.template.emmet.tokens.ZenCodingToken;
import com.intellij.codeInsight.template.impl.CustomLiveTemplateLookupElement;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.ExtensionPointName;
@@ -183,4 +185,8 @@ public abstract class ZenCodingGenerator {
public boolean hasCompletionItem() {
return false;
}
public CustomLiveTemplateLookupElement createLookupElement(@NotNull CustomLiveTemplateBase customLiveTemplate, @NotNull TemplateImpl template) {
return new CustomLiveTemplateLookupElement(customLiveTemplate, template.getKey(), template.getKey(), template.getDescription(), true, true);
}
}