mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 18:05:27 +07:00
fixed PY-6994 Paste leads to syntactically incorrect code in case pasting copied text instead of selection
This commit is contained in:
@@ -2,18 +2,17 @@ package com.jetbrains.python.editor;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.editorActions.CopyPastePreProcessor;
|
||||
import com.intellij.openapi.editor.CaretModel;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RawText;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.CharFilter;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
import com.jetbrains.python.psi.PyStringLiteralExpression;
|
||||
|
||||
@@ -52,7 +51,18 @@ public class PythonCopyPasteProcessor implements CopyPastePreProcessor {
|
||||
if (StringUtil.countChars(text, '\n') > 0 || StringUtil.startsWithWhitespace(text)) { //2, 3, 4 case from doc
|
||||
final PsiElement element = PsiUtilCore.getElementAtOffset(file, caretOffset - 1);
|
||||
if (PsiTreeUtil.getParentOfType(element, PyStringLiteralExpression.class) != null) return text;
|
||||
caretModel.moveToOffset(lineStartOffset);
|
||||
|
||||
final SelectionModel selectionModel = editor.getSelectionModel();
|
||||
if (selectionModel.getSelectionStart() != selectionModel.getSelectionEnd()) {
|
||||
final int line = document.getLineNumber(selectionModel.getSelectionStart());
|
||||
final int lineOffset = getLineStartSafeOffset(document, line);
|
||||
final PsiElement ws = file.findElementAt(lineOffset);
|
||||
int offset = ws instanceof PsiWhiteSpace? ws.getTextRange().getEndOffset() : lineOffset;
|
||||
caretModel.moveToOffset(offset);
|
||||
selectionModel.setSelection(offset, selectionModel.getSelectionEnd());
|
||||
}
|
||||
else
|
||||
caretModel.moveToOffset(lineStartOffset);
|
||||
String spaceString;
|
||||
int indent = 0;
|
||||
|
||||
@@ -69,12 +79,17 @@ public class PythonCopyPasteProcessor implements CopyPastePreProcessor {
|
||||
if (indent < 0)
|
||||
indent = StringUtil.isEmptyOrSpaces(spaceString) ? spaceString.length() : 0;
|
||||
|
||||
final String trimmed = StringUtil.trimLeading(strings.get(0)); //decrease indent if needed
|
||||
if (trimmed.startsWith("def ") || trimmed.startsWith("if ") || trimmed.startsWith("try:") ||
|
||||
trimmed.startsWith("class ") || trimmed.startsWith("for ") || trimmed.startsWith("elif ") ||
|
||||
trimmed.startsWith("else:") || trimmed.startsWith("except") || trimmed.startsWith("while ")) {
|
||||
indent = StringUtil.findFirst(spaceString, CharFilter.NOT_WHITESPACE_FILTER) / 2;
|
||||
if (indent < 0) indent = 0;
|
||||
if (indent == CodeStyleSettingsManager.getSettings(project).getIndentSize(PythonFileType.INSTANCE)) {
|
||||
indent = 0;
|
||||
}
|
||||
else {
|
||||
final String trimmed = StringUtil.trimLeading(strings.get(0)); //decrease indent if needed
|
||||
if (trimmed.startsWith("def ") || trimmed.startsWith("if ") || trimmed.startsWith("try:") ||
|
||||
trimmed.startsWith("class ") || trimmed.startsWith("for ") || trimmed.startsWith("elif ") ||
|
||||
trimmed.startsWith("else:") || trimmed.startsWith("except") || trimmed.startsWith("while ")) {
|
||||
indent = StringUtil.findFirst(spaceString, CharFilter.NOT_WHITESPACE_FILTER) / 2;
|
||||
if (indent < 0) indent = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
python/testData/copyPaste/Selection1.after.py
Normal file
9
python/testData/copyPaste/Selection1.after.py
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
def f():
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
7
python/testData/copyPaste/Selection1.dst.py
Normal file
7
python/testData/copyPaste/Selection1.dst.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
def f():
|
||||
<selection>c = 3</selection><caret>
|
||||
7
python/testData/copyPaste/Selection1.src.py
Normal file
7
python/testData/copyPaste/Selection1.src.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
<selection>if True:
|
||||
a = 1
|
||||
b = 2
|
||||
</selection>
|
||||
def f():
|
||||
c = 3
|
||||
9
python/testData/copyPaste/Selection2.after.py
Normal file
9
python/testData/copyPaste/Selection2.after.py
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
def f():
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
7
python/testData/copyPaste/Selection2.dst.py
Normal file
7
python/testData/copyPaste/Selection2.dst.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
def f():
|
||||
<selection> c = 3</selection><caret>
|
||||
7
python/testData/copyPaste/Selection2.src.py
Normal file
7
python/testData/copyPaste/Selection2.src.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
<selection>if True:
|
||||
a = 1
|
||||
b = 2
|
||||
</selection>
|
||||
def f():
|
||||
c = 3
|
||||
8
python/testData/copyPaste/Selection3.after.py
Normal file
8
python/testData/copyPaste/Selection3.after.py
Normal file
@@ -0,0 +1,8 @@
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
def f():
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
7
python/testData/copyPaste/Selection3.dst.py
Normal file
7
python/testData/copyPaste/Selection3.dst.py
Normal file
@@ -0,0 +1,7 @@
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
def f():
|
||||
<selection> c = 3
|
||||
<caret></selection>
|
||||
7
python/testData/copyPaste/Selection3.src.py
Normal file
7
python/testData/copyPaste/Selection3.src.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
<selection>if True:
|
||||
a = 1
|
||||
b = 2
|
||||
</selection>
|
||||
def f():
|
||||
c = 3
|
||||
10
python/testData/copyPaste/SelectionReverse1.after.py
Normal file
10
python/testData/copyPaste/SelectionReverse1.after.py
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
def f():
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
7
python/testData/copyPaste/SelectionReverse1.dst.py
Normal file
7
python/testData/copyPaste/SelectionReverse1.dst.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
def f():
|
||||
<caret><selection>c = 3</selection>
|
||||
7
python/testData/copyPaste/SelectionReverse1.src.py
Normal file
7
python/testData/copyPaste/SelectionReverse1.src.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
<selection>if True:
|
||||
a = 1
|
||||
b = 2
|
||||
</selection>
|
||||
def f():
|
||||
c = 3
|
||||
9
python/testData/copyPaste/SelectionReverse2.after.py
Normal file
9
python/testData/copyPaste/SelectionReverse2.after.py
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
def f():
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
7
python/testData/copyPaste/SelectionReverse2.dst.py
Normal file
7
python/testData/copyPaste/SelectionReverse2.dst.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
def f():
|
||||
<caret><selection> c = 3</selection>
|
||||
7
python/testData/copyPaste/SelectionReverse2.src.py
Normal file
7
python/testData/copyPaste/SelectionReverse2.src.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
<selection>if True:
|
||||
a = 1
|
||||
b = 2
|
||||
</selection>
|
||||
def f():
|
||||
c = 3
|
||||
9
python/testData/copyPaste/SelectionReverse3.after.py
Normal file
9
python/testData/copyPaste/SelectionReverse3.after.py
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
def f():
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
8
python/testData/copyPaste/SelectionReverse3.dst.py
Normal file
8
python/testData/copyPaste/SelectionReverse3.dst.py
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
if True:
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
def f():
|
||||
<caret><selection> c = 3
|
||||
</selection>
|
||||
7
python/testData/copyPaste/SelectionReverse3.src.py
Normal file
7
python/testData/copyPaste/SelectionReverse3.src.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
<selection>if True:
|
||||
a = 1
|
||||
b = 2
|
||||
</selection>
|
||||
def f():
|
||||
c = 3
|
||||
@@ -1,7 +1,6 @@
|
||||
def foo(self):
|
||||
x = 1
|
||||
y = 2
|
||||
|
||||
def foo(self):
|
||||
x = 1
|
||||
y = 2
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
def foo(self):
|
||||
x = 1
|
||||
y = 2
|
||||
|
||||
def foo(self):
|
||||
x = 1
|
||||
y = 2
|
||||
def foo(self):
|
||||
x = 1
|
||||
y = 2
|
||||
|
||||
z = 3
|
||||
@@ -1,8 +1,6 @@
|
||||
def f():
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
|
||||
def f():
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
@@ -47,6 +47,30 @@ public class PyCopyPasteTest extends PyTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSelection1() { //PY-6994
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSelection2() { //PY-6994
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSelection3() { //PY-6994
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSelectionReverse1() { //PY-6994
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSelectionReverse2() { //PY-6994
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSelectionReverse3() { //PY-6994
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIndent11() {
|
||||
doTestSingleLine();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user