diff options
Diffstat (limited to 'platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java')
-rw-r--r-- | platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java | 147 |
1 files changed, 71 insertions, 76 deletions
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(); } } } |