groovy string select word2
authorMaxim Medvedev <maxim.medvedev@jetbrains.com>
Mon, 19 Oct 2009 11:07:35 +0000 (15:07 +0400)
committerMaxim Medvedev <maxim.medvedev@jetbrains.com>
Mon, 19 Oct 2009 11:11:47 +0000 (15:11 +0400)
plugins/groovy/src/META-INF/plugin.xml
plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyBasicSelectioner.java
plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyLiteralSelectioner.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/_GroovyLexer.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/groovy.flex
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStringUtil.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java
plugins/groovy/test/org/jetbrains/plugins/groovy/GroovyActionsTest.java
plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java
plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/StatementsParsingTest.groovy

index f4303914726163e9dad38371e295f235d39aec6c..14365b5142f4aecc51dcb192c202492fcdccaf3a 100644 (file)
 
     <indexPatternBuilder implementation="org.jetbrains.plugins.groovy.util.GroovyIndexPatternBuilder"/>
 
+    <basicWordSelectionFilter implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyWordSelectionFilter"/>
     <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyLiteralSelectioner"/>
     <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyBlockStatementsSelectioner"/>
     <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyTypeCastSelectioner"/>
     <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyDocParamsSelectioner"/>
     <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyArgListSelectioner"/>
+    <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyGStringSelectioner" order="before wordSelectioner"/>
+    <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyParameterListSelectioner"/>
 
     <methodReferencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.AccessorReferencesSearcher"/>
     <methodReferencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.MethodLateBoundReferencesSearcher"/>
index 3c3c5ee019c469e3ab50225241623a2675465162..1ad5ef95820fc83614aea787315e6da81b39441c 100644 (file)
 
 package org.jetbrains.plugins.groovy.editor.selection;
 
-import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandler;
+import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandlerBase;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.PsiElement;
-import com.intellij.util.text.CharArrayUtil;
 
-import java.util.ArrayList;
 import java.util.List;
 
 /**
  * @author ilyas
  */
-public abstract class GroovyBasicSelectioner implements ExtendWordSelectionHandler {
-
+public abstract class GroovyBasicSelectioner extends ExtendWordSelectionHandlerBase {
   public List<TextRange> select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) {
-
-    final TextRange originalRange = e.getTextRange();
-    List<TextRange> ranges = expandToWholeLine(editorText, originalRange, true);
-
-    if (ranges.size() == 1 && ranges.contains(originalRange)) {
-      ranges = expandToWholeLine(editorText, originalRange, false);
-    }
-
-    List<TextRange> result = new ArrayList<TextRange>();
-    result.addAll(ranges);
-    return result;
-  }
-
-  static List<TextRange> expandToWholeLine(CharSequence text, TextRange range, boolean isSymmetric) {
-    int textLength = text.length();
-    List<TextRange> result = new ArrayList<TextRange>();
-
-    if (range == null) {
-      return result;
-    }
-
-    boolean hasNewLines = false;
-
-    for (int i = range.getStartOffset(); i < range.getEndOffset(); i++) {
-      char c = text.charAt(i);
-
-      if (c == '\r' || c == '\n') {
-        hasNewLines = true;
-        break;
-      }
-    }
-
-    if (!hasNewLines) {
-      result.add(range);
-    }
-
-
-    int startOffset = range.getStartOffset();
-    int endOffset = range.getEndOffset();
-    int index1 = CharArrayUtil.shiftBackward(text, startOffset - 1, " \t");
-    if (endOffset > startOffset && text.charAt(endOffset - 1) == '\n' || text.charAt(endOffset - 1) == '\r') {
-      endOffset--;
-    }
-    int index2 = Math.min(textLength, CharArrayUtil.shiftForward(text, endOffset, " \t"));
-
-    if (index1 < 0
-        || text.charAt(index1) == '\n'
-        || text.charAt(index1) == '\r'
-        || index2 == textLength
-        || text.charAt(index2) == '\n'
-        || text.charAt(index2) == '\r') {
-
-      if (!isSymmetric) {
-        if (index1 < 0 || text.charAt(index1) == '\n' || text.charAt(index1) == '\r') {
-          startOffset = index1 + 1;
-        }
-
-        if (index2 == textLength || text.charAt(index2) == '\n' || text.charAt(index2) == '\r') {
-          endOffset = index2;
-          if (endOffset < textLength) {
-            endOffset++;
-            if (endOffset < textLength && text.charAt(endOffset - 1) == '\r' && text.charAt(endOffset) == '\n') {
-              endOffset++;
-            }
-          }
-        }
-
-        result.add(new TextRange(startOffset, endOffset));
-      } else {
-        if ((index1 < 0 || text.charAt(index1) == '\n' || text.charAt(index1) == '\r') &&
-            (index2 == textLength || text.charAt(index2) == '\n' || text.charAt(index2) == '\r')) {
-          startOffset = index1 + 1;
-          endOffset = index2;
-          if (endOffset < textLength) {
-            endOffset++;
-            if (endOffset < textLength && text.charAt(endOffset - 1) == '\r' && text.charAt(endOffset) == '\n') {
-              endOffset++;
-            }
-          }
-          result.add(new TextRange(startOffset, endOffset));
-        } else {
-          result.add(range);
-        }
-      }
-    } else {
-      result.add(range);
-    }
-
-    return result;
+    List<TextRange> ranges = super.select(e, editorText, cursorOffset, editor);
+    return ranges;
   }
-
-
 }
