summaryrefslogtreecommitdiff
path: root/platform/lang-impl/src/com/intellij/find/FindUtil.java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/lang-impl/src/com/intellij/find/FindUtil.java')
-rw-r--r--platform/lang-impl/src/com/intellij/find/FindUtil.java102
1 files changed, 85 insertions, 17 deletions
diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java
index 0728ea07e2b3..edc906481398 100644
--- a/platform/lang-impl/src/com/intellij/find/FindUtil.java
+++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java
@@ -31,6 +31,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
+import com.intellij.openapi.editor.actions.EditorActionUtil;
import com.intellij.openapi.editor.actions.IncrementalFindAction;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
@@ -70,10 +71,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
+import java.util.*;
public class FindUtil {
private static final Key<Direction> KEY = Key.create("FindUtil.KEY");
@@ -385,7 +383,7 @@ public class FindUtil {
}
else {
editor.putUserData(KEY, null);
- offset = editor.getCaretModel().getOffset();
+ offset = model.isGlobal() && model.isForward() ? editor.getSelectionModel().getSelectionEnd() : editor.getCaretModel().getOffset();
if (!model.isForward() && offset > 0) {
offset--;
}
@@ -714,7 +712,18 @@ public class FindUtil {
final ScrollType scrollType = forward ? ScrollType.CENTER_DOWN : ScrollType.CENTER_UP;
if (model.isGlobal()) {
- caretModel.moveToOffset(result.getEndOffset());
+ int targetCaretPosition = result.getEndOffset();
+ if (selection.getSelectionEnd() - selection.getSelectionStart() == result.getLength()) {
+ // keeping caret's position relative to selection
+ // use case: FindNext is used after SelectNextOccurrence action
+ targetCaretPosition = caretModel.getOffset() - selection.getSelectionStart() + result.getStartOffset();
+ }
+ if (caretModel.getCaretAt(editor.offsetToVisualPosition(targetCaretPosition)) != null) {
+ // if there's a different caret at target position, don't move current caret/selection
+ // use case: FindNext is used after SelectNextOccurrence action
+ return result;
+ }
+ caretModel.moveToOffset(targetCaretPosition);
selection.removeSelection();
scrollingModel.scrollToCaret(scrollType);
scrollingModel.runActionOnScrollingFinished(
@@ -829,17 +838,12 @@ public class FindUtil {
editor.getCaretModel().addCaretListener(listener);
}
JComponent component = HintUtil.createInformationLabel(JDOMUtil.escapeText(message, false, false));
-
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- LivePreview.processNotFound();
- } else {
- final LightweightHint hint = new LightweightHint(component);
- HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, position,
- HintManager.HIDE_BY_ANY_KEY |
- HintManager.HIDE_BY_TEXT_CHANGE |
- HintManager.HIDE_BY_SCROLLING,
- 0, false);
- }
+ final LightweightHint hint = new LightweightHint(component);
+ HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, position,
+ HintManager.HIDE_BY_ANY_KEY |
+ HintManager.HIDE_BY_TEXT_CHANGE |
+ HintManager.HIDE_BY_SCROLLING,
+ 0, false);
}
public static TextRange doReplace(final Project project,
@@ -954,4 +958,68 @@ public class FindUtil {
});
return view;
}
+
+ /**
+ * Creates a selection in editor per each search result. Existing carets and selections in editor are discarded.
+ *
+ * @param caretShiftFromSelectionStart if non-negative, defines caret position relative to selection start, for each created selection.
+ * if negative, carets will be positioned at selection ends
+ */
+ public static void selectSearchResultsInEditor(@NotNull Editor editor,
+ @NotNull Iterator<FindResult> resultIterator,
+ int caretShiftFromSelectionStart) {
+ if (!editor.getCaretModel().supportsMultipleCarets()) {
+ return;
+ }
+ ArrayList<CaretState> caretStates = new ArrayList<CaretState>();
+ while (resultIterator.hasNext()) {
+ FindResult findResult = resultIterator.next();
+ int caretOffset = getCaretPosition(findResult, caretShiftFromSelectionStart);
+ int selectionStartOffset = findResult.getStartOffset();
+ int selectionEndOffset = findResult.getEndOffset();
+ EditorActionUtil.makePositionVisible(editor, caretOffset);
+ EditorActionUtil.makePositionVisible(editor, selectionStartOffset);
+ EditorActionUtil.makePositionVisible(editor, selectionEndOffset);
+ caretStates.add(new CaretState(editor.offsetToLogicalPosition(caretOffset),
+ editor.offsetToLogicalPosition(selectionStartOffset),
+ editor.offsetToLogicalPosition(selectionEndOffset)));
+ }
+ if (caretStates.isEmpty()) {
+ return;
+ }
+ editor.getCaretModel().setCaretsAndSelections(caretStates);
+ }
+
+ /**
+ * Attempts to add a new caret to editor, with selection corresponding to given search result.
+ *
+ * @param caretShiftFromSelectionStart if non-negative, defines caret position relative to selection start, for each created selection.
+ * if negative, caret will be positioned at selection end
+ * @return <code>true</code> if caret was added successfully, <code>false</code> if it cannot be done, e.g. because a caret already
+ * exists at target position
+ */
+ public static boolean selectSearchResultInEditor(@NotNull Editor editor, @NotNull FindResult result, int caretShiftFromSelectionStart) {
+ if (!editor.getCaretModel().supportsMultipleCarets()) {
+ return false;
+ }
+ int caretOffset = getCaretPosition(result, caretShiftFromSelectionStart);
+ EditorActionUtil.makePositionVisible(editor, caretOffset);
+ Caret newCaret = editor.getCaretModel().addCaret(editor.offsetToVisualPosition(caretOffset));
+ if (newCaret == null) {
+ return false;
+ }
+ else {
+ int selectionStartOffset = result.getStartOffset();
+ int selectionEndOffset = result.getEndOffset();
+ EditorActionUtil.makePositionVisible(editor, selectionStartOffset);
+ EditorActionUtil.makePositionVisible(editor, selectionEndOffset);
+ newCaret.setSelection(selectionStartOffset, selectionEndOffset);
+ return true;
+ }
+ }
+
+ private static int getCaretPosition(FindResult findResult, int caretShiftFromSelectionStart) {
+ return caretShiftFromSelectionStart < 0
+ ? findResult.getEndOffset() : Math.min(findResult.getStartOffset() + caretShiftFromSelectionStart, findResult.getEndOffset());
+ }
}