fixed PY-3687 No completion for keywords in list comprehensions
authorEkaterina Tuzova <Ekaterina.Tuzova@jetbrains.com>
Wed, 30 Oct 2013 09:26:40 +0000 (13:26 +0400)
committerEkaterina Tuzova <Ekaterina.Tuzova@jetbrains.com>
Wed, 30 Oct 2013 09:26:40 +0000 (13:26 +0400)
python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java
python/testSrc/com/jetbrains/python/PythonKeywordCompletionTest.java

index 1344f3daa02f920b4dde0536c5b9433a209947af..48bafdcf782cc9e730e6138695ccf650f6d4ee24 100644 (file)
@@ -293,9 +293,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
 
   private static final PsiElementPattern.Capture<PsiElement> IN_IMPORT_STMT =
     psiElement().inside(
-      StandardPatterns.or(
-        psiElement(PyImportStatement.class), psiElement(PyFromImportStatement.class)
-      )
+      or(psiElement(PyImportStatement.class), psiElement(PyFromImportStatement.class))
     );
 
   private static final PsiElementPattern.Capture<PsiElement> IN_PARAM_LIST = psiElement().inside(PyParameterList.class);
@@ -646,6 +644,24 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
     addExprElse();
     addRaiseFrom();
     addYieldFrom();
+    addToComprehensions();
+  }
+
+  private void addToComprehensions() {
+    extend(CompletionType.BASIC,
+           psiElement()
+             .withLanguage(PythonLanguage.getInstance())
+             .inside(psiElement(PySequenceExpression.class))
+             .andNot(psiElement().afterLeaf(or(psiElement(PyTokenTypes.LBRACE), psiElement(PyTokenTypes.LBRACKET), psiElement(PyTokenTypes.LPAR)))),
+           new PyKeywordCompletionProvider("for"));
+
+    extend(CompletionType.BASIC,
+           psiElement()
+             .withLanguage(PythonLanguage.getInstance())
+             .and(psiElement().inside(psiElement(PyComprehensionElement.class)))
+             .afterLeaf(psiElement().inside(psiElement(PyComprehensionElement.class)).and(psiElement().afterLeaf("for"))),
+           new PyKeywordCompletionProvider("in"));
+
   }
 
   private static class PyKeywordCompletionProvider extends CompletionProvider<CompletionParameters> {
index 241730f39f80e26b727ecef9c507a54d66568e5e..8280eff89e2256d6de6c5fb7d91787690d06eb3e 100644 (file)
@@ -168,4 +168,24 @@ public class PythonKeywordCompletionTest extends PyTestCase {
                             "    pass\n" +
                             "el<caret>").contains("else"));
   }
+
+  public void testForInComprehension() {  // PY-3687
+    assertContainsElements(doTestByText("L = [x fo<caret>]"), "for");
+    assertContainsElements(doTestByText("L = [x <caret>]"), "for");
+    assertContainsElements(doTestByText("L = [x <caret> x in y]"), "for");
+
+    assertDoesntContain(doTestByText("L = [<caret>]"), "for");
+    assertDoesntContain(doTestByText("L = [x for x <caret>]"), "for");
+    assertDoesntContain(doTestByText("L = [x for x <caret> in y]"), "for");
+  }
+
+  public void testInInComprehension() {  // PY-3687
+    assertContainsElements(doTestByText("L = [x for x <caret>]"), "in");
+    assertContainsElements(doTestByText("L = [x for x i<caret>]"), "in");
+    assertContainsElements(doTestByText("L = [x for x i<caret>n y]"), "in");
+
+    assertDoesntContain(doTestByText("L = [<caret>]"), "in");
+    assertDoesntContain(doTestByText("L = [x <caret> for]"), "in");
+    assertDoesntContain(doTestByText("L = [x <caret>]"), "in");
+  }
 }