Skip to content

Commit

Permalink
Find/Replace Overlay: Add a search history
Browse files Browse the repository at this point in the history
Add a search history for the Find/Replace overlay, displayed as a
dropdown below the find/replace inputs.

fixes #1907
  • Loading branch information
Wittmaxi committed Jul 1, 2024
1 parent 529474b commit 26c5880
Show file tree
Hide file tree
Showing 14 changed files with 379 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Export-Package:
org.eclipse.ui.contentassist,
org.eclipse.ui.internal.findandreplace;x-friends:="org.eclipse.ui.workbench.texteditor.tests",
org.eclipse.ui.internal.findandreplace.status;x-friends:="org.eclipse.ui.workbench.texteditor.tests",
org.eclipse.ui.internal.findandreplace.overlay;x-friends="org.eclipse.ui.workbench.texteditor.tests",
org.eclipse.ui.internal.texteditor;texteditor=split;mandatory:=texteditor;x-friends:="org.eclipse.ui.editors",
org.eclipse.ui.internal.texteditor.codemining;x-internal:=true,
org.eclipse.ui.internal.texteditor.quickdiff;x-internal:=true,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ private FindReplaceMessages() {
public static String FindReplaceOverlay_searchBar_message;
public static String FindReplaceOverlay_replaceBar_message;
public static String FindReplaceOverlay_replaceToggle_toolTip;
public static String FindReplaceOverlay_searchHistory_toolTip;
public static String FindReplaceOverlay_replaceHistory_toolTip;
public static String FindReplaceOverlayFirstTimePopup_FindReplaceOverlayFirstTimePopup_message;
public static String FindReplaceOverlayFirstTimePopup_FindReplaceOverlayFirstTimePopup_title;
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ FindReplace_ReplaceAllButton_label=Replace &All
FindReplace_SelectAllButton_label=&Select All
FindReplace_CloseButton_label=Close

# Messages for the "new" Find-Replace-Overlay
# Messages for the Find-Replace-Overlay
FindReplaceOverlay_upSearchButton_toolTip=Search backward (Shift + Enter)
FindReplaceOverlay_downSearchButton_toolTip=Search forward (Enter)
FindReplaceOverlay_searchAllButton_toolTip=Search all (Ctrl + Enter)
Expand All @@ -55,8 +55,10 @@ FindReplaceOverlay_caseSensitiveButton_toolTip=Match case (Ctrl + Shift + C)
FindReplaceOverlay_wholeWordsButton_toolTip=Match whole word (Ctrl + Shift + W)
FindReplaceOverlay_replaceButton_toolTip=Replace (Enter)
FindReplaceOverlay_replaceAllButton_toolTip=Replace all (Ctrl + Enter)
FindReplaceOverlay_searchBar_message=Find
FindReplaceOverlay_replaceBar_message=Replace
FindReplaceOverlay_searchBar_message=Find (\u2195 for history)
FindReplaceOverlay_replaceBar_message=Replace (\u2195 for history)
FindReplaceOverlay_replaceToggle_toolTip=Toggle input for replace (Ctrl + R)
FindReplaceOverlay_searchHistory_toolTip=Show search history
FindReplaceOverlay_replaceHistory_toolTip=Show replace history
FindReplaceOverlayFirstTimePopup_FindReplaceOverlayFirstTimePopup_message=Find and replace can now be done using an overlay embedded inside the editor. If you prefer the dialog, you can disable the overlay in the preferences or <a>disable it now</a>.
FindReplaceOverlayFirstTimePopup_FindReplaceOverlayFirstTimePopup_title=New Find/Replace Overlay
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,8 @@ private void writeHistory() {
settingsManager.put(sectionName, names);
}

public List<String> asList() {
return new ArrayList<>(history);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
* activation behavior, we listen for it manually and send according events if
* necessary.
*/
public class AccessibleToolBar extends Composite {
class AccessibleToolBar extends Composite {

private List<ToolBar> toolBars = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
/**
* Builder for ToolItems for {@link AccessibleToolBar}.
*/
public class AccessibleToolItemBuilder {
class AccessibleToolItemBuilder {
private final AccessibleToolBar accessibleToolBar;
private int styleBits = SWT.NONE;
private Image image;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Widget;

import org.eclipse.core.runtime.Adapters;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.layout.GridDataFactory;
Expand All @@ -62,6 +64,7 @@
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.findandreplace.FindReplaceLogic;
import org.eclipse.ui.internal.findandreplace.FindReplaceMessages;
import org.eclipse.ui.internal.findandreplace.HistoryStore;
import org.eclipse.ui.internal.findandreplace.SearchOptions;
import org.eclipse.ui.internal.findandreplace.status.IFindReplaceStatus;

Expand Down Expand Up @@ -90,27 +93,34 @@ public class FindReplaceOverlay extends Dialog {

private Composite searchContainer;
private Composite searchBarContainer;
private Text searchBar;
private HistoryTextWrapper searchBar;
private AccessibleToolBar searchTools;

private ToolItem searchInSelectionButton;
private ToolItem wholeWordSearchButton;
private ToolItem caseSensitiveSearchButton;
private ToolItem regexSearchButton;

@SuppressWarnings("unused")
private ToolItem searchUpButton;
private ToolItem searchDownButton;

@SuppressWarnings("unused")
private ToolItem searchAllButton;

private Composite replaceContainer;
private Composite replaceBarContainer;
private Text replaceBar;
private HistoryTextWrapper replaceBar;
private AccessibleToolBar replaceTools;

@SuppressWarnings("unused")
private ToolItem replaceButton;
@SuppressWarnings("unused")
private ToolItem replaceAllButton;

private Color backgroundToUse;
private Color normalTextForegroundColor;
private boolean positionAtTop = true;
private static final int HISTORY_SIZE = 15;

public FindReplaceOverlay(Shell parent, IWorkbenchPart part, IFindReplaceTarget target) {
super(parent);
Expand All @@ -119,7 +129,6 @@ public FindReplaceOverlay(Shell parent, IWorkbenchPart part, IFindReplaceTarget
setShellStyle(SWT.MODELESS);
setBlockOnOpen(false);
targetPart = part;

}

@Override
Expand All @@ -143,11 +152,14 @@ private void createFindReplaceLogic(IFindReplaceTarget target) {
private void performReplaceAll() {
BusyIndicator.showWhile(getShell() != null ? getShell().getDisplay() : Display.getCurrent(),
() -> findReplaceLogic.performReplaceAll(getFindString(), getReplaceString()));
replaceBar.storeHistory();
searchBar.storeHistory();
}

private void performSelectAll() {
BusyIndicator.showWhile(getShell() != null ? getShell().getDisplay() : Display.getCurrent(),
() -> findReplaceLogic.performSelectAll(getFindString()));
searchBar.storeHistory();
}

private KeyListener shortcuts = KeyListener.keyPressedAdapter(e -> {
Expand Down Expand Up @@ -350,31 +362,22 @@ private void restoreOverlaySettings() {

private void applyOverlayColors(Color color, boolean tryToColorReplaceBar) {
searchTools.setBackground(color);
searchInSelectionButton.setBackground(color);
wholeWordSearchButton.setBackground(color);
regexSearchButton.setBackground(color);
caseSensitiveSearchButton.setBackground(color);
searchAllButton.setBackground(color);
searchUpButton.setBackground(color);
searchDownButton.setBackground(color);

searchBarContainer.setBackground(color);
searchBar.setBackground(color);
searchContainer.setBackground(color);

if (replaceBarOpen && tryToColorReplaceBar) {
replaceContainer.setBackground(color);
replaceBar.setBackground(color);
replaceBarContainer.setBackground(color);
replaceAllButton.setBackground(color);
replaceButton.setBackground(color);
replaceTools.setBackground(color);
replaceBar.setBackground(color);
}
}

private void unbindListeners() {
getShell().removeShellListener(overlayDeactivationListener);
if (targetPart != null && targetPart instanceof StatusTextEditor textEditor) {
Control targetWidget = textEditor.getAdapter(ITextViewer.class).getTextWidget();
Control targetWidget = Adapters.adapt(textEditor, ITextViewer.class).getTextWidget();
if (targetWidget != null) {
targetWidget.getShell().removeControlListener(shellMovementListener);
targetWidget.removePaintListener(widgetMovementListener);
Expand All @@ -386,7 +389,7 @@ private void unbindListeners() {
private void bindListeners() {
getShell().addShellListener(overlayDeactivationListener);
if (targetPart instanceof StatusTextEditor textEditor) {
Control targetWidget = textEditor.getAdapter(ITextViewer.class).getTextWidget();
Control targetWidget = Adapters.adapt(textEditor, ITextViewer.class).getTextWidget();

targetWidget.getShell().addControlListener(shellMovementListener);
targetWidget.addPaintListener(widgetMovementListener);
Expand Down Expand Up @@ -433,17 +436,20 @@ private void retrieveBackgroundColor() {
textBarForRetrievingTheRightColor.dispose();
}


private void createSearchTools() {
searchTools = new AccessibleToolBar(searchContainer);
GridDataFactory.fillDefaults().grab(false, true).align(GridData.CENTER, GridData.END).applyTo(searchTools);

@SuppressWarnings("unused")
ToolItem separator = searchTools.createToolItem(SWT.SEPARATOR);

createWholeWordsButton();
createCaseSensitiveButton();
createRegexSearchButton();
createAreaSearchButton();

@SuppressWarnings("unused")
ToolItem separator = searchTools.createToolItem(SWT.SEPARATOR);
separator = searchTools.createToolItem(SWT.SEPARATOR);

searchUpButton = new AccessibleToolItemBuilder(searchTools).withStyleBits(SWT.PUSH)
.withImage(FindReplaceOverlayImages.get(FindReplaceOverlayImages.KEY_FIND_PREV))
Expand Down Expand Up @@ -519,6 +525,10 @@ private void createReplaceTools() {
Color warningColor = JFaceColors.getErrorText(getShell().getDisplay());

replaceTools = new AccessibleToolBar(replaceContainer);

@SuppressWarnings("unused")
ToolItem separator = replaceTools.createToolItem(SWT.SEPARATOR);

GridDataFactory.fillDefaults().grab(false, true).align(GridData.CENTER, GridData.END).applyTo(replaceTools);
replaceButton = new AccessibleToolItemBuilder(replaceTools).withStyleBits(SWT.PUSH)
.withImage(FindReplaceOverlayImages.get(FindReplaceOverlayImages.KEY_REPLACE))
Expand Down Expand Up @@ -546,7 +556,9 @@ private void createReplaceTools() {
}

private void createSearchBar() {
searchBar = new Text(searchBarContainer, SWT.SINGLE);
HistoryStore searchHistory = new HistoryStore(getDialogSettings(), "searchhistory", //$NON-NLS-1$
HISTORY_SIZE);
searchBar = new HistoryTextWrapper(searchHistory, searchBarContainer, SWT.SINGLE);
GridDataFactory.fillDefaults().grab(true, false).align(GridData.FILL, GridData.END).applyTo(searchBar);
searchBar.forceFocus();
searchBar.selectAll();
Expand Down Expand Up @@ -591,7 +603,8 @@ private void updateIncrementalSearch() {
}

private void createReplaceBar() {
replaceBar = new Text(replaceBarContainer, SWT.SINGLE);
HistoryStore replaceHistory = new HistoryStore(getDialogSettings(), "replacehistory", HISTORY_SIZE); //$NON-NLS-1$
replaceBar = new HistoryTextWrapper(replaceHistory, replaceBarContainer, SWT.SINGLE);
GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.END).applyTo(replaceBar);
replaceBar.setMessage(FindReplaceMessages.FindReplaceOverlay_replaceBar_message);
replaceBar.addFocusListener(FocusListener.focusLostAdapter(e -> {
Expand Down Expand Up @@ -782,7 +795,7 @@ private void positionToPart() {
}

StatusTextEditor textEditor = (StatusTextEditor) targetPart;
Control targetWidget = textEditor.getAdapter(ITextViewer.class).getTextWidget();
Control targetWidget = Adapters.adapt(textEditor, ITextViewer.class).getTextWidget();
if (!okayToUse(targetWidget)) {
this.close();
return;
Expand Down Expand Up @@ -817,6 +830,8 @@ private String getReplaceString() {

private void performSingleReplace() {
findReplaceLogic.performReplaceAndFind(getFindString(), getReplaceString());
replaceBar.storeHistory();
searchBar.storeHistory();
}

private void performSearch(boolean forward) {
Expand All @@ -826,6 +841,7 @@ private void performSearch(boolean forward) {
findReplaceLogic.performSearch(getFindString());
activateInFindReplacerIf(SearchOptions.FORWARD, oldForwardSearchSetting);
findReplaceLogic.activate(SearchOptions.INCREMENTAL);
searchBar.storeHistory();
}

private void updateFromTargetSelection() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
* shown, informing the user about the new functionality. This class will track
* whether the popup was already shown and will only show the Overlay on the
* first time the popup was shown.
*
* @since 3.17
*/
public class FindReplaceOverlayFirstTimePopup {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,24 @@
/**
* Provides Icons for the editor overlay used for performing
* find/replace-operations.
*
* @since 3.17
*/
public class FindReplaceOverlayImages {
class FindReplaceOverlayImages {
private static final String PREFIX_ELCL = TextEditorPlugin.PLUGIN_ID + ".elcl."; //$NON-NLS-1$

public static final String KEY_FIND_NEXT = PREFIX_ELCL + "select_next"; //$NON-NLS-1$
public static final String KEY_FIND_PREV = PREFIX_ELCL + "select_prev"; //$NON-NLS-1$
public static final String KEY_FIND_REGEX = PREFIX_ELCL + "regex"; //$NON-NLS-1$
public static final String KEY_REPLACE = PREFIX_ELCL + "replace"; //$NON-NLS-1$
public static final String KEY_REPLACE_ALL = PREFIX_ELCL + "replace_all"; //$NON-NLS-1$
public static final String KEY_WHOLE_WORD = PREFIX_ELCL + "whole_word"; //$NON-NLS-1$
public static final String KEY_CASE_SENSITIVE = PREFIX_ELCL + "case_sensitive"; //$NON-NLS-1$
public static final String KEY_SEARCH_ALL = PREFIX_ELCL + "search_all"; //$NON-NLS-1$
public static final String KEY_SEARCH_IN_AREA = PREFIX_ELCL + "search_in_selection"; //$NON-NLS-1$
public static final String KEY_OPEN_REPLACE_AREA = PREFIX_ELCL + "open_replace"; //$NON-NLS-1$
public static final String KEY_CLOSE_REPLACE_AREA = PREFIX_ELCL + "close_replace"; //$NON-NLS-1$
static final String KEY_FIND_NEXT = PREFIX_ELCL + "select_next"; //$NON-NLS-1$
static final String KEY_FIND_PREV = PREFIX_ELCL + "select_prev"; //$NON-NLS-1$
static final String KEY_FIND_REGEX = PREFIX_ELCL + "regex"; //$NON-NLS-1$
static final String KEY_REPLACE = PREFIX_ELCL + "replace"; //$NON-NLS-1$
static final String KEY_REPLACE_ALL = PREFIX_ELCL + "replace_all"; //$NON-NLS-1$
static final String KEY_WHOLE_WORD = PREFIX_ELCL + "whole_word"; //$NON-NLS-1$
static final String KEY_CASE_SENSITIVE = PREFIX_ELCL + "case_sensitive"; //$NON-NLS-1$
static final String KEY_SEARCH_ALL = PREFIX_ELCL + "search_all"; //$NON-NLS-1$
static final String KEY_SEARCH_IN_AREA = PREFIX_ELCL + "search_in_selection"; //$NON-NLS-1$
static final String KEY_OPEN_REPLACE_AREA = PREFIX_ELCL + "open_replace"; //$NON-NLS-1$
static final String KEY_CLOSE_REPLACE_AREA = PREFIX_ELCL + "close_replace"; //$NON-NLS-1$
static final String KEY_OPEN_HISTORY = "open_history"; //$NON-NLS-1$

/**
* The image registry containing {@link Image images}.
Expand All @@ -56,6 +59,7 @@ public class FindReplaceOverlayImages {

private final static String ELCL = ICONS_PATH + "elcl16/"; //$NON-NLS-1$


/**
* Declare all images
*/
Expand All @@ -71,6 +75,7 @@ private static void declareImages() {
declareRegistryImage(KEY_SEARCH_IN_AREA, ELCL + "search_in_area.png"); //$NON-NLS-1$
declareRegistryImage(KEY_OPEN_REPLACE_AREA, ELCL + "open_replace.png"); //$NON-NLS-1$
declareRegistryImage(KEY_CLOSE_REPLACE_AREA, ELCL + "close_replace.png"); //$NON-NLS-1$
declareRegistryImage(KEY_OPEN_HISTORY, ELCL + "open_history.png"); //$NON-NLS-1$
}

/**
Expand Down
Loading

0 comments on commit 26c5880

Please sign in to comment.