diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml
index 6b42aefb4daf..8d88911afb8d 100644
--- a/python/src/META-INF/python-plugin-common.xml
+++ b/python/src/META-INF/python-plugin-common.xml
@@ -139,6 +139,8 @@
+
diff --git a/python/src/com/jetbrains/python/codeInsight/editorActions/moveUpDown/StatementMover.java b/python/src/com/jetbrains/python/codeInsight/editorActions/moveUpDown/StatementMover.java
new file mode 100644
index 000000000000..52f0ddfe47fe
--- /dev/null
+++ b/python/src/com/jetbrains/python/codeInsight/editorActions/moveUpDown/StatementMover.java
@@ -0,0 +1,342 @@
+package com.jetbrains.python.codeInsight.editorActions.moveUpDown;
+
+import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.editorActions.moveUpDown.LineMover;
+import com.intellij.codeInsight.editorActions.moveUpDown.LineRange;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.LogicalPosition;
+import com.intellij.openapi.editor.SelectionModel;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiDocumentManagerImpl;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.jetbrains.python.psi.*;
+import com.jetbrains.python.psi.impl.PyPsiUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Author: Alexey.Ivanov
+ * Date: 23.04.2010
+ * Time: 16:44:57
+ */
+public class StatementMover extends LineMover {
+ private static final Logger LOG = Logger.getInstance("#com.jetbrains.python.codeInsight.editorActions.moveUpDown.StatementMover");
+
+ private static PsiElement[] findStatementsInRange(PsiFile file, int startOffset, int endOffset) {
+ PsiElement element1 = file.findElementAt(startOffset);
+ PsiElement element2 = file.findElementAt(endOffset - 1);
+ if (element1 instanceof PsiWhiteSpace) {
+ startOffset = element1.getTextRange().getEndOffset();
+ element1 = file.findElementAt(startOffset);
+ }
+ if (element2 instanceof PsiWhiteSpace) {
+ endOffset = element2.getTextRange().getStartOffset();
+ element2 = file.findElementAt(endOffset - 1);
+ }
+ if (element1 == null || element2 == null) {
+ return PsiElement.EMPTY_ARRAY;
+ }
+
+ PsiElement parent = PsiTreeUtil.findCommonParent(element1, element2);
+ if (parent == null) {
+ return PsiElement.EMPTY_ARRAY;
+ }
+
+ while (true) {
+ if (parent instanceof PyStatement) {
+ parent = parent.getParent();
+ break;
+ }
+ if (parent instanceof PyStatementList) {
+ break;
+ }
+ if (parent == null || parent instanceof PsiFile) {
+ return PsiElement.EMPTY_ARRAY;
+ }
+ parent = parent.getParent();
+ }
+
+ if (!parent.equals(element1)) {
+ while (!parent.equals(element1.getParent())) {
+ element1 = element1.getParent();
+ }
+ }
+
+ if (!parent.equals(element2)) {
+ while (!parent.equals(element2.getParent())) {
+ element2 = element2.getParent();
+ }
+ }
+
+ PsiElement[] children = parent.getChildren();
+ ArrayList array = new ArrayList();
+ boolean flag = false;
+ for (PsiElement child : children) {
+ if (child.equals(element1)) {
+ flag = true;
+ }
+ if (flag && !(child instanceof PsiWhiteSpace)) {
+ array.add(child);
+ }
+ if (child.equals(element2)) {
+ break;
+ }
+ }
+
+ for (PsiElement element : array) {
+ if (!(element instanceof PyStatement || element instanceof PsiWhiteSpace || element instanceof PsiComment)) {
+ return PsiElement.EMPTY_ARRAY;
+ }
+ }
+ return array.toArray(new PsiElement[array.size()]);
+ }
+
+ private static boolean isNotValidStatementRange(Pair range) {
+ return range == null ||
+ range.first == null ||
+ range.second == null ||
+ range.first.getParent() != range.second.getParent();
+ }
+
+ @Nullable
+ private static LineRange expandLineRange(LineRange range, Editor editor, PsiFile file) {
+ final SelectionModel selectionModel = editor.getSelectionModel();
+ Pair psiRange;
+ if (selectionModel.hasSelection()) {
+ final int startOffset = selectionModel.getSelectionStart();
+ final int endOffset = selectionModel.getSelectionEnd();
+ final PsiElement[] psiElements = findStatementsInRange(file, startOffset, endOffset);
+ if (psiElements.length == 0) {
+ return null;
+ }
+ psiRange = new Pair(psiElements[0], psiElements[psiElements.length - 1]);
+ }
+ else {
+ final int offset = editor.getCaretModel().getOffset();
+ PsiElement element = file.findElementAt(offset);
+ psiRange = new Pair(element, element);
+ }
+
+ psiRange = new Pair(PsiTreeUtil.getNonStrictParentOfType(psiRange.getFirst(), PyStatement.class),
+ PsiTreeUtil.getNonStrictParentOfType(psiRange.getSecond(), PyStatement.class));
+ if (psiRange.getFirst() == null || psiRange.getSecond() == null) {
+ return null;
+ }
+
+ final PsiElement parent = PsiTreeUtil.findCommonParent(psiRange.getFirst(), psiRange.getSecond());
+ final Pair elementRange = getElementRange(parent, psiRange.getFirst(), psiRange.getSecond());
+ if (isNotValidStatementRange(elementRange)) {
+ return null;
+ }
+
+ if (elementRange.getFirst() == elementRange.getSecond() && elementRange.getFirst() instanceof PyPassStatement) {
+ return null;
+ }
+
+ final int endOffset = elementRange.getSecond().getTextRange().getEndOffset();
+ final Document document = editor.getDocument();
+ if (endOffset > document.getTextLength()) {
+ LOG.assertTrue(!PsiDocumentManager.getInstance(file.getProject()).isUncommited(document));
+ LOG.assertTrue(PsiDocumentManagerImpl.checkConsistency(file, document));
+ }
+
+ int endLine;
+ if (endOffset == document.getTextLength()) {
+ endLine = document.getLineCount();
+ }
+ else {
+ endLine = editor.offsetToLogicalPosition(endOffset).line + 1;
+ endLine = Math.min(endLine, document.getLineCount());
+ }
+ endLine = Math.max(endLine, range.endLine);
+ final int startLine = Math.min(range.startLine, editor.offsetToLogicalPosition(elementRange.getFirst().getTextOffset()).line);
+ return new LineRange(startLine, endLine);
+ }
+
+ private @Nullable PyStatementList myStatementListToAddPass;
+ private @Nullable PyStatementList myStatementListToRemovePass;
+ private @NotNull PsiElement[] myElementsToDecreaseIndent;
+ private @NotNull PsiElement[] myElementsToIncreaseIndent;
+
+ @Override
+ public boolean checkAvailable(@NotNull Editor editor,
+ @NotNull PsiFile file,
+ @NotNull MoveInfo info,
+ boolean down) {
+ myStatementListToAddPass = null;
+ myStatementListToRemovePass = null;
+ myElementsToDecreaseIndent = PsiElement.EMPTY_ARRAY;
+ myElementsToIncreaseIndent = PsiElement.EMPTY_ARRAY;
+ if (!super.checkAvailable(editor, file, info, down)) {
+ return false;
+ }
+ info.indentSource = true;
+ final LineRange range = expandLineRange(info.toMove, editor, file);
+ if (range == null) {
+ return false;
+ }
+
+ info.toMove = range;
+ final int startOffset = editor.logicalPositionToOffset(new LogicalPosition(range.startLine, 0));
+ final int endOffset = editor.logicalPositionToOffset(new LogicalPosition(range.endLine, 0));
+ final PsiElement[] statements = findStatementsInRange(file, startOffset, endOffset);
+ final int length = statements.length;
+ if (length == 0) {
+ return false;
+ }
+
+ range.firstElement = statements[0];
+ range.lastElement = statements[length - 1];
+ final Document document = editor.getDocument();
+ PyStatement statement;
+ assert info.toMove2.startLine + 1 == info.toMove2.endLine;
+ if (down) {
+ statement = PsiTreeUtil.getNextSiblingOfType(range.lastElement, PyStatement.class);
+ }
+ else {
+ statement = PsiTreeUtil.getPrevSiblingOfType(range.firstElement, PyStatement.class);
+ }
+
+ if (statement == null) {
+ final PyStatementPart parentStatementPart =
+ PsiTreeUtil.getParentOfType(PsiTreeUtil.findCommonParent(range.firstElement, range.lastElement), PyStatementPart.class, false);
+ if (parentStatementPart == null) {
+ info.toMove2 = null;
+ }
+ else { //we are in statement part
+
+ final PyStatementList statementList = parentStatementPart.getStatementList();
+ assert statementList != null;
+ if (down) {
+ final PyStatementPart nextStatementPart = PsiTreeUtil.getNextSiblingOfType(statementList.getParent(), PyStatementPart.class);
+ if (nextStatementPart != null) {
+ info.toMove2 = new LineRange(range.endLine, range.endLine + 1);
+ myStatementListToRemovePass = nextStatementPart.getStatementList();
+ }
+ else {
+ final PyStatement parentStatement = PsiTreeUtil.getParentOfType(statementList, PyStatement.class);
+ if (parentStatement == null) {
+ return false;
+ }
+ final PyStatement nextStatement = PsiTreeUtil.getNextSiblingOfType(parentStatement, PyStatement.class);
+ if (nextStatement == null) {
+ return false;
+ }
+ final int startLine = editor.offsetToLogicalPosition(parentStatement.getTextRange().getEndOffset()).line;
+ final int endLine = editor.offsetToLogicalPosition(nextStatement.getTextRange().getEndOffset()).line;
+ info.toMove2 = new LineRange(startLine + 1, endLine + 1);
+
+ myElementsToDecreaseIndent = statements;
+ }
+ }
+ else {
+ final PyStatementPart prevStatementPart = PsiTreeUtil.getPrevSiblingOfType(statementList.getParent(), PyStatementPart.class);
+ if (prevStatementPart != null) {
+ myStatementListToRemovePass = prevStatementPart.getStatementList();
+ }
+ else {
+ myElementsToDecreaseIndent = statements;
+ info.toMove2 = new LineRange(range.startLine - 1, range.startLine);
+ }
+ }
+ if (Arrays.equals(statementList.getStatements(), statements)) {
+ myStatementListToAddPass = statementList;
+ }
+ }
+ return true;
+ }
+
+ info.toMove2 = new LineRange(statement, statement, document);
+
+ final PyStatementPart[] statementParts = PsiTreeUtil.getChildrenOfType(statement, PyStatementPart.class);
+ // next/previous statement has a statement parts
+ if (statementParts != null) {
+ // move inside statement part
+ if (down) {
+ final PyStatementPart statementPart = statementParts[0];
+ final int lineNumber = document.getLineNumber(statementPart.getTextRange().getStartOffset());
+ info.toMove2 = new LineRange(lineNumber, lineNumber + 1);
+ myStatementListToRemovePass = statementPart.getStatementList();
+ myElementsToIncreaseIndent = statements;
+ }
+ else {
+ final PyStatementPart statementPart = statementParts[statementParts.length - 1];
+ final int lineNumber = document.getLineNumber(statementPart.getTextRange().getEndOffset());
+ info.toMove2 = new LineRange(lineNumber, lineNumber + 1);
+ myStatementListToRemovePass = statementPart.getStatementList();
+ myElementsToIncreaseIndent = statements;
+ }
+ }
+ return true;
+ }
+
+ private void decreaseIndent(final Editor editor) {
+ final Document document = editor.getDocument();
+ for (PsiElement statement : myElementsToDecreaseIndent) {
+ final int startOffset = statement.getTextRange().getStartOffset() - 1;
+ PsiElement element = statement.getContainingFile().findElementAt(startOffset);
+ assert element instanceof PsiWhiteSpace;
+ final String text = element.getText();
+ String[] lines = text.split("\n");
+ if (lines.length == 0) {
+ continue;
+ }
+ final int indent = lines[lines.length - 1].length();
+ final int startLine = editor.offsetToLogicalPosition(startOffset).line;
+ final int endLine = editor.offsetToLogicalPosition(statement.getTextRange().getEndOffset()).line;
+ for (int line = startLine; line <= endLine; ++line) {
+ if (indent >= 4) {
+ final int lineStartOffset = document.getLineStartOffset(line);
+ document.deleteString(lineStartOffset, lineStartOffset + 4);
+ }
+ }
+ }
+ }
+
+ private void increaseIndent(final Editor editor) {
+ final Document document = editor.getDocument();
+ for (PsiElement statement : myElementsToIncreaseIndent) {
+ final int startLine = editor.offsetToLogicalPosition(statement.getTextRange().getStartOffset()).line;
+ final int endLine = editor.offsetToLogicalPosition(statement.getTextRange().getEndOffset()).line;
+ for (int line = startLine; line <= endLine; ++line) {
+ final int offset = document.getLineStartOffset(line);
+ document.insertString(offset, " ");
+ }
+ }
+ }
+
+ @Override
+ public void beforeMove(@NotNull Editor editor, @NotNull MoveInfo info, boolean down) {
+ super.beforeMove(editor, info, down);
+ if (myStatementListToAddPass != null) {
+ final PyPassStatement passStatement =
+ PyElementGenerator.getInstance(editor.getProject()).createFromText(PyPassStatement.class, "pass");
+ myStatementListToAddPass.add(passStatement);
+ CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(myStatementListToAddPass);
+ if (down) {
+ info.toMove2 = new LineRange(info.toMove2.startLine, info.toMove2.endLine + 1);
+ }
+ }
+ decreaseIndent(editor);
+ increaseIndent(editor);
+ }
+
+ @Override
+ public void afterMove(@NotNull Editor editor,
+ @NotNull PsiFile file,
+ @NotNull MoveInfo info,
+ boolean down) {
+ super.afterMove(editor, file, info, down);
+ if (myStatementListToRemovePass != null) {
+ PyPsiUtils.removeRedundantPass(myStatementListToRemovePass);
+ CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(myStatementListToRemovePass);
+ }
+ }
+}
diff --git a/python/testData/mover/betweenStatementParts.py b/python/testData/mover/betweenStatementParts.py
new file mode 100644
index 000000000000..d8e5331036a2
--- /dev/null
+++ b/python/testData/mover/betweenStatementParts.py
@@ -0,0 +1,8 @@
+class A:
+ def f(self, a, b):
+ if a:
+ b = 1
+ elif b:
+ a = 1
+ else:
+ print "a"
\ No newline at end of file
diff --git a/python/testData/mover/betweenStatementParts_afterDown.py b/python/testData/mover/betweenStatementParts_afterDown.py
new file mode 100644
index 000000000000..9346f868a30f
--- /dev/null
+++ b/python/testData/mover/betweenStatementParts_afterDown.py
@@ -0,0 +1,9 @@
+class A:
+ def f(self, a, b):
+ if a:
+ b = 1
+ elif b:
+ pass
+ else:
+ a = 1
+ print "a"
\ No newline at end of file
diff --git a/python/testData/mover/betweenStatementParts_afterUp.py b/python/testData/mover/betweenStatementParts_afterUp.py
new file mode 100644
index 000000000000..c30178e4267e
--- /dev/null
+++ b/python/testData/mover/betweenStatementParts_afterUp.py
@@ -0,0 +1,9 @@
+class A:
+ def f(self, a, b):
+ if a:
+ b = 1
+ a = 1
+ elif b:
+ pass
+ else:
+ print "a"
\ No newline at end of file
diff --git a/python/testData/mover/functions.py b/python/testData/mover/functions.py
new file mode 100644
index 000000000000..1bacefed9bca
--- /dev/null
+++ b/python/testData/mover/functions.py
@@ -0,0 +1,9 @@
+class A:
+ def a(self):
+ doSomething()
+
+ def b(self):
+ doSomething()
+
+ def c(self):
+ doSomething()
\ No newline at end of file
diff --git a/python/testData/mover/functions_afterDown.py b/python/testData/mover/functions_afterDown.py
new file mode 100644
index 000000000000..59a4c20af1fc
--- /dev/null
+++ b/python/testData/mover/functions_afterDown.py
@@ -0,0 +1,9 @@
+class A:
+ def a(self):
+ doSomething()
+
+ def c(self):
+ doSomething()
+
+ def b(self):
+ doSomething()
diff --git a/python/testData/mover/functions_afterUp.py b/python/testData/mover/functions_afterUp.py
new file mode 100644
index 000000000000..4f1eff1075a8
--- /dev/null
+++ b/python/testData/mover/functions_afterUp.py
@@ -0,0 +1,9 @@
+class A:
+ def b(self):
+ doSomething()
+
+ def a(self):
+ doSomething()
+
+ def c(self):
+ doSomething()
\ No newline at end of file
diff --git a/python/testData/mover/insideStatement.py b/python/testData/mover/insideStatement.py
new file mode 100644
index 000000000000..18674b34c9a8
--- /dev/null
+++ b/python/testData/mover/insideStatement.py
@@ -0,0 +1,8 @@
+def foo(a, b):
+ if a:
+ pass
+ else:
+ pass
+ a = 3
+ if b:
+ pass
\ No newline at end of file
diff --git a/python/testData/mover/insideStatement_afterDown.py b/python/testData/mover/insideStatement_afterDown.py
new file mode 100644
index 000000000000..4aa368a28aa0
--- /dev/null
+++ b/python/testData/mover/insideStatement_afterDown.py
@@ -0,0 +1,7 @@
+def foo(a, b):
+ if a:
+ pass
+ else:
+ pass
+ if b:
+ a = 3
diff --git a/python/testData/mover/insideStatement_afterUp.py b/python/testData/mover/insideStatement_afterUp.py
new file mode 100644
index 000000000000..3a65b21c0638
--- /dev/null
+++ b/python/testData/mover/insideStatement_afterUp.py
@@ -0,0 +1,7 @@
+def foo(a, b):
+ if a:
+ pass
+ else:
+ a = 3
+ if b:
+ pass
\ No newline at end of file
diff --git a/python/testData/mover/moveStatement.py b/python/testData/mover/moveStatement.py
new file mode 100644
index 000000000000..ce6d5a1fe7f4
--- /dev/null
+++ b/python/testData/mover/moveStatement.py
@@ -0,0 +1,12 @@
+class A:
+ def f(self, a, b):
+ while a:
+ a = a / 2
+ if a:
+ b = 1
+ elif b:
+ a = 1
+ else:
+ print "a"
+ for i in range(1, 10):
+ print i
\ No newline at end of file
diff --git a/python/testData/mover/moveStatement_afterDown.py b/python/testData/mover/moveStatement_afterDown.py
new file mode 100644
index 000000000000..122225af45d6
--- /dev/null
+++ b/python/testData/mover/moveStatement_afterDown.py
@@ -0,0 +1,12 @@
+class A:
+ def f(self, a, b):
+ while a:
+ a = a / 2
+ for i in range(1, 10):
+ if a:
+ b = 1
+ elif b:
+ a = 1
+ else:
+ print "a"
+ print i
\ No newline at end of file
diff --git a/python/testData/mover/moveStatement_afterUp.py b/python/testData/mover/moveStatement_afterUp.py
new file mode 100644
index 000000000000..25bb65e44bdc
--- /dev/null
+++ b/python/testData/mover/moveStatement_afterUp.py
@@ -0,0 +1,12 @@
+class A:
+ def f(self, a, b):
+ while a:
+ if a:
+ b = 1
+ elif b:
+ a = 1
+ else:
+ print "a"
+ a = a / 2
+ for i in range(1, 10):
+ print i
\ No newline at end of file
diff --git a/python/testData/mover/outsideStatement.py b/python/testData/mover/outsideStatement.py
new file mode 100644
index 000000000000..262d3c6b06a0
--- /dev/null
+++ b/python/testData/mover/outsideStatement.py
@@ -0,0 +1,6 @@
+a = 1
+
+if a:
+ a = 3
+
+a = 4
\ No newline at end of file
diff --git a/python/testData/mover/outsideStatement_afterDown.py b/python/testData/mover/outsideStatement_afterDown.py
new file mode 100644
index 000000000000..dbf351cf442f
--- /dev/null
+++ b/python/testData/mover/outsideStatement_afterDown.py
@@ -0,0 +1,7 @@
+a = 1
+
+if a:
+ pass
+
+a = 4
+a = 3
diff --git a/python/testData/mover/outsideStatement_afterUp.py b/python/testData/mover/outsideStatement_afterUp.py
new file mode 100644
index 000000000000..11eae085d793
--- /dev/null
+++ b/python/testData/mover/outsideStatement_afterUp.py
@@ -0,0 +1,7 @@
+a = 1
+
+a = 3
+if a:
+ pass
+
+a = 4
\ No newline at end of file
diff --git a/python/testData/mover/selection.py b/python/testData/mover/selection.py
new file mode 100644
index 000000000000..d8cbff6450f7
--- /dev/null
+++ b/python/testData/mover/selection.py
@@ -0,0 +1,11 @@
+def f(a, b, c):
+ if b:
+ pass
+ elif a:
+ c = 1
+ if b:
+ a = 3
+ else:
+ b = 4
+ else:
+ pass
diff --git a/python/testData/mover/selection_afterDown.py b/python/testData/mover/selection_afterDown.py
new file mode 100644
index 000000000000..d155980979bf
--- /dev/null
+++ b/python/testData/mover/selection_afterDown.py
@@ -0,0 +1,11 @@
+def f(a, b, c):
+ if b:
+ pass
+ elif a:
+ pass
+ else:
+ c = 1
+ if b:
+ a = 3
+ else:
+ b = 4
diff --git a/python/testData/mover/selection_afterUp.py b/python/testData/mover/selection_afterUp.py
new file mode 100644
index 000000000000..c809c94ab1c4
--- /dev/null
+++ b/python/testData/mover/selection_afterUp.py
@@ -0,0 +1,11 @@
+def f(a, b, c):
+ if b:
+ c = 1
+ if b:
+ a = 3
+ else:
+ b = 4
+ elif a:
+ pass
+ else:
+ pass
diff --git a/python/testData/mover/simple.py b/python/testData/mover/simple.py
new file mode 100644
index 000000000000..cfdc0f47eac3
--- /dev/null
+++ b/python/testData/mover/simple.py
@@ -0,0 +1,2 @@
+a = 1
+b = 2
diff --git a/python/testData/mover/simple_afterDown.py b/python/testData/mover/simple_afterDown.py
new file mode 100644
index 000000000000..1ff50af0c469
--- /dev/null
+++ b/python/testData/mover/simple_afterDown.py
@@ -0,0 +1,2 @@
+b = 2
+a = 1
diff --git a/python/testData/mover/simple_afterUp.py b/python/testData/mover/simple_afterUp.py
new file mode 100644
index 000000000000..223ca50d9950
--- /dev/null
+++ b/python/testData/mover/simple_afterUp.py
@@ -0,0 +1,2 @@
+a = 1
+b = 2
diff --git a/python/testSrc/com/jetbrains/python/PyStatementMoverTest.java b/python/testSrc/com/jetbrains/python/PyStatementMoverTest.java
new file mode 100644
index 000000000000..2fa8ead98a2c
--- /dev/null
+++ b/python/testSrc/com/jetbrains/python/PyStatementMoverTest.java
@@ -0,0 +1,63 @@
+package com.jetbrains.python;
+
+import com.intellij.codeInsight.editorActions.moveUpDown.MoveStatementDownAction;
+import com.intellij.codeInsight.editorActions.moveUpDown.MoveStatementUpAction;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.jetbrains.python.fixtures.PyLightFixtureTestCase;
+
+/**
+ * Created by IntelliJ IDEA.
+ * Author: Alexey.Ivanov
+ * Date: 05.05.2010
+ * Time: 18:20:20
+ */
+public class PyStatementMoverTest extends PyLightFixtureTestCase {
+ private void doTest() throws Exception {
+ final String testName = getTestName(true);
+ myFixture.configureByFile("mover/" + testName + ".py");
+ performAction(new MoveStatementUpAction().getHandler());
+ myFixture.checkResultByFile("mover/" + testName + "_afterUp.py", true);
+
+ FileDocumentManager.getInstance().reloadFromDisk(myFixture.getDocument(myFixture.getFile()));
+ myFixture.configureByFile("mover/" + getTestName(true) + ".py");
+ performAction(new MoveStatementDownAction().getHandler());
+ myFixture.checkResultByFile("mover/" + testName + "_afterDown.py", true);
+ }
+
+ private void performAction(EditorActionHandler handler) {
+ final Editor editor = myFixture.getEditor();
+ if (handler.isEnabled(editor, null)) {
+ handler.execute(editor, null);
+ }
+ }
+
+ public void testSimple() throws Exception {
+ doTest();
+ }
+
+ public void testOutsideStatement() throws Exception {
+ doTest();
+ }
+
+ public void testInsideStatement() throws Exception {
+ doTest();
+ }
+
+ public void testFunctions() throws Exception {
+ doTest();
+ }
+
+ public void testBetweenStatementParts() throws Exception {
+ doTest();
+ }
+
+ public void testMoveStatement() throws Exception {
+ doTest();
+ }
+
+ public void testSelection() throws Exception {
+ doTest();
+ }
+}