diff --git a/python/src/com/jetbrains/python/codeInsight/editorActions/moveUpDown/PyStatementMover.java b/python/src/com/jetbrains/python/codeInsight/editorActions/moveUpDown/PyStatementMover.java index 1029d91d59c6..1feb02f19159 100644 --- a/python/src/com/jetbrains/python/codeInsight/editorActions/moveUpDown/PyStatementMover.java +++ b/python/src/com/jetbrains/python/codeInsight/editorActions/moveUpDown/PyStatementMover.java @@ -10,10 +10,7 @@ import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiComment; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; +import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.util.PsiTreeUtil; @@ -29,13 +26,37 @@ public class PyStatementMover extends LineMover { public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) { if (!(file instanceof PyFile)) return false; final int offset = editor.getCaretModel().getOffset(); - PsiElement elementToMove = PyUtil.findNonWhitespaceAtOffset(file, offset); - if (elementToMove == null) return false; - elementToMove = getCommentOrStatement(editor.getDocument(), elementToMove); - info.toMove = new MyLineRange(elementToMove); - info.toMove2 = getDestinationScope(file, editor, elementToMove, down); + final SelectionModel selectionModel = editor.getSelectionModel(); + + if (!selectionModel.hasSelection()) { + PsiElement elementToMove = PyUtil.findNonWhitespaceAtOffset(file, offset); + if (elementToMove == null) return false; + elementToMove = getCommentOrStatement(editor.getDocument(), elementToMove); + info.toMove = new MyLineRange(elementToMove, elementToMove); + info.toMove2 = getDestinationScope(file, editor, elementToMove, down); + } + else { + final int start = selectionModel.getSelectionStart(); + final int end = selectionModel.getSelectionEnd() - 1; + PsiElement elementToMove1 = PyUtil.findNonWhitespaceAtOffset(file, start); + PsiElement elementToMove2 = PyUtil.findNonWhitespaceAtOffset(file, end); + if (elementToMove1 == null || elementToMove2 == null) return false; + elementToMove1 = getCommentOrStatement(editor.getDocument(), elementToMove1); + elementToMove2 = getCommentOrStatement(editor.getDocument(), elementToMove2); + + if (PsiTreeUtil.isAncestor(elementToMove1, elementToMove2, false)) { + elementToMove2 = elementToMove1; + } + else if (PsiTreeUtil.isAncestor(elementToMove2, elementToMove1, false)) { + elementToMove1 = elementToMove2; + } + info.toMove = new MyLineRange(elementToMove1, elementToMove2); + info.toMove2 = getDestinationScope(file, editor, down ? elementToMove2 : elementToMove1, down); + + } info.indentTarget = false; info.indentSource = false; + return true; } @@ -43,7 +64,6 @@ public class PyStatementMover extends LineMover { private static LineRange getDestinationScope(@NotNull final PsiFile file, @NotNull final Editor editor, @NotNull final PsiElement elementToMove, boolean down) { final Document document = file.getViewProvider().getDocument(); - if (document == null) return null; final int offset = down ? elementToMove.getTextRange().getEndOffset() : elementToMove.getTextRange().getStartOffset(); @@ -230,6 +250,7 @@ public class PyStatementMover extends LineMover { int lineEndOffset, boolean down) { PsiElement destination = elementToMove.getContainingFile().findElementAt(lineEndOffset); if (destination == null) return null; + if (destination instanceof PsiComment) return destination; PsiElement sibling = down ? PsiTreeUtil.getNextSiblingOfType(elementToMove, PyStatement.class) : PsiTreeUtil.getPrevSiblingOfType(elementToMove, PyStatement.class); if (elementToMove instanceof PyClass) { @@ -241,7 +262,7 @@ public class PyStatementMover extends LineMover { else destination = null; } else { - destination = getCommentOrStatement(document, destination); + destination = getCommentOrStatement(document, sibling == null ? destination : sibling); } return destination; } @@ -269,75 +290,205 @@ public class PyStatementMover extends LineMover { PostprocessReformattingAspect.getInstance(editor.getProject()).disablePostprocessFormattingInside(new Runnable() { @Override public void run() { - final PsiElement elementToMove = ((MyLineRange)toMove).myElement; + final PsiElement startToMove = ((MyLineRange)toMove).myStartElement; + final PsiElement endToMove = ((MyLineRange)toMove).myEndElement; + final PsiFile file = startToMove.getContainingFile(); final SelectionModel selectionModel = editor.getSelectionModel(); final CaretModel caretModel = editor.getCaretModel(); - final int shift = caretModel.getOffset() - elementToMove.getTextOffset(); - final boolean hasSelection = selectionModel.hasSelection(); - final int selectionStart = selectionModel.getSelectionStart(); - final int selectionEnd = selectionModel.getSelectionEnd(); - final int selectionShift = selectionStart - elementToMove.getTextOffset(); + final int selectionStart = selectionModel.getSelectionStart(); + boolean isSelectionStartAtCaret = caretModel.getOffset() == selectionStart; + final SelectionContainer selectionLen = getSelectionLenContainer(editor, ((MyLineRange)toMove)); + + int shift = getCaretShift(startToMove, endToMove, caretModel, isSelectionStartAtCaret); + + final boolean hasSelection = selectionModel.hasSelection(); int offset; if (((ScopeRange)toMove2).isTheSameLevel()) { offset = moveTheSameLevel((ScopeRange)toMove2, (MyLineRange)toMove); } else { - offset = moveInOut(((MyLineRange)toMove).myElement, editor, info); + offset = moveInOut(((MyLineRange)toMove), editor, info); } - - final int documentLength = editor.getDocument().getTextLength(); - int newCaretOffset = offset + shift; - if (newCaretOffset >= documentLength) newCaretOffset = documentLength; - caretModel.moveToOffset(newCaretOffset); + restoreCaretAndSelection(file, editor, isSelectionStartAtCaret, hasSelection, selectionLen, + shift, offset, (MyLineRange)toMove); info.toMove2 = info.toMove; //do not move further - if (hasSelection) { - int newSelectionStart = offset + selectionShift; - int newSelectionEnd = newSelectionStart + selectionEnd - selectionStart; - if (newSelectionEnd >= documentLength) - newSelectionEnd = documentLength; - selectionModel.setSelection(newSelectionStart, newSelectionEnd); - } } }); } } - private static int moveTheSameLevel(@NotNull final ScopeRange toMove2, @NotNull final MyLineRange toMove) { - final PsiElement anchor = toMove2.getAnchor(); - final PsiElement elementToMove = toMove.myElement; + private static SelectionContainer getSelectionLenContainer(@NotNull final Editor editor, @NotNull final MyLineRange toMove) { + final SelectionModel selectionModel = editor.getSelectionModel(); + final PsiElement startToMove = toMove.myStartElement; + final PsiElement endToMove = toMove.myEndElement; + final int selectionStart = selectionModel.getSelectionStart(); + final int selectionEnd = selectionModel.getSelectionEnd(); - final PsiElement anchorCopy = anchor.copy(); - final PsiElement addedElement = anchor.replace(elementToMove); - elementToMove.replace(anchorCopy); + final TextRange range = startToMove.getTextRange(); + final int column = editor.offsetToLogicalPosition(selectionStart).column; + final int additionalSelection = range.getStartOffset() > selectionStart ? range.getStartOffset() - selectionStart : 0; + if (startToMove == endToMove) return new SelectionContainer(selectionEnd - range.getStartOffset(), additionalSelection, column == 0); + int len = range.getStartOffset() <= selectionStart ? range.getEndOffset() - selectionStart : startToMove.getTextLength(); - return addedElement.getTextOffset(); + PsiElement tmp = startToMove.getNextSibling(); + while (tmp != endToMove && tmp != null) { + if (!(tmp instanceof PsiWhiteSpace)) + len += tmp.getTextLength(); + tmp = tmp.getNextSibling(); + } + len = len + selectionEnd - endToMove.getTextOffset(); + + return new SelectionContainer(len, additionalSelection, column == 0); } - private static int moveInOut(@NotNull final PsiElement elementToMove, @NotNull final Editor editor, @NotNull final MoveInfo info) { + private static void restoreCaretAndSelection(@NotNull final PsiFile file, @NotNull final Editor editor, boolean selectionStartAtCaret, + boolean hasSelection, @NotNull final SelectionContainer selectionContainer, int shift, + int offset, @NotNull final MyLineRange toMove) { + final Document document = editor.getDocument(); + final SelectionModel selectionModel = editor.getSelectionModel(); + final CaretModel caretModel = editor.getCaretModel(); + Integer selectionLen = selectionContainer.myLen; + final PsiElement at = file.findElementAt(offset); + if (at != null) { + final PsiElement added = getCommentOrStatement(document, at); + int size = toMove.size; + if (size > 1) { + PsiElement tmp = added.getNextSibling(); + while (size > 1 && tmp != null) { + if (tmp instanceof PsiWhiteSpace) { + if (!selectionStartAtCaret) + shift += tmp.getTextLength(); + selectionLen += tmp.getTextLength(); + } + tmp = tmp.getNextSibling(); + size -= 1; + } + } + if (shift < 0) shift = 0; + final int column = editor.offsetToLogicalPosition(added.getTextRange().getStartOffset()).column; + if (selectionContainer.myAtTheBeginning || column < selectionContainer.myAdditional) { + selectionLen += column; + } + else { + selectionLen += selectionContainer.myAdditional; + } + if (selectionContainer.myAtTheBeginning && selectionStartAtCaret) + shift = -column; + } + + final int documentLength = document.getTextLength(); + int newCaretOffset = offset + shift; + if (newCaretOffset >= documentLength) newCaretOffset = documentLength; + caretModel.moveToOffset(newCaretOffset); + + if (hasSelection) { + if (selectionStartAtCaret) { + int newSelectionEnd = newCaretOffset + selectionLen; + selectionModel.setSelection(newCaretOffset, newSelectionEnd); + } + else { + int newSelectionStart = newCaretOffset - selectionLen; + selectionModel.setSelection(newSelectionStart, newCaretOffset); + } + } + } + + private static int getCaretShift(PsiElement startToMove, PsiElement endToMove, CaretModel caretModel, boolean selectionStartAtCaret) { + int shift; + if (selectionStartAtCaret) { + shift = caretModel.getOffset() - startToMove.getTextRange().getStartOffset(); + } + else { + shift = caretModel.getOffset(); + if (startToMove != endToMove) { + shift += startToMove.getTextLength(); + + PsiElement tmp = startToMove.getNextSibling(); + while (tmp != endToMove && tmp != null) { + if (!(tmp instanceof PsiWhiteSpace)) + shift += tmp.getTextLength(); + tmp = tmp.getNextSibling(); + } + } + + shift -= endToMove.getTextOffset(); + } + return shift; + } + + private static int moveTheSameLevel(@NotNull final ScopeRange toMove2, @NotNull final MyLineRange toMove) { + final PsiElement anchor = toMove2.getAnchor(); + final PsiElement anchorCopy = anchor.copy(); + PsiElement startToMove = toMove.myStartElement; + final PsiElement endToMove = toMove.myEndElement; + + final PsiElement parent = anchor.getParent(); + PsiElement tmp = startToMove.getNextSibling(); + + if (startToMove != endToMove && tmp != null) { + parent.addRangeAfter(tmp, endToMove, anchor); + } + + PsiElement startCopy = startToMove.copy(); + startToMove.replace(anchorCopy); + final PsiElement addedElement = anchor.replace(startCopy); + + if (startToMove != endToMove && tmp != null) { + parent.deleteChildRange(tmp, endToMove); + } + + return addedElement.getTextRange().getStartOffset(); + } + + private static int moveInOut(@NotNull final MyLineRange toMove, @NotNull final Editor editor, @NotNull final MoveInfo info) { boolean removePass = false; final ScopeRange toMove2 = (ScopeRange)info.toMove2; final PsiElement scope = toMove2.getScope(); final PsiElement anchor = toMove2.getAnchor(); final Project project = scope.getProject(); - if (scope instanceof PyStatementList && !(elementToMove instanceof PsiComment)) { + final PsiElement startElement = toMove.myStartElement; + final PsiElement endElement = toMove.myEndElement; + PsiElement parent = startElement.getParent(); + + if (scope instanceof PyStatementList && !(startElement == endElement && startElement instanceof PsiComment)) { final PyStatement[] statements = ((PyStatementList)scope).getStatements(); if (statements.length == 1 && statements[0] == anchor && statements[0] instanceof PyPassStatement) { removePass = true; } } - final PsiElement addedElement = toMove2.isAddBefore() ? scope.addBefore(elementToMove, anchor) : scope.addAfter(elementToMove, anchor); - addPassStatement(elementToMove, project); + final PsiElement addedElement; + PsiElement nextSibling = startElement.getNextSibling(); + if (toMove2.isAddBefore()) { + PsiElement tmp = endElement.getPrevSibling(); + if (startElement != endElement && tmp != null) { + addedElement = scope.addRangeBefore(startElement, tmp, anchor); + scope.addBefore(endElement, anchor); + } + else { + addedElement = scope.addBefore(endElement, anchor); + } + } + else { + if (startElement != endElement) { + scope.addRangeAfter(nextSibling, endElement, anchor); + } + addedElement = scope.addAfter(startElement, anchor); + } + addPassStatement(toMove, project); - elementToMove.delete(); + if (startElement != endElement && nextSibling != null) { + parent.deleteChildRange(nextSibling, endElement); + } + startElement.delete(); final int addedElementLine = editor.getDocument().getLineNumber(addedElement.getTextOffset()); final PsiFile file = scope.getContainingFile(); - adjustLineIndents(editor, scope, project, addedElement); + adjustLineIndents(editor, scope, project, addedElement, toMove.size); if (removePass) { ApplicationManager.getApplication().runWriteAction(new Runnable() { @@ -348,23 +499,25 @@ public class PyStatementMover extends LineMover { final int endOffset = document.getLineCount() <= lineNumber + 1 ? document.getLineEndOffset(lineNumber) : document.getLineStartOffset(lineNumber + 1); document.deleteString(document.getLineStartOffset(lineNumber), endOffset); - PsiDocumentManager.getInstance(elementToMove.getProject()).commitAllDocuments(); + PsiDocumentManager.getInstance(startElement.getProject()).commitAllDocuments(); } }); } int offset = addedElement.getTextRange().getStartOffset(); - if ((addedElement instanceof PsiComment || addedElement instanceof PyPassStatement) && offset == 0) { // PsiComment gets broken after adjust indent - final PsiElement psiElement = PyUtil.findNonWhitespaceAtOffset(file, editor.getDocument().getLineEndOffset(addedElementLine) - 1); + int newLine = editor.getDocument().getLineNumber(offset); + if (newLine != addedElementLine && !removePass) { // PsiComment gets broken after adjust indent + PsiElement psiElement = PyUtil.findNonWhitespaceAtOffset(file, editor.getDocument().getLineEndOffset(addedElementLine) - 1); if (psiElement != null) { - offset = psiElement.getTextOffset(); + psiElement = getCommentOrStatement(editor.getDocument(), psiElement); + offset = psiElement.getTextRange().getStartOffset(); } } return offset; } private static void adjustLineIndents(@NotNull final Editor editor, @NotNull final PsiElement scope, @NotNull final Project project, - @NotNull final PsiElement addedElement) { + @NotNull final PsiElement addedElement, int size) { final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); final Document document = editor.getDocument(); @@ -372,35 +525,79 @@ public class PyStatementMover extends LineMover { int line1 = editor.offsetToLogicalPosition(scope.getTextRange().getStartOffset()).line; int line2 = editor.offsetToLogicalPosition(scope.getTextRange().getEndOffset()).line; codeStyleManager.adjustLineIndent(scope.getContainingFile(), - new TextRange(document.getLineStartOffset(line1), document.getLineStartOffset(line2))); + new TextRange(document.getLineStartOffset(line1), document.getLineEndOffset(line2))); } else { int line1 = editor.offsetToLogicalPosition(addedElement.getTextRange().getStartOffset()).line; - int line2 = editor.offsetToLogicalPosition(addedElement.getTextRange().getEndOffset()).line; + PsiElement end = addedElement; + while (size > 0) { + PsiElement tmp = end.getNextSibling(); + if (tmp == null) break; + size -= 1; + end = tmp; + } + int endOffset = end.getTextRange().getEndOffset(); + int line2 = editor.offsetToLogicalPosition(endOffset).line; codeStyleManager.adjustLineIndent(scope.getContainingFile(), - new TextRange(document.getLineStartOffset(line1), document.getLineStartOffset(line2))); + new TextRange(document.getLineStartOffset(line1), document.getLineEndOffset(line2))); } } - private static void addPassStatement(@NotNull final PsiElement elementToMove, @NotNull final Project project) { - final PyStatementList initialScope = getStatementList(elementToMove); - if (initialScope != null && !(elementToMove instanceof PsiComment)) { - if (initialScope.getStatements().length == 1) { + private static void addPassStatement(@NotNull final MyLineRange toMove, @NotNull final Project project) { + final PsiElement startElement = toMove.myStartElement; + final PsiElement endElement = toMove.myEndElement; + final PyStatementList initialScope = getStatementList(startElement); + + if (initialScope != null && !(startElement == endElement && startElement instanceof PsiComment)) { + if (initialScope.getStatements().length == toMove.statementsSize) { final PyPassStatement passStatement = PyElementGenerator.getInstance(project).createPassStatement(); initialScope.addAfter(passStatement, initialScope.getStatements()[initialScope.getStatements().length - 1]); } } } - // use to keep element + // use to keep elements static class MyLineRange extends LineRange { - public PsiElement myElement; - public MyLineRange(@NotNull PsiElement element) { - super(element); - myElement = element; + private PsiElement myStartElement; + private PsiElement myEndElement; + int size = 0; + int statementsSize = 0; + + public MyLineRange(@NotNull PsiElement start, PsiElement end) { + super(start, end); + myStartElement = start; + myEndElement = end; + + if (myStartElement == myEndElement) { + size = 1; + statementsSize = 1; + } + else { + PsiElement counter = myStartElement; + while (counter != myEndElement && counter != null) { + size += 1; + if (!(counter instanceof PsiWhiteSpace) && !(counter instanceof PsiComment)) + statementsSize += 1; + counter = counter.getNextSibling(); + } + size += 1; + if (!(counter instanceof PsiWhiteSpace) && !(counter instanceof PsiComment)) + statementsSize += 1; + } } } + static class SelectionContainer { + private int myLen; + private int myAdditional; + private boolean myAtTheBeginning; + + public SelectionContainer(int len, int additional, boolean atTheBeginning) { + myLen = len; + myAdditional = additional; + myAtTheBeginning = atTheBeginning; + } + } // Use when element scope changed static class ScopeRange extends LineRange { private PsiElement myScope; diff --git a/python/testData/mover/functionBlock.py b/python/testData/mover/functionBlock.py index 4d56a739773a..a1d82defb995 100644 --- a/python/testData/mover/functionBlock.py +++ b/python/testData/mover/functionBlock.py @@ -3,7 +3,7 @@ class A: def foo(self): pass - def bar(self): + def bar(self): pass def baz(self): diff --git a/python/testData/mover/functionBlock_afterDown.py b/python/testData/mover/functionBlock_afterDown.py index df7b1816f075..76573105c17b 100644 --- a/python/testData/mover/functionBlock_afterDown.py +++ b/python/testData/mover/functionBlock_afterDown.py @@ -6,5 +6,5 @@ class A: def baz(self): pass - def bar(self): + def bar(self): pass diff --git a/python/testData/mover/functionBlock_afterUp.py b/python/testData/mover/functionBlock_afterUp.py index 23e117f86deb..8e4c3e8e3449 100644 --- a/python/testData/mover/functionBlock_afterUp.py +++ b/python/testData/mover/functionBlock_afterUp.py @@ -1,6 +1,6 @@ class A: - def bar(self): + def bar(self): pass def foo(self): diff --git a/python/testData/mover/multiLineSelection.py b/python/testData/mover/multiLineSelection.py new file mode 100644 index 000000000000..a39dd09abfbe --- /dev/null +++ b/python/testData/mover/multiLineSelection.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 +a = 1 +b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection1.py b/python/testData/mover/multiLineSelection1.py new file mode 100644 index 000000000000..34793532bd96 --- /dev/null +++ b/python/testData/mover/multiLineSelection1.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection10.py b/python/testData/mover/multiLineSelection10.py new file mode 100644 index 000000000000..1feb611509ef --- /dev/null +++ b/python/testData/mover/multiLineSelection10.py @@ -0,0 +1,3 @@ +if True: + a = 2 + b = 3 \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection10_afterDown.py b/python/testData/mover/multiLineSelection10_afterDown.py new file mode 100644 index 000000000000..f7f86067d041 --- /dev/null +++ b/python/testData/mover/multiLineSelection10_afterDown.py @@ -0,0 +1,4 @@ +if True: + pass +a = 2 +b = 3 diff --git a/python/testData/mover/multiLineSelection10_afterUp.py b/python/testData/mover/multiLineSelection10_afterUp.py new file mode 100644 index 000000000000..c8820eb48b4a --- /dev/null +++ b/python/testData/mover/multiLineSelection10_afterUp.py @@ -0,0 +1,4 @@ +a = 2 +b = 3 +if True: + pass \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection1_afterDown.py b/python/testData/mover/multiLineSelection1_afterDown.py new file mode 100644 index 000000000000..bf6c71ded912 --- /dev/null +++ b/python/testData/mover/multiLineSelection1_afterDown.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection1_afterUp.py b/python/testData/mover/multiLineSelection1_afterUp.py new file mode 100644 index 000000000000..6bfe19a0e49f --- /dev/null +++ b/python/testData/mover/multiLineSelection1_afterUp.py @@ -0,0 +1,6 @@ +class Test(object): + + def q(self): + a = 1 + b = 2 + c = 3 diff --git a/python/testData/mover/multiLineSelection2.py b/python/testData/mover/multiLineSelection2.py new file mode 100644 index 000000000000..8f21d8f84386 --- /dev/null +++ b/python/testData/mover/multiLineSelection2.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection2_afterDown.py b/python/testData/mover/multiLineSelection2_afterDown.py new file mode 100644 index 000000000000..a39dd09abfbe --- /dev/null +++ b/python/testData/mover/multiLineSelection2_afterDown.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 +a = 1 +b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection2_afterUp.py b/python/testData/mover/multiLineSelection2_afterUp.py new file mode 100644 index 000000000000..b4d97ba6442c --- /dev/null +++ b/python/testData/mover/multiLineSelection2_afterUp.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection3.py b/python/testData/mover/multiLineSelection3.py new file mode 100644 index 000000000000..16d4f334c15e --- /dev/null +++ b/python/testData/mover/multiLineSelection3.py @@ -0,0 +1,6 @@ +class Test(object): + + def q(self): + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection3_afterDown.py b/python/testData/mover/multiLineSelection3_afterDown.py new file mode 100644 index 000000000000..37979de98e2f --- /dev/null +++ b/python/testData/mover/multiLineSelection3_afterDown.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + pass + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection3_afterUp.py b/python/testData/mover/multiLineSelection3_afterUp.py new file mode 100644 index 000000000000..1eb7f260008e --- /dev/null +++ b/python/testData/mover/multiLineSelection3_afterUp.py @@ -0,0 +1,6 @@ +class Test(object): + + a = 1 + b = 2 + def q(self): + pass diff --git a/python/testData/mover/multiLineSelection4.py b/python/testData/mover/multiLineSelection4.py new file mode 100644 index 000000000000..366f1416dc57 --- /dev/null +++ b/python/testData/mover/multiLineSelection4.py @@ -0,0 +1,5 @@ +class Test(object): + a = 1 + b = 2 + def q(self): + c = 3 diff --git a/python/testData/mover/multiLineSelection4_afterDown.py b/python/testData/mover/multiLineSelection4_afterDown.py new file mode 100644 index 000000000000..12acd9e4d62a --- /dev/null +++ b/python/testData/mover/multiLineSelection4_afterDown.py @@ -0,0 +1,5 @@ +class Test(object): + def q(self): + a = 1 + b = 2 + c = 3 diff --git a/python/testData/mover/multiLineSelection4_afterUp.py b/python/testData/mover/multiLineSelection4_afterUp.py new file mode 100644 index 000000000000..77efa8867436 --- /dev/null +++ b/python/testData/mover/multiLineSelection4_afterUp.py @@ -0,0 +1,5 @@ +a = 1 +b = 2 +class Test(object): + def q(self): + c = 3 diff --git a/python/testData/mover/multiLineSelection5.py b/python/testData/mover/multiLineSelection5.py new file mode 100644 index 000000000000..c80458f7fdbf --- /dev/null +++ b/python/testData/mover/multiLineSelection5.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 +a = 1 +b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection5_afterDown.py b/python/testData/mover/multiLineSelection5_afterDown.py new file mode 100644 index 000000000000..090fc013c9cb --- /dev/null +++ b/python/testData/mover/multiLineSelection5_afterDown.py @@ -0,0 +1,8 @@ +class Test(object): + + def q(self): + c = 3 + +a = 1 +b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection5_afterUp.py b/python/testData/mover/multiLineSelection5_afterUp.py new file mode 100644 index 000000000000..43c1869a9ca4 --- /dev/null +++ b/python/testData/mover/multiLineSelection5_afterUp.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection6.py b/python/testData/mover/multiLineSelection6.py new file mode 100644 index 000000000000..ff550717771d --- /dev/null +++ b/python/testData/mover/multiLineSelection6.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection6_afterDown.py b/python/testData/mover/multiLineSelection6_afterDown.py new file mode 100644 index 000000000000..9f25091fc0ad --- /dev/null +++ b/python/testData/mover/multiLineSelection6_afterDown.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection6_afterUp.py b/python/testData/mover/multiLineSelection6_afterUp.py new file mode 100644 index 000000000000..7271ffca7fee --- /dev/null +++ b/python/testData/mover/multiLineSelection6_afterUp.py @@ -0,0 +1,6 @@ +class Test(object): + + def q(self): + a = 1 + b = 2 + c = 3 diff --git a/python/testData/mover/multiLineSelection7.py b/python/testData/mover/multiLineSelection7.py new file mode 100644 index 000000000000..295eaa3575b4 --- /dev/null +++ b/python/testData/mover/multiLineSelection7.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection7_afterDown.py b/python/testData/mover/multiLineSelection7_afterDown.py new file mode 100644 index 000000000000..c4fca890ce9a --- /dev/null +++ b/python/testData/mover/multiLineSelection7_afterDown.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 +a = 1 +b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection7_afterUp.py b/python/testData/mover/multiLineSelection7_afterUp.py new file mode 100644 index 000000000000..e9bd1d5d304f --- /dev/null +++ b/python/testData/mover/multiLineSelection7_afterUp.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection8.py b/python/testData/mover/multiLineSelection8.py new file mode 100644 index 000000000000..230368c45f49 --- /dev/null +++ b/python/testData/mover/multiLineSelection8.py @@ -0,0 +1,6 @@ +class Test(object): + + def q(self): + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection8_afterDown.py b/python/testData/mover/multiLineSelection8_afterDown.py new file mode 100644 index 000000000000..f5959ba6eba1 --- /dev/null +++ b/python/testData/mover/multiLineSelection8_afterDown.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + pass + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection8_afterUp.py b/python/testData/mover/multiLineSelection8_afterUp.py new file mode 100644 index 000000000000..09549a464544 --- /dev/null +++ b/python/testData/mover/multiLineSelection8_afterUp.py @@ -0,0 +1,6 @@ +class Test(object): + + a = 1 + b = 2 + def q(self): + pass diff --git a/python/testData/mover/multiLineSelection9.py b/python/testData/mover/multiLineSelection9.py new file mode 100644 index 000000000000..48303dee4344 --- /dev/null +++ b/python/testData/mover/multiLineSelection9.py @@ -0,0 +1,5 @@ +class Test(object): + a = 1 + b = 2 + def q(self): + c = 3 diff --git a/python/testData/mover/multiLineSelection9_afterDown.py b/python/testData/mover/multiLineSelection9_afterDown.py new file mode 100644 index 000000000000..304eef1d5353 --- /dev/null +++ b/python/testData/mover/multiLineSelection9_afterDown.py @@ -0,0 +1,5 @@ +class Test(object): + def q(self): + a = 1 + b = 2 + c = 3 diff --git a/python/testData/mover/multiLineSelection9_afterUp.py b/python/testData/mover/multiLineSelection9_afterUp.py new file mode 100644 index 000000000000..2443faf6c509 --- /dev/null +++ b/python/testData/mover/multiLineSelection9_afterUp.py @@ -0,0 +1,5 @@ +a = 1 +b = 2 +class Test(object): + def q(self): + c = 3 diff --git a/python/testData/mover/multiLineSelection_afterDown.py b/python/testData/mover/multiLineSelection_afterDown.py new file mode 100644 index 000000000000..68ff29f877c2 --- /dev/null +++ b/python/testData/mover/multiLineSelection_afterDown.py @@ -0,0 +1,8 @@ +class Test(object): + + def q(self): + c = 3 + +a = 1 +b = 2 + \ No newline at end of file diff --git a/python/testData/mover/multiLineSelection_afterUp.py b/python/testData/mover/multiLineSelection_afterUp.py new file mode 100644 index 000000000000..bf6c71ded912 --- /dev/null +++ b/python/testData/mover/multiLineSelection_afterUp.py @@ -0,0 +1,7 @@ +class Test(object): + + def q(self): + c = 3 + a = 1 + b = 2 + \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyStatementMoverTest.java b/python/testSrc/com/jetbrains/python/PyStatementMoverTest.java index cfa467515ab3..63bf2623195a 100644 --- a/python/testSrc/com/jetbrains/python/PyStatementMoverTest.java +++ b/python/testSrc/com/jetbrains/python/PyStatementMoverTest.java @@ -188,10 +188,55 @@ public class PyStatementMoverTest extends PyTestCase { public void testLastComment1() { //PY-6408 doTest(); } + public void testMultiCompound() { //PY-7658 doTest(); } + public void testMultiLineSelection() { + doTest(); + } + + public void testMultiLineSelection1() { + doTest(); + } + + public void testMultiLineSelection2() { + doTest(); + } + + public void testMultiLineSelection3() { + doTest(); + } + + public void testMultiLineSelection4() { + doTest(); + } + + public void testMultiLineSelection5() { //0 + doTest(); + } + + public void testMultiLineSelection6() { + doTest(); + } + + public void testMultiLineSelection7() { + doTest(); + } + + public void testMultiLineSelection8() { + doTest(); + } + + public void testMultiLineSelection9() { + doTest(); + } + + public void testMultiLineSelection10() { + doTest(); + } + public void testWith() { // PY-5202 try { setLanguageLevel(LanguageLevel.PYTHON27);