Skip to content

Commit

Permalink
Fix Replace/Find behavior for RegEx search eclipse-platform#1540
Browse files Browse the repository at this point in the history
The replace functionality of the FindAndReplaceLogic checks whether the
current selection fits to the current search string and otherwise
performs a find operation first. To this end, it compares the text
selection with the search string, even if regex search is used. In regex
search mode, this check will usually fail and a find operation is
performed even though a correct string is already selected. This results
in the replacement of the next instead of the current match.

With this change, the check for whether the currently selected string
fits to the search string properly considers regex search mode. It also
adds an according regression test.

Fixes eclipse-platform#1540
  • Loading branch information
HeikoKlare committed Jan 22, 2024
1 parent 55034d1 commit a3b8f42
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.eclipse.swt.custom.BusyIndicator;
Expand Down Expand Up @@ -593,13 +594,23 @@ public boolean performReplaceAndFind(String findString, String replaceString) {
@Override
public boolean performSelectAndReplace(String findString, String replaceString) {
resetStatus();
boolean needToSelectFirst = !getCurrentSelection().equals(findString);
if (needToSelectFirst) {
if (!isFindStringSelected(findString)) {
performSearch(findString);
}
return replaceSelection(replaceString);
}

private boolean isFindStringSelected(String findString) {
String selectedString = getCurrentSelection();
if (isActive(SearchOptions.REGEX)) {
int patternFlags = isActive(SearchOptions.CASE_SENSITIVE) ? 0 : Pattern.CASE_INSENSITIVE;
Pattern pattern = Pattern.compile(findString, patternFlags);
return pattern.matcher(selectedString).find();
} else {
return getCurrentSelection().equals(findString);
}
}

@Override
public void updateTarget(IFindReplaceTarget newTarget, boolean canEditTarget) {
resetStatus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ public void testPerformSelectAndReplaceBackward() {
expectStatusEmpty(findReplaceLogic);
}


@Test
public void testPerformReplaceAndFind() {
TextViewer textViewer= setupTextViewer("Hello<replace>World<replace>!");
Expand All @@ -237,6 +236,36 @@ public void testPerformReplaceAndFind() {
expectStatusIsCode(findReplaceLogic, FindStatus.StatusCode.NO_MATCH);
}

@Test
public void testPerformReplaceAndFindRegEx() {
TextViewer textViewer= setupTextViewer("Hello<replace>World<replace>!<replace>!");
IFindReplaceLogic findReplaceLogic= setupFindReplaceLogicObject(textViewer);
findReplaceLogic.activate(SearchOptions.FORWARD);
findReplaceLogic.activate(SearchOptions.REGEX);

boolean status= findReplaceLogic.performReplaceAndFind("<(\\w*)>", " ");
assertThat(status, is(true));
assertThat(textViewer.getDocument().get(), equalTo("Hello World<replace>!<replace>!"));
assertThat(findReplaceLogic.getTarget().getSelectionText(), equalTo("<replace>"));
expectStatusEmpty(findReplaceLogic);

status= findReplaceLogic.performReplaceAndFind("<(\\w*)>", " ");
assertThat(status, is(true));
assertThat(textViewer.getDocument().get(), equalTo("Hello World !<replace>!"));
assertThat(findReplaceLogic.getTarget().getSelectionText(), equalTo("<replace>"));
expectStatusEmpty(findReplaceLogic);

status= findReplaceLogic.performReplaceAndFind("<(\\w*)>", " ");
assertThat(status, is(true));
assertThat(textViewer.getDocument().get(), equalTo("Hello World ! !"));
expectStatusIsCode(findReplaceLogic, FindStatus.StatusCode.NO_MATCH);

status= findReplaceLogic.performReplaceAndFind("<(\\w*)>", " ");
assertEquals("Status wasn't correctly returned", false, status);
assertEquals("Text shouldn't have been changed", "Hello World ! !", textViewer.getDocument().get());
expectStatusIsCode(findReplaceLogic, FindStatus.StatusCode.NO_MATCH);
}

@Test
public void testPerformSelectAllForward() {
TextViewer textViewer= setupTextViewer("AbAbAbAb");
Expand Down

0 comments on commit a3b8f42

Please sign in to comment.