Skip to content

Commit

Permalink
Implement a Modern Find/Replace-Overlay
Browse files Browse the repository at this point in the history
This PR implements and tests a find/replace dialog which can be
overlayed on top of the editor. The overlay uses the FindReplaceLogic
which is also used by the existing find/replace dialog.
The overlay can be enabled and disabled in the preferences.

#1090
  • Loading branch information
Maximilian Wittmer authored and vogella committed Jun 7, 2024
1 parent 9e05ee3 commit 3a2e413
Show file tree
Hide file tree
Showing 34 changed files with 1,796 additions and 10 deletions.
2 changes: 1 addition & 1 deletion bundles/org.eclipse.ui.editors/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.ui.editors; singleton:=true
Bundle-Version: 3.17.300.qualifier
Bundle-Version: 3.18.0.qualifier
Bundle-Activator: org.eclipse.ui.internal.editors.text.EditorsPlugin
Bundle-ActivationPolicy: lazy
Bundle-Vendor: %providerName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,8 @@ private OverlayPreferenceStore createDialogOverlayStore() {
ArrayList<OverlayKey> overlayKeys= new ArrayList<>();

overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_LEADING_SPACES));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_USE_FIND_REPLACE_OVERLAY));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_FIND_REPLACE_OVERLAY_AT_BOTTOM));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_ENCLOSED_SPACES));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_TRAILING_SPACES));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_LEADING_IDEOGRAPHIC_SPACES));
Expand Down Expand Up @@ -729,6 +731,8 @@ private OverlayPreferenceStore createOverlayStore() {
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, AbstractTextEditor.PREFERENCE_COLOR_FIND_SCOPE));

overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE_COLOR));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_USE_FIND_REPLACE_OVERLAY));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_FIND_REPLACE_OVERLAY_AT_BOTTOM));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE));

overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.INT, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH));
Expand Down Expand Up @@ -859,6 +863,15 @@ public void widgetSelected(SelectionEvent e) {
IntegerDomain lineSpaceDomain= new IntegerDomain(0, 1000);
addTextField(appearanceComposite, lineSpacing, lineSpaceDomain, 15, 0);

label= TextEditorMessages.TextEditorPreferencePage_useFindReplaceOverlay;
Preference useFindReplaceOverlay= new Preference(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_USE_FIND_REPLACE_OVERLAY, label, null);
final Button useOverlay= addCheckBox(appearanceComposite, useFindReplaceOverlay, new BooleanDomain(), 0);

label= TextEditorMessages.TextEditorPreferencePage_showFindReplaceOverlayAtBottom;
Preference findReplaceOverlayAtBottom= new Preference(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_FIND_REPLACE_OVERLAY_AT_BOTTOM, label, null);
final Button overlayAtBottom= addCheckBox(appearanceComposite, findReplaceOverlayAtBottom, new BooleanDomain(), 0);
createDependency(useOverlay, useFindReplaceOverlay, new Control[] { overlayAtBottom });

label= TextEditorMessages.TextEditorPreferencePage_enableWordWrap;
Preference enableWordWrap= new Preference(AbstractTextEditor.PREFERENCE_WORD_WRAP_ENABLED, label, null);
addCheckBox(appearanceComposite, enableWordWrap, new BooleanDomain(), 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ private TextEditorMessages() {
public static String LinkedModeConfigurationBlock_DASHED_BOX;
public static String TextEditorPreferencePage_displayedTabWidth;
public static String TextEditorPreferencePage_lineSpacing;
public static String TextEditorPreferencePage_useFindReplaceOverlay;
public static String TextEditorPreferencePage_showFindReplaceOverlayAtBottom;
public static String TextEditorPreferencePage_enableWordWrap;
public static String TextEditorPreferencePage_convertTabsToSpaces;
public static String TextEditorPreferencePage_undoHistorySize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ EditorsPlugin_internal_error=Internal Error

TextEditorPreferencePage_displayedTabWidth=Displayed &tab width:
TextEditorPreferencePage_lineSpacing=Line &spacing (extra % of font height):
TextEditorPreferencePage_useFindReplaceOverlay=Use find/replace overla&y
TextEditorPreferencePage_showFindReplaceOverlayAtBottom=&Display find/replace overlay at bottom of editor
TextEditorPreferencePage_enableWordWrap=&Enable word wrap when opening an editor
TextEditorPreferencePage_convertTabsToSpaces=&Insert spaces for tabs
TextEditorPreferencePage_undoHistorySize=&Undo history size:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,30 @@ private AbstractDecoratedTextEditorPreferenceConstants() {
* </p>
*/
public final static String EDITOR_LINE_NUMBER_RULER= "lineNumberRuler"; //$NON-NLS-1$

/**
* A named preference that controls whether the find/replace overlay is used in place of the
* dialog.
*
* <p>
* The preference value is of type <code>Boolean</code>
* </p>
*
* @since 3.18
*/
public final static String EDITOR_USE_FIND_REPLACE_OVERLAY= "useFindReplaceOverlay"; //$NON-NLS-1$

/**
* A named preference that controls whether the editor overlay to access find and replace
* functionality should be aligned to the bottom of the editor page instead of to the top.
*
* <p>
* The preference value is of type <code>Boolean</code>
* </p>
*
* @since 3.18
*/
public final static String EDITOR_FIND_REPLACE_OVERLAY_AT_BOTTOM= "findReplaceOverlayAtBottom"; //$NON-NLS-1$

/**
* A named preference that controls if the caret offset is shown in the status line.
Expand Down Expand Up @@ -723,6 +747,8 @@ private AbstractDecoratedTextEditorPreferenceConstants() {
* @param store the preference store to be initialized
*/
public static void initializeDefaultValues(IPreferenceStore store) {
store.setDefault(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_USE_FIND_REPLACE_OVERLAY, true);
store.setDefault(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_FIND_REPLACE_OVERLAY_AT_BOTTOM, false);
store.setDefault(AbstractDecoratedTextEditorPreferenceConstants.USE_ANNOTATIONS_PREFERENCE_PAGE, false);
store.setDefault(AbstractDecoratedTextEditorPreferenceConstants.USE_QUICK_DIFF_PREFERENCE_PAGE, false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Require-Bundle:
org.eclipse.core.expressions;bundle-version="[3.4.100,4.0.0)",
org.eclipse.jface.text;bundle-version="[3.19.0,4.0.0)",
org.eclipse.swt;bundle-version="[3.107.0,4.0.0)",
org.eclipse.ui;bundle-version="[3.5.0,4.0.0)"
org.eclipse.ui;bundle-version="[3.5.0,4.0.0)",
org.eclipse.jface.notifications
Bundle-RequiredExecutionEnvironment: JavaSE-17
Automatic-Module-Name: org.eclipse.ui.workbench.texteditor
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.
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.
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.
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.
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.
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.
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.
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.
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 @@ -60,5 +60,18 @@ private FindReplaceMessages() {
public static String FindReplace_SelectAllButton_label;
public static String FindReplace_CloseButton_label;


public static String FindReplaceOverlay_downSearchButton_toolTip;
public static String FindReplaceOverlay_upSearchButton_toolTip;
public static String FindReplaceOverlay_searchAllButton_toolTip;
public static String FindReplaceOverlay_searchInSelectionButton_toolTip;
public static String FindReplaceOverlay_regexSearchButton_toolTip;
public static String FindReplaceOverlay_caseSensitiveButton_toolTip;
public static String FindReplaceOverlay_wholeWordsButton_toolTip;
public static String FindReplaceOverlay_replaceButton_toolTip;
public static String FindReplaceOverlay_replaceAllButton_toolTip;
public static String FindReplaceOverlay_searchBar_message;
public static String FindReplaceOverlay_replaceBar_message;
public static String FindReplaceOverlay_replaceToggle_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 @@ -43,4 +43,20 @@ FindReplace_ReplaceFindButton_label=Replace/Fin&d
FindReplace_ReplaceSelectionButton_label=&Replace
FindReplace_ReplaceAllButton_label=Replace &All
FindReplace_SelectAllButton_label=&Select All
FindReplace_CloseButton_label=Close
FindReplace_CloseButton_label=Close

# Messages for the "new" Find-Replace-Overlay
FindReplaceOverlay_upSearchButton_toolTip=Search backward (Shift + Enter)
FindReplaceOverlay_downSearchButton_toolTip=Search forward (Enter)
FindReplaceOverlay_searchAllButton_toolTip=Search all (Ctrl + Enter)
FindReplaceOverlay_searchInSelectionButton_toolTip=Only search in selected area (Ctrl + Shift + A)
FindReplaceOverlay_regexSearchButton_toolTip=Match regular expression pattern (Ctrl + Shift + P)
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_replaceToggle_toolTip=Toggle input for replace (Ctrl + R)
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 @@ -21,6 +21,10 @@
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.core.runtime.preferences.InstanceScope;

import org.eclipse.jface.dialogs.IPageChangedListener;
import org.eclipse.jface.dialogs.PageChangedEvent;
Expand Down Expand Up @@ -54,6 +58,39 @@
*/
public class FindReplaceAction extends ResourceAction implements IUpdate {

private static final String INSTANCE_SCOPE_NODE_NAME = "org.eclipse.ui.editors"; //$NON-NLS-1$

private static final String USE_FIND_REPLACE_OVERLAY = "useFindReplaceOverlay"; //$NON-NLS-1$

private static final String FIND_REPLACE_OVERLAY_AT_BOTTOM = "findReplaceOverlayAtBottom"; //$NON-NLS-1$

private boolean shouldUseOverlay() {
IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(INSTANCE_SCOPE_NODE_NAME);
boolean overlayPreference = preferences.getBoolean(USE_FIND_REPLACE_OVERLAY, true);
return overlayPreference && fWorkbenchPart instanceof StatusTextEditor;
}

private static boolean shouldPositionOverlayOnTop() {
IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(INSTANCE_SCOPE_NODE_NAME);
return !preferences.getBoolean(FIND_REPLACE_OVERLAY_AT_BOTTOM, false);
}

private IPreferenceChangeListener overlayDialogPreferenceListener = new IPreferenceChangeListener() {

@Override
public void preferenceChange(PreferenceChangeEvent event) {
if (overlay == null) {
return;
}
if (event.getKey().equals(USE_FIND_REPLACE_OVERLAY)) {
overlay.close();
} else if (event.getKey().equals(FIND_REPLACE_OVERLAY_AT_BOTTOM)) {
overlay.setPositionToTop(shouldPositionOverlayOnTop());
}
}

};

/**
* Represents the "global" find/replace dialog. It tracks the active
* part and retargets the find/replace dialog accordingly. The find/replace
Expand Down Expand Up @@ -219,7 +256,6 @@ public void checkShell(Shell shell) {

}


/**
* Listener for disabling the dialog on shell close.
* <p>
Expand All @@ -246,6 +282,8 @@ public void checkShell(Shell shell) {
*/
private Shell fShell;

private FindReplaceOverlay overlay;

/**
* Creates a new find/replace action for the given workbench part.
* <p>
Expand All @@ -264,6 +302,8 @@ public FindReplaceAction(ResourceBundle bundle, String prefix, IWorkbenchPart wo
Assert.isLegal(workbenchPart != null);
fWorkbenchPart= workbenchPart;
update();

hookDialogPreferenceListener();
}

/**
Expand Down Expand Up @@ -291,6 +331,8 @@ public FindReplaceAction(ResourceBundle bundle, String prefix, Shell shell, IFin
fTarget= target;
fShell= shell;
update();

hookDialogPreferenceListener();
}

/**
Expand All @@ -312,13 +354,29 @@ public FindReplaceAction(ResourceBundle bundle, String prefix, IWorkbenchWindow
super(bundle, prefix);
fWorkbenchWindow= workbenchWindow;
update();

hookDialogPreferenceListener();
}

private void hookDialogPreferenceListener() {
IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(INSTANCE_SCOPE_NODE_NAME);
preferences.addPreferenceChangeListener(overlayDialogPreferenceListener);
}

@Override
public void run() {
if (fTarget == null)
if (fTarget == null) {
return;
}

if (shouldUseOverlay()) {
showOverlayInEditor();
} else {
showDialog();
}
}

private void showDialog() {
final FindReplaceDialog dialog;
final boolean isEditable;

Expand Down Expand Up @@ -352,6 +410,24 @@ public void run() {
dialog.open();
}

private void showOverlayInEditor() {
if (overlay == null) {
Shell shellToUse = null;

if (fShell == null) {
shellToUse = fWorkbenchPart.getSite().getShell();
} else {
shellToUse = fShell;
}
overlay = new FindReplaceOverlay(shellToUse, fWorkbenchPart, fTarget);

FindReplaceOverlayFirstTimePopup.displayPopupIfNotAlreadyShown(shellToUse);
}

overlay.setPositionToTop(shouldPositionOverlayOnTop());
overlay.open();
}

@Override
public void update() {

Expand Down
Loading

0 comments on commit 3a2e413

Please sign in to comment.