Skip to content

Commit

Permalink
Find/replace: always select text when search input receives focus #2012
Browse files Browse the repository at this point in the history
When the FindReplaceOverlay is opened, the search input field is
initialized with the string currently selected in the target editor and
this string is selected in the search input field. In consequence,
starting to type after opening the dialog replaces the search string.
When there is no selection in the target editor, the current search
string is kept, but it is not selected. So starting to type will insert
further text before the current search string instead of replacing it.
This is inconsistent with the existing FindReplaceDialog.

This change improves the behavior to always select the search string
when the input field receives focus. According test cases are added.

Fixes #2012
  • Loading branch information
HeikoKlare committed Jul 15, 2024
1 parent dfff9bf commit 816820a
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -332,11 +332,11 @@ public int open() {
overlayOpen = true;
applyOverlayColors(backgroundToUse, true);
updateFromTargetSelection();
searchBar.forceFocus();

getShell().layout();
updatePlacementAndVisibility();

searchBar.forceFocus();
return returnCode;
}

Expand Down Expand Up @@ -936,19 +936,16 @@ private void performSearch(boolean forward) {

private void updateFromTargetSelection() {
String selectionText = findReplaceLogic.getTarget().getSelectionText();
if (selectionText.isEmpty()) {
return;
}
if (selectionText.contains("\n")) { //$NON-NLS-1$
findReplaceLogic.deactivate(SearchOptions.GLOBAL);
searchInSelectionButton.setSelection(true);
} else {
} else if (!selectionText.isEmpty()) {
if (findReplaceLogic.isRegExSearchAvailableAndActive()) {
selectionText = FindReplaceDocumentAdapter.escapeForRegExPattern(selectionText);
}
searchBar.setText(selectionText);
searchBar.setSelection(0, selectionText.length());
}
searchBar.setSelection(0, searchBar.getText().length());
}

private void evaluateFindReplaceStatus() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,20 +166,20 @@ public void testShiftEnterReversesSearchDirection() {
assertEquals(0, (target.getSelection()).x);
assertEquals(4, (target.getSelection()).y);

dialog.simulateEnterInFindInputField(false);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, false);
assertEquals(5, (target.getSelection()).x);
assertEquals(4, (target.getSelection()).y);

dialog.simulateEnterInFindInputField(true);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, true);
assertEquals(0, (target.getSelection()).x);
assertEquals(4, (target.getSelection()).y);

// Keypad-Enter is also valid for navigating
dialog.simulateKeyPressInFindInputField(SWT.KEYPAD_CR, false);
dialog.simulateKeyboardInteractionInFindInputField(SWT.KEYPAD_CR, false);
assertEquals(5, (target.getSelection()).x);
assertEquals(4, (target.getSelection()).y);

dialog.simulateKeyPressInFindInputField(SWT.KEYPAD_CR, true);
dialog.simulateKeyboardInteractionInFindInputField(SWT.KEYPAD_CR, true);
assertEquals(0, (target.getSelection()).x);
assertEquals(4, (target.getSelection()).y);
}
Expand Down Expand Up @@ -214,7 +214,7 @@ public void testFindWithWholeWordEnabledWithMultipleWords() {
dialog.assertDisabled(SearchOptions.WHOLE_WORD);
dialog.assertSelected(SearchOptions.WHOLE_WORD);

dialog.simulateEnterInFindInputField(false);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, false);
assertThat(target.getSelectionText(), is(dialog.getFindText()));

assertEquals(0, (target.getSelection()).x);
Expand All @@ -228,11 +228,11 @@ public void testRegExSearch() {
dialog.setFindText("(a|bc)");

IFindReplaceTarget target= dialog.getTarget();
dialog.simulateEnterInFindInputField(false);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, false);
assertEquals(0, (target.getSelection()).x);
assertEquals(1, (target.getSelection()).y);

dialog.simulateEnterInFindInputField(false);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, false);
assertEquals(1, (target.getSelection()).x);
assertEquals(2, (target.getSelection()).y);
}
Expand Down Expand Up @@ -303,6 +303,28 @@ public void testActivateDialogWithSelectionActive() {
assertThat(fTextViewer.getDocument().get(), is("text" + System.lineSeparator() + System.lineSeparator()));
}

@Test
public void testSearchTextSelectedWhenOpeningDialog() {
openTextViewer("test");
fTextViewer.setSelection(new TextSelection(0, 4));
initializeFindReplaceUIForTextViewer();
assertEquals("test", dialog.getFindText());

dialog.simulateKeystrokeInFindInputField('w');
assertEquals("w", dialog.getFindText());
}

@Test
public void testSearchTextSelectedWhenSwitchingFocusToDialog() {
openTextViewer("");
initializeFindReplaceUIForTextViewer();
dialog.setFindText("text");
reopenFindReplaceUIForTextViewer();

dialog.simulateKeystrokeInFindInputField('w');
assertEquals("w", dialog.getFindText());
}

