mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-204836: show breadcrumbs for previous element if caret is just outside to the right
This behaviour is consistent with the Python fixes in PY-22449 and with brace matcher logic. Python and Ruby breadcrumb tests are guarding this logic.
This commit is contained in:
+2
-1
@@ -75,7 +75,8 @@ public class XmlTagTreeHighlightingPass extends TextEditorHighlightingPass {
|
||||
}
|
||||
|
||||
final int offset = myEditor.getCaretModel().getOffset();
|
||||
PsiElement[] elements = PsiFileBreadcrumbsCollector.getLinePsiElements(offset,
|
||||
PsiElement[] elements = PsiFileBreadcrumbsCollector.getLinePsiElements(myEditor,
|
||||
offset,
|
||||
myFile.getVirtualFile(),
|
||||
myProject, myInfoProvider);
|
||||
|
||||
|
||||
@@ -15,11 +15,13 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.availability.PsiAvailabilityService;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.ui.breadcrumbs.BreadcrumbsProvider;
|
||||
import com.intellij.ui.breadcrumbs.BreadcrumbsUtil;
|
||||
import com.intellij.ui.components.breadcrumbs.Crumb;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -107,7 +109,7 @@ public class PsiFileBreadcrumbsCollector extends FileBreadcrumbsCollector {
|
||||
BreadcrumbsProvider defaultInfoProvider = findProvider(editor, file);
|
||||
|
||||
Collection<Pair<PsiElement, BreadcrumbsProvider>> pairs =
|
||||
getLineElements(offset, file, myProject, defaultInfoProvider, true);
|
||||
getLineElements(editor, offset, file, myProject, defaultInfoProvider, true);
|
||||
|
||||
if (pairs == null) return null;
|
||||
|
||||
@@ -137,12 +139,13 @@ public class PsiFileBreadcrumbsCollector extends FileBreadcrumbsCollector {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Collection<Pair<PsiElement, BreadcrumbsProvider>> getLineElements(int offset,
|
||||
private static Collection<Pair<PsiElement, BreadcrumbsProvider>> getLineElements(Editor editor,
|
||||
int offset,
|
||||
VirtualFile file,
|
||||
Project project,
|
||||
BreadcrumbsProvider defaultInfoProvider,
|
||||
boolean checkSettings) {
|
||||
PsiElement element = findFirstBreadcrumbedElement(offset, file, project, defaultInfoProvider, checkSettings);
|
||||
PsiElement element = findStartElement(editor, offset, file, project, defaultInfoProvider, checkSettings);
|
||||
if (element == null) return null;
|
||||
|
||||
LinkedList<Pair<PsiElement, BreadcrumbsProvider>> result = new LinkedList<>();
|
||||
@@ -159,6 +162,41 @@ public class PsiFileBreadcrumbsCollector extends FileBreadcrumbsCollector {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds first breadcrumb-rendering element, possibly shifting offset backwards, skipping whitespaces and grabbing previous element
|
||||
* This logic solves inconsistency with brace matcher. For example,
|
||||
* <pre><code>
|
||||
* class Foo {
|
||||
* public void bar() {
|
||||
*
|
||||
* } <caret>
|
||||
* }
|
||||
* </code></pre>
|
||||
* will highlight bar's braces, looking backwards. So it should include it to breadcrumbs, too.
|
||||
*/
|
||||
@Nullable
|
||||
private static PsiElement findStartElement(Editor editor,
|
||||
int offset,
|
||||
VirtualFile file,
|
||||
Project project,
|
||||
BreadcrumbsProvider defaultInfoProvider,
|
||||
boolean checkSettings) {
|
||||
PsiElement middleElement = findFirstBreadcrumbedElement(offset, file, project, defaultInfoProvider, checkSettings);
|
||||
|
||||
// Let's simulate brace matcher logic of searching brace backwards (see `BraceHighlightingHandler.updateBraces`)
|
||||
CharSequence chars = editor.getDocument().getCharsSequence();
|
||||
int leftOffset = CharArrayUtil.shiftBackward(chars, offset - 1, "\t ");
|
||||
leftOffset = leftOffset >= 0 ? leftOffset : offset - 1;
|
||||
|
||||
PsiElement leftElement = findFirstBreadcrumbedElement(leftOffset, file, project, defaultInfoProvider, checkSettings);
|
||||
if (leftElement != null && (middleElement == null || PsiTreeUtil.isAncestor(middleElement, leftElement, true))) {
|
||||
return leftElement;
|
||||
}
|
||||
else {
|
||||
return middleElement;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement findFirstBreadcrumbedElement(final int offset,
|
||||
final VirtualFile file,
|
||||
@@ -225,8 +263,12 @@ public class PsiFileBreadcrumbsCollector extends FileBreadcrumbsCollector {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement[] getLinePsiElements(int offset, VirtualFile file, Project project, BreadcrumbsProvider infoProvider) {
|
||||
Collection<Pair<PsiElement, BreadcrumbsProvider>> pairs = getLineElements(offset, file, project, infoProvider, false);
|
||||
public static PsiElement[] getLinePsiElements(Editor editor,
|
||||
int offset,
|
||||
VirtualFile file,
|
||||
Project project,
|
||||
BreadcrumbsProvider infoProvider) {
|
||||
Collection<Pair<PsiElement, BreadcrumbsProvider>> pairs = getLineElements(editor, offset, file, project, infoProvider, false);
|
||||
return pairs == null ? null : toPsiElementArray(pairs);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user