IDEA-79862 Java: auto-insert space after completing "extends" and "implements"
authorpeter <peter@jetbrains.com>
Wed, 1 Feb 2012 17:58:58 +0000 (18:58 +0100)
committerpeter <peter@jetbrains.com>
Wed, 1 Feb 2012 19:56:01 +0000 (20:56 +0100)
java/java-impl/src/com/intellij/codeInsight/completion/Java15CompletionData.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
java/java-tests/testData/codeInsight/completion/keywords/extends-8-result.java
platform/lang-api/src/com/intellij/codeInsight/TailType.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java
plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy

index f539c346b66204b464137a37686673fdeb71f5cc..92a4c9dc5aa3616345fa913909f85f866de63738 100644 (file)
@@ -31,7 +31,7 @@ public class Java15CompletionData extends JavaCompletionData {
     //static keyword in static import
     {
       final CompletionVariant variant = new CompletionVariant(PsiImportList.class, new LeftNeighbour(new TextFilter (PsiKeyword.IMPORT)));
-      variant.addCompletion(PsiKeyword.STATIC, TailType.HUMBLE_SPACE);
+      variant.addCompletion(PsiKeyword.STATIC, TailType.HUMBLE_SPACE_BEFORE_WORD);
 
       registerVariant(variant);
     }
@@ -46,7 +46,7 @@ public class Java15CompletionData extends JavaCompletionData {
       final CompletionVariant variant = new CompletionVariant(PsiJavaFile.class, position);
       variant.includeScopeClass(PsiClass.class);
 
-      variant.addCompletion(PsiKeyword.INTERFACE, TailType.HUMBLE_SPACE);
+      variant.addCompletion(PsiKeyword.INTERFACE, TailType.HUMBLE_SPACE_BEFORE_WORD);
 
       registerVariant(variant);
     }
@@ -55,7 +55,7 @@ public class Java15CompletionData extends JavaCompletionData {
       final CompletionVariant variant = new CompletionVariant(PsiJavaFile.class, CLASS_START);
       variant.includeScopeClass(PsiClass.class);
 
-      variant.addCompletion(PsiKeyword.ENUM, TailType.HUMBLE_SPACE);
+      variant.addCompletion(PsiKeyword.ENUM, TailType.HUMBLE_SPACE_BEFORE_WORD);
       registerVariant(variant);
     }
 
@@ -68,8 +68,8 @@ public class Java15CompletionData extends JavaCompletionData {
       final CompletionVariant variant = new CompletionVariant(JavaMemberNameCompletionContributor.INSIDE_TYPE_PARAMS_PATTERN);
       variant.includeScopeClass(PsiVariable.class, true);
       variant.includeScopeClass(PsiExpressionStatement.class, true);
-      variant.addCompletion(PsiKeyword.SUPER, TailType.HUMBLE_SPACE);
-      variant.addCompletion(PsiKeyword.EXTENDS, TailType.HUMBLE_SPACE);
+      variant.addCompletion(PsiKeyword.SUPER, TailType.HUMBLE_SPACE_BEFORE_WORD);
+      variant.addCompletion(PsiKeyword.EXTENDS, TailType.HUMBLE_SPACE_BEFORE_WORD);
       registerVariant(variant);
     }
   }
index 5d9d2a0155a4b9738de5f8fca88c4a5f8950bd75..276a5a2cdc8b43fe5db3de0f0a9ae753b4a19ac9 100644 (file)
@@ -273,7 +273,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
 // completion
       final CompletionVariant variant = new CompletionVariant(position);
       variant.includeScopeClass(PsiClass.class, true);
-      variant.addCompletion(PsiKeyword.EXTENDS, TailType.HUMBLE_SPACE);
+      variant.addCompletion(PsiKeyword.EXTENDS, TailType.HUMBLE_SPACE_BEFORE_WORD);
       variant.excludeScopeClass(PsiAnonymousClass.class);
       variant.excludeScopeClass(PsiTypeParameter.class);
 
@@ -294,7 +294,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
 // completion
       final CompletionVariant variant = new CompletionVariant(position);
       variant.includeScopeClass(PsiClass.class, true);
-      variant.addCompletion(PsiKeyword.IMPLEMENTS, TailType.HUMBLE_SPACE);
+      variant.addCompletion(PsiKeyword.IMPLEMENTS, TailType.HUMBLE_SPACE_BEFORE_WORD);
       variant.excludeScopeClass(PsiAnonymousClass.class);
 
       registerVariant(variant);
@@ -306,7 +306,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
           psiElement(PsiIdentifier.class).afterLeaf(
             psiElement().withText(string().oneOf(",", "<")).withParent(PsiTypeParameterList.class))));
       //variant.includeScopeClass(PsiClass.class, true);
