mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
Java: fix selection behaviour for String Templates (IDEA-333906)
GitOrigin-RevId: 0727e9c5b4a56d752bc38d7fc6fa22ca676dd9ba
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8925dcb722
commit
2ebaab02d1
@@ -7,60 +7,80 @@ import com.intellij.lexer.StringLiteralLexer;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.BasicLiteralUtil;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.impl.source.BasicJavaAstTreeUtil;
|
||||
import com.intellij.psi.impl.source.BasicElementTypes;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.psi.impl.source.BasicElementTypes.BASIC_STRING_LITERALS;
|
||||
|
||||
public class LiteralSelectioner extends AbstractBasicBackBasicSelectioner {
|
||||
|
||||
@Override
|
||||
public boolean canSelect(@NotNull PsiElement e) {
|
||||
return BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(e), BASIC_STRING_LITERALS);
|
||||
IElementType type = e.getNode().getElementType();
|
||||
return BasicElementTypes.BASIC_STRING_LITERALS.contains(type) ||
|
||||
BasicElementTypes.BASIC_STRING_TEMPLATE_FRAGMENTS.contains(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextRange> select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) {
|
||||
List<TextRange> result = super.select(e, editorText, cursorOffset, editor);
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
ASTNode node = BasicJavaAstTreeUtil.toNode(e);
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
boolean textBlock = BasicJavaAstTreeUtil.isTextBlock(node);
|
||||
StringLiteralLexer lexer = textBlock
|
||||
? new StringLiteralLexer(StringLiteralLexer.NO_QUOTE_CHAR, JavaTokenType.TEXT_BLOCK_LITERAL, true, "s{")
|
||||
: new StringLiteralLexer('"', JavaTokenType.STRING_LITERAL);
|
||||
TextRange range = node.getTextRange();
|
||||
SelectWordUtil.addWordHonoringEscapeSequences(editorText, range, cursorOffset, lexer, result);
|
||||
if (textBlock) {
|
||||
int contentStart = StringUtil.indexOf(editorText, '\n', range.getStartOffset());
|
||||
if (contentStart == -1) return result;
|
||||
int start = contentStart + 1;
|
||||
int end = range.getEndOffset();
|
||||
end -= StringUtil.endsWith(editorText, start, end, "\"\"\"") ? 4 : 1;
|
||||
for (; end >= start; end--) {
|
||||
char c = editorText.charAt(end);
|
||||
if (c == '\n' || !Character.isWhitespace(c)) {
|
||||
end += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (start < end) result.add(new TextRange(start, end));
|
||||
}
|
||||
else {
|
||||
int endOffset = editorText.charAt(range.getEndOffset() - 1) == '"'
|
||||
? range.getEndOffset() - 1
|
||||
: range.getEndOffset();
|
||||
result.add(new TextRange(range.getStartOffset() + 1, endOffset));
|
||||
}
|
||||
if (result == null) return null;
|
||||
|
||||
ASTNode node = e.getNode();
|
||||
StringLiteralLexer lexer = new StringLiteralLexer(StringLiteralLexer.NO_QUOTE_CHAR, node.getElementType(), true, "s{");
|
||||
SelectWordUtil.addWordHonoringEscapeSequences(editorText, node.getTextRange(), cursorOffset, lexer, result);
|
||||
result.add(getContentRange(node, editorText));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static TextRange getContentRange(ASTNode node, @NotNull CharSequence text) {
|
||||
final IElementType tokenType = node.getElementType();
|
||||
final TextRange range = node.getTextRange();
|
||||
|
||||
if (tokenType == JavaTokenType.STRING_TEMPLATE_BEGIN || tokenType == JavaTokenType.STRING_TEMPLATE_MID ||
|
||||
tokenType == JavaTokenType.TEXT_BLOCK_TEMPLATE_MID) {
|
||||
return new TextRange(range.getStartOffset() + 1, range.getEndOffset() - 2);
|
||||
}
|
||||
else if (tokenType == JavaTokenType.STRING_TEMPLATE_END || tokenType == JavaTokenType.STRING_LITERAL) {
|
||||
int end = text.charAt(range.getEndOffset() - 1) == '"'
|
||||
? range.getEndOffset() - 1
|
||||
: range.getEndOffset();
|
||||
return new TextRange(range.getStartOffset() + 1, end);
|
||||
}
|
||||
else if (tokenType == JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN || tokenType == JavaTokenType.TEXT_BLOCK_TEMPLATE_END ||
|
||||
tokenType == JavaTokenType.TEXT_BLOCK_LITERAL) {
|
||||
int start;
|
||||
if (tokenType == JavaTokenType.TEXT_BLOCK_TEMPLATE_END) {
|
||||
start = range.getStartOffset() + 1;
|
||||
}
|
||||
else {
|
||||
start = range.getStartOffset() + 3;
|
||||
while (BasicLiteralUtil.isTextBlockWhiteSpace(text.charAt(start))) start++;
|
||||
if (text.charAt(start) == '\n') start++;
|
||||
}
|
||||
int end;
|
||||
if (tokenType == JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN) {
|
||||
end = range.getEndOffset() - 2;
|
||||
}
|
||||
else {
|
||||
end = range.getEndOffset();
|
||||
end -= StringUtil.endsWith(text, start, end, "\"\"\"") ? 4 : 1;
|
||||
for (; end >= start; end--) {
|
||||
char c = text.charAt(end);
|
||||
if (c == '\n' || !Character.isWhitespace(c)) {
|
||||
end += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new TextRange(start, end);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user