mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 18:05:27 +07:00
PY-296 'Move statement up/down' on method name line should move the whole method
This commit is contained in:
@@ -139,6 +139,8 @@
|
||||
<codeInsight.gotoSuper language="Python" implementationClass="com.jetbrains.python.codeInsight.PyGotoSuperHandler"/>
|
||||
<gotoDeclarationHandler implementation="com.jetbrains.python.codeInsight.PyBreakContinueGotoProvider" order="FIRST"/>
|
||||
<lang.smartEnterProcessor language="Python" implementationClass="com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor"/>
|
||||
<statementUpDownMover implementation="com.jetbrains.python.codeInsight.editorActions.moveUpDown.StatementMover" id="statement"
|
||||
order="before line"/>
|
||||
|
||||
<filePropertyPusher implementation="com.jetbrains.python.psi.impl.PythonLanguageLevelPusher"/>
|
||||
|
||||
|
||||
@@ -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<PsiElement> array = new ArrayList<PsiElement>();
|
||||
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<PsiElement, PsiElement> 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<PsiElement, PsiElement> 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<PsiElement, PsiElement>(psiElements[0], psiElements[psiElements.length - 1]);
|
||||
}
|
||||
else {
|
||||
final int offset = editor.getCaretModel().getOffset();
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
psiRange = new Pair<PsiElement, PsiElement>(element, element);
|
||||
}
|
||||
|
||||
psiRange = new Pair<PsiElement, PsiElement>(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<PsiElement, PsiElement> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
python/testData/mover/betweenStatementParts.py
Normal file
8
python/testData/mover/betweenStatementParts.py
Normal file
@@ -0,0 +1,8 @@
|
||||
class A:
|
||||
def f(self, a, b):
|
||||
if a:
|
||||
b = 1
|
||||
elif b:
|
||||
a = <caret>1
|
||||
else:
|
||||
print "a"
|
||||
9
python/testData/mover/betweenStatementParts_afterDown.py
Normal file
9
python/testData/mover/betweenStatementParts_afterDown.py
Normal file
@@ -0,0 +1,9 @@
|
||||
class A:
|
||||
def f(self, a, b):
|
||||
if a:
|
||||
b = 1
|
||||
elif b:
|
||||
pass
|
||||
else:
|
||||
a = 1
|
||||
print "a"
|
||||
9
python/testData/mover/betweenStatementParts_afterUp.py
Normal file
9
python/testData/mover/betweenStatementParts_afterUp.py
Normal file
@@ -0,0 +1,9 @@
|
||||
class A:
|
||||
def f(self, a, b):
|
||||
if a:
|
||||
b = 1
|
||||
a = 1
|
||||
elif b:
|
||||
pass
|
||||
else:
|
||||
print "a"
|
||||
9
python/testData/mover/functions.py
Normal file
9
python/testData/mover/functions.py
Normal file
@@ -0,0 +1,9 @@
|
||||
class A:
|
||||
def a(self):
|
||||
doSomething()
|
||||
|
||||
def b<caret>(self):
|
||||
doSomething()
|
||||
|
||||
def c(self):
|
||||
doSomething()
|
||||
9
python/testData/mover/functions_afterDown.py
Normal file
9
python/testData/mover/functions_afterDown.py
Normal file
@@ -0,0 +1,9 @@
|
||||
class A:
|
||||
def a(self):
|
||||
doSomething()
|
||||
|
||||
def c(self):
|
||||
doSomething()
|
||||
|
||||
def b(self):
|
||||
doSomething()
|
||||
9
python/testData/mover/functions_afterUp.py
Normal file
9
python/testData/mover/functions_afterUp.py
Normal file
@@ -0,0 +1,9 @@
|
||||
class A:
|
||||
def b(self):
|
||||
doSomething()
|
||||
|
||||
def a(self):
|
||||
doSomething()
|
||||
|
||||
def c(self):
|
||||
doSomething()
|
||||
8
python/testData/mover/insideStatement.py
Normal file
8
python/testData/mover/insideStatement.py
Normal file
@@ -0,0 +1,8 @@
|
||||
def foo(a, b):
|
||||
if a:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
a = <caret>3
|
||||
if b:
|
||||
pass
|
||||
7
python/testData/mover/insideStatement_afterDown.py
Normal file
7
python/testData/mover/insideStatement_afterDown.py
Normal file
@@ -0,0 +1,7 @@
|
||||
def foo(a, b):
|
||||
if a:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
if b:
|
||||
a = 3
|
||||
7
python/testData/mover/insideStatement_afterUp.py
Normal file
7
python/testData/mover/insideStatement_afterUp.py
Normal file
@@ -0,0 +1,7 @@
|
||||
def foo(a, b):
|
||||
if a:
|
||||
pass
|
||||
else:
|
||||
a = 3
|
||||
if b:
|
||||
pass
|
||||
12
python/testData/mover/moveStatement.py
Normal file
12
python/testData/mover/moveStatement.py
Normal file
@@ -0,0 +1,12 @@
|
||||
class A:
|
||||
def f(self, a, b):
|
||||
while a:
|
||||
a = a / 2
|
||||
if a:
|
||||
b = 1
|
||||
elif<caret> b:
|
||||
a = 1
|
||||
else:
|
||||
print "a"
|
||||
for i in range(1, 10):
|
||||
print i
|
||||
12
python/testData/mover/moveStatement_afterDown.py
Normal file
12
python/testData/mover/moveStatement_afterDown.py
Normal file
@@ -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
|
||||
12
python/testData/mover/moveStatement_afterUp.py
Normal file
12
python/testData/mover/moveStatement_afterUp.py
Normal file
@@ -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
|
||||
6
python/testData/mover/outsideStatement.py
Normal file
6
python/testData/mover/outsideStatement.py
Normal file
@@ -0,0 +1,6 @@
|
||||
a = 1
|
||||
|
||||
if a:
|
||||
a <caret>= 3
|
||||
|
||||
a = 4
|
||||
7
python/testData/mover/outsideStatement_afterDown.py
Normal file
7
python/testData/mover/outsideStatement_afterDown.py
Normal file
@@ -0,0 +1,7 @@
|
||||
a = 1
|
||||
|
||||
if a:
|
||||
pass
|
||||
|
||||
a = 4
|
||||
a = 3
|
||||
7
python/testData/mover/outsideStatement_afterUp.py
Normal file
7
python/testData/mover/outsideStatement_afterUp.py
Normal file
@@ -0,0 +1,7 @@
|
||||
a = 1
|
||||
|
||||
a = 3
|
||||
if a:
|
||||
pass
|
||||
|
||||
a = 4
|
||||
11
python/testData/mover/selection.py
Normal file
11
python/testData/mover/selection.py
Normal file
@@ -0,0 +1,11 @@
|
||||
def f(a, b, c):
|
||||
if b:
|
||||
pass
|
||||
elif a:
|
||||
c = <selection>1
|
||||
if b:
|
||||
a = 3
|
||||
else:
|
||||
b<caret></selection> = 4
|
||||
else:
|
||||
pass
|
||||
11
python/testData/mover/selection_afterDown.py
Normal file
11
python/testData/mover/selection_afterDown.py
Normal file
@@ -0,0 +1,11 @@
|
||||
def f(a, b, c):
|
||||
if b:
|
||||
pass
|
||||
elif a:
|
||||
pass
|
||||
else:
|
||||
c = <selection>1
|
||||
if b:
|
||||
a = 3
|
||||
else:
|
||||
b</selection> = 4
|
||||
11
python/testData/mover/selection_afterUp.py
Normal file
11
python/testData/mover/selection_afterUp.py
Normal file
@@ -0,0 +1,11 @@
|
||||
def f(a, b, c):
|
||||
if b:
|
||||
c = <selection>1
|
||||
if b:
|
||||
a = 3
|
||||
else:
|
||||
b</selection> = 4
|
||||
elif a:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
2
python/testData/mover/simple.py
Normal file
2
python/testData/mover/simple.py
Normal file
@@ -0,0 +1,2 @@
|
||||
a =<caret> 1
|
||||
b = 2
|
||||
2
python/testData/mover/simple_afterDown.py
Normal file
2
python/testData/mover/simple_afterDown.py
Normal file
@@ -0,0 +1,2 @@
|
||||
b = 2
|
||||
a = 1
|
||||
2
python/testData/mover/simple_afterUp.py
Normal file
2
python/testData/mover/simple_afterUp.py
Normal file
@@ -0,0 +1,2 @@
|
||||
a = 1
|
||||
b = 2
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user