IDEA-138306 Moving code through collapsed code breaks it

This commit is contained in:
Dmitry Batrak
2015-03-27 13:47:36 +03:00
parent f15ac71333
commit 3a30a57687
6 changed files with 110 additions and 1 deletions
@@ -0,0 +1,15 @@
import javax.swing.*;
import java.lang.Override;
import java.lang.Runnable;
class Test {
void m() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println();
}
<selection> System.out.println();
<caret></selection> });
}
}
@@ -0,0 +1,15 @@
import javax.swing.*;
import java.lang.Override;
import java.lang.Runnable;
class Test {
void m() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println();
}
});
<selection> System.out.println();
<caret></selection> }
}
@@ -0,0 +1,46 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.editorActions;
import com.intellij.codeInsight.folding.CodeFoldingManager;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.LightCodeInsightTestCase;
public class JavaMoveLineTest extends LightCodeInsightTestCase {
private static final String BASE_PATH = "/codeInsight/editorActions/moveLine/";
@Override
protected LanguageLevel getLanguageLevel() {
return LanguageLevel.JDK_1_7; // to enable folding of lambdas
}
public void testMoveThroughFolding() throws Exception {
configureByFile(BASE_PATH + "/" + getTestName(false) + ".java");
CodeFoldingManager.getInstance(ourProject).buildInitialFoldings(myEditor);
FoldRegion lambdaStart = myEditor.getFoldingModel().getFoldRegion(140, 227);
assertNotNull(lambdaStart);
assertFalse(lambdaStart.isExpanded());
FoldRegion lambdaEnd = myEditor.getFoldingModel().getFoldRegion(248, 272);
assertNotNull(lambdaEnd);
assertFalse(lambdaEnd.isExpanded());
executeAction(IdeActions.ACTION_MOVE_LINE_UP_ACTION);
checkResultByFile(BASE_PATH + "/" + getTestName(false) + "-after.java");
}
}
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.editorActions.moveUpDown;
import com.intellij.codeInsight.folding.CodeFoldingManager;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
@@ -206,6 +207,6 @@ class MoverWrapper {
final int selectionRelativeOffset = selectionStart - moveOffset;
int newSelectionStart = insOffset + selectionRelativeOffset;
int newSelectionEnd = newSelectionStart + selectionEnd - selectionStart;
editor.getSelectionModel().setSelection(newSelectionStart, newSelectionEnd);
EditorUtil.setSelectionExpandingFoldedRegionsIfNeeded(editor, newSelectionStart, newSelectionEnd);
}
}
@@ -289,6 +289,8 @@ public interface IdeActions {
String ACTION_MOVE_STATEMENT_UP_ACTION = "MoveStatementUp";
String ACTION_MOVE_STATEMENT_DOWN_ACTION = "MoveStatementDown";
String ACTION_MOVE_LINE_UP_ACTION = "MoveLineUp";
String ACTION_COMPARE_CLIPBOARD_WITH_SELECTION = "CompareClipboardWithSelection";
@@ -865,6 +865,36 @@ public final class EditorUtil {
int line = document.getLineNumber(offset);
return offset == document.getLineEndOffset(line);
}
/**
* Setting selection using {@link SelectionModel#setSelection(int, int)} or {@link Caret#setSelection(int, int)} methods can result
* in resulting selection range to be larger than requested (in case requested range intersects with collapsed fold regions).
* This method will make sure interfering collapsed regions are expanded first, so that resulting selection range is exactly as
* requested.
*/
public static void setSelectionExpandingFoldedRegionsIfNeeded(@NotNull Editor editor, int startOffset, int endOffset) {
FoldingModel foldingModel = editor.getFoldingModel();
FoldRegion startFoldRegion = foldingModel.getCollapsedRegionAtOffset(startOffset);
if (startFoldRegion != null && (startFoldRegion.getStartOffset() == startOffset || startFoldRegion.isExpanded())) {
startFoldRegion = null;
}
FoldRegion endFoldRegion = foldingModel.getCollapsedRegionAtOffset(endOffset);
if (endFoldRegion != null && (endFoldRegion.getStartOffset() == endOffset || endFoldRegion.isExpanded())) {
endFoldRegion = null;
}
if (startFoldRegion != null || endFoldRegion != null) {
final FoldRegion finalStartFoldRegion = startFoldRegion;
final FoldRegion finalEndFoldRegion = endFoldRegion;
foldingModel.runBatchFoldingOperation(new Runnable() {
@Override
public void run() {
if (finalStartFoldRegion != null) finalStartFoldRegion.setExpanded(true);
if (finalEndFoldRegion != null) finalEndFoldRegion.setExpanded(true);
}
});
}
editor.getSelectionModel().setSelection(startOffset, endOffset);
}
}