WEB-12614 Emmet Filters

This commit is contained in:
Alexander Zolotov
2014-07-07 17:16:14 +04:00
parent 9804bfcc8c
commit 23de2fd41f
11 changed files with 154 additions and 45 deletions
@@ -217,7 +217,7 @@ select.xsd.schema.dialog.title=Select XSD Schema
emmet.title=Emmet
emmet.configuration.title=Emmet
emmet.enable.label=&Enable XML Emmet
emmet.enable.bem.filter=Enable &BEM filter by default
emmet.filters.enabled.by.default=Filters enabled by default
emmet.enable.preview=Enable &abbreviation preview
emmet.expand.abbreviation.with=Expand &abbreviation with
@@ -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,6 +15,8 @@
*/
package com.intellij.application.options.emmet;
import com.intellij.codeInsight.template.emmet.filters.BemEmmetFilter;
import com.intellij.codeInsight.template.emmet.filters.ZenCodingFilter;
import com.intellij.codeInsight.template.impl.TemplateSettings;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.*;
@@ -26,11 +28,8 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Map;
import java.util.Set;
/**
* User: zolotov
* Date: 2/20/13
*/
@State(
name = "EmmetOptions",
storages = {
@@ -39,24 +38,46 @@ import java.util.Map;
)}
)
public class EmmetOptions implements PersistentStateComponent<EmmetOptions>, ExportableComponent {
/**
* @deprecated delete after IDEA 14
*/
private boolean myBemFilterEnabledByDefault = false;
private boolean myEmmetEnabled = true;
private int myEmmetExpandShortcut = TemplateSettings.TAB_CHAR;
private boolean myFuzzySearchEnabled = true;
private boolean myAutoInsertCssPrefixedEnabled = true;
private boolean myPreviewEnabled = false;
private Set<String> myFiltersEnabledByDefault = ContainerUtil.newHashSet();
@NotNull
private Map<String, Integer> prefixes = ContainerUtil.newHashMap();
/**
* @deprecated delete after IDEA 14
*/
public boolean isBemFilterEnabledByDefault() {
return myBemFilterEnabledByDefault;
}
/**
* @deprecated delete after IDEA 14
*/
public void setBemFilterEnabledByDefault(boolean enableBemFilterByDefault) {
myBemFilterEnabledByDefault = enableBemFilterByDefault;
}
@NotNull
public Set<String> getFiltersEnabledByDefault() {
return myFiltersEnabledByDefault;
}
public void setFiltersEnabledByDefault(@NotNull Set<String> filtersEnabledByDefault) {
myFiltersEnabledByDefault = filtersEnabledByDefault;
}
public boolean isFilterEnabledByDefault(@NotNull ZenCodingFilter filter) {
return myFiltersEnabledByDefault.contains(filter.getSuffix());
}
public void setEmmetExpandShortcut(int emmetExpandShortcut) {
myEmmetExpandShortcut = emmetExpandShortcut;
}
@@ -126,6 +147,11 @@ public class EmmetOptions implements PersistentStateComponent<EmmetOptions>, Exp
@Override
public void loadState(final EmmetOptions state) {
XmlSerializerUtil.copyBean(state, this);
// todo delete after IDEA 14
if (myFiltersEnabledByDefault.isEmpty() && myBemFilterEnabledByDefault) {
myFiltersEnabledByDefault.add(BemEmmetFilter.SUFFIX);
}
}
public static EmmetOptions getInstance() {
@@ -19,14 +19,6 @@
</clientProperties>
<border type="none" title="XML"/>
<children>
<component id="9ed4c" class="com.intellij.ui.components.JBCheckBox" binding="myEnableBEMFilterJBCheckBox" default-binding="true">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/XmlBundle" key="emmet.enable.bem.filter"/>
</properties>
</component>
<component id="446a3" class="com.intellij.ui.components.JBCheckBox" binding="myEnableEmmetJBCheckBox" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
@@ -37,12 +29,28 @@
</component>
<component id="c52c1" class="com.intellij.ui.components.JBCheckBox" binding="myEnablePreviewJBCheckBox">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/XmlBundle" key="emmet.enable.preview"/>
</properties>
</component>
<grid id="cdbb7" binding="myFiltersListPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="3282c" class="com.intellij.ui.CheckBoxList" binding="myFiltersCheckBoxList">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
</children>
</grid>
</children>
</grid>
<vspacer id="27c08">
@@ -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,34 +15,46 @@
*/
package com.intellij.application.options.emmet;
import com.intellij.codeInsight.template.emmet.filters.ZenCodingFilter;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.ui.CheckBoxList;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xml.XmlBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Set;
/**
* User: zolotov
* Date: 2/20/13
*/
public class XmlEmmetConfigurable implements UnnamedConfigurable, Disposable, Configurable.NoScroll {
private JBCheckBox myEnableBEMFilterJBCheckBox;
private JPanel myPanel;
private JBCheckBox myEnableEmmetJBCheckBox;
private JBCheckBox myEnablePreviewJBCheckBox;
private CheckBoxList<ZenCodingFilter> myFiltersCheckBoxList;
private JPanel myFiltersListPanel;
public XmlEmmetConfigurable() {
myEnableEmmetJBCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
boolean selected = myEnableEmmetJBCheckBox.isSelected();
myEnableBEMFilterJBCheckBox.setEnabled(selected);
myEnablePreviewJBCheckBox.setEnabled(selected);
myFiltersCheckBoxList.setEnabled(selected);
}
});
myFiltersListPanel.setBorder(IdeBorderFactory.createTitledBorder(XmlBundle.message("emmet.filters.enabled.by.default"), false));
myFiltersCheckBoxList.setItems(ZenCodingFilter.getInstances(), new Function<ZenCodingFilter, String>() {
@Override
public String fun(ZenCodingFilter filter) {
return filter.getDisplayName();
}
});
}
@@ -62,29 +74,43 @@ public class XmlEmmetConfigurable implements UnnamedConfigurable, Disposable, Co
EmmetOptions emmetOptions = EmmetOptions.getInstance();
return emmetOptions.isEmmetEnabled() != myEnableEmmetJBCheckBox.isSelected() ||
emmetOptions.isPreviewEnabled() != myEnablePreviewJBCheckBox.isSelected() ||
emmetOptions.isBemFilterEnabledByDefault() != myEnableBEMFilterJBCheckBox.isSelected();
!emmetOptions.getFiltersEnabledByDefault().equals(enabledFilters());
}
@Override
public void apply() throws ConfigurationException {
EmmetOptions emmetOptions = EmmetOptions.getInstance();
emmetOptions.setEmmetEnabled(myEnableEmmetJBCheckBox.isSelected());
emmetOptions.setBemFilterEnabledByDefault(myEnableBEMFilterJBCheckBox.isSelected());
emmetOptions.setPreviewEnabled(myEnablePreviewJBCheckBox.isSelected());
emmetOptions.setFiltersEnabledByDefault(enabledFilters());
}
@Override
public void reset() {
EmmetOptions emmetOptions = EmmetOptions.getInstance();
myEnableEmmetJBCheckBox.setSelected(emmetOptions.isEmmetEnabled());
myEnableBEMFilterJBCheckBox.setEnabled(emmetOptions.isEmmetEnabled());
myEnableBEMFilterJBCheckBox.setSelected(emmetOptions.isBemFilterEnabledByDefault());
myEnablePreviewJBCheckBox.setEnabled(emmetOptions.isEmmetEnabled());
myEnablePreviewJBCheckBox.setSelected(emmetOptions.isPreviewEnabled());
Set<String> enabledByDefault = emmetOptions.getFiltersEnabledByDefault();
for (ZenCodingFilter filter : ZenCodingFilter.getInstances()) {
myFiltersCheckBoxList.setItemSelected(filter, enabledByDefault.contains(filter.getSuffix()));
}
}
@Override
public void disposeUIResources() {
}
@NotNull
private Set<String> enabledFilters() {
Set<String> result = ContainerUtil.newHashSet();
for (ZenCodingFilter filter : ZenCodingFilter.getInstances()) {
if (myFiltersCheckBoxList.isItemSelected(filter)) {
result.add(filter.getSuffix());
}
}
return result;
}
}
@@ -20,7 +20,6 @@ import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.intellij.application.options.emmet.EmmetOptions;
import com.intellij.codeInsight.template.emmet.nodes.GenerationNode;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.util.Couple;
@@ -51,6 +50,8 @@ import static com.google.common.collect.Lists.newLinkedList;
* And documentation here: http://docs.emmet.io/filters/bem/
*/
public class BemEmmetFilter extends ZenCodingFilter {
public static final String SUFFIX = "bem";
private static final Key<BemState> BEM_STATE = Key.create("BEM_STATE");
private static final String ELEMENT_SEPARATOR = "__";
@@ -95,13 +96,14 @@ public class BemEmmetFilter extends ZenCodingFilter {
@NotNull
@Override
public String getSuffix() {
return "bem";
public String getDisplayName() {
return "BEM";
}
@NotNull
@Override
public boolean isAppliedByDefault(@NotNull PsiElement context) {
return EmmetOptions.getInstance().isBemFilterEnabledByDefault();
public String getSuffix() {
return SUFFIX;
}
@Override
@@ -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.
@@ -68,4 +68,10 @@ public class CommentZenCodingFilter extends ZenCodingFilter {
public boolean isMyContext(@NotNull PsiElement context) {
return context.getLanguage() instanceof XMLLanguage;
}
@NotNull
@Override
public String getDisplayName() {
return "Comment tags";
}
}
@@ -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.
@@ -43,4 +43,10 @@ public class EscapeZenCodingFilter extends ZenCodingFilter {
public boolean isMyContext(@NotNull PsiElement context) {
return context.getLanguage() instanceof XMLLanguage;
}
@NotNull
@Override
public String getDisplayName() {
return "Escape";
}
}
@@ -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.
@@ -57,4 +57,10 @@ public class SingleLineEmmetFilter extends ZenCodingFilter {
public boolean isMyContext(@NotNull PsiElement context) {
return context.getLanguage() instanceof XMLLanguage;
}
@NotNull
@Override
public String getDisplayName() {
return "Single line";
}
}
@@ -1,3 +1,18 @@
/*
* 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.
* 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.filters;
import com.intellij.codeInsight.template.emmet.nodes.GenerationNode;
@@ -29,6 +44,12 @@ public class TrimZenCodingFilter extends ZenCodingFilter {
return context.getLanguage() instanceof XMLLanguage;
}
@NotNull
@Override
public String getDisplayName() {
return "Trim line markers";
}
@NotNull
@Override
public String filterText(@NotNull String text, @NotNull TemplateToken token) {
@@ -65,7 +86,6 @@ public class TrimZenCodingFilter extends ZenCodingFilter {
final String surroundedText = node.getSurroundedText();
if (surroundedText != null) {
node.setSurroundedText(PATTERN.matcher(surroundedText).replaceAll(""));
} else if(node.getTemplateToken() == TemplateToken.EMPTY_TEMPLATE_TOKEN) {
}
for (GenerationNode child : node.getChildren()) {
doFilter(child);
@@ -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.
@@ -90,6 +90,12 @@ public class XslZenCodingFilter extends ZenCodingFilter {
@Override
public boolean isAppliedByDefault(@NotNull PsiElement context) {
return XslTextContextType.isXslOrXsltFile(context.getContainingFile());
return XslTextContextType.isXslOrXsltFile(context.getContainingFile()) || super.isAppliedByDefault(context);
}
@NotNull
@Override
public String getDisplayName() {
return "XSL tuning";
}
}
@@ -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,6 +15,7 @@
*/
package com.intellij.codeInsight.template.emmet.filters;
import com.intellij.application.options.emmet.EmmetOptions;
import com.intellij.codeInsight.template.emmet.nodes.GenerationNode;
import com.intellij.codeInsight.template.emmet.tokens.TemplateToken;
import com.intellij.openapi.extensions.ExtensionPointName;
@@ -29,10 +30,9 @@ import java.util.List;
* @author Eugene.Kudelevsky
*/
public abstract class ZenCodingFilter {
public static final ExtensionPointName<ZenCodingFilter> EP_NAME =
new ExtensionPointName<ZenCodingFilter>("com.intellij.xml.zenCodingFilter");
public static final ExtensionPointName<ZenCodingFilter> EP_NAME = new ExtensionPointName<ZenCodingFilter>("com.intellij.xml.zenCodingFilter");
private static final ZenCodingFilter[] ourStandartFilters = new ZenCodingFilter[]{
private static final ZenCodingFilter[] OUR_STANDARD_FILTERS = new ZenCodingFilter[]{
new XslZenCodingFilter(),
new CommentZenCodingFilter(),
new EscapeZenCodingFilter(),
@@ -57,12 +57,15 @@ public abstract class ZenCodingFilter {
public abstract boolean isMyContext(@NotNull PsiElement context);
public boolean isAppliedByDefault(@NotNull PsiElement context) {
return false;
return EmmetOptions.getInstance().isFilterEnabledByDefault(this);
}
@NotNull
public abstract String getDisplayName();
public static List<ZenCodingFilter> getInstances() {
List<ZenCodingFilter> generators = new ArrayList<ZenCodingFilter>();
Collections.addAll(generators, ourStandartFilters);
Collections.addAll(generators, OUR_STANDARD_FILTERS);
Collections.addAll(generators, EP_NAME.getExtensions());
return generators;
}