completing character classes
authorMaxim Mossienko <Maxim.Mossienko@jetbrains.com>
Mon, 29 Sep 2008 18:02:21 +0000 (22:02 +0400)
committerMaxim Mossienko <Maxim.Mossienko@jetbrains.com>
Mon, 29 Sep 2008 18:02:21 +0000 (22:02 +0400)
RegExpSupport/RegExpSupport.iml
RegExpSupport/src/META-INF/plugin.xml
RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java [new file with mode: 0644]
RegExpSupport/src/org/intellij/lang/regexp/RegExpDocumentionProvider.java [new file with mode: 0644]
RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguage.java
RegExpSupport/test/test/RegExpCompletionTest.java [new file with mode: 0644]
RegExpSupport/testData/completion/BackSlashVariants.regexp [new file with mode: 0644]
RegExpSupport/testData/completion/PropertyAlpha.regexp [new file with mode: 0644]
RegExpSupport/testData/completion/PropertyAlphaExpected.regexp [new file with mode: 0644]
RegExpSupport/testData/completion/PropertyVariants.regexp [new file with mode: 0644]

index 1c538b6691c320c7ee9acc8c2e71cfca9731ba17..670e32acd0aa27e41d7ee8635a086710a66c9ef4 100644 (file)
@@ -13,6 +13,7 @@
     <orderEntry type="module" module-name="openapi" />
     <orderEntry type="library" name="JUnit4" level="project" />
     <orderEntry type="module" module-name="lang-impl" />
+    <orderEntry type="module" module-name="ExtendedApi" />
   </component>
   <component name="RetroweaverPlugin">
     <setting name="active" value="false" />
index a3cef7ba9e1bdd4d25d294c0855e1544c2072188..5203c1acb1c313b2b302a6ba743172050efffaf0 100644 (file)
@@ -19,5 +19,8 @@
 
   <extensions defaultExtensionNs="com.intellij">
     <errorHandler implementation="com.intellij.diagnostic.ITNReporter" />
+
+    <lang.documentationProvider language="RegExp" implementationClass="org.intellij.lang.regexp.RegExpDocumentionProvider"/>
+    <completion.contributor implementation="org.intellij.lang.regexp.RegExpCompletionContributor"/>
   </extensions>
 </idea-plugin>
diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java
new file mode 100644 (file)
index 0000000..c7a9927
--- /dev/null
@@ -0,0 +1,80 @@
+package org.intellij.lang.regexp;
+
+import com.intellij.codeInsight.TailType;
+import com.intellij.codeInsight.completion.*;
+import com.intellij.codeInsight.lookup.LookupElementFactory;
+import com.intellij.codeInsight.lookup.MutableLookupElement;
+import com.intellij.patterns.ElementPattern;
+import static com.intellij.patterns.PlatformPatterns.psiElement;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.ProcessingContext;
+import org.intellij.lang.regexp.psi.impl.RegExpPropertyImpl;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: vnikolaenko
+ * Date: 22.09.2008
+ * Time: 12:14:14
+ * To change this template use File | Settings | File Templates.
+ */
+public class RegExpCompletionContributor extends CompletionContributor {
+    public RegExpCompletionContributor() {
+        final ElementPattern<PsiElement> backSlashPattern = psiElement().withText("\\\\");
+        extend(CompletionType.BASIC, psiElement().afterLeaf(backSlashPattern), new CharacterClassesNameCompletionProvider());
+
+        final ElementPattern<PsiElement> propertyPattern
+                = psiElement().withText("p").afterLeaf(backSlashPattern);
+        extend(CompletionType.BASIC, psiElement().afterLeaf(propertyPattern), new PropertyCompletionProvider());
+
+        final ElementPattern<PsiElement> propertyNamePattern
+                = psiElement().afterLeaf(psiElement().withText("{").afterLeaf(propertyPattern));
+        extend(CompletionType.BASIC, propertyNamePattern, new PropertyNameCompletionProvider());
+    }
+
+    private static MutableLookupElement<String> addLookupElement(final CompletionResultSet result,
+                                                                 final String name) {
+        MutableLookupElement<String> element = LookupElementFactory.getInstance().createLookupElement(name);
+        result.addElement(element);
+        return element;
+    }
+
+    private static class PropertyNameCompletionProvider extends CompletionProvider<CompletionParameters> {
+
+        public void addCompletions(@NotNull final CompletionParameters parameters,
+                                   final ProcessingContext context,
+                                   @NotNull final CompletionResultSet result) {
+              for (String[] stringArray : RegExpPropertyImpl.PROPERTY_NAMES) {
+                  addLookupElement(result, stringArray[0]).setTailType(TailType.createSimpleTailType('}'));
+              }
+        }
+    }
+
+    private static class PropertyCompletionProvider extends CompletionProvider<CompletionParameters> {
+
+        public void addCompletions(@NotNull final CompletionParameters parameters,
+                                   final ProcessingContext context,
+                                   @NotNull final CompletionResultSet result) {
+            for (String[] stringArray : RegExpPropertyImpl.PROPERTY_NAMES) {
+                addLookupElement(result, "{" + stringArray[0] + "}");
+            }
+        }
+    }
+    private static class CharacterClassesNameCompletionProvider extends CompletionProvider<CompletionParameters> {
+
+        public void addCompletions(@NotNull final CompletionParameters parameters,
+                                   final ProcessingContext context,
+                                   @NotNull final CompletionResultSet result) {
+          String[] completions = {
+                "d", "D", "s", "S", "w", "W", "b", "B", "A", "G", "Z", "z", "Q", "E",
+                "t", "n", "r", "f", "a", "e"
+            };
+            for (String s : completions) {
+                addLookupElement(result, s);
+            }
+            for (String[] stringArray : RegExpPropertyImpl.PROPERTY_NAMES) {
+                addLookupElement(result, "p{" + stringArray[0] + "}");
+            }
+        }
+    }
+}
diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpDocumentionProvider.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpDocumentionProvider.java
new file mode 100644 (file)
index 0000000..6fe4d1f
--- /dev/null
@@ -0,0 +1,55 @@
+package org.intellij.lang.regexp;
+
+import com.intellij.lang.documentation.QuickDocumentationProvider;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiManager;
+import org.intellij.lang.regexp.psi.impl.RegExpPropertyImpl;
+import org.intellij.lang.regexp.psi.impl.RegExpElementImpl;
+import org.intellij.lang.regexp.psi.RegExpGroup;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: vnikolaenko
+ * Date: 17.09.2008
+ * Time: 19:24:29
+ * To change this template use File | Settings | File Templates.
+ */
+public class RegExpDocumentionProvider extends QuickDocumentationProvider {
+    @Nullable
+    public String getUrlFor(PsiElement element, PsiElement originalElement) {
+        return null;
+    }
+
+    @Nullable
+    public String generateDoc(PsiElement element, PsiElement originalElement) {
+        if (element instanceof RegExpPropertyImpl) {
+            String elementName = ((RegExpPropertyImpl)element).getCategoryNode().getText();
+            for (String[] stringArray : RegExpPropertyImpl.PROPERTY_NAMES) {
+                if (stringArray[0].equals(elementName)) {
+                    return "Property block stands for " + stringArray[1];
+                }
+            }
+        }
+        return null;
+    }
+
+    @Nullable
+    public PsiElement getDocumentationElementForLookupItem(PsiManager psiManager, Object object, PsiElement element){
+        return null;
+    }
+
+    @Nullable
+    public PsiElement getDocumentationElementForLink(PsiManager psiManager, String link, PsiElement context) {
+        return null;
+    }
+
+    @Nullable
+    public String getQuickNavigateInfo(PsiElement element) {
+        if (element instanceof RegExpGroup) {
+            return "Capturing Group: " + ((RegExpElementImpl)element).getUnescapedText();
+        } else {
+            return null;
+        }
+    }
+}
index c62146bb36d4cb3bc8ec95b5e1106f000dc46938..b61e75ee7b52b9a6fa2dd716ee9fe2f58e7ba7f6 100644 (file)
  */
 package org.intellij.lang.regexp;
 
-import com.intellij.lang.BracePair;
-import com.intellij.lang.Language;
-import com.intellij.lang.LanguageAnnotators;
-import com.intellij.lang.LanguageBraceMatching;
-import com.intellij.lang.LanguageDocumentation;
-import com.intellij.lang.LanguageParserDefinitions;
-import com.intellij.lang.LanguageSurrounders;
-import com.intellij.lang.PairedBraceMatcher;
-import com.intellij.lang.documentation.QuickDocumentationProvider;
+import com.intellij.lang.*;
 import com.intellij.openapi.fileTypes.SingleLazyInstanceSyntaxHighlighterFactory;
 import com.intellij.openapi.fileTypes.SyntaxHighlighter;
 import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
