don't insert a space after a keyword if there's already one
authorpeter <peter@jetbrains.com>
Thu, 5 Jan 2012 12:32:53 +0000 (13:32 +0100)
committerpeter <peter@jetbrains.com>
Thu, 5 Jan 2012 19:38:46 +0000 (20:38 +0100)
java/java-impl/src/com/intellij/codeInsight/completion/Java15CompletionData.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaAwareCompletionData.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/ExtendsWithRightContextInClassTypeParameters-out.java
java/java-tests/testData/codeInsight/completion/keywords/extends-8-result.java
java/java-tests/testData/codeInsight/completion/keywords/methodScope-5-out.java
java/java-tests/testData/codeInsight/completion/normal/FieldType_after.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 6559888c789826111beb123a7cda8088477eae57..f539c346b66204b464137a37686673fdeb71f5cc 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.INSERT_SPACE);
+      variant.addCompletion(PsiKeyword.STATIC, TailType.HUMBLE_SPACE);
 
       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.INSERT_SPACE);
+      variant.addCompletion(PsiKeyword.INTERFACE, TailType.HUMBLE_SPACE);
 
       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.INSERT_SPACE);
+      variant.addCompletion(PsiKeyword.ENUM, TailType.HUMBLE_SPACE);
       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.INSERT_SPACE);
-      variant.addCompletion(PsiKeyword.EXTENDS, TailType.INSERT_SPACE);
+      variant.addCompletion(PsiKeyword.SUPER, TailType.HUMBLE_SPACE);
+      variant.addCompletion(PsiKeyword.EXTENDS, TailType.HUMBLE_SPACE);
       registerVariant(variant);
     }
   }
index ac1aa851c6338d8ae4692ea1eca9045fb6879b51..37a648bbb14db60bf7afd3c38af2aa9669ed4afa 100644 (file)
@@ -51,7 +51,7 @@ public class JavaAwareCompletionData extends CompletionData{
         if (context.shouldAddCompletionChar()) {
           return;
         }
-        if (tailType != TailType.NONE) {
+        if (tailType != TailType.NONE && tailType.isApplicable(context)) {
           tailType.processTail(context.getEditor(), context.getTailOffset());
         }
       }
index af1f43bc578abb438befc01844546779e0de5bd9..78d73295c387d5d5813fff51039567e805e91e6b 100644 (file)
@@ -210,7 +210,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
 // package keyword completion
     {
       final CompletionVariant variant = new CompletionVariant(PsiJavaFile.class, new StartElementFilter());
-      variant.addCompletion(PsiKeyword.PACKAGE);
+      variant.addCompletion(PsiKeyword.PACKAGE, TailType.INSERT_SPACE);
       registerVariant(variant);
     }
 
@@ -271,7 +271,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
 // completion
       final CompletionVariant variant = new CompletionVariant(position);
       variant.includeScopeClass(PsiClass.class, true);
-      variant.addCompletion(PsiKeyword.EXTENDS, TailType.INSERT_SPACE);
+      variant.addCompletion(PsiKeyword.EXTENDS, TailType.HUMBLE_SPACE);
       variant.excludeScopeClass(PsiAnonymousClass.class);
       variant.excludeScopeClass(PsiTypeParameter.class);
 
@@ -292,7 +292,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
 // completion
       final CompletionVariant variant = new CompletionVariant(position);
       variant.includeScopeClass(PsiClass.class, true);
-      variant.addCompletion(PsiKeyword.IMPLEMENTS, TailType.INSERT_SPACE);
+      variant.addCompletion(PsiKeyword.IMPLEMENTS, TailType.HUMBLE_SPACE);
       variant.excludeScopeClass(PsiAnonymousClass.class);
 
       registerVariant(variant);
@@ -304,7 +304,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.INSERT_SPACE);
+      variant.addCompletion(PsiKeyword.EXTENDS, TailType.HUMBLE_SPACE);
       registerVariant(variant);
     }
   }
@@ -412,7 +412,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
           return TailType.SEMICOLON;
         }
 
-        return TailType.INSERT_SPACE;
+        return TailType.HUMBLE_SPACE;
       }
       scope = scope.getParent();
     }
@@ -454,7 +454,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.INSERT_SPACE));
+        result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.FINAL), TailType.HUMBLE_SPACE));
       }
     }
 
@@ -506,13 +506,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.INSERT_SPACE));
+      result.addElement(TailTypeDecorator.withTail(createKeyword(position, PsiKeyword.FINAL), TailType.HUMBLE_SPACE));
     }
 
     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.INSERT_SPACE));
+        result.addElement(new OverrideableSpace(createKeyword(position, s), TailType.HUMBLE_SPACE));
       }
     }
 
@@ -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.INSERT_SPACE));
+        result.addElement(inCast ? keyword : new OverrideableSpace(keyword, TailType.HUMBLE_SPACE));
       }
     }
     if (declaration) {
-      result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.VOID), TailType.INSERT_SPACE));
+      result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.VOID), TailType.HUMBLE_SPACE));
     }
   }
 