-      variant.addCompletion(PsiKeyword.EXTENDS, TailType.HUMBLE_SPACE);
+      variant.addCompletion(PsiKeyword.EXTENDS, TailType.HUMBLE_SPACE_BEFORE_WORD);
       registerVariant(variant);
     }
   }
@@ -414,7 +414,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
           return TailType.SEMICOLON;
         }
 
-        return TailType.HUMBLE_SPACE;
+        return TailType.HUMBLE_SPACE_BEFORE_WORD;
       }
       scope = scope.getParent();
     }
@@ -456,7 +456,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
     }
     if (statement != null && statement.getTextRange().getStartOffset() == position.getTextRange().getStartOffset()) {
       if (!psiElement().withSuperParent(2, PsiSwitchStatement.class).accepts(statement)) {
-        result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.FINAL), TailType.HUMBLE_SPACE));
+        result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.FINAL), TailType.HUMBLE_SPACE_BEFORE_WORD));
       }
     }
 
@@ -508,13 +508,13 @@ public class JavaCompletionData extends JavaAwareCompletionData{
     }
 
     if (INSIDE_PARAMETER_LIST.accepts(position) && !psiElement().afterLeaf(PsiKeyword.FINAL).accepts(position) && !AFTER_DOT.accepts(position)) {
-      result.addElement(TailTypeDecorator.withTail(createKeyword(position, PsiKeyword.FINAL), TailType.HUMBLE_SPACE));
+      result.addElement(TailTypeDecorator.withTail(createKeyword(position, PsiKeyword.FINAL), TailType.HUMBLE_SPACE_BEFORE_WORD));
     }
 
     if (CLASS_START.isAcceptable(position, position) &&
         PsiTreeUtil.getNonStrictParentOfType(position, PsiLiteralExpression.class, PsiComment.class) == null) {
       for (String s : ModifierChooser.getKeywords(position)) {
-        result.addElement(new OverrideableSpace(createKeyword(position, s), TailType.HUMBLE_SPACE));
+        result.addElement(new OverrideableSpace(createKeyword(position, s), TailType.HUMBLE_SPACE_BEFORE_WORD));
       }
     }
 
@@ -589,11 +589,11 @@ public class JavaCompletionData extends JavaAwareCompletionData{
         isStatementPosition(position)) {
       for (String primitiveType : PRIMITIVE_TYPES) {
         LookupElement keyword = createKeyword(position, primitiveType);
-        result.addElement(inCast ? keyword : new OverrideableSpace(keyword, TailType.HUMBLE_SPACE));
+        result.addElement(inCast ? keyword : new OverrideableSpace(keyword, TailType.HUMBLE_SPACE_BEFORE_WORD));
       }
     }
     if (declaration) {
-      result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.VOID), TailType.HUMBLE_SPACE));
+      result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.VOID), TailType.HUMBLE_SPACE_BEFORE_WORD));
     }
   }
 
@@ -606,7 +606,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
     if (psiElement().insideSequence(true, psiElement(PsiLabeledStatement.class),
                                     or(psiElement(PsiFile.class), psiElement(PsiMethod.class),
                                        psiElement(PsiClassInitializer.class))).accepts(position)) {
-      tailType = TailType.HUMBLE_SPACE;
+      tailType = TailType.HUMBLE_SPACE_BEFORE_WORD;
     }
     else {
       tailType = TailType.SEMICOLON;
index ee310b9cc7e05d1b580a6e7bed63331e0e9834ce..649a4ed6e7ff973314b51e7711e14639fa5c01fa 100644 (file)
@@ -264,7 +264,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
           for (PsiClassType ref : method.getThrowsList().getReferencedTypes()) {
             final PsiClass exception = ref.resolve();
             if (exception != null && throwsSet.add(exception)) {
-              result.addElement(TailTypeDecorator.withTail(new JavaPsiClassReferenceElement(exception), TailType.HUMBLE_SPACE));
+              result.addElement(TailTypeDecorator.withTail(new JavaPsiClassReferenceElement(exception), TailType.HUMBLE_SPACE_BEFORE_WORD));
             }
           }
         }
@@ -282,7 +282,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
         if (tryBlock == null) return;
 
         for (final PsiClassType type : ExceptionUtil.getThrownExceptions(tryBlock.getStatements())) {
-          result.addElement(TailTypeDecorator.withTail(PsiTypeLookupItem.createLookupItem(type, tryBlock).setInsertHandler(new DefaultInsertHandler()), TailType.HUMBLE_SPACE));
+          result.addElement(TailTypeDecorator.withTail(PsiTypeLookupItem.createLookupItem(type, tryBlock).setInsertHandler(new DefaultInsertHandler()), TailType.HUMBLE_SPACE_BEFORE_WORD));
         }
       }
     });
index cfcb2504f90365f23da84f4f8d3088ac9dd99f53..46fe4caea6dc8b93eda2d95298eff2a0df9e85ab 100644 (file)
@@ -1,4 +1,4 @@
 class AAA{}
 