index 93c9bb2122449f8f7e364a40b5bdf0e68eafb7b8..bbeed25f2909ff4c1779f791e49b84e7b204fd71 100644 (file)
@@ -21,7 +21,9 @@ import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.PsiElement;
 import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
+import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mGSTRING_CONTENT;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
+import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
 
 import java.util.List;
 
@@ -40,19 +42,51 @@ public class GroovyLiteralSelectioner extends GroovyBasicSelectioner {
     if (node == null) return false;
     ASTNode[] children = node.getChildren(null);
     return children.length == 1 &&
-        (children[0].getElementType() == GroovyTokenTypes.mSTRING_LITERAL ||
+           (children[0].getElementType() == GroovyTokenTypes.mSTRING_LITERAL ||
             children[0].getElementType() == GroovyTokenTypes.mGSTRING_LITERAL);
   }
 
   public List<TextRange> select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) {
     List<TextRange> result = super.select(e, editorText, cursorOffset, editor);
 
-    TextRange range = e.getTextRange();
+/*    TextRange range = e.getTextRange();
     if (range.getLength() <= 2) {
       result.add(range);
-    } else {
+    }
+    else {
       result.add(new TextRange(range.getStartOffset() + 1, range.getEndOffset() - 1));
+    }*/
+
+    int startOffset = -1;
+    int endOffset = -1;
+    final String text = e.getText();
+    final int stringOffset = e.getTextOffset();
+    if (e.getNode().getElementType() == mGSTRING_CONTENT) {
+      int cur;
+      int index = -1;
+      while (true) {
+        cur = text.indexOf('\n', index + 1);
+        if (cur < 0 || cur + stringOffset > cursorOffset) break;
+        index = cur;
+      }
+      if (index >= 0) {
+        startOffset = stringOffset + index + 1;
+      }
+
+      index = text.indexOf('\n', cursorOffset - stringOffset);
+      if (index >= 0) {
+        endOffset = stringOffset + index + 1;
+      }
     }
+
+    if (startOffset >= 0 && endOffset >= 0) {
+      result.add(new TextRange(startOffset, endOffset));
+    }
+
+    final String content = GrStringUtil.removeQuotes(text);
+
+    final int offset = stringOffset + text.indexOf(content);
+    result.add(new TextRange(offset, offset + content.length()));
     return result;
   }
 }