index 511a8529c357cd91895bde1624e25f7f28773817..ee310b9cc7e05d1b580a6e7bed63331e0e9834ce 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.INSERT_SPACE));
+              result.addElement(TailTypeDecorator.withTail(new JavaPsiClassReferenceElement(exception), TailType.HUMBLE_SPACE));
             }
           }
         }
@@ -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.INSERT_SPACE));
+          result.addElement(TailTypeDecorator.withTail(PsiTypeLookupItem.createLookupItem(type, tryBlock).setInsertHandler(new DefaultInsertHandler()), TailType.HUMBLE_SPACE));
         }
       }
     });
index 46fe4caea6dc8b93eda2d95298eff2a0df9e85ab..cfcb2504f90365f23da84f4f8d3088ac9dd99f53 100644 (file)
@@ -1,4 +1,4 @@
 class AAA{}
 
-class BBB extends AAA implements <caret> {
+class BBB extends AAA implements<caret> {
 }
index 26fd20c10a04a01cec3a37e711372462f00216c5..5ee694dc44d2079a4a5494d499167e89cadfae3b 100644 (file)
@@ -1,5 +1,5 @@
 public class A{
- public void method(final <caret> String){
+ public void method(final<caret> String){
   
  }
 }
index a5209a87c6871042b32501c1818e2f78262abfd5..172e9db8387900305c8e511bd72dc07526d55b4a 100644 (file)
@@ -1,4 +1,4 @@
 class A {
-    private long <caret> localizedStringManager;
+    private long<caret> localizedStringManager;
 
 }
index cc177dfb0cedb3cb04ac7f214682fb7737d503e8..10ece49eb3f2a8d7d9da76c3709173ff913df3bf 100644 (file)
@@ -87,8 +87,33 @@ public abstract class TailType {
       return "COMMA";
     }
   };
+  /**
+   * insert a space, overtype if already present
+   */
   public static final TailType SPACE = new CharTailType(' ');
+  /**
+   * always insert a space
+   */
   public static final TailType INSERT_SPACE = new CharTailType(' ', false);
+  /**
+   * insert a space unless there's one at the caret position already
+   */
+  public static final TailType HUMBLE_SPACE = new CharTailType(' ', false) {
+
+    @Override
+    public boolean isApplicable(@NotNull InsertionContext context) {
+      CharSequence text = context.getDocument().getCharsSequence();
+      if (text.length() > context.getTailOffset() && text.charAt(context.getTailOffset()) == ' ') {
+        return false;
+      }
+      return super.isApplicable(context);
+    }
+
+    @Override
+    public String toString() {
+      return "HUMBLE_SPACE";
+    }
+  };
   public static final TailType DOT = new CharTailType('.');
 
   public static final TailType CASE_COLON = new CharTailType(':');
index 481456ce95c8a9c967210ce229d77c47a2630db6..4575552beb155d87b61a57585e15faa3d96f8711 100644 (file)
@@ -85,19 +85,21 @@ public class GroovyCompletionData {
 
       addTypeDefinitionKeywords(result, position);
       for (String keyword : addExtendsImplements(position)) {
-        result.addElement(keyword(keyword, TailType.INSERT_SPACE));
+        result.addElement(keyword(keyword, TailType.HUMBLE_SPACE));
       }
 
       registerControlCompletion(position, result);
 
       if (parent instanceof GrExpression) {
-        addKeywords(result, false, PsiKeyword.TRUE, PsiKeyword.FALSE, PsiKeyword.NULL, PsiKeyword.SUPER, PsiKeyword.NEW, PsiKeyword.THIS, "as");
+        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));
       }
 
       if (isInfixOperatorPosition(position)) {
         addKeywords(result, true, "in", PsiKeyword.INSTANCEOF);
       } else if (suggestThrows(position)) {
-        addKeywords(result, true, PsiKeyword.THROWS);
+        result.addElement(keyword(PsiKeyword.THROWS, TailType.INSERT_SPACE));
       } else if (suggestPrimitiveTypes(position)) {
         boolean inCast = psiElement()
           .afterLeaf(psiElement().withText("(").withParent(psiElement(GrParenthesizedExpression.class, GrTypeCastExpression.class)))
@@ -144,7 +146,7 @@ public class GroovyCompletionData {
       addKeywords(result, true, PsiKeyword.CLASS, PsiKeyword.INTERFACE, PsiKeyword.ENUM);
     }
     if (afterAtInType(position)) {
-      result.addElement(keyword(PsiKeyword.INTERFACE, TailType.INSERT_SPACE));
+      result.addElement(keyword(PsiKeyword.INTERFACE, TailType.HUMBLE_SPACE));
     }
   }
 
@@ -185,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.INSERT_SPACE : TailType.NONE));
+      result.addElement(keyword(s, space ? TailType.HUMBLE_SPACE : TailType.NONE));
     }
   }
 
index c14cbc698efeb3680b8a143f77db8eba6853bda7..10d443c28edc136232885ceae88aa06f7b0eb4fe 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() {
@@ -1114,8 +1114,8 @@ 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> {}'
+    checkCompletion 'class A <caret> ArrayList {}', '\n', 'class A extends<caret> ArrayList {}'
+    checkSingleItemCompletion 'class Foo impl<caret> {}', 'class Foo implements<caret> {}'
   }
 
   public void testPreferInterfacesInImplements() {