Merge branch 'go_to_next_or_prev_marked_occurrence'

This commit is contained in:
Petr Kudriavtsev
2017-12-13 17:35:01 +03:00
5 changed files with 123 additions and 0 deletions
@@ -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<Integer> ordering = myDirection.ordering;
final int caretOffset = editor.getCaretModel().getOffset();
final int startOffset = file.getTextRange().getStartOffset();
final int endOffset = file.getTextRange().getEndOffset();
final Ref<Integer> first = new Ref<>();
final Ref<Integer> 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<Integer> ordering;
Direction(Comparator<Integer> ordering) {
this.ordering = ordering;
}
};
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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
@@ -330,6 +330,8 @@
<action id="SelectAllOccurrences" class="com.intellij.openapi.editor.actions.SelectAllOccurrencesAction"/>
<action id="SelectNextOccurrence" class="com.intellij.openapi.editor.actions.SelectNextOccurrenceAction"/>
<action id="UnselectPreviousOccurrence" class="com.intellij.openapi.editor.actions.UnselectPreviousOccurrenceAction"/>
<action id="GotoNextElementUnderCaretUsage" class="com.intellij.codeInsight.daemon.impl.actions.GotoNextElementUnderCaretUsageAction"/>
<action id="GotoPrevElementUnderCaretUsage" class="com.intellij.codeInsight.daemon.impl.actions.GotoPrevElementUnderCaretUsageAction"/>
<separator/>
<action id="FindInPath" class="com.intellij.find.actions.FindInPathAction"/>
<action id="ReplaceInPath" class="com.intellij.find.actions.ReplaceInPathAction"/>