Skip to content

Commit 46003dd

Browse files
committed
This pr stores the current editor caret position when user starts typing
a new search pattern.
1 parent 80643f0 commit 46003dd

File tree

2 files changed

+99
-1
lines changed

2 files changed

+99
-1
lines changed

bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/findandreplace/FindReplaceLogic.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ public class FindReplaceLogic implements IFindReplaceLogic {
5050
private IFindReplaceStatus status;
5151
private IFindReplaceTarget target;
5252
private Point incrementalBaseLocation;
53-
53+
private Point restoreBaseLocation = new Point(0, 0);
54+
private boolean isSetRestoreBaseLocation = true;
5455
private boolean isTargetSupportingRegEx;
5556
private boolean isTargetEditable;
5657
private final Set<SearchOptions> searchOptions = new HashSet<>();
@@ -60,6 +61,11 @@ public class FindReplaceLogic implements IFindReplaceLogic {
6061

6162
@Override
6263
public void setFindString(String findString) {
64+
if (this.findString.isEmpty() && !findString.isEmpty()) {
65+
// User just started a new search after clearing previous search.
66+
if (target != null)
67+
restoreBaseLocation = target.getSelection();
68+
}
6369
this.findString = Objects.requireNonNull(findString);
6470
if (isAvailableAndActive(SearchOptions.INCREMENTAL)) {
6571
performSearch(true);
@@ -165,6 +171,10 @@ private static boolean isWord(String str) {
165171
public void resetIncrementalBaseLocation() {
166172
if (target != null && shouldInitIncrementalBaseLocation()) {
167173
incrementalBaseLocation = target.getSelection();
174+
if (isSetRestoreBaseLocation) {
175+
restoreBaseLocation = incrementalBaseLocation;
176+
isSetRestoreBaseLocation = false;
177+
}
168178
} else {
169179
incrementalBaseLocation = new Point(0, 0);
170180
}
@@ -324,6 +334,7 @@ public boolean performSearch() {
324334
private boolean performSearch(boolean updateFromIncrementalBaseLocation) {
325335
resetStatus();
326336
if (findString.isEmpty()) {
337+
restoreSelectionIfEmpty();
327338
return false;
328339
}
329340

@@ -338,6 +349,22 @@ private boolean performSearch(boolean updateFromIncrementalBaseLocation) {
338349
return somethingFound;
339350
}
340351

352+
/**
353+
* Restores the original caret/selection position when the search field becomes
354+
* empty.
355+
*/
356+
private void restoreSelectionIfEmpty() {
357+
if (restoreBaseLocation == null)
358+
return;
359+
incrementalBaseLocation = restoreBaseLocation;
360+
if (target instanceof IFindReplaceTargetExtension extension)
361+
extension.setSelection(restoreBaseLocation.x, restoreBaseLocation.y);
362+
}
363+
364+
Point getRestoreBaseLocation() {
365+
return restoreBaseLocation;
366+
}
367+
341368
/**
342369
* Replaces all occurrences of the user's findString with the replace string.
343370
* Returns the number of replacements that occur.

tests/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/internal/findandreplace/FindReplaceLogicTest.java

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,77 @@ public void testResetIncrementalBaseLocation() {
833833
findReplaceLogic.resetIncrementalBaseLocation();
834834
findReplaceLogic.performSearch();
835835
assertThat(textViewer.getSelectedRange(), is(new Point(5, 4)));
836+
837+
textViewer.setSelectedRange(7, 0);
838+
findReplaceLogic.resetIncrementalBaseLocation();
839+
findReplaceLogic.performSearch();
840+
assertThat(textViewer.getSelectedRange(), is(new Point(10, 4)));
841+
842+
textViewer.setSelectedRange(10, 0);
843+
findReplaceLogic.resetIncrementalBaseLocation();
844+
findReplaceLogic.performSearch();
845+
assertThat(textViewer.getSelectedRange(), is(new Point(10, 4)));
846+
assertThat(((FindReplaceLogic) findReplaceLogic).getRestoreBaseLocation(), is(new Point(10, 0)));
847+
}
848+
849+
@Test
850+
public void testRestoreBaseLocationCapturedOnNewSearch() {
851+
String setupString= "alpha beta gamma";
852+
TextViewer textViewer= setupTextViewer(setupString);
853+
textViewer.setSelectedRange(6, 0); // caret after 'alpha '
854+
IFindReplaceLogic logic= setupFindReplaceLogicObject(textViewer);
855+
logic.activate(SearchOptions.FORWARD);
856+
logic.activate(SearchOptions.INCREMENTAL);
857+
858+
// Initially empty find string
859+
logic.setFindString("");
860+
// Now start a new search (transition empty -> non-empty)
861+
logic.setFindString("beta");
862+
// Expect the stored restore location to match the caret before search started
863+
assertThat(((FindReplaceLogic) logic).getRestoreBaseLocation(), is(new Point(6, 0)));
864+
}
865+
866+
@Test
867+
public void testCaretRestoredWhenSearchCleared() {
868+
String setupString= "alpha beta gamma";
869+
TextViewer textViewer= setupTextViewer(setupString);
870+
textViewer.setSelectedRange(0, 0);
871+
IFindReplaceLogic logic= setupFindReplaceLogicObject(textViewer);
872+
logic.activate(SearchOptions.FORWARD);
873+
logic.activate(SearchOptions.INCREMENTAL);
874+
875+
logic.setFindString("beta");
876+
assertThat(textViewer.getSelectedRange(), is(new Point(6, 4))); // found "beta"
877+
878+
// Clear the search field - should restore caret
879+
logic.setFindString("");
880+
logic.performSearch();
881+
// Expect caret restored to starting location (0,0)
882+
assertThat(textViewer.getSelectedRange(), is(new Point(0, 0)));
883+
}
884+
885+
@Test
886+
public void testRestoreBaseLocationRefreshedBetweenSessions() {
887+
String setupString= "alpha beta gamma";
888+
TextViewer textViewer= setupTextViewer(setupString);
889+
IFindReplaceLogic logic= setupFindReplaceLogicObject(textViewer);
890+
logic.activate(SearchOptions.FORWARD);
891+
logic.activate(SearchOptions.INCREMENTAL);
892+
893+
// First search session
894+
textViewer.setSelectedRange(0, 0);
895+
logic.setFindString("alpha");
896+
assertThat(((FindReplaceLogic) logic).getRestoreBaseLocation(), is(new Point(0, 0)));
897+
898+
// Clear the search (simulate reopen of overlay)
899+
logic.setFindString("");
900+
logic.performSearch();
901+
902+
// Move caret and start new search session
903+
textViewer.setSelectedRange(6, 0);
904+
logic.setFindString("beta");
905+
// Verify that restoreBaseLocation updated to the new caret position
906+
assertThat(((FindReplaceLogic) logic).getRestoreBaseLocation(), is(new Point(6, 0)));
836907
}
837908

838909
@Test

0 commit comments

Comments
 (0)