IDEA-131578 Folding 'blinks' when navigating to a method

This commit is contained in:
Dmitry Batrak
2014-10-21 10:42:52 +04:00
parent 45a12fa4f3
commit aee6089787
5 changed files with 64 additions and 12 deletions
@@ -15,6 +15,15 @@
*/
package com.intellij.openapi.editor.impl;
import com.intellij.codeInsight.daemon.impl.CodeFoldingPassFactory;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.PsiMethod;
import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.FileEditorManagerTestCase;
import com.intellij.testFramework.PlatformTestUtil;
import org.jdom.JDOMException;
@@ -47,6 +56,29 @@ public class JavaFileEditorManagerTest extends FileEditorManagerTestCase {
" </component>");
}
public void testFoldingIsNotBlinkingOnNavigationToSingleLineMethod() {
VirtualFile file = getFile("/src/Bar.java");
PsiJavaFile psiFile = (PsiJavaFile)getPsiManager().findFile(file);
assertNotNull(psiFile);
PsiMethod method = psiFile.getClasses()[0].getMethods()[0];
method.navigate(true);
FileEditor[] editors = myManager.getEditors(file);
assertEquals(1, editors.length);
Editor editor = ((TextEditor)editors[0]).getEditor();
FoldRegion[] regions = editor.getFoldingModel().getAllFoldRegions();
assertEquals(2, regions.length);
assertTrue(regions[0].isExpanded());
assertTrue(regions[1].isExpanded());
EditorTestUtil.runTextEditorHighlightingPass(editor, CodeFoldingPassFactory.class);
regions = editor.getFoldingModel().getAllFoldRegions();
assertEquals(2, regions.length);
assertTrue(regions[0].isExpanded());
assertTrue(regions[1].isExpanded());
}
@Override
protected String getTestDataPath() {
return PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/java/java-tests/testData/fileEditorManager";
@@ -49,6 +49,8 @@ import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.List;
import static com.intellij.codeInsight.folding.impl.UpdateFoldRegionsOperation.ApplyDefaultStateMode.*;
public class CodeFoldingManagerImpl extends CodeFoldingManager implements ProjectComponent {
private final Project myProject;
@@ -246,7 +248,7 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec
if (isFoldingsInitializedInEditor(editor)) return;
if (DumbService.isDumb(myProject) && !FoldingUpdate.supportsDumbModeFolding(editor)) return;
foldingModel.runBatchFoldingOperationDoNotCollapseCaret(new UpdateFoldRegionsOperation(myProject, editor, file, foldingMap, true, false));
foldingModel.runBatchFoldingOperationDoNotCollapseCaret(new UpdateFoldRegionsOperation(myProject, editor, file, foldingMap, YES, false));
initFolding(editor);
}
};
@@ -51,6 +51,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import static com.intellij.codeInsight.folding.impl.UpdateFoldRegionsOperation.ApplyDefaultStateMode.*;
public class FoldingUpdate {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.folding.impl.FoldingUpdate");
@@ -116,7 +118,8 @@ public class FoldingUpdate {
final boolean applyDefaultState) {
final FoldingMap elementsToFoldMap = getFoldingsFor(project, file, document, quick);
final UpdateFoldRegionsOperation operation = new UpdateFoldRegionsOperation(project, editor, file, elementsToFoldMap, applyDefaultState, false);
final UpdateFoldRegionsOperation operation = new UpdateFoldRegionsOperation(project, editor, file, elementsToFoldMap,
applyDefaultState ? EXCEPT_CARET_REGION : NO, false);
Runnable runnable = new Runnable() {
@Override
public void run() {
@@ -190,7 +193,8 @@ public class FoldingUpdate {
PsiFile injectedFile = injectedFiles.get(i);
if (!injectedEditor.getDocument().isValid()) continue;
FoldingMap map = maps.get(i);
updateOperations.add(new UpdateFoldRegionsOperation(project, injectedEditor, injectedFile, map, applyDefaultState, true));
updateOperations.add(new UpdateFoldRegionsOperation(project, injectedEditor, injectedFile, map,
applyDefaultState ? EXCEPT_CARET_REGION : NO, true));
}
foldingModel.runBatchFoldingOperation(new Runnable() {
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -23,6 +23,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.FoldingGroup;
import com.intellij.openapi.editor.ex.FoldingModelEx;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
@@ -42,13 +43,15 @@ import static com.intellij.util.containers.ContainerUtil.newTroveMap;
* @author cdr
*/
class UpdateFoldRegionsOperation implements Runnable {
enum ApplyDefaultStateMode { YES, EXCEPT_CARET_REGION, NO }
private static final Logger LOG = Logger.getInstance("#" + UpdateFoldRegionsOperation.class.getName());
private final Project myProject;
private final Editor myEditor;
private final PsiFile myFile;
private final boolean myApplyDefaultState;
private final ApplyDefaultStateMode myApplyDefaultState;
private final FoldingUpdate.FoldingMap myElementsToFoldMap;
private final boolean myForInjected;
@@ -56,7 +59,7 @@ class UpdateFoldRegionsOperation implements Runnable {
@NotNull Editor editor,
@NotNull PsiFile file,
@NotNull FoldingUpdate.FoldingMap elementsToFoldMap,
boolean applyDefaultState,
ApplyDefaultStateMode applyDefaultState,
boolean forInjected) {
myProject = project;
myEditor = editor;
@@ -144,8 +147,14 @@ class UpdateFoldRegionsOperation implements Runnable {
}
private boolean shouldExpandNewRegion(PsiElement element, TextRange range, Map<TextRange, Boolean> rangeToExpandStatusMap) {
if (myApplyDefaultState) {
if (myApplyDefaultState != ApplyDefaultStateMode.NO) {
// Considering that this code is executed only on initial fold regions construction on editor opening.
if (myApplyDefaultState == ApplyDefaultStateMode.EXCEPT_CARET_REGION) {
TextRange lineRange = OpenFileDescriptor.getRangeToUnfoldOnNavigation(myEditor);
if (lineRange.intersects(range)) {
return true;
}
}
return !FoldingPolicy.isCollapseByDefault(element);
}
@@ -224,11 +224,7 @@ public class OpenFileDescriptor implements Navigatable {
private static void unfoldCurrentLine(@NotNull final Editor editor) {
final FoldRegion[] allRegions = editor.getFoldingModel().getAllFoldRegions();
final int offset = editor.getCaretModel().getOffset();
int line = editor.getDocument().getLineNumber(offset);
int start = editor.getDocument().getLineStartOffset(line);
int end = editor.getDocument().getLineEndOffset(line);
final TextRange range = new TextRange(start, end);
final TextRange range = getRangeToUnfoldOnNavigation(editor);
editor.getFoldingModel().runBatchFoldingOperation(new Runnable() {
@Override
public void run() {
@@ -241,6 +237,15 @@ public class OpenFileDescriptor implements Navigatable {
});
}
@NotNull
public static TextRange getRangeToUnfoldOnNavigation(@NotNull Editor editor) {
final int offset = editor.getCaretModel().getOffset();
int line = editor.getDocument().getLineNumber(offset);
int start = editor.getDocument().getLineStartOffset(line);
int end = editor.getDocument().getLineEndOffset(line);
return new TextRange(start, end);
}
private static void scrollToCaret(@NotNull Editor e) {
e.getScrollingModel().scrollToCaret(ScrollType.CENTER);
}