Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*******************************************************************************
* Copyright (c) 2026 Vogella GmbH 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
*******************************************************************************/

package org.eclipse.ui.internal.quickaccess;

import java.util.function.Supplier;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.quickaccess.QuickAccessElement;

/**
* Wraps a {@link QuickAccessProvider} behind a {@link Supplier} so the wrapped
* provider is constructed only when first queried for elements rather than at
* dialog open time. Identity ({@code getId()}) and the
* {@code requiresUiAccess()} flag are answered without forcing instantiation
* so the caller can sort, filter, and route providers by thread without
* triggering lazy construction.
*/
final class LazyQuickAccessProvider extends QuickAccessProvider {

private final String id;
private final boolean requiresUiAccess;
private final Supplier<QuickAccessProvider> supplier;
private volatile QuickAccessProvider delegate;

LazyQuickAccessProvider(String id, boolean requiresUiAccess, Supplier<QuickAccessProvider> supplier) {
this.id = id;
this.requiresUiAccess = requiresUiAccess;
this.supplier = supplier;
}

private QuickAccessProvider delegate() {
QuickAccessProvider d = delegate;
if (d == null) {
synchronized (this) {
d = delegate;
if (d == null) {
d = supplier.get();
delegate = d;
}
}
}
return d;
}

@Override
public String getId() {
return id;
}

@Override
public boolean requiresUiAccess() {
return requiresUiAccess;
}

@Override
public String getName() {
return delegate().getName();
}

@Override
public ImageDescriptor getImageDescriptor() {
return delegate().getImageDescriptor();
}

@Override
public QuickAccessElement[] getElements() {
return delegate().getElements();
}

@Override
public QuickAccessElement[] getElementsSorted(String filter, IProgressMonitor monitor) {
return delegate().getElementsSorted(filter, monitor);
}

@Override
public QuickAccessElement findElement(String id, String filterText) {
return delegate().findElement(id, filterText);
}

@Override
protected void doReset() {
QuickAccessProvider d = delegate;
if (d != null) {
d.reset();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.eclipse.core.commands.Command;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.Assert;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.jface.bindings.TriggerSequence;
Expand Down Expand Up @@ -116,20 +117,28 @@ public QuickAccessDialog(IWorkbenchWindow window, Command invokingCommand) {
final MWindow model = workbenchWindow.getModel();

BusyIndicator.showWhile(window.getShell() == null ? null : window.getShell().getDisplay(), () -> {
final CommandProvider commandProvider = new CommandProvider();
commandProvider.setContext(model.getContext().getActiveLeaf());
final IEclipseContext commandContext = model.getContext().getActiveLeaf();
final MApplication application = model.getContext().get(MApplication.class);
List<QuickAccessProvider> providers = new ArrayList<>();
previousPicksProvider = new PreviousPicksProvider(MAXIMUM_NUMBER_OF_ELEMENTS);
previousPicksProvider.setElementsInitializer(() -> restorePreviousEntries(providers));
providers.add(previousPicksProvider);
providers.add(new EditorProvider());
providers.add(new ViewProvider(model.getContext().get(MApplication.class), model));
providers.add(new PerspectiveProvider());
providers.add(commandProvider);
providers.add(new ActionProvider());
providers.add(new WizardProvider());
providers.add(new PreferenceProvider());
providers.add(new PropertiesProvider());
providers.add(new LazyQuickAccessProvider("org.eclipse.ui.editors", true, EditorProvider::new)); //$NON-NLS-1$
providers.add(new LazyQuickAccessProvider("org.eclipse.e4.ui.parts", true, //$NON-NLS-1$
() -> new ViewProvider(application, model)));
providers.add(
new LazyQuickAccessProvider("org.eclipse.ui.perspectives", true, PerspectiveProvider::new)); //$NON-NLS-1$
providers.add(new LazyQuickAccessProvider("org.eclipse.ui.commands", true, () -> { //$NON-NLS-1$
CommandProvider cp = new CommandProvider();
cp.setContext(commandContext);
return cp;
}));
providers.add(new LazyQuickAccessProvider("org.eclipse.ui.actions", true, ActionProvider::new)); //$NON-NLS-1$
providers.add(new LazyQuickAccessProvider("org.eclipse.ui.wizards", false, WizardProvider::new)); //$NON-NLS-1$
providers.add(
new LazyQuickAccessProvider("org.eclipse.ui.preferences", true, PreferenceProvider::new)); //$NON-NLS-1$
providers.add(
new LazyQuickAccessProvider("org.eclipse.ui.properties", true, PropertiesProvider::new)); //$NON-NLS-1$
providers.addAll(QuickAccessExtensionManager.getProviders(() -> {
if (display != null) {
display.asyncExec(() -> {
Expand All @@ -139,7 +148,7 @@ public QuickAccessDialog(IWorkbenchWindow window, Command invokingCommand) {
});
}
}));
providers.add(new HelpSearchProvider());
providers.add(new LazyQuickAccessProvider("search.help", false, HelpSearchProvider::new)); //$NON-NLS-1$

Collection<String> previousPickProviderIds = getPreviousPickProviderIds(getDialogSettings());
previousPicksProvider.setInvolvedProviders(
Expand Down
Loading