Skip to content

Commit befcf92

Browse files
committed
File Search should offer to search in all opened editors
Adds "Files opened in editors" scope to the "Text" search. Fixes #1116
1 parent 04265de commit befcf92

File tree

9 files changed

+150
-21
lines changed

9 files changed

+150
-21
lines changed

bundles/org.eclipse.search/new search/org/eclipse/search/ui/ISearchPageContainer.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ public interface ISearchPageContainer {
6161
*/
6262
public static final int SELECTED_PROJECTS_SCOPE= 3;
6363

64+
/**
65+
* Current Project scope (value <code>4</code>).
66+
*
67+
* @since 3.16
68+
*/
69+
public static final int OPENED_EDITORS_SCOPE = 4;
70+
6471
/**
6572
* Returns the selection with which this container was opened.
6673
*
@@ -85,18 +92,22 @@ public interface ISearchPageContainer {
8592
public void setPerformActionEnabled(boolean state);
8693

8794
/**
88-
* Returns search container's selected scope.
89-
* The scope is WORKSPACE_SCOPE, SELECTED_PROJECTS_SCOPE, SELECTION_SCOPE or WORKING_SET_SCOPE.
95+
* Returns search container's selected scope. The scope is WORKSPACE_SCOPE,
96+
* SELECTED_PROJECTS_SCOPE, SELECTION_SCOPE, OPENED_EDITORS_SCOPE or
97+
* WORKING_SET_SCOPE.
9098
*
9199
* @return the selected scope
92100
* @since 2.0
93101
*/
94102
public int getSelectedScope();
95103

96104
/**
97-
* Sets the selected scope of this search page container.
98-
* The scope is WORKSPACE_SCOPE, SELECTED_PROJECTS_SCOPE, SELECTION_SCOPE or WORKING_SET_SCOPE.
99-
* @param scope the newly selected scope
105+
* Sets the selected scope of this search page container. The scope is
106+
* WORKSPACE_SCOPE, SELECTED_PROJECTS_SCOPE, SELECTION_SCOPE,
107+
* OPENED_EDITORS_SCOPE or WORKING_SET_SCOPE.
108+
*
109+
* @param scope
110+
* the newly selected scope
100111
*
101112
* @since 2.0
102113
*/

bundles/org.eclipse.search/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@
293293
extensions="*:1"
294294
showScopeSection="true"
295295
canSearchEnclosingProjects="true"
296+
canSearchOpenedEditors="true"
296297
class="org.eclipse.search.internal.ui.text.TextSearchPage">
297298
</page>
298299
</extension>

bundles/org.eclipse.search/schema/searchPages.exsd

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,14 @@ The page can be activated by the user via the &quot;Customize...&quot; button on
170170
<annotation>
171171
<documentation>
172172
If this attribute is missing or set to &quot;false&quot;, the &quot;Enclosing Projects&quot; search scope is not shown in the search dialog&apos;s scope part.
173+
If the attribute &quot;showScopeSection&quot; is missing or set to &quot;false&quot;, this attribute will be ignored.
174+
</documentation>
175+
</annotation>
176+
</attribute>
177+
<attribute name="canSearchOpenedEditors" type="boolean">
178+
<annotation>
179+
<documentation>
180+
If this attribute is missing or set to &quot;false&quot;, the &quot;Opened Editors&quot; search scope is not shown in the search dialog&apos;s scope part.
173181
If the attribute &quot;showScopeSection&quot; is missing or set to &quot;false&quot;, this attribute will be ignored.
174182
</documentation>
175183
</annotation>

bundles/org.eclipse.search/search/org/eclipse/search/internal/ui/ScopePart.java

Lines changed: 99 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Collections;
2020
import java.util.HashSet;
2121
import java.util.Iterator;
22+
import java.util.LinkedHashSet;
2223
import java.util.List;
2324
import java.util.Set;
2425

@@ -50,9 +51,13 @@
5051
import org.eclipse.jface.viewers.IStructuredSelection;
5152
import org.eclipse.jface.window.Window;
5253

54+
import org.eclipse.ui.IEditorInput;
55+
import org.eclipse.ui.IEditorPart;
56+
import org.eclipse.ui.IEditorReference;
5357
import org.eclipse.ui.IWorkbenchPage;
5458
import org.eclipse.ui.IWorkingSet;
5559
import org.eclipse.ui.IWorkingSetManager;
60+
import org.eclipse.ui.PartInitException;
5661
import org.eclipse.ui.PlatformUI;
5762
import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog;
5863

@@ -77,9 +82,11 @@ public class ScopePart {
7782
private Button fUseSelection;
7883
private Button fUseProject;
7984
private Button fUseWorkingSet;
85+
private Button fUseOpenedEditors;
8086

8187
private int fScope;
8288
private boolean fCanSearchEnclosingProjects;
89+
private boolean fCanSearchOpenedEditors;
8390
private Text fWorkingSetText;
8491
private IWorkingSet[] fWorkingSets;
8592

@@ -89,36 +96,50 @@ public class ScopePart {
8996
private boolean fActiveEditorCanProvideScopeSelection;
9097

9198
/**
92-
* Returns a new scope part with workspace as initial scope.
93-
* The part is not yet created.
94-
* @param searchDialog The parent container
95-
* @param searchEnclosingProjects If true, add the 'search enclosing project' radio button
99+
* Returns a new scope part with workspace as initial scope. The part is not
100+
* yet created.
101+
*
102+
* @param searchDialog
103+
* The parent container
104+
* @param searchEnclosingProjects
105+
* If true, add the 'search enclosing project' radio button
106+
* @param searchOpenedEditors
107+
* If true, add the 'search opened editors' radio button
96108
*/
97-
public ScopePart(SearchDialog searchDialog, boolean searchEnclosingProjects) {
109+
public ScopePart(SearchDialog searchDialog, boolean searchEnclosingProjects, boolean searchOpenedEditors) {
98110
fSearchDialog= searchDialog;
99111
fCanSearchEnclosingProjects= searchEnclosingProjects;
112+
fCanSearchOpenedEditors = searchOpenedEditors;
100113

101114
fSettingsStore= SearchPlugin.getDefault().getDialogSettingsSection(DIALOG_SETTINGS_KEY);
102-
fScope= getStoredScope(fSettingsStore, searchEnclosingProjects);
115+
fScope = getStoredScope(fSettingsStore, searchEnclosingProjects, searchOpenedEditors);
103116

104117
fWorkingSets= getStoredWorkingSets();
105118
}
106119

107-
private static int getStoredScope(IDialogSettings settingsStore, boolean canSearchEnclosingProjects) {
120+
private static int getStoredScope(IDialogSettings settingsStore, boolean canSearchEnclosingProjects,
121+
boolean cansearchOpenedEditors) {
108122
int scope;
109123
try {
110124
scope= settingsStore.getInt(STORE_SCOPE);
111125
} catch (NumberFormatException ex) {
112126
scope= ISearchPageContainer.WORKSPACE_SCOPE;
113127
}
114-
if (scope != ISearchPageContainer.WORKING_SET_SCOPE
115-
&& scope != ISearchPageContainer.SELECTION_SCOPE
116-
&& scope != ISearchPageContainer.SELECTED_PROJECTS_SCOPE
117-
&& scope != ISearchPageContainer.WORKSPACE_SCOPE)
118-
scope= ISearchPageContainer.WORKSPACE_SCOPE;
128+
if (scope != ISearchPageContainer.WORKING_SET_SCOPE
129+
&& scope != ISearchPageContainer.SELECTION_SCOPE
130+
&& scope != ISearchPageContainer.SELECTED_PROJECTS_SCOPE
131+
&& scope != ISearchPageContainer.OPENED_EDITORS_SCOPE
132+
&& scope != ISearchPageContainer.WORKSPACE_SCOPE) {
133+
scope = ISearchPageContainer.WORKSPACE_SCOPE;
134+
}
135+
136+
if (!canSearchEnclosingProjects && scope == ISearchPageContainer.SELECTED_PROJECTS_SCOPE) {
137+
scope = ISearchPageContainer.WORKSPACE_SCOPE;
138+
}
119139

120-
if (!canSearchEnclosingProjects && scope == ISearchPageContainer.SELECTED_PROJECTS_SCOPE)
140+
if (!cansearchOpenedEditors && scope == ISearchPageContainer.OPENED_EDITORS_SCOPE) {
121141
scope= ISearchPageContainer.WORKSPACE_SCOPE;
142+
}
122143

123144
return scope;
124145
}
@@ -203,6 +224,43 @@ public static List<IResource> selectedResourcesFromContainer(ISearchPageContaine
203224
return resources;
204225
}
205226

227+
public static List<IResource> selectedResourcesFromEditors() {
228+
IEditorReference[] editorReferences = getEditorReferences();
229+
Set<IResource> resources = new LinkedHashSet<>();
230+
for (IEditorReference ref : editorReferences) {
231+
IFile file;
232+
IResource resource;
233+
try {
234+
IEditorInput editorInput = ref.getEditorInput();
235+
resource = editorInput.getAdapter(IResource.class);
236+
if (resource != null) {
237+
resources.add(resource);
238+
continue;
239+
}
240+
file = editorInput.getAdapter(IFile.class);
241+
if (file != null) {
242+
resources.add(file);
243+
continue;
244+
}
245+
// May trigger editor init
246+
IEditorPart editor = ref.getEditor(true);
247+
resource = editor.getAdapter(IResource.class);
248+
if (resource != null) {
249+
resources.add(resource);
250+
continue;
251+
}
252+
file = editor.getAdapter(IFile.class);
253+
if (file != null) {
254+
resources.add(file);
255+
continue;
256+
}
257+
} catch (PartInitException e) {
258+
// continue
259+
}
260+
}
261+
return new ArrayList<>(resources);
262+
}
263+
206264
private String getSelectedResurcesButtonText() {
207265
int size = selectedResourcesFromContainer(fSearchDialog).size();
208266
if (size == 1) {
@@ -242,11 +300,13 @@ public int getSelectedScope() {
242300
* @param scope the scope to be selected in this part
243301
*/
244302
public void setSelectedScope(int scope) {
245-
Assert.isLegal(scope >= 0 && scope <= 3);
303+
Assert.isLegal(
304+
scope >= ISearchPageContainer.WORKSPACE_SCOPE && scope <= ISearchPageContainer.OPENED_EDITORS_SCOPE);
246305
Assert.isNotNull(fUseWorkspace);
247306
Assert.isNotNull(fUseSelection);
248307
Assert.isNotNull(fUseWorkingSet);
249308
Assert.isNotNull(fUseProject);
309+
Assert.isNotNull(fUseOpenedEditors);
250310

251311
fSettingsStore.put(STORE_SCOPE, scope);
252312

@@ -259,13 +319,22 @@ public void setSelectedScope(int scope) {
259319
}
260320
} else if (scope == ISearchPageContainer.SELECTION_SCOPE && !fUseSelection.isEnabled()) {
261321
scope= fUseProject.isEnabled() ? ISearchPageContainer.SELECTED_PROJECTS_SCOPE : ISearchPageContainer.WORKSPACE_SCOPE;
322+
} else if (scope == ISearchPageContainer.OPENED_EDITORS_SCOPE) {
323+
if (!fCanSearchOpenedEditors) {
324+
SearchPlugin.log(new Status(IStatus.WARNING, NewSearchUI.PLUGIN_ID, IStatus.WARNING,
325+
"Opened editors scope set on search page that does not support it", null)); //$NON-NLS-1$
326+
scope = ISearchPageContainer.WORKSPACE_SCOPE;
327+
} else if (!fUseOpenedEditors.isEnabled()) {
328+
scope = ISearchPageContainer.WORKSPACE_SCOPE;
329+
}
262330
}
263331
fScope= scope;
264332

265333
fUseWorkspace.setSelection(scope == ISearchPageContainer.WORKSPACE_SCOPE);
266334
fUseSelection.setSelection(scope == ISearchPageContainer.SELECTION_SCOPE);
267335
fUseProject.setSelection(scope == ISearchPageContainer.SELECTED_PROJECTS_SCOPE);
268336
fUseWorkingSet.setSelection(scope == ISearchPageContainer.WORKING_SET_SCOPE);
337+
fUseOpenedEditors.setSelection(scope == ISearchPageContainer.OPENED_EDITORS_SCOPE);
269338

270339
updateSearchPageContainerActionPerformedEnablement();
271340

@@ -276,7 +345,7 @@ public void setActiveEditorCanProvideScopeSelection(boolean state) {
276345
fUseSelection.setEnabled(canSearchInSelection());
277346

278347
// Reinitialize the controls
279-
fScope= getStoredScope(fSettingsStore, fCanSearchEnclosingProjects);
348+
fScope = getStoredScope(fSettingsStore, fCanSearchEnclosingProjects, fCanSearchOpenedEditors);
280349
setSelectedScope(fScope);
281350
}
282351

@@ -381,6 +450,16 @@ public Composite createPart(Composite parent) {
381450
if (!fCanSearchEnclosingProjects)
382451
fUseProject.setVisible(false);
383452

453+
fUseOpenedEditors = new Button(fPart, SWT.RADIO);
454+
fUseOpenedEditors.setData(Integer.valueOf(ISearchPageContainer.OPENED_EDITORS_SCOPE));
455+
fUseOpenedEditors.setText(SearchMessages.ScopePart_openedEditorsScope_text);
456+
fUseOpenedEditors.setToolTipText(SearchMessages.ScopePart_openedEditorsScope_tooltip_text);
457+
fUseOpenedEditors.setEnabled(!selectedResourcesFromEditors().isEmpty());
458+
459+
gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
460+
gd.horizontalSpan = 4;
461+
fUseOpenedEditors.setLayoutData(gd);
462+
384463
fUseWorkingSet= new Button(fPart, SWT.RADIO);
385464
fUseWorkingSet.setData(Integer.valueOf(ISearchPageContainer.WORKING_SET_SCOPE));
386465
fUseWorkingSet.setText(SearchMessages.ScopePart_workingSetScope_text);
@@ -421,6 +500,7 @@ public void widgetSelected(SelectionEvent e) {
421500
fUseSelection.addSelectionListener(scopeChangedLister);
422501
fUseProject.addSelectionListener(scopeChangedLister);
423502
fUseWorkingSet.addSelectionListener(scopeChangedLister);
503+
fUseOpenedEditors.addSelectionListener(scopeChangedLister);
424504

425505
// Set initial scope
426506
setSelectedScope(fScope);
@@ -432,6 +512,10 @@ public void widgetSelected(SelectionEvent e) {
432512
return fPart;
433513
}
434514

515+
private static IEditorReference[] getEditorReferences() {
516+
return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences();
517+
}
518+
435519
private boolean canSearchInSelection() {
436520
ISelection selection= fSearchDialog.getSelection();
437521
return (selection instanceof IStructuredSelection) && !selection.isEmpty()

bundles/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDialog.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,8 @@ public void handleException(Throwable ex) {
771771
c.setLayout(new GridLayout());
772772

773773
int index= fDescriptors.indexOf(descriptor);
774-
fScopeParts[index]= new ScopePart(this, descriptor.canSearchInProjects());
774+
fScopeParts[index] = new ScopePart(this, descriptor.canSearchInProjects(),
775+
descriptor.canSearchInOpenedEditors());
775776
Control part= fScopeParts[index].createPart(c);
776777
applyDialogFont(part);
777778
part.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));

bundles/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ private SearchMessages() {
191191
public static String ScopePart_workingSetText_accessible_label;
192192
public static String ScopePart_workingSetScope_text;
193193
public static String ScopePart_workspaceScope_text;
194+
public static String ScopePart_openedEditorsScope_text;
195+
public static String ScopePart_openedEditorsScope_tooltip_text;
194196
public static String ScopePart_workingSetConcatenation;
195197
public static String CopyToClipboardAction_label;
196198
public static String CopyToClipboardAction_tooltip;

bundles/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ ScopePart_workingSetChooseButton_text= C&hoose...
202202
ScopePart_workingSetText_accessible_label=Working set name
203203
ScopePart_workingSetScope_text=Wor&king set:
204204
ScopePart_workspaceScope_text= &Workspace
205+
ScopePart_openedEditorsScope_text=Files opened in &editors
206+
ScopePart_openedEditorsScope_tooltip_text=Only workspace files (in projects) are supported
205207

206208
# Concatenate two working set names e.g. "Source, Lib"
207209
ScopePart_workingSetConcatenation= {0}, {1}

bundles/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPageDescriptor.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class SearchPageDescriptor implements IPluginContribution, Comparable<SearchPage
6464
private final static String EXTENSIONS_ATTRIBUTE= "extensions"; //$NON-NLS-1$
6565
private final static String SHOW_SCOPE_SECTION_ATTRIBUTE= "showScopeSection"; //$NON-NLS-1$
6666
private final static String CAN_SEARCH_ENCLOSING_PROJECTS= "canSearchEnclosingProjects"; //$NON-NLS-1$
67+
private final static String CAN_SEARCH_OPENED_EDITORS = "canSearchOpenedEditors"; //$NON-NLS-1$
6768
private final static String ENABLED_ATTRIBUTE= "enabled"; //$NON-NLS-1$
6869
private final static String SEARCH_VIEW_HELP_CONTEXT_ID_ATTRIBUTE= "searchViewHelpContextId"; //$NON-NLS-1$
6970

@@ -186,6 +187,19 @@ public boolean canSearchInProjects() {
186187
return Boolean.parseBoolean(fElement.getAttribute(CAN_SEARCH_ENCLOSING_PROJECTS));
187188
}
188189

190+
/**
191+
* Returns <code>true</code> if the page can handle searches in opened
192+
* editors. The value should be ignored if <code>showScopeSection()</code>
193+
* returns <code>false</code>.
194+
*
195+
* This attribute is optional and defaults to <code>false</code>.
196+
*
197+
* @return Returns if the page can handle searches in opened editors
198+
*/
199+
public boolean canSearchInOpenedEditors() {
200+
return Boolean.parseBoolean(fElement.getAttribute(CAN_SEARCH_OPENED_EDITORS));
201+
}
202+
189203
/**
190204
* @return Returns the page's preferred size
191205
*/

bundles/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchPage.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ public FileTextSearchScope createTextSearchScope() {
323323
return getSelectedResourcesScope();
324324
case ISearchPageContainer.SELECTED_PROJECTS_SCOPE:
325325
return getEnclosingProjectScope();
326+
case ISearchPageContainer.OPENED_EDITORS_SCOPE:
327+
return getOpenedEditorstScope();
326328
case ISearchPageContainer.WORKING_SET_SCOPE:
327329
IWorkingSet[] workingSets= getContainer().getSelectedWorkingSets();
328330
return FileTextSearchScope.newSearchScope(workingSets, getExtensions(), fSearchDerived);
@@ -352,6 +354,10 @@ private FileTextSearchScope getEnclosingProjectScope() {
352354
return FileTextSearchScope.newSearchScope(res, getExtensions(), fSearchDerived);
353355
}
354356

357+
private FileTextSearchScope getOpenedEditorstScope() {
358+
IResource[] arr = ScopePart.selectedResourcesFromEditors().toArray(new IResource[0]);
359+
return FileTextSearchScope.newSearchScope(arr, getExtensions(), fSearchDerived);
360+
}
355361

356362
private SearchPatternData findInPrevious(String pattern) {
357363
for (SearchPatternData element : fPreviousSearchPatterns) {

0 commit comments

Comments
 (0)