-class BBB extends AAA implements<caret> {
+class BBB extends AAA implements <caret> {
 }
index 10ece49eb3f2a8d7d9da76c3709173ff913df3bf..a4b31b7eb817df88976a5aee0138df87d7515461 100644 (file)
@@ -96,14 +96,15 @@ public abstract class TailType {
    */
   public static final TailType INSERT_SPACE = new CharTailType(' ', false);
   /**
-   * insert a space unless there's one at the caret position already
+   * insert a space unless there's one at the caret position already, followed by a sowrd
    */
-  public static final TailType HUMBLE_SPACE = new CharTailType(' ', false) {
+  public static final TailType HUMBLE_SPACE_BEFORE_WORD = new CharTailType(' ', false) {
 
     @Override
     public boolean isApplicable(@NotNull InsertionContext context) {
       CharSequence text = context.getDocument().getCharsSequence();
-      if (text.length() > context.getTailOffset() && text.charAt(context.getTailOffset()) == ' ') {
+      int tail = context.getTailOffset();
+      if (text.length() > tail + 1 && text.charAt(tail) == ' ' && Character.isLetter(text.charAt(tail + 1))) {
         return false;
       }
       return super.isApplicable(context);
@@ -111,7 +112,7 @@ public abstract class TailType {
 
     @Override
     public String toString() {
-      return "HUMBLE_SPACE";
+      return "HUMBLE_SPACE_BEFORE_WORD";
     }
   };
   public static final TailType DOT = new CharTailType('.');
index 4575552beb155d87b61a57585e15faa3d96f8711..67504d48865e96df3c148704162cdf7f675a58a7 100644 (file)
@@ -85,7 +85,7 @@ public class GroovyCompletionData {
 
       addTypeDefinitionKeywords(result, position);
       for (String keyword : addExtendsImplements(position)) {
-        result.addElement(keyword(keyword, TailType.HUMBLE_SPACE));
+        result.addElement(keyword(keyword, TailType.HUMBLE_SPACE_BEFORE_WORD));
       }
 
       registerControlCompletion(position, result);
@@ -93,7 +93,7 @@ public class GroovyCompletionData {
       if (parent instanceof GrExpression) {
         addKeywords(result, false, PsiKeyword.TRUE, PsiKeyword.FALSE, PsiKeyword.NULL, PsiKeyword.SUPER, PsiKeyword.THIS);
         result.addElement(keyword(PsiKeyword.NEW, TailType.INSERT_SPACE));
-        result.addElement(keyword("as", TailType.HUMBLE_SPACE));
+        result.addElement(keyword("as", TailType.HUMBLE_SPACE_BEFORE_WORD));
       }
 
       if (isInfixOperatorPosition(position)) {
@@ -146,7 +146,7 @@ public class GroovyCompletionData {
       addKeywords(result, true, PsiKeyword.CLASS, PsiKeyword.INTERFACE, PsiKeyword.ENUM);
     }
     if (afterAtInType(position)) {
-      result.addElement(keyword(PsiKeyword.INTERFACE, TailType.HUMBLE_SPACE));
+      result.addElement(keyword(PsiKeyword.INTERFACE, TailType.HUMBLE_SPACE_BEFORE_WORD));
     }
   }
 
@@ -187,7 +187,7 @@ public class GroovyCompletionData {
 
   public static void addKeywords(CompletionResultSet result, boolean space, String... keywords) {
     for (String s : keywords) {
-      result.addElement(keyword(s, space ? TailType.HUMBLE_SPACE : TailType.NONE));
+      result.addElement(keyword(s, space ? TailType.HUMBLE_SPACE_BEFORE_WORD : TailType.NONE));
     }
   }
 
index 10d443c28edc136232885ceae88aa06f7b0eb4fe..94794bebd83b7fbcf4303e43b033fba75462f105 100644 (file)
@@ -1064,7 +1064,7 @@ class X {
   }
 
   public void testInnerClassStart() {
-    checkSingleItemCompletion 'class Foo { cl<caret> }', 'class Foo { class<caret> }'
+    checkSingleItemCompletion 'class Foo { cl<caret> }', 'class Foo { class <caret> }'
   }
 
   public void testPropertyBeforeAccessor() {
@@ -1115,7 +1115,7 @@ public class KeyVO {
   public void testSpaceTail() {
     checkCompletion 'class A <caret> ArrayList {}', ' ', 'class A extends <caret> ArrayList {}'
     checkCompletion 'class A <caret> ArrayList {}', '\n', 'class A extends<caret> ArrayList {}'
-    checkSingleItemCompletion 'class Foo impl<caret> {}', 'class Foo implements<caret> {}'
+    checkSingleItemCompletion 'class Foo impl<caret> {}', 'class Foo implements <caret> {}'
   }
 
   public void testPreferInterfacesInImplements() {