diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/actions/GotoElementUnderCaretUsageBase.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/actions/GotoElementUnderCaretUsageBase.java new file mode 100644 index 000000000000..17365b0380f3 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/actions/GotoElementUnderCaretUsageBase.java @@ -0,0 +1,85 @@ +/* + * Copyright 2000-2017 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.codeInsight.daemon.impl.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerEx; +import com.intellij.codeInsight.daemon.impl.HighlightInfoType; +import com.intellij.openapi.editor.Caret; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorModificationUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Ref; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; + +import java.util.Comparator; + +/*package*/ abstract class GotoElementUnderCaretUsageBase extends BaseCodeInsightAction implements CodeInsightActionHandler { + + @NotNull + private final Direction myDirection; + + /** + * @param direction defines direction for next usage searching. + */ + public GotoElementUnderCaretUsageBase(@NotNull Direction direction) { + myDirection = direction; + } + + @NotNull + @Override + protected CodeInsightActionHandler getHandler() { + return this; + } + + @Override + public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { + final Comparator ordering = myDirection.ordering; + final int caretOffset = editor.getCaretModel().getOffset(); + final int startOffset = file.getTextRange().getStartOffset(); + final int endOffset = file.getTextRange().getEndOffset(); + final Ref first = new Ref<>(); + final Ref next = new Ref<>(); + DaemonCodeAnalyzerEx.processHighlights(editor.getDocument(), project, null, startOffset, endOffset, info -> { + if (info.type == HighlightInfoType.ELEMENT_UNDER_CARET_READ || info.type == HighlightInfoType.ELEMENT_UNDER_CARET_WRITE) { + if (ordering.compare(info.startOffset, caretOffset) > 0 && ordering.compare(info.endOffset, caretOffset) > 0) { + if (next.isNull() || ordering.compare(next.get(), info.startOffset) > 0) { + next.set(info.startOffset); + } + } + if (first.isNull() || ordering.compare(first.get(), info.startOffset) > 0) { + first.set(info.startOffset); + } + } + return true; + }); + if (!next.isNull()) { + moveCaret(editor, editor.getCaretModel().getCurrentCaret(), next.get()); + } else if (!first.isNull()) { + moveCaret(editor, editor.getCaretModel().getCurrentCaret(), first.get()); + } else { + // It's ok, do nothing. + } + } + + private static void moveCaret(Editor editor, Caret caret, int offset) { + caret.removeSelection(); + caret.moveToOffset(offset); + EditorModificationUtil.scrollToCaret(editor); + } + + protected enum Direction { + FORWARD((l, r) -> l - r), + BACKWARD((l, r) -> r - l); + + public final Comparator ordering; + + Direction(Comparator ordering) { + this.ordering = ordering; + } + }; +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/actions/GotoNextElementUnderCaretUsageAction.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/actions/GotoNextElementUnderCaretUsageAction.java new file mode 100644 index 000000000000..b4b5b97c0006 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/actions/GotoNextElementUnderCaretUsageAction.java @@ -0,0 +1,16 @@ +/* + * Copyright 2000-2017 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.codeInsight.daemon.impl.actions; + +/** + * Action moves caret to the next highlighted element under caret. + * + * Please note, it works only if option "Highlight usages of element at caret" turned on. + * @see com.intellij.codeInsight.CodeInsightSettings#HIGHLIGHT_IDENTIFIER_UNDER_CARET highlight usages + */ +public class GotoNextElementUnderCaretUsageAction extends GotoElementUnderCaretUsageBase { + public GotoNextElementUnderCaretUsageAction() { + super(Direction.FORWARD); + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/actions/GotoPrevElementUnderCaretUsageAction.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/actions/GotoPrevElementUnderCaretUsageAction.java new file mode 100644 index 000000000000..fd0eaea692ee --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/actions/GotoPrevElementUnderCaretUsageAction.java @@ -0,0 +1,16 @@ +/* + * Copyright 2000-2017 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.codeInsight.daemon.impl.actions; + +/** + * Action moves caret to the previous highlighted element under caret. + * + * Please note, it works only if option "Highlight usages of element at caret" turned on. + * @see com.intellij.codeInsight.CodeInsightSettings#HIGHLIGHT_IDENTIFIER_UNDER_CARET highlight usages + */ +public class GotoPrevElementUnderCaretUsageAction extends GotoElementUnderCaretUsageBase { + public GotoPrevElementUnderCaretUsageAction() { + super(Direction.BACKWARD); + } +} diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index c8a8541544d8..e50478f47982 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -512,6 +512,10 @@ action.GotoDeclaration.text=_Declaration action.GotoDeclaration.description=Navigate to the declaration of the symbol at caret action.GotoImplementation.text=I_mplementation(s) action.GotoImplementation.description=Navigate to the implementation(s) of the selected class or method +action.GotoNextElementUnderCaretUsage.text=Go to next highlighted element usage +action.GotoNextElementUnderCaretUsage.description=Navigate to the next highlighted element usage +action.GotoPrevElementUnderCaretUsage.text=Go to previous highlighted element usage +action.GotoPrevElementUnderCaretUsage.description=Navigate to the previous highlighted element usage action.GotoTypeDeclaration.text=_Type Declaration action.GotoTypeDeclaration.description=Navigate to the declaration of the symbol's type at caret action.GotoSuperMethod.text=S_uper Method diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 10a0c10390a9..87f0bc8549ba 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -330,6 +330,8 @@ + +