-import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.tree.IElementType;
-import org.intellij.lang.regexp.psi.RegExpGroup;
-import org.intellij.lang.regexp.psi.impl.RegExpElementImpl;
 import org.intellij.lang.regexp.surroundWith.SimpleSurroundDescriptor;
 import org.intellij.lang.regexp.validation.RegExpAnnotator;
 import org.jetbrains.annotations.NotNull;
@@ -54,17 +43,6 @@ public class RegExpLanguage extends Language {
                 return new RegExpHighlighter(null, parserDefinition);
             }
         });
-
-        LanguageDocumentation.INSTANCE.addExplicitExtension(this, new QuickDocumentationProvider() {
-            @Nullable
-            public String getQuickNavigateInfo(PsiElement element) {
-                if (element instanceof RegExpGroup) {
-                    return "Capturing Group: " + ((RegExpElementImpl)element).getUnescapedText();
-                } else {
-                    return null;
-                }
-            }
-        });
     }
 
     @NotNull
diff --git a/RegExpSupport/test/test/RegExpCompletionTest.java b/RegExpSupport/test/test/RegExpCompletionTest.java
new file mode 100644 (file)
index 0000000..6cf24ee
--- /dev/null
@@ -0,0 +1,57 @@
+package test;
+
+import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
+import org.intellij.lang.regexp.psi.impl.RegExpPropertyImpl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: vnikolaenko
+ * Date: 25.09.2008
+ * Time: 15:10:10
+ */
+public class RegExpCompletionTest extends CodeInsightFixtureTestCase {
+
+    // util methods
+    private String getInputDataFileName(String testName) {
+        return Character.toUpperCase(testName.charAt(0)) + testName.substring(1) + ".regexp";
+    }
+
+    private String getExpectedResultFileName(String testName) {
+        return Character.toUpperCase(testName.charAt(0)) + testName.substring(1) + "Expected" + ".regexp";
+    }
+
+    public void testBackSlashVariants() throws Throwable {
+        java.util.List<String> nameList = new ArrayList<String>(Arrays.asList("d", "D", "s", "S", "w", "W", "b", "B", "A", "G", "Z", "z", "Q", "E",
+                "t", "n", "r", "f", "a", "e"));
+        for (String[] stringArray : RegExpPropertyImpl.PROPERTY_NAMES) {
+            nameList.add("p{" + stringArray[0] + "}");
+        }
+        myFixture.testCompletionVariants(getInputDataFileName(getTestName(true)), nameList.toArray(new String[nameList.size()]));
+    }
+
+    public void testPropertyVariants() throws Throwable {
+        java.util.List<String> nameList = new ArrayList<String>();
+        for (String[] stringArray : RegExpPropertyImpl.PROPERTY_NAMES) {
+            nameList.add("{" + stringArray[0] + "}");
+        }
+        myFixture.testCompletionVariants(getInputDataFileName(getTestName(true)), nameList.toArray(new String[nameList.size()]));
+    }
+
+    public void testPropertyAlpha() throws Throwable {
+        doTest();
+    }
+
+    public void doTest() throws Throwable {
+        String inputDataFileName = getInputDataFileName(getTestName(true));
+        String expectedResultFileName = getExpectedResultFileName(getTestName(true));
+        myFixture.testCompletion(inputDataFileName, expectedResultFileName);
+    }
+
+    @Override
+    protected String getBasePath() {
+        return "/svnPlugins/RegExpSupport/testData/completion";
+    }
+}
diff --git a/RegExpSupport/testData/completion/BackSlashVariants.regexp b/RegExpSupport/testData/completion/BackSlashVariants.regexp
new file mode 100644 (file)
index 0000000..144e478
--- /dev/null
@@ -0,0 +1 @@
+[0-9]\\<caret>
diff --git a/RegExpSupport/testData/completion/PropertyAlpha.regexp b/RegExpSupport/testData/completion/PropertyAlpha.regexp
new file mode 100644 (file)
index 0000000..9650913
--- /dev/null
@@ -0,0 +1 @@
+\\p{Alp<caret>}
diff --git a/RegExpSupport/testData/completion/PropertyAlphaExpected.regexp b/RegExpSupport/testData/completion/PropertyAlphaExpected.regexp
new file mode 100644 (file)
index 0000000..03696e6
--- /dev/null
@@ -0,0 +1 @@
+\\p{Alpha}
diff --git a/RegExpSupport/testData/completion/PropertyVariants.regexp b/RegExpSupport/testData/completion/PropertyVariants.regexp
new file mode 100644 (file)
index 0000000..ee205bc
--- /dev/null
@@ -0,0 +1 @@
+[0-9].*\\p<caret>