Proper word selection inside string literals in JSON

This commit is contained in:
Mikhail Golubev
2014-09-19 16:41:55 +04:00
parent 3a5cc28e01
commit 47df72b32c
8 changed files with 85 additions and 0 deletions
@@ -0,0 +1,15 @@
package com.intellij.json.editor.selection;
import com.intellij.json.JsonParserDefinition;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiElement;
/**
* @author Mikhail Golubev
*/
public class JsonBasicWordSelectionFilter implements Condition<PsiElement> {
@Override
public boolean value(PsiElement element) {
return !(JsonParserDefinition.STRING_LITERALS.contains(element.getNode().getElementType()));
}
}
@@ -0,0 +1,39 @@
package com.intellij.json.editor.selection;
import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandlerBase;
import com.intellij.codeInsight.editorActions.SelectWordUtil;
import com.intellij.json.JsonParserDefinition;
import com.intellij.json.psi.JsonStringLiteral;
import com.intellij.lexer.StringLiteralLexer;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import java.util.ArrayList;
import java.util.List;
import static com.intellij.json.JsonElementTypes.SINGLE_QUOTED_STRING;
/**
* @author Mikhail Golubev
*/
public class JsonStringLiteralSelectionHandler extends ExtendWordSelectionHandlerBase {
@Override
public boolean canSelect(PsiElement e) {
return JsonParserDefinition.STRING_LITERALS.contains(e.getNode().getElementType());
}
@Override
public List<TextRange> select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) {
final PsiElement parent = e.getParent();
assert parent instanceof JsonStringLiteral;
final IElementType type = e.getNode().getElementType();
final StringLiteralLexer lexer = new StringLiteralLexer(type == SINGLE_QUOTED_STRING ? '\'' : '"', type, false, "/", false, false);
final List<TextRange> result = new ArrayList<TextRange>();
SelectWordUtil.addWordHonoringEscapeSequences(editorText, e.getTextRange(), cursorOffset, lexer, result);
result.add(ElementManipulators.getValueTextRange(parent).shiftRight(parent.getTextOffset()));
return result;
}
}
@@ -0,0 +1,17 @@
package com.intellij.json;
import com.intellij.testFramework.fixtures.CodeInsightTestUtil;
/**
* @author Mikhail Golubev
*/
public class JsonWordSelectionTest extends JsonTestCase {
private void doTest() {
CodeInsightTestUtil.doWordSelectionTestOnDirectory(myFixture, "selectWord/" + getTestName(false), "json");
}
public void testEscapeAwareness() {
doTest();
}
}
@@ -0,0 +1,3 @@
[
"\tree \n<selection>ode</selection>"
]
@@ -0,0 +1,3 @@
[
"<selection>\tree \node</selection>"
]
@@ -0,0 +1,3 @@
[
<selection>"\tree \node"</selection>
]
@@ -0,0 +1,3 @@
[
"\tree \nod<caret>e"
]
@@ -40,6 +40,8 @@
<statementUpDownMover implementation="com.intellij.json.editor.lineMover.JsonLineMover" id="JSON" order="before line"/>
<liveTemplateContext implementation="com.intellij.json.JsonContextType"/>
<spellchecker.support language="JSON" implementationClass="com.intellij.json.JsonSpellcheckerStrategy"/>
<extendWordSelectionHandler implementation="com.intellij.json.editor.selection.JsonStringLiteralSelectionHandler"/>
<basicWordSelectionFilter implementation="com.intellij.json.editor.selection.JsonBasicWordSelectionFilter"/>
<!-- Annotators -->
<annotator language="JSON" implementationClass="com.intellij.json.codeinsight.JsonStringLiteralAnnotator"/>