diff --git a/python/src/com/jetbrains/python/editor/PythonCopyPasteProcessor.java b/python/src/com/jetbrains/python/editor/PythonCopyPasteProcessor.java index 8bf8cf12cdf2..5992c1689626 100644 --- a/python/src/com/jetbrains/python/editor/PythonCopyPasteProcessor.java +++ b/python/src/com/jetbrains/python/editor/PythonCopyPasteProcessor.java @@ -12,7 +12,10 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.util.PsiUtilCore; +import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyFile; +import com.jetbrains.python.psi.PyFunction; +import com.jetbrains.python.psi.PyStatementList; import java.util.List; @@ -48,7 +51,32 @@ public class PythonCopyPasteProcessor implements CopyPastePreProcessor { final int lineNumber = document.getLineNumber(caretOffset); final int offset = getLineStartSafeOffset(document, lineNumber); final PsiElement element1 = PsiUtilCore.getElementAtOffset(file, offset); + boolean moved = false; if (element instanceof PsiWhiteSpace && element == element1) { + final PsiElement prevSibling = element.getPrevSibling(); + PyStatementList statementList = null; + if (prevSibling instanceof PyFunction) { + statementList = ((PyFunction)prevSibling).getStatementList(); + } + else if (prevSibling instanceof PyClass) { + statementList = ((PyClass)prevSibling).getStatementList(); + } + // Caret beyond actual indent -- move to the actual offset + if (statementList != null) { + final PsiElement lastChild = statementList.getLastChild(); + if (lastChild != null) { + final PsiElement whiteSpace = lastChild.getPrevSibling(); + if (whiteSpace instanceof PsiWhiteSpace) { + int relatedOffset = whiteSpace.getTextRange().getEndOffset(); + final int indent = relatedOffset - getLineStartSafeOffset(document, document.getLineNumber(relatedOffset)); + if (caretOffset > indent) { + caretModel.moveToOffset(offset + indent); + moved = true; + } + } + } + } + final List strings = StringUtil.split(element.getText(), "\n"); //user already prepared place to paste to and we just want to indent right if (StringUtil.countChars(element.getText(), '\n') > 2) { @@ -62,7 +90,7 @@ public class PythonCopyPasteProcessor implements CopyPastePreProcessor { if (!strings.isEmpty()) newText += strings.get(strings.size()-1); //pasted text'll be the only one statement in block - if (!element.getText().endsWith("\n")) + if (!element.getText().endsWith("\n") && !moved) caretModel.moveToOffset(element.getTextRange().getEndOffset()); } } diff --git a/python/testData/copyPaste/multiLine/IndentInnerFunction2.after.py b/python/testData/copyPaste/multiLine/IndentInnerFunction2.after.py new file mode 100644 index 000000000000..933900cac4f5 --- /dev/null +++ b/python/testData/copyPaste/multiLine/IndentInnerFunction2.after.py @@ -0,0 +1,9 @@ +def foo(self): + x = 1 + y = 2 + + def foo(self): + x = 1 + y = 2 + +z = 3 \ No newline at end of file diff --git a/python/testData/copyPaste/multiLine/IndentInnerFunction2.dst.py b/python/testData/copyPaste/multiLine/IndentInnerFunction2.dst.py new file mode 100644 index 000000000000..e5ba0a209d8c --- /dev/null +++ b/python/testData/copyPaste/multiLine/IndentInnerFunction2.dst.py @@ -0,0 +1,5 @@ +def foo(self): + x = 1 + y = 2 + +z = 3 \ No newline at end of file diff --git a/python/testData/copyPaste/multiLine/IndentInnerFunction2.src.py b/python/testData/copyPaste/multiLine/IndentInnerFunction2.src.py new file mode 100644 index 000000000000..6d09083689a6 --- /dev/null +++ b/python/testData/copyPaste/multiLine/IndentInnerFunction2.src.py @@ -0,0 +1,4 @@ +def foo(self): + x = 1 + y = 2 + diff --git a/python/testSrc/com/jetbrains/python/PyCopyPasteTest.java b/python/testSrc/com/jetbrains/python/PyCopyPasteTest.java index b6c67b4903a9..f8b2194aba3f 100644 --- a/python/testSrc/com/jetbrains/python/PyCopyPasteTest.java +++ b/python/testSrc/com/jetbrains/python/PyCopyPasteTest.java @@ -151,6 +151,10 @@ public class PyCopyPasteTest extends PyTestCase { doTestMultiLine(); } + public void testIndentInnerFunction2() { //PY-6886 + doTestMultiLine(); + } + public void testIndentFunction() { doTestMultiLine(); }