mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
don't expand single-line closure foldings when editing inside them
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.folding.impl;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil;
|
||||
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
|
||||
import com.intellij.codeInsight.generation.OverrideImplementUtil;
|
||||
import com.intellij.lang.ASTNode;
|
||||
@@ -47,7 +48,10 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAware {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.folding.impl.JavaFoldingBuilder");
|
||||
@@ -312,7 +316,9 @@ public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAwar
|
||||
if (importKeyword == null) return null;
|
||||
int startOffset = importKeyword.getTextRange().getEndOffset() + 1;
|
||||
int endOffset = statements[statements.length - 1].getTextRange().getEndOffset();
|
||||
return new TextRange(startOffset, endOffset);
|
||||
if (!hasErrorElementsNearby(element.getContainingFile(), startOffset, endOffset)) {
|
||||
return new TextRange(startOffset, endOffset);
|
||||
}
|
||||
}
|
||||
if (element instanceof PsiDocComment) {
|
||||
return element.getTextRange();
|
||||
@@ -330,6 +336,16 @@ public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAwar
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean hasErrorElementsNearby(final PsiFile file, int startOffset, int endOffset) {
|
||||
endOffset = CharArrayUtil.shiftForward(file.getText(), endOffset, " \t\n");
|
||||
for (PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffset, endOffset)) {
|
||||
if (element instanceof PsiErrorElement) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static TextRange getFileHeader(PsiJavaFile file) {
|
||||
PsiElement first = file.getFirstChild();
|
||||
|
||||
@@ -167,6 +167,32 @@ class Test {
|
||||
assertEquals(2, closureFolds.size())
|
||||
}
|
||||
|
||||
public void "test closure folding doesn't expand when editing inside"() {
|
||||
def text = """\
|
||||
class Test {
|
||||
void test() {
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
System.out.println(<caret>);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
configure text
|
||||
def foldingModel = myFixture.editor.foldingModel as FoldingModelImpl
|
||||
def closureStartFold = foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable"))
|
||||
assertNotNull closureStartFold
|
||||
assertFalse closureStartFold.expanded
|
||||
assert text.substring(closureStartFold.endOffset).startsWith('System') //one line closure
|
||||
|
||||
myFixture.type('2')
|
||||
myFixture.doHighlighting()
|
||||
closureStartFold = foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable"))
|
||||
assert closureStartFold
|
||||
}
|
||||
|
||||
public void testFindInFolding() {
|
||||
def text = """\
|
||||
class Test {
|
||||
|
||||
-1
@@ -131,7 +131,6 @@ class MoverWrapper {
|
||||
}
|
||||
});
|
||||
}
|
||||
CodeFoldingManager.getInstance(project).allowFoldingOnCaretLine(editor);
|
||||
|
||||
if (hasSelection) {
|
||||
restoreSelection(editor, selectionStart, selectionEnd, start, myInfo.range2.getStartOffset());
|
||||
|
||||
@@ -50,14 +50,4 @@ public abstract class CodeFoldingManager {
|
||||
|
||||
public abstract void releaseFoldings(Editor editor);
|
||||
public abstract void buildInitialFoldings(Editor editor);
|
||||
|
||||
/**
|
||||
* Asks do not perform automatic expansion of fold region that is located on the caret line during the next fold regions update.
|
||||
* <p/>
|
||||
* This method is necessary because fold regions that are located on caret line are automatically expanded to prevent problem
|
||||
* from IDEA-64687. However, we don't want such an expansion when we, for example, move method up or down.
|
||||
*
|
||||
* @param editor target editor
|
||||
*/
|
||||
public abstract void allowFoldingOnCaretLine(@NotNull Editor editor);
|
||||
}
|
||||
|
||||
-5
@@ -331,9 +331,4 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec
|
||||
document.putUserData(FOLDING_STATE_INFO_IN_DOCUMENT_KEY, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void allowFoldingOnCaretLine(@NotNull Editor editor) {
|
||||
editor.putUserData(UpdateFoldRegionsOperation.ALLOW_FOLDING_ON_CARET_LINE_KEY, true);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-24
@@ -18,14 +18,12 @@ package com.intellij.codeInsight.folding.impl;
|
||||
|
||||
import com.intellij.lang.folding.FoldingDescriptor;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
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.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -43,9 +41,6 @@ import static com.intellij.util.containers.CollectionFactory.newTroveMap;
|
||||
* @author cdr
|
||||
*/
|
||||
class UpdateFoldRegionsOperation implements Runnable {
|
||||
|
||||
static final Key<Boolean> ALLOW_FOLDING_ON_CARET_LINE_KEY = Key.create("AllowFoldingOnCaretLine.KEY");
|
||||
|
||||
private final Project myProject;
|
||||
private final Editor myEditor;
|
||||
private final PsiFile myFile;
|
||||
@@ -80,9 +75,6 @@ class UpdateFoldRegionsOperation implements Runnable {
|
||||
List<FoldRegion> newRegions = addNewRegions(info, foldingModel, rangeToExpandStatusMap, shouldExpand, groupExpand);
|
||||
|
||||
applyExpandStatus(newRegions, shouldExpand, groupExpand);
|
||||
|
||||
// Reset the key.
|
||||
myEditor.putUserData(ALLOW_FOLDING_ON_CARET_LINE_KEY, false);
|
||||
}
|
||||
|
||||
private static void applyExpandStatus(@NotNull List<FoldRegion> newRegions,
|
||||
@@ -147,24 +139,9 @@ class UpdateFoldRegionsOperation implements Runnable {
|
||||
// Considering that this code is executed only on initial fold regions construction on editor opening.
|
||||
return !FoldingPolicy.isCollapseByDefault(element);
|
||||
}
|
||||
boolean caretInside;
|
||||
if (myEditor.getUserData(ALLOW_FOLDING_ON_CARET_LINE_KEY) == Boolean.TRUE) {
|
||||
caretInside = FoldingUtil.caretInsideRange(myEditor, range);
|
||||
}
|
||||
else {
|
||||
final Document document = myEditor.getDocument();
|
||||
final int firstLine = document.getLineNumber(range.getStartOffset());
|
||||
final int lastLine = document.getLineNumber(range.getEndOffset());
|
||||
int caretOffset = myEditor.getCaretModel().getOffset();
|
||||
if (caretOffset > myEditor.getDocument().getTextLength()) {
|
||||
return false;
|
||||
}
|
||||
final int currentLine = document.getLineNumber(caretOffset);
|
||||
caretInside = firstLine <= currentLine && currentLine <= lastLine;
|
||||
}
|
||||
|
||||
final Boolean oldStatus = rangeToExpandStatusMap.get(range);
|
||||
return oldStatus == null || caretInside || oldStatus.booleanValue();
|
||||
return oldStatus == null || FoldingUtil.caretInsideRange(myEditor, range) || oldStatus.booleanValue();
|
||||
}
|
||||
|
||||
private void removeInvalidRegions(@NotNull EditorFoldingInfo info,
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.plugins.groovy.lang.folding;
|
||||
|
||||
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
|
||||
import com.intellij.codeInsight.folding.impl.JavaFoldingBuilder;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.folding.CustomFoldingBuilder;
|
||||
import com.intellij.lang.folding.FoldingDescriptor;
|
||||
@@ -194,7 +195,7 @@ public class GroovyFoldingBuilder extends CustomFoldingBuilder implements Groovy
|
||||
int start = first.getTextRange().getStartOffset();
|
||||
int end = marker.getTextRange().getEndOffset();
|
||||
int tail = "import ".length();
|
||||
if (start + tail < end) {
|
||||
if (start + tail < end && !JavaFoldingBuilder.hasErrorElementsNearby(first.getContainingFile(), start, end)) {
|
||||
descriptors.add(new FoldingDescriptor(first.getNode(), new TextRange(start + tail, end)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user