mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
highlighting for slashy strings
This commit is contained in:
+8
-8
@@ -23,6 +23,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrRegex;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
|
||||
|
||||
import java.util.List;
|
||||
@@ -39,30 +40,29 @@ public class GroovyLiteralSelectioner extends GroovyBasicSelectioner {
|
||||
}
|
||||
|
||||
private static boolean isLiteral(PsiElement element) {
|
||||
if (element instanceof GrListOrMap) {
|
||||
return true;
|
||||
}
|
||||
if (element instanceof GrListOrMap) return true;
|
||||
|
||||
if (!(element instanceof GrLiteral)) return false;
|
||||
if (element instanceof GrRegex && ((GrRegex)element).getInjections().length == 0) return true;
|
||||
|
||||
ASTNode node = element.getNode();
|
||||
if (node == null) return false;
|
||||
ASTNode firstNode = node.getFirstChildNode();
|
||||
final IElementType type = firstNode.getElementType();
|
||||
return firstNode == node.getLastChildNode() && (type == mSTRING_LITERAL || type == mGSTRING_LITERAL || type == mREGEX_LITERAL);
|
||||
return firstNode == node.getLastChildNode() && (type == mSTRING_LITERAL || type == mGSTRING_LITERAL);
|
||||
}
|
||||
|
||||
public List<TextRange> select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) {
|
||||
List<TextRange> result = super.select(e, editorText, cursorOffset, editor);
|
||||
|
||||
if (e instanceof GrListOrMap) {
|
||||
return result;
|
||||
}
|
||||
if (e instanceof GrListOrMap) return result;
|
||||
|
||||
int startOffset = -1;
|
||||
int endOffset = -1;
|
||||
final String text = e.getText();
|
||||
final int stringOffset = e.getTextOffset();
|
||||
if (e.getNode().getElementType() == mGSTRING_CONTENT) {
|
||||
final IElementType elementType = e.getNode().getElementType();
|
||||
if (elementType == mGSTRING_CONTENT || elementType == mREGEX_CONTENT || elementType == mDOLLAR_SLASH_REGEX_CONTENT) {
|
||||
int cur;
|
||||
int index = -1;
|
||||
while (true) {
|
||||
|
||||
+4
-1
@@ -46,7 +46,10 @@ public class GroovyWordSelectionFilter implements Condition<PsiElement> {
|
||||
type == mGDOC_TAG_VALUE_TOKEN ||
|
||||
type == mREGEX_BEGIN ||
|
||||
type == mREGEX_CONTENT ||
|
||||
type == mREGEX_END) {
|
||||
type == mREGEX_END ||
|
||||
type == mDOLLAR_SLASH_REGEX_BEGIN ||
|
||||
type == mDOLLAR_SLASH_REGEX_CONTENT ||
|
||||
type == mDOLLAR_SLASH_REGEX_END) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,8 +49,6 @@ public class DefaultHighlighter {
|
||||
@NonNls
|
||||
static final String STRING_ID = "String";
|
||||
@NonNls
|
||||
static final String REGEXP_ID = "Regular expression";
|
||||
@NonNls
|
||||
static final String BRACES_ID = "Braces";
|
||||
@NonNls
|
||||
static final String BRACKETS_ID = "Brackets";
|
||||
@@ -150,9 +148,6 @@ public class DefaultHighlighter {
|
||||
public static TextAttributesKey STRING = TextAttributesKey.createTextAttributesKey(STRING_ID,
|
||||
SyntaxHighlighterColors.STRING.getDefaultAttributes());
|
||||
|
||||
public static TextAttributesKey REGEXP = TextAttributesKey.createTextAttributesKey(REGEXP_ID,
|
||||
SyntaxHighlighterColors.VALID_STRING_ESCAPE.getDefaultAttributes());
|
||||
|
||||
public static TextAttributesKey BRACES = TextAttributesKey.createTextAttributesKey(BRACES_ID,
|
||||
SyntaxHighlighterColors.BRACES.getDefaultAttributes());
|
||||
|
||||
|
||||
+29
-22
@@ -19,14 +19,18 @@ package org.jetbrains.plugins.groovy.highlighter;
|
||||
import com.intellij.lang.BracePair;
|
||||
import com.intellij.lang.PairedBraceMatcher;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
|
||||
|
||||
import static com.intellij.psi.TokenType.WHITE_SPACE;
|
||||
import static org.jetbrains.plugins.groovy.GroovyFileType.GROOVY_LANGUAGE;
|
||||
import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_INLINE_TAG_END;
|
||||
import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_INLINE_TAG_START;
|
||||
import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_TAG_VALUE_LPAREN;
|
||||
import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_TAG_VALUE_RPAREN;
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*;
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.COMMENT_SET;
|
||||
|
||||
/**
|
||||
* Brace matcher for Groovy language
|
||||
@@ -36,32 +40,35 @@ import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
|
||||
public class GroovyBraceMatcher implements PairedBraceMatcher {
|
||||
|
||||
private static final BracePair[] PAIRS = {
|
||||
new BracePair(GroovyTokenTypes.mLPAREN, GroovyTokenTypes.mRPAREN, false),
|
||||
new BracePair(GroovyTokenTypes.mLBRACK, GroovyTokenTypes.mRBRACK, false),
|
||||
new BracePair(GroovyTokenTypes.mLCURLY, GroovyTokenTypes.mRCURLY, true),
|
||||
new BracePair(mLPAREN, mRPAREN, false),
|
||||
new BracePair(mLBRACK, mRBRACK, false),
|
||||
new BracePair(mLCURLY, mRCURLY, true),
|
||||
|
||||
new BracePair(GroovyDocTokenTypes.mGDOC_INLINE_TAG_START, GroovyDocTokenTypes.mGDOC_INLINE_TAG_END, true),
|
||||
new BracePair(GroovyDocTokenTypes.mGDOC_TAG_VALUE_LPAREN, GroovyDocTokenTypes.mGDOC_TAG_VALUE_RPAREN, false),
|
||||
new BracePair(mGDOC_INLINE_TAG_START, mGDOC_INLINE_TAG_END, true),
|
||||
new BracePair(mGDOC_TAG_VALUE_LPAREN, mGDOC_TAG_VALUE_RPAREN, false),
|
||||
|
||||
new BracePair(GroovyTokenTypes.mGSTRING_BEGIN, GroovyTokenTypes.mGSTRING_END, false),
|
||||
new BracePair(GroovyTokenTypes.mREGEX_BEGIN, GroovyTokenTypes.mREGEX_END, false)
|
||||
new BracePair(mGSTRING_BEGIN, mGSTRING_END, false),
|
||||
new BracePair(mREGEX_BEGIN, mREGEX_END, false),
|
||||
new BracePair(mDOLLAR_SLASH_REGEX_BEGIN, mDOLLAR_SLASH_REGEX_END, false),
|
||||
};
|
||||
|
||||
public BracePair[] getPairs() {
|
||||
return PAIRS;
|
||||
}
|
||||
|
||||
public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType ibraceType, @Nullable IElementType tokenType) {
|
||||
public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType braceType, @Nullable IElementType tokenType) {
|
||||
return tokenType == null
|
||||
|| TokenType.WHITE_SPACE == tokenType
|
||||
|| TokenSets.COMMENT_SET.contains(tokenType)
|
||||
|| tokenType == GroovyTokenTypes.mSEMI
|
||||
|| tokenType == GroovyTokenTypes.mCOMMA
|
||||
|| tokenType == GroovyTokenTypes.mRPAREN
|
||||
|| tokenType == GroovyTokenTypes.mRBRACK
|
||||
|| tokenType == GroovyTokenTypes.mRCURLY
|
||||
|| tokenType == GroovyTokenTypes.mGSTRING_BEGIN
|
||||
|| tokenType.getLanguage() != GroovyFileType.GROOVY_LANGUAGE;
|
||||
|| tokenType == WHITE_SPACE
|
||||
|| tokenType == mSEMI
|
||||
|| tokenType == mCOMMA
|
||||
|| tokenType == mRPAREN
|
||||
|| tokenType == mRBRACK
|
||||
|| tokenType == mRCURLY
|
||||
|| tokenType == mGSTRING_BEGIN
|
||||
|| tokenType == mREGEX_BEGIN
|
||||
|| tokenType == mDOLLAR_SLASH_REGEX_BEGIN
|
||||
|| COMMENT_SET.contains(tokenType)
|
||||
|| tokenType.getLanguage() != GROOVY_LANGUAGE;
|
||||
}
|
||||
|
||||
public int getCodeConstructStart(PsiFile file, int openingBraceOffset) {
|
||||
|
||||
-1
@@ -58,7 +58,6 @@ public class GroovyColorsAndFontsPage implements ColorSettingsPage {
|
||||
new AttributesDescriptor("Number", DefaultHighlighter.NUMBER),
|
||||
new AttributesDescriptor("GString", DefaultHighlighter.GSTRING),
|
||||
new AttributesDescriptor("String", DefaultHighlighter.STRING),
|
||||
new AttributesDescriptor("Regular expression", DefaultHighlighter.REGEXP),
|
||||
new AttributesDescriptor("Braces", DefaultHighlighter.BRACES),
|
||||
new AttributesDescriptor("Brackets", DefaultHighlighter.BRACKETS),
|
||||
new AttributesDescriptor("Parentheses", DefaultHighlighter.PARENTHESES),
|
||||
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.highlighter;
|
||||
|
||||
import com.intellij.lexer.LexerBase;
|
||||
import com.intellij.psi.StringEscapesTokenTypes;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GroovySlashyStringLexer extends LexerBase {
|
||||
private CharSequence myBuffer;
|
||||
private int myStart;
|
||||
private int myBufferEnd;
|
||||
private IElementType myTokenType;
|
||||
private int myEnd;
|
||||
|
||||
|
||||
public GroovySlashyStringLexer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
|
||||
myBuffer = buffer;
|
||||
myEnd = startOffset;
|
||||
myBufferEnd = endOffset;
|
||||
myTokenType = locateToken();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private IElementType locateToken() {
|
||||
if (myEnd >= myBufferEnd) return null;
|
||||
|
||||
myStart = myEnd;
|
||||
if (checkForEscape(myStart)) {
|
||||
myEnd = myStart + 2;
|
||||
return StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN;
|
||||
}
|
||||
|
||||
while (myEnd < myBufferEnd && !checkForEscape(myEnd)) myEnd++;
|
||||
return GroovyTokenTypes.mREGEX_CONTENT;
|
||||
}
|
||||
|
||||
private boolean checkForEscape(int start) {
|
||||
return myBuffer.charAt(start) == '\\' && start + 1 < myBufferEnd && myBuffer.charAt(start + 1) == '/';
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getState() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IElementType getTokenType() {
|
||||
return myTokenType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTokenStart() {
|
||||
return myStart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTokenEnd() {
|
||||
return myEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void advance() {
|
||||
myTokenType = locateToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getBufferSequence() {
|
||||
return myBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBufferEnd() {
|
||||
return myBufferEnd;
|
||||
}
|
||||
}
|
||||
+3
-15
@@ -62,10 +62,6 @@ public class GroovySyntaxHighlighter extends SyntaxHighlighterBase implements Gr
|
||||
mWRONG
|
||||
);
|
||||
|
||||
static final TokenSet tWRONG_REGEX = TokenSet.create(
|
||||
mWRONG_REGEX_LITERAL
|
||||
);
|
||||
|
||||
static final TokenSet tGSTRINGS = TokenSet.create(
|
||||
mGSTRING_BEGIN,
|
||||
mGSTRING_CONTENT,
|
||||
@@ -77,15 +73,6 @@ public class GroovySyntaxHighlighter extends SyntaxHighlighterBase implements Gr
|
||||
mSTRING_LITERAL
|
||||
);
|
||||
|
||||
static final TokenSet tREGEXP = TokenSet.create(
|
||||
mREGEX_LITERAL,
|
||||
|
||||
mREGEX_BEGIN,
|
||||
mREGEX_CONTENT,
|
||||
mREGEX_END
|
||||
|
||||
);
|
||||
|
||||
static final TokenSet tBRACES = TokenSet.create(
|
||||
mLCURLY,
|
||||
mRCURLY
|
||||
@@ -210,8 +197,7 @@ public class GroovySyntaxHighlighter extends SyntaxHighlighterBase implements Gr
|
||||
fillMap(ATTRIBUTES, tNUMBERS, DefaultHighlighter.NUMBER);
|
||||
fillMap(ATTRIBUTES, tGSTRINGS, DefaultHighlighter.GSTRING);
|
||||
fillMap(ATTRIBUTES, tSTRINGS, DefaultHighlighter.STRING);
|
||||
fillMap(ATTRIBUTES, tREGEXP, DefaultHighlighter.REGEXP);
|
||||
fillMap(ATTRIBUTES, tWRONG_REGEX, DefaultHighlighter.REGEXP);
|
||||
fillMap(ATTRIBUTES, DefaultHighlighter.STRING, mREGEX_BEGIN, mREGEX_CONTENT, mREGEX_END, mDOLLAR_SLASH_REGEX_BEGIN, mDOLLAR_SLASH_REGEX_CONTENT, mDOLLAR_SLASH_REGEX_END);
|
||||
fillMap(ATTRIBUTES, tBRACES, DefaultHighlighter.BRACES);
|
||||
fillMap(ATTRIBUTES, tBRACKETS, DefaultHighlighter.BRACKETS);
|
||||
fillMap(ATTRIBUTES, tPARENTHESES, DefaultHighlighter.PARENTHESES);
|
||||
@@ -234,6 +220,8 @@ public class GroovySyntaxHighlighter extends SyntaxHighlighterBase implements Gr
|
||||
new IElementType[]{GroovyTokenTypes.mGSTRING_LITERAL}, IElementType.EMPTY_ARRAY);
|
||||
registerSelfStoppingLayer(new StringLiteralLexer(StringLiteralLexer.NO_QUOTE_CHAR, GroovyTokenTypes.mGSTRING_CONTENT, true, "$"),
|
||||
new IElementType[]{GroovyTokenTypes.mGSTRING_CONTENT}, IElementType.EMPTY_ARRAY);
|
||||
registerSelfStoppingLayer(new GroovySlashyStringLexer(), new IElementType[]{GroovyTokenTypes.mREGEX_CONTENT},
|
||||
IElementType.EMPTY_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-8
@@ -111,10 +111,7 @@ public class GroovyLiteralCopyPasteProcessor extends StringLiteralCopyPasteProce
|
||||
protected String escapeCharCharacters(@NotNull String s, @NotNull PsiElement token, boolean escapeSlashes) {
|
||||
IElementType tokenType = token.getNode().getElementType();
|
||||
|
||||
if (tokenType == mREGEX_CONTENT ||
|
||||
tokenType == mREGEX_LITERAL ||
|
||||
tokenType == mDOLLAR_SLASH_REGEX_CONTENT ||
|
||||
tokenType == mDOLLAR_SLASH_REGEX_LITERAL) {
|
||||
if (tokenType == mREGEX_CONTENT || tokenType == mDOLLAR_SLASH_REGEX_CONTENT) {
|
||||
if (escapeSlashes) {
|
||||
return StringUtil.escapeSlashes(s);
|
||||
}
|
||||
@@ -149,10 +146,7 @@ public class GroovyLiteralCopyPasteProcessor extends StringLiteralCopyPasteProce
|
||||
protected String unescape(String text, PsiElement token) {
|
||||
final IElementType tokenType = token.getNode().getElementType();
|
||||
|
||||
if (tokenType == mREGEX_CONTENT ||
|
||||
tokenType == mREGEX_LITERAL ||
|
||||
tokenType == mDOLLAR_SLASH_REGEX_CONTENT ||
|
||||
tokenType == mDOLLAR_SLASH_REGEX_LITERAL) {
|
||||
if (tokenType == mREGEX_CONTENT || tokenType == mDOLLAR_SLASH_REGEX_CONTENT) {
|
||||
return StringUtil.unescapeSlashes(text);
|
||||
}
|
||||
|
||||
|
||||
@@ -73,9 +73,6 @@ public interface GroovyTokenTypes extends GroovyDocElementTypes {
|
||||
IElementType mGSTRING_CONTENT = new GroovyElementType("Gstring content");
|
||||
IElementType mGSTRING_END = new GroovyElementType("Gstring end");
|
||||
|
||||
IElementType mREGEX_LITERAL = new GroovyElementType("regexp");
|
||||
IElementType mDOLLAR_SLASH_REGEX_LITERAL = new GroovyElementType("$/ regexp");
|
||||
|
||||
IElementType mREGEX_BEGIN = new GroovyElementType("regex begin");
|
||||
IElementType mREGEX_CONTENT = new GroovyElementType("regex content");
|
||||
IElementType mREGEX_END = new GroovyElementType("regex end");
|
||||
|
||||
@@ -68,9 +68,7 @@ public abstract class TokenSets {
|
||||
kFALSE,
|
||||
kNULL,
|
||||
mSTRING_LITERAL,
|
||||
mGSTRING_LITERAL,
|
||||
mREGEX_LITERAL,
|
||||
mDOLLAR_SLASH_REGEX_LITERAL
|
||||
mGSTRING_LITERAL
|
||||
);
|
||||
|
||||
public static final TokenSet BUILT_IN_TYPE = TokenSet.create(
|
||||
@@ -123,10 +121,8 @@ public abstract class TokenSets {
|
||||
|
||||
public static TokenSet STRING_LITERALS = TokenSet.create(
|
||||
mSTRING_LITERAL,
|
||||
mREGEX_LITERAL,
|
||||
mREGEX_CONTENT,
|
||||
mDOLLAR_SLASH_REGEX_CONTENT,
|
||||
mDOLLAR_SLASH_REGEX_LITERAL,
|
||||
mGSTRING_LITERAL,
|
||||
mGSTRING_CONTENT,
|
||||
mGSTRING_BEGIN,
|
||||
|
||||
Reference in New Issue
Block a user