summaryrefslogtreecommitdiff
path: root/platform/lang-impl/src/com/intellij/find/impl/livePreview
diff options
context:
space:
mode:
Diffstat (limited to 'platform/lang-impl/src/com/intellij/find/impl/livePreview')
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java47
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewController.java19
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java147
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/livePreview/SelectionManager.java90
4 files changed, 185 insertions, 118 deletions
diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java
index c20b5925721d..4ba97e0151e5 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -121,7 +121,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
}
highlightUsages();
- updateCursorHighlighting(false);
+ updateCursorHighlighting();
if (myInSmartUpdate) {
clearUnusedHightlighters();
myInSmartUpdate = false;
@@ -218,9 +218,9 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
}
@Override
- public void cursorMoved(boolean toChangeSelection) {
+ public void cursorMoved() {
updateInSelectionHighlighters();
- updateCursorHighlighting(toChangeSelection);
+ updateCursorHighlighting();
}
@Override
@@ -228,14 +228,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
dumpState();
}
- @Override
- public void editorChanged(SearchResults sr, Editor oldEditor) {
- removeFromEditor();
- oldEditor.getDocument().removeDocumentListener(this);
- mySearchResults.getEditor().getDocument().addDocumentListener(this);
- }
-
- private void updateCursorHighlighting(boolean scroll) {
+ private void updateCursorHighlighting() {
hideBalloon();
if (myCursorHighlighter != null) {
@@ -245,7 +238,6 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
final FindResult cursor = mySearchResults.getCursor();
Editor editor = mySearchResults.getEditor();
- SelectionModel selection = editor.getSelectionModel();
if (cursor != null) {
Set<RangeHighlighter> dummy = new HashSet<RangeHighlighter>();
highlightRange(cursor, new TextAttributes(null, null, Color.BLACK, EffectType.ROUNDED_BOX, 0), dummy);
@@ -253,33 +245,6 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
myCursorHighlighter = dummy.iterator().next();
}
- if (scroll) {
- if (mySearchResults.getFindModel().isGlobal()) {
- FoldingModel foldingModel = editor.getFoldingModel();
- final FoldRegion[] allRegions = editor.getFoldingModel().getAllFoldRegions();
-
- foldingModel.runBatchFoldingOperation(new Runnable() {
- @Override
- public void run() {
- for (FoldRegion region : allRegions) {
- if (!region.isValid()) continue;
- if (cursor.intersects(TextRange.create(region))) {
- region.setExpanded(true);
- }
- }
- }
- });
- selection.setSelection(cursor.getStartOffset(), cursor.getEndOffset());
-
- editor.getCaretModel().moveToOffset(cursor.getEndOffset());
- editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
- } else {
- if (!SearchResults.insideVisibleArea(editor, cursor)) {
- LogicalPosition pos = editor.offsetToLogicalPosition(cursor.getStartOffset());
- editor.getScrollingModel().scrollTo(pos, ScrollType.CENTER);
- }
- }
- }
editor.getScrollingModel().runActionOnScrollingFinished(new Runnable() {
@Override
public void run() {
@@ -496,6 +461,8 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
new Processor<RangeHighlighterEx>() {
@Override
public boolean process(RangeHighlighterEx highlighter) {
+ if (!highlighter.getEditorFilter().avaliableIn(mySearchResults.getEditor())) return true;
+
TextAttributes textAttributes =
highlighter.getTextAttributes();
if (highlighter.getUserData(SEARCH_MARKER) != null &&
diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewController.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewController.java
index 8368f1b2f2aa..94a6c3f9c1bc 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewController.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewController.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.find.impl.livePreview;
import com.intellij.find.*;
@@ -83,9 +98,9 @@ public class LivePreviewController implements LivePreview.Delegate, FindUtil.Rep
public void moveCursor(SearchResults.Direction direction) {
if (direction == SearchResults.Direction.UP) {
- mySearchResults.prevOccurrence();
+ mySearchResults.prevOccurrence(false);
} else {
- mySearchResults.nextOccurrence();
+ mySearchResults.nextOccurrence(false);
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java
index dff4989bb2f6..39b17dd2acc8 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java
@@ -21,9 +21,7 @@ import com.intellij.find.FindModel;
import com.intellij.find.FindResult;
import com.intellij.find.FindUtil;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.RangeMarker;
-import com.intellij.openapi.editor.SelectionModel;
+import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -38,6 +36,7 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import com.intellij.util.containers.Stack;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -70,6 +69,7 @@ public class SearchResults implements DocumentListener {
private @Nullable FindResult myCursor;
+ @NotNull
private List<FindResult> myOccurrences = new ArrayList<FindResult>();
private final Set<RangeMarker> myExcluded = new HashSet<RangeMarker>();
@@ -90,6 +90,8 @@ public class SearchResults implements DocumentListener {
private final Stack<Pair<FindModel, FindResult>> myCursorPositions = new Stack<Pair<FindModel, FindResult>>();
+ private final SelectionManager mySelectionManager = new SelectionManager(this);
+
public SearchResults(Editor editor, Project project) {
myEditor = editor;
myProject = project;
@@ -127,9 +129,8 @@ public class SearchResults implements DocumentListener {
public void exclude(FindResult occurrence) {
boolean include = false;
- final TextRange r = occurrence;
for (RangeMarker rangeMarker : myExcluded) {
- if (TextRange.areSegmentsEqual(rangeMarker, r)) {
+ if (TextRange.areSegmentsEqual(rangeMarker, occurrence)) {
myExcluded.remove(rangeMarker);
rangeMarker.dispose();
include = true;
@@ -137,7 +138,7 @@ public class SearchResults implements DocumentListener {
}
}
if (!include) {
- myExcluded.add(myEditor.getDocument().createRangeMarker(r.getStartOffset(), r.getEndOffset(), true));
+ myExcluded.add(myEditor.getDocument().createRangeMarker(occurrence.getStartOffset(), occurrence.getEndOffset(), true));
}
notifyChanged();
}
@@ -149,8 +150,7 @@ public class SearchResults implements DocumentListener {
public interface SearchResultsListener {
void searchResultsUpdated(SearchResults sr);
- void editorChanged(SearchResults sr, Editor oldEditor);
- void cursorMoved(boolean toChangeSelection);
+ void cursorMoved();
void updateFinished();
}
@@ -175,6 +175,7 @@ public class SearchResults implements DocumentListener {
return myCursor;
}
+ @NotNull
public List<FindResult> getOccurrences() {
return myOccurrences;
}
@@ -184,19 +185,7 @@ public class SearchResults implements DocumentListener {
return myProject;
}
- public synchronized void setEditor(Editor editor) {
- Editor oldOne = myEditor;
- myEditor = editor;
- notifyEditorChanged(oldOne);
- }
-
- private void notifyEditorChanged(Editor oldOne) {
- for (SearchResultsListener listener : myListeners) {
- listener.editorChanged(this, oldOne);
- }
- }
-
- public synchronized Editor getEditor() {
+ public Editor getEditor() {
return myEditor;
}
@@ -334,7 +323,7 @@ public class SearchResults implements DocumentListener {
myEditor.getDocument().removeDocumentListener(this);
}
- private void searchCompleted(List<FindResult> occurrences, Editor editor, @Nullable FindModel findModel,
+ private void searchCompleted(@NotNull List<FindResult> occurrences, Editor editor, @Nullable FindModel findModel,
boolean toChangeSelection, @Nullable TextRange next, int stamp) {
if (stamp < myLastUpdatedStamp){
return;
@@ -344,7 +333,7 @@ public class SearchResults implements DocumentListener {
return;
}
myOccurrences = occurrences;
- final TextRange oldCursorRange = myCursor != null ? myCursor : null;
+ final TextRange oldCursorRange = myCursor;
Collections.sort(myOccurrences, new Comparator<FindResult>() {
@Override
public int compare(FindResult findResult, FindResult findResult1) {
@@ -357,7 +346,10 @@ public class SearchResults implements DocumentListener {
updateExcluded();
notifyChanged();
if (oldCursorRange == null || myCursor == null || !myCursor.equals(oldCursorRange)) {
- notifyCursorMoved(toChangeSelection);
+ if (toChangeSelection) {
+ mySelectionManager.updateSelection(true, true);
+ }
+ notifyCursorMoved();
}
dumpIfNeeded();
}
@@ -389,7 +381,7 @@ public class SearchResults implements DocumentListener {
myCursor = firstOccurrenceAfterOffset(oldCursorRange.getEndOffset());
} else {
if (justReplaced) {
- nextOccurrence(false, next, false, justReplaced);
+ nextOccurrence(false, next, false, true, false);
} else {
FindResult afterCaret = oldCursorRange == null ? firstOccurrenceAtOrAfterCaret() : firstOccurrenceAfterCaret();
if (afterCaret != null) {
@@ -405,7 +397,7 @@ public class SearchResults implements DocumentListener {
}
}
if (!justReplaced && myCursor == null && hasMatches()) {
- nextOccurrence(true, oldCursorRange, false, false);
+ nextOccurrence(true, oldCursorRange, false, false, false);
}
if (toPush && myCursor != null){
push();
@@ -445,6 +437,13 @@ public class SearchResults implements DocumentListener {
return occurrence;
}
}
+ int selectionStartOffset = getEditor().getSelectionModel().getSelectionStart();
+ int selectionEndOffset = getEditor().getSelectionModel().getSelectionEnd();
+ for (FindResult occurrence : myOccurrences) {
+ if (selectionEndOffset >= occurrence.getEndOffset() && selectionStartOffset <= occurrence.getStartOffset()) {
+ return occurrence;
+ }
+ }
return firstOccurrenceAfterCaret();
}
@@ -462,25 +461,6 @@ public class SearchResults implements DocumentListener {
}
@Nullable
- private FindResult firstVisibleOccurrence() {
- int offset = Integer.MAX_VALUE;
- FindResult firstOccurrence = null;
- FindResult firstVisibleOccurrence = null;
- for (FindResult o : getOccurrences()) {
- if (insideVisibleArea(myEditor, o)) {
- if (firstVisibleOccurrence == null || o.getStartOffset() < firstVisibleOccurrence.getStartOffset()) {
- firstVisibleOccurrence = o;
- }
- }
- if (o.getStartOffset() < offset) {
- offset = o.getStartOffset();
- firstOccurrence = o;
- }
- }
- return firstVisibleOccurrence != null ? firstVisibleOccurrence : firstOccurrence;
- }
-
- @Nullable
private FindResult firstOccurrenceBeforeCaret() {
int offset = getEditor().getCaretModel().getOffset();
return firstOccurrenceBeforeOffset(offset);
@@ -554,32 +534,45 @@ public class SearchResults implements DocumentListener {
return null;
}
- public void prevOccurrence() {
- FindResult next = null;
- if (myFindModel == null) return;
- boolean processFromTheBeginning = false;
- if (myNotFoundState) {
- myNotFoundState = false;
- processFromTheBeginning = true;
- }
- if (!myFindModel.isGlobal()) {
- if (myCursor != null) {
- next = prevOccurrence(myCursor);
+ public void prevOccurrence(boolean findSelected) {
+ if (findSelected) {
+ if (mySelectionManager.removeCurrentSelection()) {
+ myCursor = firstOccurrenceAtOrAfterCaret();
}
- } else {
- next = firstOccurrenceBeforeCaret();
- }
- if (next == null) {
- if (processFromTheBeginning) {
- if (hasMatches()) {
- next = getOccurrences().get(getOccurrences().size()-1);
+ else {
+ myCursor = null;
+ }
+ notifyCursorMoved();
+ }
+ else {
+ FindResult next = null;
+ if (myFindModel == null) return;
+ boolean processFromTheBeginning = false;
+ if (myNotFoundState) {
+ myNotFoundState = false;
+ processFromTheBeginning = true;
+ }
+ if (!myFindModel.isGlobal()) {
+ if (myCursor != null) {
+ next = prevOccurrence(myCursor);
+ }
+ }
+ else {
+ next = firstOccurrenceBeforeCaret();
+ }
+ if (next == null) {
+ if (processFromTheBeginning) {
+ if (hasMatches()) {
+ next = getOccurrences().get(getOccurrences().size() - 1);
+ }
+ }
+ else {
+ setNotFoundState(false);
}
- } else {
- setNotFoundState(false);
}
- }
- moveCursorTo(next);
+ moveCursorTo(next, false);
+ }
push();
}
@@ -587,13 +580,13 @@ public class SearchResults implements DocumentListener {
myCursorPositions.push(Pair.create(myFindModel, myCursor));
}
- public void nextOccurrence() {
+ public void nextOccurrence(boolean retainOldSelection) {
if (myFindModel == null) return;
- nextOccurrence(false, myCursor != null ? myCursor : null, true, false);
+ nextOccurrence(false, myCursor, true, false, retainOldSelection);
push();
}
- private void nextOccurrence(boolean processFromTheBeginning, TextRange cursor, boolean toNotify, boolean justReplaced) {
+ private void nextOccurrence(boolean processFromTheBeginning, TextRange cursor, boolean toNotify, boolean justReplaced, boolean retainOldSelection) {
FindResult next;
if (myNotFoundState) {
myNotFoundState = false;
@@ -614,22 +607,24 @@ public class SearchResults implements DocumentListener {
}
}
if (toNotify) {
- moveCursorTo(next);
+ moveCursorTo(next, retainOldSelection);
} else {
myCursor = next;
}
}
- public void moveCursorTo(FindResult next) {
- if (next != null) {
+ public void moveCursorTo(FindResult next, boolean retainOldSelection) {
+ if (next != null && !mySelectionManager.isSelected(next)) {
+ retainOldSelection &= (myCursor != null && mySelectionManager.isSelected(myCursor));
myCursor = next;
- notifyCursorMoved(true);
+ mySelectionManager.updateSelection(!retainOldSelection, false);
+ notifyCursorMoved();
}
}
- private void notifyCursorMoved(boolean toChangeSelection) {
+ private void notifyCursorMoved() {
for (SearchResultsListener listener : myListeners) {
- listener.cursorMoved(toChangeSelection);
+ listener.cursorMoved();
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SelectionManager.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SelectionManager.java
new file mode 100644
index 000000000000..50f37927c506
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SelectionManager.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.find.impl.livePreview;
+
+import com.intellij.find.FindResult;
+import com.intellij.find.FindUtil;
+import com.intellij.openapi.editor.*;
+import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
+
+public class SelectionManager {
+ @NotNull private final SearchResults mySearchResults;
+
+ public SelectionManager(@NotNull SearchResults results) {
+ mySearchResults = results;
+ }
+
+ public void updateSelection(boolean removePreviousSelection, boolean removeAllPreviousSelections) {
+ Editor editor = mySearchResults.getEditor();
+ if (removeAllPreviousSelections) {
+ editor.getCaretModel().removeSecondaryCarets();
+ }
+ final FindResult cursor = mySearchResults.getCursor();
+ if (cursor == null) {
+ return;
+ }
+ if (mySearchResults.getFindModel().isGlobal()) {
+ if (removePreviousSelection || removeAllPreviousSelections) {
+ FoldingModel foldingModel = editor.getFoldingModel();
+ final FoldRegion[] allRegions = editor.getFoldingModel().getAllFoldRegions();
+
+ foldingModel.runBatchFoldingOperation(new Runnable() {
+ @Override
+ public void run() {
+ for (FoldRegion region : allRegions) {
+ if (!region.isValid()) continue;
+ if (cursor.intersects(TextRange.create(region))) {
+ region.setExpanded(true);
+ }
+ }
+ }
+ });
+ editor.getSelectionModel().setSelection(cursor.getStartOffset(), cursor.getEndOffset());
+ editor.getCaretModel().moveToOffset(cursor.getEndOffset());
+ }
+ else {
+ FindUtil.selectSearchResultInEditor(editor, cursor, -1);
+ }
+ editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
+ } else {
+ if (!SearchResults.insideVisibleArea(editor, cursor)) {
+ LogicalPosition pos = editor.offsetToLogicalPosition(cursor.getStartOffset());
+ editor.getScrollingModel().scrollTo(pos, ScrollType.CENTER);
+ }
+ }
+ }
+
+ public boolean removeCurrentSelection() {
+ Editor editor = mySearchResults.getEditor();
+ CaretModel caretModel = editor.getCaretModel();
+ Caret primaryCaret = caretModel.getPrimaryCaret();
+ if (caretModel.getCaretCount() > 1) {
+ caretModel.removeCaret(primaryCaret);
+ return true;
+ }
+ else {
+ primaryCaret.moveToOffset(primaryCaret.getSelectionStart());
+ primaryCaret.removeSelection();
+ return false;
+ }
+ }
+
+ public boolean isSelected(@NotNull FindResult result) {
+ Editor editor = mySearchResults.getEditor();
+ return editor.getCaretModel().getCaretAt(editor.offsetToVisualPosition(result.getEndOffset())) != null;
+ }
+}