private void assertScopeActivationOnTextInput(String input) {
openTextViewer(input);
fTextViewer.setSelection(new TextSelection(0, fTextViewer.getDocument().toString().length()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ public interface IFindReplaceUIAccess {

void select(SearchOptions option);

void simulateEnterInFindInputField(boolean shiftPressed);
void simulateKeyboardInteractionInFindInputField(int keyCode, boolean shiftPressed);

void simulateKeyPressInFindInputField(int keyCode, boolean shiftPressed);
void simulateKeystrokeInFindInputField(char character);

String getFindText();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*******************************************************************************/
package org.eclipse.ui.internal.findandreplace.overlay;

import static org.eclipse.ui.internal.findandreplace.FindReplaceTestUtil.runEventQueue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

Expand All @@ -36,7 +37,6 @@
import org.eclipse.jface.text.IFindReplaceTargetExtension;

import org.eclipse.ui.internal.findandreplace.FindReplaceLogic;
import org.eclipse.ui.internal.findandreplace.FindReplaceTestUtil;
import org.eclipse.ui.internal.findandreplace.IFindReplaceLogic;
import org.eclipse.ui.internal.findandreplace.IFindReplaceUIAccess;
import org.eclipse.ui.internal.findandreplace.SearchOptions;
Expand Down Expand Up @@ -142,21 +142,24 @@ public void unselect(SearchOptions option) {
}

@Override
public void simulateEnterInFindInputField(boolean shiftPressed) {
simulateKeyPressInFindInputField(SWT.CR, shiftPressed);
}

@Override
public void simulateKeyPressInFindInputField(int keyCode, boolean shiftPressed) {
public void simulateKeyboardInteractionInFindInputField(int keyCode, boolean shiftPressed) {
final Event event= new Event();
event.type= SWT.KeyDown;
event.keyCode= keyCode;
if (shiftPressed) {
event.stateMask= SWT.SHIFT;
}
event.keyCode= keyCode;
find.notifyListeners(SWT.KeyDown, event);
find.traverse(SWT.TRAVERSE_RETURN, event);
FindReplaceTestUtil.runEventQueue();
runEventQueue();
}

@Override
public void simulateKeystrokeInFindInputField(char character) {
final Event event= new Event();
event.type= SWT.KeyDown;
event.character= character;
find.getDisplay().post(event);
runEventQueue();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,23 +169,26 @@ public Shell getActiveShell() {
}

@Override
public void simulateEnterInFindInputField(boolean shiftPressed) {
simulateKeyPressInFindInputField(SWT.CR, shiftPressed);
}

@Override
public void simulateKeyPressInFindInputField(int keyCode, boolean shiftPressed) {
public void simulateKeyboardInteractionInFindInputField(int keyCode, boolean shiftPressed) {
final Event event= new Event();
event.type= SWT.Traverse;
event.detail= SWT.TRAVERSE_RETURN;
event.character= (char) keyCode;
event.type= SWT.KeyDown;
if (shiftPressed) {
event.stateMask= SWT.SHIFT;
}
event.keyCode= keyCode;
findCombo.traverse(SWT.TRAVERSE_RETURN, event);
runEventQueue();
}

@Override
public void simulateKeystrokeInFindInputField(char character) {
final Event event= new Event();
event.type= SWT.KeyDown;
event.character= character;
findCombo.getDisplay().post(event);
runEventQueue();
}

@Override
public String getReplaceText() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,19 @@ public void testFocusNotChangedWhenEnterPressed() {

dialog.findCombo.setFocus();
dialog.setFindText("line");
dialog.simulateEnterInFindInputField(false);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, false);
ensureHasFocusOnGTK();

assertTrue(dialog.getFindCombo().isFocusControl());

Button wrapCheckBox= dialog.getButtonForSearchOption(SearchOptions.WRAP);
Button globalRadioButton= dialog.getButtonForSearchOption(SearchOptions.GLOBAL);
wrapCheckBox.setFocus();
dialog.simulateEnterInFindInputField(false);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, false);
assertTrue(wrapCheckBox.isFocusControl());

globalRadioButton.setFocus();
dialog.simulateEnterInFindInputField(false);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, false);
assertTrue(globalRadioButton.isFocusControl());
}

Expand Down Expand Up @@ -124,22 +124,22 @@ public void testShiftEnterReversesSearchDirectionDialogSpecific() {
ensureHasFocusOnGTK();
IFindReplaceTarget target= dialog.getTarget();

dialog.simulateEnterInFindInputField(false);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, false);
assertEquals(0, (target.getSelection()).x);
assertEquals(4, (target.getSelection()).y);

dialog.simulateEnterInFindInputField(false);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, false);
assertEquals(5, (target.getSelection()).x);
assertEquals(4, (target.getSelection()).y);

dialog.simulateEnterInFindInputField(true);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, true);
assertEquals(0, (target.getSelection()).x);
assertEquals(4, (target.getSelection()).y);

// This part only makes sense for the FindReplaceDialog since not every UI might have stored
// the search direction as a state
dialog.unselect(SearchOptions.FORWARD);
dialog.simulateEnterInFindInputField(true);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, true);
assertEquals(5, (target.getSelection()).x);
}

Expand Down Expand Up @@ -211,15 +211,15 @@ public void testFindWithWholeWordEnabledWithMultipleWordsNotIncremental() {
dialog.select(SearchOptions.WRAP);
IFindReplaceTarget target= dialog.getTarget();

dialog.simulateEnterInFindInputField(false);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, false);
assertEquals(0, (target.getSelection()).x);
assertEquals(3, (target.getSelection()).y);

dialog.setFindText("two wo");
dialog.assertDisabled(SearchOptions.WHOLE_WORD);
dialog.assertSelected(SearchOptions.WHOLE_WORD);

dialog.simulateEnterInFindInputField(false);
dialog.simulateKeyboardInteractionInFindInputField(SWT.CR, false);
assertThat(target.getSelectionText(), is(dialog.getFindText()));

assertEquals(0, (target.getSelection()).x);
Expand Down

0 comments on commit 816820a

Please sign in to comment.