\ No newline at end of file
index 6c340cedc376cbdc5459960875163986c2d08e8d..5cf550ac1c35f2f4a586fda9f9f8204e45850661 100644 (file)
@@ -1,4 +1,4 @@
-/* The following code was generated by JFlex 1.4.1 on 12.10.09 13:24 */
+/* The following code was generated by JFlex 1.4.1 on 15.10.09 16:49 */
 
 /*
  * Copyright 2000-2007 JetBrains s.r.o.
@@ -19,14 +19,15 @@ package org.jetbrains.plugins.groovy.lang.lexer;
 
 import com.intellij.lexer.FlexLexer;
 import com.intellij.psi.tree.IElementType;
-
-import java.util.Stack;
+import java.util.*;
+import java.lang.reflect.Field;
+import org.jetbrains.annotations.NotNull;
 
 
 /**
  * This class is a scanner generated by 
  * <a href="http://www.jflex.de/">JFlex</a> 1.4.1
- * on 12.10.09 13:24 from the specification file
+ * on 15.10.09 16:49 from the specification file
  * <tt>groovy.flex</tt>
  */
 public class _GroovyLexer implements FlexLexer, GroovyTokenTypes {
@@ -213,7 +214,7 @@ public class _GroovyLexer implements FlexLexer, GroovyTokenTypes {
     "\0\u0460\0\u04a6\0\u04ec\0\u0532\0\u0578\0\u05be\0\u0604\0\u064a"+
     "\0\u0690\0\u06d6\0\u0690\0\u071c\0\u0762\0\u07a8\0\u07ee\0\u0834"+
     "\0\u087a\0\u08c0\0\u0906\0\u094c\0\u0992\0\u09d8\0\u0a1e\0\u0a64"+
-    "\0\u0aaa\0\u0af0\0\u0b36\0\u0690\0\u0b7c\0\u0bc2\0\u0c08\0\u0c4e"+
+    "\0\u0aaa\0\u0af0\0\u0b36\0\u087a\0\u0b7c\0\u0bc2\0\u0c08\0\u0c4e"+
     "\0\u0c94\0\u0cda\0\u0690\0\u0690\0\u0d20\0\u0d66\0\u0690\0\u0690"+
     "\0\u0690\0\u0690\0\u0690\0\u0690\0\u0dac\0\u0df2\0\u0690\0\u0e38"+
     "\0\u0e7e\0\u0ec4\0\u0f0a\0\u0690\0\u0690\0\u0f50\0\u0f96\0\u0fdc"+
@@ -762,23 +763,22 @@ public class _GroovyLexer implements FlexLexer, GroovyTokenTypes {
   private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
 
   private static final String ZZ_ATTRIBUTE_PACKED_0 =
-    "\21\0\1\1\6\0\1\11\1\1\1\11\20\1\1\11"+
-    "\6\1\2\11\2\1\6\11\2\1\1\11\4\1\2\11"+
-    "\6\1\1\11\1\1\2\11\1\1\1\11\2\1\1\0"+
-    "\2\11\1\7\1\1\1\11\1\1\2\3\1\11\1\1"+
-    "\1\11\2\1\2\11\2\1\3\11\1\1\1\11\2\1"+
-    "\5\11\5\1\1\11\2\1\1\11\1\1\1\11\1\3"+
-    "\1\11\3\1\1\11\1\1\1\11\1\1\1\0\3\1"+
-    "\1\11\1\1\2\11\1\1\6\11\2\0\15\1\5\11"+
-    "\1\0\1\1\1\11\11\1\2\0\2\1\1\0\1\1"+
-    "\2\11\1\1\1\11\1\1\1\0\1\11\1\0\6\11"+
-    "\21\1\1\0\2\1\2\5\3\0\2\1\1\0\3\1"+
-    "\2\0\3\1\1\5\1\0\2\1\1\11\1\1\1\0"+
-    "\17\1\2\11\14\1\1\11\1\1\1\11\1\1\4\11"+
-    "\1\0\25\1\2\11\1\0\10\1\2\11\30\1\3\0"+
-    "\1\1\1\0\1\11\24\1\1\15\1\0\5\1\1\11"+
-    "\1\0\21\1\2\0\1\1\1\0\24\1\1\0\15\1"+
-    "\2\0\63\1";
+    "\21\0\1\1\6\0\1\11\1\1\1\11\27\1\2\11"+
+    "\2\1\6\11\2\1\1\11\4\1\2\11\6\1\1\11"+
+    "\1\1\2\11\1\1\1\11\2\1\1\0\2\11\1\7"+
+    "\1\1\1\11\1\1\2\3\1\11\1\1\1\11\2\1"+
+    "\2\11\2\1\3\11\1\1\1\11\2\1\5\11\5\1"+
+    "\1\11\2\1\1\11\1\1\1\11\1\3\1\11\3\1"+
+    "\1\11\1\1\1\11\1\1\1\0\3\1\1\11\1\1"+
+    "\2\11\1\1\6\11\2\0\15\1\5\11\1\0\1\1"+
+    "\1\11\11\1\2\0\2\1\1\0\1\1\2\11\1\1"+
+    "\1\11\1\1\1\0\1\11\1\0\6\11\21\1\1\0"+
+    "\2\1\2\5\3\0\2\1\1\0\3\1\2\0\3\1"+
+    "\1\5\1\0\2\1\1\11\1\1\1\0\17\1\2\11"+
+    "\14\1\1\11\1\1\1\11\1\1\4\11\1\0\25\1"+
+    "\2\11\1\0\10\1\2\11\30\1\3\0\1\1\1\0"+
+    "\1\11\24\1\1\15\1\0\5\1\1\11\1\0\21\1"+
+    "\2\0\1\1\1\0\24\1\1\0\15\1\2\0\63\1";
 
   private static int [] zzUnpackAttribute() {
     int [] result = new int[482];
index a1b31116d588e64aea86b3d0ad423845d4289f58..b9973b69465ca1b7e00d09028042814c691e83b6 100644 (file)
@@ -125,7 +125,7 @@ mNUM_BIG_DECIMAL = {mNUM_INT_PART} ( ("." {mDIGIT}+ {mEXPONENT}? {mBIG_SUFFIX}?)
 
 mLETTER = [:letter:] | "_"
 
-mIDENT = {mLETTER} ({mLETTER} | {mDIGIT} | \$)*
+mIDENT = ({mLETTER}|\$) ({mLETTER} | {mDIGIT} | \$)*
 mIDENT_NOBUCKS = {mLETTER} ({mLETTER} | {mDIGIT})*
 
 
index 023b7eb84a170f54c54bb8bbba51be082e959297..3fed2f69db3e021d7adb09b34f9d2b1597735506 100644 (file)
@@ -137,10 +137,6 @@ public class GrModifierListImpl extends GroovyPsiElementImpl implements GrModifi
       }
     }
 
-    if (parent instanceof GrTypeDefinition && PsiModifier.STATIC.equals(modifier)) {
-      if (((GrTypeDefinition)parent).getContainingClass() == null) return true;
-    }
-
     return false;
   }
 
index c1d417a185726a0d8882f12a256dc302c58cea37..3fa3e885f47dfd9f6c8c9321d9db88e281cc61b9 100644 (file)
@@ -234,7 +234,8 @@ public class GrStringUtil {
         final GrClosableBlock closableBlock = ((GrStringInjection)child).getClosableBlock();
         final GrReferenceExpression refExpr = (GrReferenceExpression)closableBlock.getStatements()[0];
         final GrReferenceExpression copy = (GrReferenceExpression)refExpr.copy();
-        closableBlock.replace(copy);
+        final ASTNode oldNode = closableBlock.getNode();
+        oldNode.getTreeParent().replaceChild(oldNode, copy.getNode());
       }
     }
   }
