From ca386a08f230be6a2da4d7dd32d52ec1028b55f0 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Wed, 10 Apr 2019 14:01:38 +0300 Subject: [PATCH] diff: do not hide breadcrumbs in folded ranges if method declaration is collapsed Ex: if method has long JavaDoc and has modifications in JavaDoc and body, making method name invisible. --- .../tools/fragmented/UnifiedDiffViewer.java | 2 +- .../diff/tools/util/FoldingModelSupport.java | 57 +++++++++++++++---- .../xml/breadcrumbs/NavigatableCrumb.java | 4 +- .../intellij/xml/breadcrumbs/PsiCrumb.java | 13 +++-- 4 files changed, 60 insertions(+), 16 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffViewer.java index 80acd63edcae..fa6577f866ca 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/UnifiedDiffViewer.java @@ -1317,7 +1317,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase { @Nullable @Override - protected String getDescription(int lineNumber, int index) { + protected FoldedRangeDescription getDescription(int lineNumber, int index) { if (myProject == null) return null; int masterLine = myLineConvertor.convert(lineNumber); if (masterLine == -1) return null; diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/FoldingModelSupport.java b/platform/diff-impl/src/com/intellij/diff/tools/util/FoldingModelSupport.java index 7fab5a1e51c3..38c92937e47a 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/FoldingModelSupport.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/FoldingModelSupport.java @@ -32,6 +32,7 @@ import com.intellij.psi.PsiFile; import com.intellij.ui.components.breadcrumbs.Crumb; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; +import com.intellij.xml.breadcrumbs.NavigatableCrumb; import gnu.trove.TIntFunction; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -157,7 +158,7 @@ public class FoldingModelSupport { @Nullable @Override - protected String getDescription(int lineNumber, int index) { + protected FoldedRangeDescription getDescription(int lineNumber, int index) { if (myProject == null) return null; return getLineSeparatorDescription(myProject, myEditors[index].getDocument(), lineNumber); } @@ -240,21 +241,27 @@ public class FoldingModelSupport { String[] descriptions = new String[myCount]; for (int i = 0; i < myCount; i++) { - String startDescription = getDescription(starts[i], i); - String endDescription = getDescription(ends[i], i); - if (Comparing.equal(startDescription, endDescription)) continue; - descriptions[i] = endDescription; + FoldedRangeDescription startDescription = getDescription(starts[i], i); + FoldedRangeDescription endDescription = getDescription(ends[i], i); + if (endDescription == null) continue; + if (Comparing.equal(startDescription, endDescription) && + !(endDescription.anchorLine != -1 && starts[i] <= endDescription.anchorLine)) { + continue; + } + descriptions[i] = endDescription.description; } return new Data.Block(regions, descriptions); } @Nullable - protected abstract String getDescription(int lineNumber, int index); + protected abstract FoldedRangeDescription getDescription(int lineNumber, int index); } @Nullable - protected static String getLineSeparatorDescription(@NotNull Project project, @NotNull Document document, int lineNumber) { + protected static FoldedRangeDescription getLineSeparatorDescription(@NotNull Project project, + @NotNull Document document, + int lineNumber) { return ReadAction.compute(() -> { ProgressManager.checkCanceled(); PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); @@ -265,13 +272,43 @@ public class FoldingModelSupport { int offset = document.getLineStartOffset(lineNumber); FileBreadcrumbsCollector collector = FileBreadcrumbsCollector.findBreadcrumbsCollector(project, virtualFile); - Iterable crumbs = collector.computeCrumbs(virtualFile, document, offset, null); - if (!crumbs.iterator().hasNext()) return null; + List crumbs = ContainerUtil.newArrayList(collector.computeCrumbs(virtualFile, document, offset, null)); + if (crumbs.isEmpty()) return null; - return StringUtil.join(crumbs, it -> it.getText(), " > "); + String description = StringUtil.join(crumbs, it -> it.getText(), " > "); + + Crumb lastCrumb = crumbs.get(crumbs.size() - 1); + int anchorOffset = lastCrumb instanceof NavigatableCrumb ? ((NavigatableCrumb)lastCrumb).getAnchorOffset() : -1; + int anchorLine = anchorOffset != -1 ? document.getLineNumber(anchorOffset) : -1; + + return new FoldedRangeDescription(description, anchorLine); }); } + protected static class FoldedRangeDescription { + @NotNull private final String description; + private final int anchorLine; + + private FoldedRangeDescription(@NotNull String description, int anchorLine) { + this.description = description; + this.anchorLine = anchorLine; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FoldedRangeDescription that = (FoldedRangeDescription)o; + return Objects.equals(description, that.description) && + Objects.equals(anchorLine, that.anchorLine); + } + + @Override + public int hashCode() { + return Objects.hash(description, anchorLine); + } + } + private class FoldingInstaller { @NotNull private final ExpandSuggester myExpandSuggester; diff --git a/platform/platform-api/src/com/intellij/xml/breadcrumbs/NavigatableCrumb.java b/platform/platform-api/src/com/intellij/xml/breadcrumbs/NavigatableCrumb.java index bd2dde6c8b06..546a7b8b6640 100644 --- a/platform/platform-api/src/com/intellij/xml/breadcrumbs/NavigatableCrumb.java +++ b/platform/platform-api/src/com/intellij/xml/breadcrumbs/NavigatableCrumb.java @@ -1,4 +1,4 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.xml.breadcrumbs; import com.intellij.openapi.editor.Editor; @@ -16,5 +16,7 @@ public interface NavigatableCrumb extends Crumb { @Nullable TextRange getHighlightRange(); + default int getAnchorOffset() { return -1; } + void navigate(@NotNull Editor editor, boolean withSelection); } diff --git a/xml/impl/src/com/intellij/xml/breadcrumbs/PsiCrumb.java b/xml/impl/src/com/intellij/xml/breadcrumbs/PsiCrumb.java index b8583836199c..4e258a356fe0 100644 --- a/xml/impl/src/com/intellij/xml/breadcrumbs/PsiCrumb.java +++ b/xml/impl/src/com/intellij/xml/breadcrumbs/PsiCrumb.java @@ -37,6 +37,11 @@ final class PsiCrumb extends Crumb.Impl implements NavigatableCrumb { return tooltip; } + @Override + public int getAnchorOffset() { + PsiElement element = anchor.retrieve(); + return element != null ? element.getTextOffset() : -1; + } @Override public TextRange getHighlightRange() { @@ -46,10 +51,10 @@ final class PsiCrumb extends Crumb.Impl implements NavigatableCrumb { @Override public void navigate(@NotNull Editor editor, boolean withSelection) { - PsiElement element = anchor.retrieve(); - if (element == null) return; - - moveEditorCaretTo(editor, element.getTextOffset()); + int offset = getAnchorOffset(); + if (offset != -1) { + moveEditorCaretTo(editor, offset); + } if (withSelection) { final TextRange range = getHighlightRange();