From 95580cc1edff02b08d00b7179a3a55c9404ba741 Mon Sep 17 00:00:00 2001 From: Aung Nanda Oo Date: Fri, 19 Sep 2025 17:48:36 -0700 Subject: [PATCH 1/2] Add global search result navigation shortcuts --- .../search2/internal/ui/SearchMessages.java | 4 + .../internal/ui/SearchMessages.properties | 4 + .../GlobalNextPrevSearchEntryHandler.java | 80 +++++++++++++++++++ bundles/org.eclipse.search/plugin.xml | 26 ++++++ 4 files changed, 114 insertions(+) create mode 100644 bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/basic/views/GlobalNextPrevSearchEntryHandler.java diff --git a/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/SearchMessages.java b/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/SearchMessages.java index 75adbe4b6a2..2324a479d62 100644 --- a/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/SearchMessages.java +++ b/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/SearchMessages.java @@ -69,6 +69,10 @@ private SearchMessages() { public static String ShowNextResultAction_tooltip; public static String ShowPreviousResultAction_label; public static String ShowPreviousResultAction_tooltip; + public static String GlobalNextSearchEntryAction_label; + public static String GlobalNextSearchEntryAction_tooltip; + public static String GlobalPreviousSearchEntryAction_label; + public static String GlobalPreviousSearchEntryAction_tooltip; public static String RemoveMatchAction_label; public static String RemoveMatchAction_tooltip; public static String DefaultSearchViewPage_show_match; diff --git a/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/SearchMessages.properties b/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/SearchMessages.properties index 0973f594f8a..ea6f180cc49 100644 --- a/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/SearchMessages.properties +++ b/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/SearchMessages.properties @@ -42,6 +42,10 @@ ShowNextResultAction_label=Next Match ShowNextResultAction_tooltip=Show Next Match ShowPreviousResultAction_label=Previous Match ShowPreviousResultAction_tooltip=Show Previous Match +GlobalNextSearchEntryAction_label=Next Search Entry +GlobalNextSearchEntryAction_tooltip=Go to Next Search Result +GlobalPreviousSearchEntryAction_label=Previous Search Entry +GlobalPreviousSearchEntryAction_tooltip=Go to Previous Search Result RemoveMatchAction_label=Remove Match RemoveMatchAction_tooltip=Remove Currently Showing Match DefaultSearchViewPage_show_match=Show Match diff --git a/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/basic/views/GlobalNextPrevSearchEntryHandler.java b/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/basic/views/GlobalNextPrevSearchEntryHandler.java new file mode 100644 index 00000000000..947eea9221b --- /dev/null +++ b/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/basic/views/GlobalNextPrevSearchEntryHandler.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2024 Eclipse Foundation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eclipse Foundation - initial API and implementation + *******************************************************************************/ +package org.eclipse.search2.internal.ui.basic.views; + +import java.util.HashMap; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.NotEnabledException; +import org.eclipse.core.commands.NotHandledException; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.core.commands.common.NotDefinedException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExecutableExtension; +import org.eclipse.swt.widgets.Event; +import org.eclipse.ui.IWorkbenchCommandConstants; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.handlers.IHandlerService; + +/** + * Global handler for navigating to next/previous search results without requiring + * focus on the Search view. This handler provides a seamless workflow for + * navigating through search results while editing. + * + * @since 3.17 + */ +public class GlobalNextPrevSearchEntryHandler extends AbstractHandler implements IExecutableExtension { + private String searchCommand = IWorkbenchCommandConstants.NAVIGATE_NEXT; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event); + ICommandService cs = (ICommandService) window.getService(ICommandService.class); + + // Show the Search view + Command showView = cs.getCommand(IWorkbenchCommandConstants.VIEWS_SHOW_VIEW); + HashMap parms = new HashMap(); + parms.put(IWorkbenchCommandConstants.VIEWS_SHOW_VIEW_PARM_ID, "org.eclipse.search.ui.views.SearchView"); + ParameterizedCommand showSearchView = ParameterizedCommand.generateCommand(showView, parms); + + IHandlerService hs = window.getService(IHandlerService.class); + try { + // Execute the sequence: show search view -> navigate -> activate editor + hs.executeCommand(showSearchView, (Event)event.getTrigger()); + hs.executeCommand(searchCommand, (Event)event.getTrigger()); + hs.executeCommand(IWorkbenchCommandConstants.WINDOW_ACTIVATE_EDITOR, (Event)event.getTrigger()); + } catch (NotDefinedException e) { + throw new ExecutionException(e.getMessage(), e); + } catch (NotEnabledException e) { + throw new ExecutionException(e.getMessage(), e); + } catch (NotHandledException e) { + throw new ExecutionException(e.getMessage(), e); + } + + return null; + } + + @Override + public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { + if ("previous".equals(data)) { + searchCommand = IWorkbenchCommandConstants.NAVIGATE_PREVIOUS; + } + } +} diff --git a/bundles/org.eclipse.search/plugin.xml b/bundles/org.eclipse.search/plugin.xml index 7a7739a4da1..3c4c0477d6a 100644 --- a/bundles/org.eclipse.search/plugin.xml +++ b/bundles/org.eclipse.search/plugin.xml @@ -104,6 +104,20 @@ name="%command.performTextSearchFile.name" description="%command.performTextSearchFile.description" /> + + @@ -162,6 +176,18 @@ commandId="org.eclipse.search.ui.performTextSearchWorkspace" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" sequence="M1+M3+T"/> + + + + From 70320e04f447db54ccce195f31268797f77746e4 Mon Sep 17 00:00:00 2001 From: ShuWald Date: Thu, 25 Sep 2025 11:04:46 -0700 Subject: [PATCH 2/2] Resolve casing error --- .../ui/basic/views/GlobalNextPrevSearchEntryHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/basic/views/GlobalNextPrevSearchEntryHandler.java b/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/basic/views/GlobalNextPrevSearchEntryHandler.java index 947eea9221b..97b70a77e70 100644 --- a/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/basic/views/GlobalNextPrevSearchEntryHandler.java +++ b/bundles/org.eclipse.search/newsearch/org/eclipse/search2/internal/ui/basic/views/GlobalNextPrevSearchEntryHandler.java @@ -46,7 +46,7 @@ public class GlobalNextPrevSearchEntryHandler extends AbstractHandler implements @Override public Object execute(ExecutionEvent event) throws ExecutionException { IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event); - ICommandService cs = (ICommandService) window.getService(ICommandService.class); + ICommandService cs = window.getService(ICommandService.class); // Show the Search view Command showView = cs.getCommand(IWorkbenchCommandConstants.VIEWS_SHOW_VIEW);