zen coding activation migrate to TemplateManager again
authorEugene Kudelevsky <Eugene.Kudelevsky@jetbrains.com>
Sat, 10 Apr 2010 15:44:33 +0000 (19:44 +0400)
committerEugene Kudelevsky <Eugene.Kudelevsky@jetbrains.com>
Sat, 10 Apr 2010 16:44:01 +0000 (20:44 +0400)
platform/lang-impl/src/com/intellij/codeInsight/template/CustomLiveTemplate.java
platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java
xml/impl/src/com/intellij/application/options/editor/WebEditorOptions.java
xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form
xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsProvider.java
xml/impl/src/com/intellij/codeInsight/completion/XmlSmartEnterProcessor.java
xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingTemplate.java

index 47bbc2c689c880e32f9309b1ceb05908d3ec05d7..c3e9748382e3c7839cab2590f9293978882f07fa 100644 (file)
@@ -37,4 +37,6 @@ public interface CustomLiveTemplate {
 
   @NotNull
   String getTitle();
+
+  char getShortcut();
 }
index f468b813c4b07304cf279af050050e117688ed77..937e00618f1945f3054ed867d57e98327a27c832 100644 (file)
@@ -220,11 +220,49 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
     }
   }
 
+  private static boolean containsTemplateStartingBefore(Map<TemplateImpl, String> template2argument,
+                                                        int offset,
+                                                        int caretOffset,
+                                                        CharSequence text) {
+    for (TemplateImpl template : template2argument.keySet()) {
+      String argument = template2argument.get(template);
+      int templateStart = getTemplateStart(template, argument, caretOffset, text);
+      if (templateStart <= offset) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   public boolean startTemplate(final Editor editor, char shortcutChar, final PairProcessor<String, String> processor) {
     PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, myProject);
     if (file == null) return false;
     TemplateSettings templateSettings = TemplateSettings.getInstance();
+
     Map<TemplateImpl, String> template2argument = findMatchingTemplates(file, editor, shortcutChar, templateSettings);
+
+    for (final CustomLiveTemplate customLiveTemplate : CustomLiveTemplate.EP_NAME.getExtensions()) {
+      if (shortcutChar == customLiveTemplate.getShortcut()) {
+        int caretOffset = editor.getCaretModel().getOffset();
+        if (customLiveTemplate.isApplicable(file, caretOffset, false)) {
+          final CustomTemplateCallback callback = new CustomTemplateCallback(editor, file);
+          String key = customLiveTemplate.computeTemplateKey(callback);
+          if (key != null) {
+            int offsetBeforeKey = caretOffset - key.length();
+            CharSequence text = editor.getDocument().getCharsSequence();
+            if (template2argument == null || !containsTemplateStartingBefore(template2argument, offsetBeforeKey, caretOffset, text)) {
+              callback.getEditor().getDocument().deleteString(offsetBeforeKey, caretOffset);
+              customLiveTemplate.expand(key, callback, new TemplateInvokationListener() {
+                public void finished(boolean inSeparateEvent) {
+                  callback.finish();
+                }
+              });
+              return true;
+            }
+          }
+        }
+      }
+    }
     return startNonCustomTemplates(template2argument, editor, processor);
   }
 
index 5d6dc1cc95801470a595b62c792efc65b97189c3..bdc71a0f573c38cb58e3ea319440bf6c6f52d8b7 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.application.options.editor;
 
+import com.intellij.codeInsight.template.impl.TemplateSettings;
 import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.components.*;
 import com.intellij.util.xmlb.XmlSerializerUtil;
@@ -43,6 +44,7 @@ public class WebEditorOptions implements PersistentStateComponent<WebEditorOptio
   private boolean myAutomaticallyInsertRequiredAttributes = true;
   private boolean myAutomaticallyStartAttribute = true;
   private boolean myEnableZenCoding = true;
+  private char myZenCodingExpandShortcut = TemplateSettings.TAB_CHAR;
 
   public static WebEditorOptions getInstance() {
     return ServiceManager.getService(WebEditorOptions.class);
@@ -80,6 +82,14 @@ public class WebEditorOptions implements PersistentStateComponent<WebEditorOptio
     myAutomaticallyInsertRequiredAttributes = automaticallyInsertRequiredAttributes;
   }
 
+  public char getZenCodingExpandShortcut() {
+    return myZenCodingExpandShortcut;
+  }
+
+  public void setZenCodingExpandShortcut(char zenCodingExpandShortcut) {
+    myZenCodingExpandShortcut = zenCodingExpandShortcut;
+  }
+
   public boolean isAutomaticallyStartAttribute() {
     return myAutomaticallyStartAttribute;
   }
index a7175bbc42b5a906e28170e1fd7d88cb2adea97a..e2d177d40e82796f8371147a6a070b8f8e858864 100644 (file)
@@ -3,12 +3,12 @@
   <grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="2" 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>
-      <xy x="20" y="20" width="519" height="400"/>
+      <xy x="20" y="20" width="362" height="400"/>
     </constraints>
     <properties/>
     <border type="none"/>
     <children>
-      <grid id="247ce" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+      <grid id="247ce" layout-manager="GridLayoutManager" row-count="5" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
         <margin top="0" left="0" bottom="0" right="0"/>
         <constraints>
           <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -18,7 +18,7 @@
         <children>
           <component id="f6c8c" class="javax.swing.JCheckBox" binding="myAutomaticallyInsertClosingTagCheckBox" default-binding="true">
             <constraints>
-              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+              <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
               <text value="Automatically insert closing tag"/>
@@ -26,7 +26,7 @@
           </component>
           <component id="9f825" class="javax.swing.JCheckBox" binding="myAutomaticallyInsertRequiredAttributesCheckBox" default-binding="true">
             <constraints>
-              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+              <grid row="1" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
               <text value="Automatically insert required attributes"/>
@@ -34,7 +34,7 @@
           </component>
           <component id="4bf74" class="javax.swing.JCheckBox" binding="myAutomaticallyStartAttributeAfterCheckBox" default-binding="true">
             <constraints>
-              <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+              <grid row="2" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
               <selected value="false"/>
           </component>
           <component id="ba426" class="javax.swing.JCheckBox" binding="myEnableZenCodingCheckBox">
             <constraints>
-              <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+              <grid row="3" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
               <text value="Enable Zen Coding"/>
             </properties>
           </component>
+          <component id="7c51c" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="3" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text value="Expand abbreviation with"/>
+            </properties>
+          </component>
+          <component id="ed567" class="javax.swing.JComboBox" binding="myZenCodingExpandShortcutCombo">
+            <constraints>
+              <grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+          </component>
+          <hspacer id="8ee6f">
+            <constraints>
+              <grid row="4" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+            </constraints>
+          </hspacer>
         </children>
       </grid>
       <vspacer id="e0bcf">
index 698797e30497545ce02ed06ebf3cebcdabea830c..b48806d3b871eed755de58fb0861cc19f9de1395 100644 (file)
  */
 package com.intellij.application.options.editor;
 
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.codeInsight.template.impl.TemplateSettings;
 import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.xml.XmlBundle;
 
 import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 
 /**
  * @author spleaner
@@ -29,6 +33,22 @@ public class WebEditorOptionsProvider implements EditorOptionsProvider {
   private JCheckBox myAutomaticallyInsertRequiredAttributesCheckBox;
   private JCheckBox myAutomaticallyStartAttributeAfterCheckBox;
   private JCheckBox myEnableZenCodingCheckBox;
+  private JComboBox myZenCodingExpandShortcutCombo;
+
+  private static final String SPACE = CodeInsightBundle.message("template.shortcut.space");
+  private static final String TAB = CodeInsightBundle.message("template.shortcut.tab");
+  private static final String ENTER = CodeInsightBundle.message("template.shortcut.enter");
+
+  {
+    myZenCodingExpandShortcutCombo.addItem(SPACE);
+    myZenCodingExpandShortcutCombo.addItem(TAB);
+    myZenCodingExpandShortcutCombo.addItem(ENTER);
+    myEnableZenCodingCheckBox.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        myZenCodingExpandShortcutCombo.setEnabled(myEnableZenCodingCheckBox.isSelected());
+      }
+    });
+  }
 
   public String getDisplayName() {
     return XmlBundle.message("web.editor.configuration.title");
@@ -46,12 +66,24 @@ public class WebEditorOptionsProvider implements EditorOptionsProvider {
     return myWholePanel;
   }
 
+  private char getSelectedZenCodingExpandShortcut() {
+    Object selectedItem = myZenCodingExpandShortcutCombo.getSelectedItem();
+    if (TAB.equals(selectedItem)) {
+      return TemplateSettings.TAB_CHAR;
+    }
+    else if (ENTER.equals(selectedItem)) {
+      return TemplateSettings.ENTER_CHAR;
+    }
+    return TemplateSettings.SPACE_CHAR;
+  }
+
   public boolean isModified() {
     final WebEditorOptions xmlEditorOptions = WebEditorOptions.getInstance();
     return xmlEditorOptions.isAutomaticallyInsertClosingTag() != myAutomaticallyInsertClosingTagCheckBox.isSelected() ||
            xmlEditorOptions.isAutomaticallyInsertRequiredAttributes() != myAutomaticallyInsertRequiredAttributesCheckBox.isSelected() ||
            xmlEditorOptions.isAutomaticallyStartAttribute() != myAutomaticallyStartAttributeAfterCheckBox.isSelected() ||
-           xmlEditorOptions.isZenCodingEnabled() != myEnableZenCodingCheckBox.isSelected();
+           xmlEditorOptions.isZenCodingEnabled() != myEnableZenCodingCheckBox.isSelected() ||
+           xmlEditorOptions.getZenCodingExpandShortcut() != getSelectedZenCodingExpandShortcut();
   }
 
   public void apply() throws ConfigurationException {
@@ -60,6 +92,7 @@ public class WebEditorOptionsProvider implements EditorOptionsProvider {
     xmlEditorOptions.setAutomaticallyInsertRequiredAttributes(myAutomaticallyInsertRequiredAttributesCheckBox.isSelected());
     xmlEditorOptions.setAutomaticallyStartAttribute(myAutomaticallyStartAttributeAfterCheckBox.isSelected());
     xmlEditorOptions.setEnableZenCoding(myEnableZenCodingCheckBox.isSelected());
+    xmlEditorOptions.setZenCodingExpandShortcut(getSelectedZenCodingExpandShortcut());
   }
 
   public void reset() {
@@ -68,6 +101,18 @@ public class WebEditorOptionsProvider implements EditorOptionsProvider {
     myAutomaticallyInsertRequiredAttributesCheckBox.setSelected(xmlEditorOptions.isAutomaticallyInsertRequiredAttributes());
     myAutomaticallyStartAttributeAfterCheckBox.setSelected(xmlEditorOptions.isAutomaticallyStartAttribute());
     myEnableZenCodingCheckBox.setSelected(xmlEditorOptions.isZenCodingEnabled());
+    myZenCodingExpandShortcutCombo.setEnabled(xmlEditorOptions.isZenCodingEnabled());
+
+    char shortcut = WebEditorOptions.getInstance().getZenCodingExpandShortcut();
+    if (shortcut == TemplateSettings.TAB_CHAR) {
+      myZenCodingExpandShortcutCombo.setSelectedItem(TAB);
+    }
+    else if (shortcut == TemplateSettings.ENTER_CHAR) {
+      myZenCodingExpandShortcutCombo.setSelectedItem(ENTER);
+    }
+    else {
+      myZenCodingExpandShortcutCombo.setSelectedItem(SPACE);
+    }
   }
 
   public void disposeUIResources() {
index b8bc8e1004723edb131702eef00ed73e8a800b43..8810fc9c568d1a05815b80371f5a6549f645617f 100644 (file)
@@ -16,7 +16,6 @@
 package com.intellij.codeInsight.completion;
 
 import com.intellij.codeInsight.editorActions.smartEnter.SmartEnterProcessor;
-import com.intellij.codeInsight.template.zencoding.XmlZenCodingTemplate;
 import com.intellij.lang.ASTNode;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
@@ -42,10 +41,11 @@ public class XmlSmartEnterProcessor extends SmartEnterProcessor {
   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.XmlSmartEnterProcessor");
 
   public boolean process(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile psiFile) {
-    if (!completeEndTag(project, editor, psiFile)) {
+    /*if (!completeEndTag(project, editor, psiFile)) {
       return XmlZenCodingTemplate.startZenCoding(editor, psiFile, null);
     }
-    return true;
+    return true;*/
+    return completeEndTag(project, editor, psiFile);
   }
 
   private boolean completeEndTag(Project project, Editor editor, PsiFile psiFile) {
index a50fb18297afcc866cce86954892eb791f3220db..f46965b3cb5c543d0d63b0507ab9b63758a1576f 100644 (file)
@@ -336,7 +336,7 @@ public class XmlZenCodingTemplate implements CustomLiveTemplate {
   }
 
   public boolean isApplicable(PsiFile file, int offset, boolean selection) {
-    return selection && isApplicable(file, offset);
+    return isApplicable(file, offset);
   }
 
   private static boolean isApplicable(PsiFile file, int offset) {
@@ -425,6 +425,10 @@ public class XmlZenCodingTemplate implements CustomLiveTemplate {
     return XmlBundle.message("zen.coding.title");
   }
 
+  public char getShortcut() {
+    return WebEditorOptions.getInstance().getZenCodingExpandShortcut();
+  }
+
   @Nullable
   static XmlTag parseXmlTagInTemplate(String templateString, CustomTemplateCallback callback, boolean createPhysicalFile) {
     XmlFile xmlFile = (XmlFile)PsiFileFactory.getInstance(callback.getProject())