mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
IDEA-66777 (Pasting escapes quotes too eagerly) tests will follow
This commit is contained in:
+51
-27
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.editorActions;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RawText;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.LineTokenizer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
@@ -26,17 +28,13 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
|
||||
public String preprocessOnCopy(final PsiFile file, final int[] startOffsets, final int[] endOffsets, final String text) {
|
||||
boolean isLiteral = true;
|
||||
for (int i = 0; i < startOffsets.length && isLiteral; i++) {
|
||||
final int startOffset = startOffsets[i];
|
||||
final PsiElement elementAtCaret = file.findElementAt(startOffset);
|
||||
if (!(elementAtCaret instanceof PsiJavaToken &&
|
||||
(((PsiJavaToken) elementAtCaret)).getTokenType() == JavaTokenType.STRING_LITERAL &&
|
||||
startOffset >= elementAtCaret.getTextRange().getStartOffset() &&
|
||||
endOffsets[i] <= elementAtCaret.getTextRange().getEndOffset())) {
|
||||
if (findLiteralTokenType(file, startOffsets[i], endOffsets[i]) == null) {
|
||||
isLiteral = false;
|
||||
}
|
||||
}
|
||||
@@ -47,28 +45,54 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
|
||||
public String preprocessOnPaste(final Project project, final PsiFile file, final Editor editor, String text, final RawText rawText) {
|
||||
final Document document = editor.getDocument();
|
||||
PsiDocumentManager.getInstance(project).commitDocument(document);
|
||||
int caretOffset = editor.getCaretModel().getOffset();
|
||||
PsiElement elementAtCaret = file.findElementAt(caretOffset);
|
||||
if (elementAtCaret instanceof PsiJavaToken && caretOffset > elementAtCaret.getTextOffset()) {
|
||||
final IElementType tokenType = ((PsiJavaToken)elementAtCaret).getTokenType();
|
||||
if (tokenType == JavaTokenType.STRING_LITERAL) {
|
||||
if (rawText != null && rawText.rawText != null) return rawText.rawText; // Copied from the string literal. Copy as is.
|
||||
final SelectionModel selectionModel = editor.getSelectionModel();
|
||||
|
||||
StringBuilder buffer = new StringBuilder(text.length());
|
||||
CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
|
||||
@NonNls String breaker = codeStyleSettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE ? "\\n\"\n+ \"" : "\\n\" +\n\"";
|
||||
final String[] lines = LineTokenizer.tokenize(text.toCharArray(), false, true);
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
String line = lines[i];
|
||||
buffer.append(StringUtil.escapeStringCharacters(line));
|
||||
if (i != lines.length - 1) buffer.append(breaker);
|
||||
}
|
||||
text = buffer.toString();
|
||||
}
|
||||
else if (tokenType == JavaTokenType.CHARACTER_LITERAL) {
|
||||
if (rawText != null && rawText.rawText != null) return rawText.rawText; // Copied from the string literal. Copy as is.
|
||||
// pastes in block selection mode (column mode) are not handled by a CopyPasteProcessor
|
||||
final int selectionStart = selectionModel.getSelectionStart();
|
||||
final int selectionEnd = selectionModel.getSelectionEnd();
|
||||
IElementType tokenType = findLiteralTokenType(file, selectionStart, selectionEnd);
|
||||
|
||||
if (tokenType == JavaTokenType.STRING_LITERAL) {
|
||||
if (rawText != null && rawText.rawText != null) return rawText.rawText; // Copied from the string literal. Copy as is.
|
||||
|
||||
StringBuilder buffer = new StringBuilder(text.length());
|
||||
CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
|
||||
@NonNls String breaker = codeStyleSettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE ? "\\n\"\n+ \"" : "\\n\" +\n\"";
|
||||
final String[] lines = LineTokenizer.tokenize(text.toCharArray(), false, true);
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
String line = lines[i];
|
||||
buffer.append(StringUtil.escapeStringCharacters(line));
|
||||
if (i != lines.length - 1) buffer.append(breaker);
|
||||
}
|
||||
text = buffer.toString();
|
||||
}
|
||||
else if (tokenType == JavaTokenType.CHARACTER_LITERAL) {
|
||||
if (rawText != null && rawText.rawText != null) return rawText.rawText; // Copied from the string literal. Copy as is.
|
||||
return escapeCharCharacters(text);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static IElementType findLiteralTokenType(PsiFile file, int selectionStart, int selectionEnd) {
|
||||
final PsiElement elementAtSelection = file.findElementAt(selectionStart);
|
||||
if (!(elementAtSelection instanceof PsiJavaToken)) {
|
||||
return null;
|
||||
}
|
||||
final IElementType tokenType = ((PsiJavaToken)elementAtSelection).getTokenType();
|
||||
if ((tokenType != JavaTokenType.STRING_LITERAL && tokenType != JavaTokenType.CHARACTER_LITERAL)) {
|
||||
return null;
|
||||
}
|
||||
final TextRange textRange = elementAtSelection.getTextRange();
|
||||
if (selectionStart <= textRange.getStartOffset() || selectionEnd >= textRange.getEndOffset()) {
|
||||
return null;
|
||||
}
|
||||
return tokenType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String escapeCharCharacters(@NotNull String s) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
StringUtil.escapeStringCharacters(s.length(), s, "\'", buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user