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
Maximilian Wittmer authored and Maximilian Wittmer committed Jul 6, 2024
1 parent 44dc49e commit d1c288c
Show file tree
Hide file tree
Showing 11 changed files with 689 additions and 24 deletions.
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 @@ -73,6 +73,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 @@ -47,6 +47,7 @@ FindReplace_CloseButton_label=Close

# Messages for the find/replace overlay
FindReplaceOverlay_closeButton_toolTip=Close (Esc)
>>>>>>> d0e86d6 Find/Replace Overlay: Add a search history
FindReplaceOverlay_upSearchButton_toolTip=Search backward (Shift + Enter)
FindReplaceOverlay_downSearchButton_toolTip=Search forward (Enter)
FindReplaceOverlay_searchAllButton_toolTip=Search all (Ctrl + Enter)
Expand All @@ -56,8 +57,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 @@ -44,6 +44,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 @@ -61,6 +63,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 @@ -89,28 +92,36 @@ 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 AccessibleToolBar closeTools;
private ToolItem closeButton;

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 +130,6 @@ public FindReplaceOverlay(Shell parent, IWorkbenchPart part, IFindReplaceTarget
setShellStyle(SWT.MODELESS);
setBlockOnOpen(false);
targetPart = part;

}

@Override
Expand All @@ -143,11 +153,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 @@ -382,31 +395,22 @@ private void applyOverlayColors(Color color, boolean tryToColorReplaceBar) {
closeButton.setBackground(color);

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 @@ -418,7 +422,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 @@ -466,17 +470,20 @@ private void retrieveBackgroundColor() {
textBarForRetrievingTheRightColor.dispose();
}


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

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

createCaseSensitiveButton();
createRegexSearchButton();
createWholeWordsButton();
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 @@ -562,6 +569,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 @@ -589,7 +600,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 @@ -634,7 +647,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 @@ -813,7 +827,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 @@ -848,6 +862,8 @@ private String getReplaceString() {

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

private void performSearch(boolean forward) {
Expand All @@ -857,6 +873,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,11 @@
* 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.
<<<<<<< Upstream, based on 4674cdf92b73b519d7f1fc85ba15112cfa2d5a2f
*
* @since 3.17
=======
>>>>>>> 529474b Find/Replace overlay: move components into internal package
*/
public class FindReplaceOverlayFirstTimePopup {

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

static final String KEY_CLOSE = PREFIX_ELCL + "close"; //$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$
Expand All @@ -47,6 +48,7 @@ class FindReplaceOverlayImages {
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 @@ -57,6 +59,7 @@ class FindReplaceOverlayImages {

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


/**
* Declare all images
*/
Expand All @@ -73,6 +76,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 d1c288c

Please sign in to comment.