index 4d7a1720aee353d9a3ff1c164a0d1408d20f9aa5..10e86375ff713c5e324fd049c6271f419a81cc50 100644 (file)
@@ -423,7 +423,7 @@ public class PsiUtil {
         if (qualifier != null) {
           if (qualifier instanceof GrReferenceExpression) {
             PsiElement qualifierResolved = ((GrReferenceExpression)qualifier).resolve();
-            if (qualifierResolved instanceof PsiClass) { //static context
+            if (qualifierResolved instanceof PsiClass || qualifierResolved instanceof PsiPackage) { //static context
               if (owner instanceof PsiClass) {
                 return true;
               }
index f4314edbf9ae31c80ea1f5977afd7325a8e13253..24fb8d43f5a4db09a16d57ddd49cde6443a15ddf 100644 (file)
@@ -33,8 +33,22 @@ public class GroovyActionsTest extends LightCodeInsightFixtureTestCase {
   }
 
   public void testSelectWordBeforeMethod() throws Throwable {
+    doTestForSelectWord(1);
+  }
+
+  public void testSWInGString1() throws Exception {doTestForSelectWord(1);}
+  public void testSWInGString2() throws Exception {doTestForSelectWord(2);}
+  public void testSWInGString3() throws Exception {doTestForSelectWord(3);}
+  public void testSWInGString4() throws Exception {doTestForSelectWord(4);}
+  public void testSWInGString5() throws Exception {doTestForSelectWord(5);}
+  public void testSWInParameterList() throws Exception {doTestForSelectWord(3);}
+
+  private void doTestForSelectWord(int count) throws Exception {
     myFixture.configureByFile(getTestName(false) + ".groovy");
-    performEditorAction(IdeActions.ACTION_EDITOR_SELECT_WORD_AT_CARET);
+    myFixture.getEditor().getSettings().setCamelWords(true);
+    for (int i = 0; i < count; i++) {
+      performEditorAction(IdeActions.ACTION_EDITOR_SELECT_WORD_AT_CARET);
+    }
     myFixture.checkResultByFile(getTestName(false) + "_after.groovy");
   }
 
index 3acf1083f2dbbac44ec9959bf53facc142d9494d..971ba82df0e177ab16422c01198899ccd652c005 100644 (file)
@@ -183,4 +183,8 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase {
   }
 
   public void testRawOverridedMethod() throws Exception {doTest();}
+
+  public void testFQNJavaClassesUsages() throws Exception {
+    doTest();
+  }
 }
\ No newline at end of file
index b9e52452fa7ae7a0321f2a62d1540144047ee5d0..dafbff39ca18d54362ef6e0a528c7f57c98bfd29 100644 (file)
@@ -42,6 +42,7 @@ public class StatementsParsingTest extends GroovyParsingTestCase {
   public void testDeclaration$decl7() throws Throwable { doTest(); }
   public void testDeclaration$decl8() throws Throwable { doTest(); }
   public void testDeclaration$decl9() throws Throwable { doTest(); }
+  public void testDeclaration$dollar() throws Throwable {doTest();}
   public void testDeclaration$groovyMain() throws Throwable { doTest(); }
   public void testDeclaration$GRVY1451() throws Throwable { doTest("declaration/GRVY-1451.test"); }
   public void testDeclaration$methodCallAsMultiDecl() throws Throwable { doTest(); }