[run] IJPL-797 Extract API from ChooseRunConfigurationPopup and mark it with ApiStatus.Internal

GitOrigin-RevId: 37ab7243d35f58f12ea32fbd594a9cc8f79917ec
This commit is contained in:
Yuriy Artamonov
2025-08-16 17:38:25 +00:00
committed by intellij-monorepo-bot
parent 1f44419d00
commit 5c56dca6d2
11 changed files with 797 additions and 769 deletions
@@ -1,7 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.execution.impl
import com.intellij.execution.actions.ChooseRunConfigurationPopup
import com.intellij.execution.actions.ChooseRunConfigurationManager
import com.intellij.execution.actions.ExecutorProvider
import com.intellij.execution.application.ApplicationConfigurationType
import com.intellij.execution.impl.RunConfigurableNodeKind.*
@@ -245,7 +245,7 @@ internal class RunConfigurableTest {
val executorProvider = ExecutorProvider { throw UnsupportedOperationException() }
val dataContext = DataManager.getInstance().getDataContext(configurable.tree)
assertThat(ChooseRunConfigurationPopup.createSettingsList(runManager, executorProvider, false, false, dataContext).joinToString("\n") {
assertThat(ChooseRunConfigurationManager.createSettingsList(runManager, executorProvider, false, false, dataContext).joinToString("\n") {
val value = it.value
if (value is String) {
"[$value]"
@@ -262,7 +262,7 @@ internal class RunConfigurableTest {
[5]
JUnit: All in titled5 (level: TEMPORARY)
""".trimIndent())
assertThat(ChooseRunConfigurationPopup.createSettingsList(runManager, executorProvider, false, true, dataContext).joinToString("\n") {
assertThat(ChooseRunConfigurationManager.createSettingsList(runManager, executorProvider, false, true, dataContext).joinToString("\n") {
val value = it.value
if (value is String) {
"[$value]"
@@ -262,32 +262,6 @@ a:com.intellij.execution.actions.BaseRunConfigurationAction
- s:suggestRunActionName(com.intellij.execution.configurations.RunConfiguration):java.lang.String
- update(com.intellij.openapi.actionSystem.AnActionEvent):V
- pa:updatePresentation(com.intellij.openapi.actionSystem.Presentation,java.lang.String,com.intellij.execution.actions.ConfigurationContext):V
f:com.intellij.execution.actions.ChooseRunConfigurationPopup
- com.intellij.execution.actions.ExecutorProvider
- <init>(com.intellij.openapi.project.Project,java.lang.String,com.intellij.execution.Executor,com.intellij.execution.Executor):V
- s:createFlatSettingsList(com.intellij.openapi.project.Project):java.util.List
- s:createSettingsList(com.intellij.execution.impl.RunManagerImpl,com.intellij.execution.actions.ExecutorProvider,Z,Z,com.intellij.openapi.actionSystem.DataContext):java.util.List
- s:createSettingsList(com.intellij.openapi.project.Project,com.intellij.execution.actions.ExecutorProvider,com.intellij.openapi.actionSystem.DataContext,Z):java.util.List
- s:createSettingsList(com.intellij.openapi.project.Project,com.intellij.execution.actions.ExecutorProvider,Z):java.util.List
- s:deleteConfiguration(com.intellij.openapi.project.Project,com.intellij.execution.RunnerAndConfigurationSettings,com.intellij.openapi.ui.popup.JBPopup):V
- getExecutor():com.intellij.execution.Executor
a:com.intellij.execution.actions.ChooseRunConfigurationPopup$ItemWrapper
- com.intellij.ui.popup.NumericMnemonicItem
- p:<init>(java.lang.Object):V
- p:<init>(java.lang.Object,Z):V
- available(com.intellij.execution.Executor):Z
- canBeDeleted():Z
- equals(java.lang.Object):Z
- getNextStep(com.intellij.openapi.project.Project,com.intellij.execution.actions.ChooseRunConfigurationPopup):com.intellij.openapi.ui.popup.PopupStep
- getType():com.intellij.execution.configurations.ConfigurationType
- getValue():java.lang.Object
- hasActions():Z
- hashCode():I
- isDynamic():Z
- a:perform(com.intellij.openapi.project.Project,com.intellij.execution.Executor,com.intellij.openapi.actionSystem.DataContext):V
- setDynamic(Z):V
- s:wrap(com.intellij.openapi.project.Project,com.intellij.execution.RunnerAndConfigurationSettings):com.intellij.execution.actions.ChooseRunConfigurationPopup$ItemWrapper
- s:wrap(com.intellij.openapi.project.Project,com.intellij.execution.RunnerAndConfigurationSettings,Z):com.intellij.execution.actions.ChooseRunConfigurationPopup$ItemWrapper
c:com.intellij.execution.actions.ChooseRunConfigurationPopupAction
- com.intellij.openapi.actionSystem.AnAction
- com.intellij.openapi.project.DumbAware
+6
View File
@@ -27,6 +27,12 @@ com.intellij.execution.InputRedirectAware$InputRedirectOptions
- a:setRedirectInputPath(java.lang.String):V
com.intellij.execution.RunConfigurationConverter
- a:convertRunConfigurationOnDemand(org.jdom.Element):Z
f:com.intellij.execution.actions.ChooseRunConfigurationManager
- <init>():V
- s:createFlatSettingsList(com.intellij.openapi.project.Project):java.util.List
- s:createSettingsList(com.intellij.execution.impl.RunManagerImpl,com.intellij.execution.actions.ExecutorProvider,Z,Z,com.intellij.openapi.actionSystem.DataContext):java.util.List
- s:createSettingsList(com.intellij.openapi.project.Project,com.intellij.execution.actions.ExecutorProvider,com.intellij.openapi.actionSystem.DataContext,Z):java.util.List
- s:deleteConfiguration(com.intellij.openapi.project.Project,com.intellij.execution.RunnerAndConfigurationSettings,com.intellij.openapi.ui.popup.JBPopup):V
com.intellij.execution.actions.ExecutorProvider
- a:getExecutor():com.intellij.execution.Executor
c:com.intellij.execution.actions.StopAction
@@ -0,0 +1,739 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.execution.actions;
import com.intellij.CommonBundle;
import com.intellij.execution.*;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.execution.executors.ExecutorGroup;
import com.intellij.execution.impl.EditConfigurationsDialog;
import com.intellij.execution.impl.RunManagerImpl;
import com.intellij.execution.impl.RunManagerImplKt;
import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl;
import com.intellij.execution.runners.ExecutionUtil;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DoNotAskOption;
import com.intellij.openapi.ui.MessageDialogBuilder;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.ListSeparator;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import java.util.*;
import static java.util.Objects.requireNonNull;
public final class ChooseRunConfigurationManager {
public static @NotNull List<ChooseRunConfigurationPopup.ItemWrapper<?>> createSettingsList(@NotNull Project project,
@NotNull ExecutorProvider executorProvider,
@NotNull DataContext dataContext,
boolean isCreateEditAction) {
RunManager runManager = RunManager.getInstanceIfCreated(project);
if (runManager == null) {
return Collections.emptyList();
}
//noinspection TestOnlyProblems
return createSettingsList((RunManagerImpl)runManager, executorProvider, isCreateEditAction,
Registry.is("run.popup.move.folders.to.top", false), dataContext);
}
public static List<ChooseRunConfigurationPopup.ItemWrapper<?>> createFlatSettingsList(@NotNull Project project) {
return RunManagerImplKt.createFlatSettingsList(project);
}
@TestOnly
public static @NotNull List<ChooseRunConfigurationPopup.ItemWrapper<?>> createSettingsList(@NotNull RunManagerImpl runManager,
@NotNull ExecutorProvider executorProvider,
boolean isCreateEditAction,
boolean isMoveFoldersToTop,
@NotNull DataContext dataContext) {
List<ChooseRunConfigurationPopup.ItemWrapper<?>> result = new ArrayList<>();
if (isCreateEditAction) {
result.add(createEditAction());
}
Project project = runManager.getProject();
final RunnerAndConfigurationSettings selectedConfiguration = runManager.getSelectedConfiguration();
if (selectedConfiguration != null) {
addActionsForSelected(selectedConfiguration, project, result);
}
Map<RunnerAndConfigurationSettings, ChooseRunConfigurationPopup.ItemWrapper<?>> wrappedExisting = new LinkedHashMap<>();
List<FolderWrapper> folderWrappers = new SmartList<>();
for (Map<String, List<RunnerAndConfigurationSettings>> folderToConfigurations : runManager.getConfigurationsGroupedByTypeAndFolder(
false).values()) {
if (isMoveFoldersToTop) {
for (Map.Entry<String, List<RunnerAndConfigurationSettings>> entry : folderToConfigurations.entrySet()) {
final String folderName = entry.getKey();
List<RunnerAndConfigurationSettings> configurations = entry.getValue();
if (folderName != null) {
folderWrappers.add(createFolderItem(project, executorProvider, selectedConfiguration, folderName, configurations));
}
else {
for (RunnerAndConfigurationSettings configuration : configurations) {
wrapAndAdd(project, configuration, selectedConfiguration, wrappedExisting);
}
}
}
}
else {
// add only folders
for (Map.Entry<String, List<RunnerAndConfigurationSettings>> entry : folderToConfigurations.entrySet()) {
final String folderName = entry.getKey();
if (folderName != null) {
result.add(createFolderItem(project, executorProvider, selectedConfiguration, folderName, entry.getValue()));
}
}
// add configurations
List<RunnerAndConfigurationSettings> configurations = folderToConfigurations.get(null);
if (!ContainerUtil.isEmpty(configurations)) {
for (RunnerAndConfigurationSettings configuration : configurations) {
result.add(wrapAndAdd(project, configuration, selectedConfiguration, wrappedExisting));
}
}
}
}
if (isMoveFoldersToTop) {
result.addAll(folderWrappers);
}
if (!DumbService.isDumb(project)) {
populateWithDynamicRunners(result, wrappedExisting, project, RunManagerEx.getInstanceEx(project), selectedConfiguration, dataContext);
}
if (isMoveFoldersToTop) {
result.addAll(wrappedExisting.values());
}
return result;
}
public static void deleteConfiguration(@NotNull Project project,
@NotNull RunnerAndConfigurationSettings configurationSettings,
@Nullable JBPopup popupToCancel) {
RunManagerConfig runManagerConfig = RunManagerImpl.getInstanceImpl(project).getConfig();
boolean confirmed;
if (runManagerConfig.isDeletionFromPopupRequiresConfirmation()) {
if (popupToCancel != null) {
popupToCancel.cancel();
}
confirmed = MessageDialogBuilder.yesNo(CommonBundle.message("title.confirmation"),
ExecutionBundle.message("are.you.sure.you.want.to.delete.0", configurationSettings.getName()))
.doNotAsk(new DoNotAskOption.Adapter() {
@Override
public void rememberChoice(boolean isSelected, int exitCode) {
runManagerConfig.setDeletionFromPopupRequiresConfirmation(!isSelected);
}
@Override
public @NotNull String getDoNotShowMessage() {
return ExecutionBundle.message("don.t.ask.again");
}
@Override
public boolean shouldSaveOptionsOnCancel() {
return true;
}
})
.ask(project);
}
else {
confirmed = true;
}
if (confirmed) {
RunManager.getInstance(project).removeConfiguration(configurationSettings);
}
}
private static @NotNull ChooseRunConfigurationPopup.ItemWrapper<?> wrapAndAdd(@NotNull Project project,
@NotNull RunnerAndConfigurationSettings configuration,
@Nullable RunnerAndConfigurationSettings selectedConfiguration,
@NotNull Map<RunnerAndConfigurationSettings, ChooseRunConfigurationPopup.ItemWrapper<?>> wrappedExisting) {
ChooseRunConfigurationPopup.ItemWrapper<?> wrapped = ChooseRunConfigurationPopup.ItemWrapper.wrap(project, configuration);
if (configuration == selectedConfiguration) {
wrapped.setMnemonic(1);
}
wrappedExisting.put(configuration, wrapped);
return wrapped;
}
private static @NotNull FolderWrapper createFolderItem(@NotNull Project project,
@NotNull ExecutorProvider executorProvider,
@Nullable RunnerAndConfigurationSettings selectedConfiguration,
@NotNull String folderName,
@NotNull List<? extends RunnerAndConfigurationSettings> configurations) {
boolean isSelected = selectedConfiguration != null && configurations.contains(selectedConfiguration);
String value = folderName;
if (isSelected) {
value += " (mnemonic is to \"" + selectedConfiguration.getName() + "\")";
}
FolderWrapper
result = new FolderWrapper(project, executorProvider, value, configurations);
if (isSelected) {
result.setMnemonic(1);
}
return result;
}
private static void addActionsForSelected(@NotNull RunnerAndConfigurationSettings selectedConfiguration,
@NotNull Project project,
@NotNull List<ChooseRunConfigurationPopup.ItemWrapper<?>> result) {
boolean isFirst = true;
final ExecutionTarget activeTarget = ExecutionTargetManager.getActiveTarget(project);
for (ExecutionTarget eachTarget : ExecutionTargetManager.getTargetsToChooseFor(project, selectedConfiguration.getConfiguration())) {
ChooseRunConfigurationPopup.ItemWrapper<ExecutionTarget>
itemWrapper = new ChooseRunConfigurationPopup.ItemWrapper<>(eachTarget, isFirst) {
@Override
public Icon getIcon() {
return requireNonNull(getValue()).getIcon();
}
@Override
public String getText() {
return requireNonNull(getValue()).getDisplayName();
}
@Override
public void perform(final @NotNull Project project, final @NotNull Executor executor, @NotNull DataContext context) {
ExecutionTargetManager.setActiveTarget(project, requireNonNull(getValue()));
ExecutionUtil.doRunConfiguration(selectedConfiguration, executor, null, null, context);
}
@Override
public boolean available(Executor executor) {
return true;
}
};
itemWrapper.setChecked(eachTarget.equals(activeTarget));
result.add(itemWrapper);
isFirst = false;
}
}
private static @NotNull ChooseRunConfigurationPopup.ItemWrapper<Void> createEditAction() {
ChooseRunConfigurationPopup.ItemWrapper<Void> result = new ChooseRunConfigurationPopup.ItemWrapper<>(null) {
@Override
public Icon getIcon() {
return AllIcons.Actions.EditSource;
}
@Override
public String getText() {
return UIUtil.removeMnemonic(ActionsBundle.message("action.editRunConfigurations.text"));
}
@Override
public void perform(final @NotNull Project project, final @NotNull Executor executor, @NotNull DataContext context) {
if (new EditConfigurationsDialog(project) {
@Override
protected void init() {
setOKButtonText(executor.getActionName());
myExecutor = executor;
super.init();
}
}.showAndGet()) {
ApplicationManager.getApplication().invokeLater(() -> {
RunnerAndConfigurationSettings configuration = RunManager.getInstance(project).getSelectedConfiguration();
if (configuration != null) {
ExecutionUtil.doRunConfiguration(configuration, executor, null, null, context);
}
}, project.getDisposed());
}
}
@Override
public boolean available(Executor executor) {
return true;
}
};
result.setMnemonic(0);
return result;
}
private static void populateWithDynamicRunners(List<ChooseRunConfigurationPopup.ItemWrapper<?>> result,
Map<RunnerAndConfigurationSettings, ChooseRunConfigurationPopup.ItemWrapper<?>> existing,
Project project,
RunManager manager,
RunnerAndConfigurationSettings selectedConfiguration,
@NotNull DataContext dataContext) {
final ConfigurationContext context = ConfigurationContext.getFromContext(dataContext, ActionPlaces.UNKNOWN);
List<ConfigurationFromContext> producers = PreferredProducerFind.getConfigurationsFromContext(context.getLocation(),
context, false, true);
if (producers == null) return;
producers = ContainerUtil.sorted(producers, ConfigurationFromContext.NAME_COMPARATOR);
final RunnerAndConfigurationSettings[] preferred = {null};
int i = 2; // selectedConfiguration == null ? 1 : 2;
for (final ConfigurationFromContext fromContext : producers) {
final RunnerAndConfigurationSettings configuration = fromContext.getConfigurationSettings();
if (existing.containsKey(configuration)) {
ChooseRunConfigurationPopup.ItemWrapper<?> wrapper = existing.get(configuration);
if (wrapper.getMnemonic() != 1) {
wrapper.setMnemonic(i);
i++;
}
}
else {
if (selectedConfiguration != null && configuration.equals(selectedConfiguration)) continue;
if (preferred[0] == null) {
preferred[0] = configuration;
}
ChooseRunConfigurationPopup.ItemWrapper<?> wrapper = new ChooseRunConfigurationPopup.ItemWrapper<Object>(configuration) {
@Override
public Icon getIcon() {
return RunManagerEx.getInstanceEx(project).getConfigurationIcon(configuration);
}
@Override
public String getText() {
return Executor.shortenNameIfNeeded(configuration.getName()) + configuration.getConfiguration().getPresentableType();
}
@Override
public boolean available(Executor executor) {
return ProgramRunner.getRunner(executor.getId(), configuration.getConfiguration()) != null;
}
@Override
public void perform(@NotNull Project project, @NotNull Executor executor, @NotNull DataContext context) {
manager.setTemporaryConfiguration(configuration);
RunManager.getInstance(project).setSelectedConfiguration(configuration);
ExecutionUtil.doRunConfiguration(configuration, executor, null, null, context);
}
@Override
public PopupStep<?> getNextStep(@NotNull Project project, final @NotNull ChooseRunConfigurationPopup action) {
return new ConfigurationActionsStep(project, action, configuration, isDynamic());
}
@Override
public boolean hasActions() {
return true;
}
};
wrapper.setDynamic(true);
wrapper.setMnemonic(i);
result.add(wrapper);
i++;
}
}
}
static final class FolderWrapper extends ChooseRunConfigurationPopup.ItemWrapper<String> {
private final Project myProject;
private final ExecutorProvider myExecutorProvider;
final List<? extends RunnerAndConfigurationSettings> myConfigurations;
private FolderWrapper(Project project,
ExecutorProvider executorProvider,
@Nullable String value,
List<? extends RunnerAndConfigurationSettings> configurations) {
super(value);
myProject = project;
myExecutorProvider = executorProvider;
myConfigurations = configurations;
}
@Override
public void perform(@NotNull Project project, @NotNull Executor executor, @NotNull DataContext context) {
RunManager runManager = RunManager.getInstance(project);
RunnerAndConfigurationSettings selectedConfiguration = runManager.getSelectedConfiguration();
if (myConfigurations.contains(selectedConfiguration)) {
runManager.setSelectedConfiguration(selectedConfiguration);
ExecutionUtil.runConfiguration(requireNonNull(selectedConfiguration), myExecutorProvider.getExecutor());
}
}
@Override
public @NotNull Icon getIcon() {
return AllIcons.Nodes.Folder;
}
@Override
public String getText() {
return getValue();
}
@Override
public @Nullable ConfigurationType getType() {
return Registry.is("run.popup.move.folders.to.top") || myConfigurations.isEmpty()
? null
: myConfigurations.get(0).getType();
}
@Override
public boolean hasActions() {
return true;
}
@Override
public PopupStep<?> getNextStep(Project project, ChooseRunConfigurationPopup action) {
List<ConfigurationActionsStep> steps = new ArrayList<>();
for (RunnerAndConfigurationSettings settings : myConfigurations) {
steps.add(new ConfigurationActionsStep(project, action, settings, false));
}
return new FolderStep(myProject, myExecutorProvider, null, steps, action);
}
}
static final class FolderStep extends BaseListPopupStep<ConfigurationActionsStep> {
private final Project myProject;
private final ChooseRunConfigurationPopup myPopup;
private final ExecutorProvider myExecutorProvider;
private FolderStep(Project project,
ExecutorProvider executorProvider,
@NlsSafe String folderName,
List<ConfigurationActionsStep> children,
ChooseRunConfigurationPopup popup) {
super(folderName, children, new ArrayList<>());
myProject = project;
myExecutorProvider = executorProvider;
myPopup = popup;
}
@Override
public PopupStep<?> onChosen(ConfigurationActionsStep selectedValue, boolean finalChoice) {
if (finalChoice) {
if (myPopup.myEditConfiguration) {
final RunnerAndConfigurationSettings settings = selectedValue.getSettings();
return doFinalStep(() -> myPopup.editConfiguration(myProject, settings));
}
return doFinalStep(() -> {
RunnerAndConfigurationSettings settings = selectedValue.getSettings();
RunManager.getInstance(myProject).setSelectedConfiguration(settings);
ExecutionUtil.runConfiguration(settings, myExecutorProvider.getExecutor());
});
}
else {
return selectedValue;
}
}
@Override
public Icon getIconFor(ConfigurationActionsStep aValue) {
return aValue.getIcon();
}
@Override
public @NotNull String getTextFor(ConfigurationActionsStep value) {
return value.getName();
}
@Override
public boolean hasSubstep(ConfigurationActionsStep selectedValue) {
return !selectedValue.getValues().isEmpty();
}
}
static final class ConfigurationListPopupStep extends BaseListPopupStep<ChooseRunConfigurationPopup.ItemWrapper<?>> {
private final Project myProject;
private final ChooseRunConfigurationPopup myAction;
private int myDefaultConfiguration = -1;
ConfigurationListPopupStep(final @NotNull ChooseRunConfigurationPopup action,
final @NotNull Project project,
final @NotNull @Nls String title,
@NotNull List<ChooseRunConfigurationPopup.ItemWrapper<?>> list) {
super(title, list);
myProject = project;
myAction = action;
if (-1 == getDefaultOptionIndex()) {
myDefaultConfiguration = getDynamicIndex();
}
boolean hasMnemonics = ContainerUtil.exists(getValues(), wrapper -> wrapper.getMnemonic() != -1);
if (hasMnemonics) getValues().forEach(wrapper -> wrapper.setMnemonicsEnabled(true));
}
private int getDynamicIndex() {
int i = 0;
for (ChooseRunConfigurationPopup.ItemWrapper<?> wrapper : getValues()) {
if (wrapper.isDynamic()) {
return i;
}
i++;
}
return -1;
}
@Override
public boolean isAutoSelectionEnabled() {
return false;
}
@Override
public ListSeparator getSeparatorAbove(ChooseRunConfigurationPopup.ItemWrapper value) {
if (value.addSeparatorAbove()) return new ListSeparator();
List<ChooseRunConfigurationPopup.ItemWrapper<?>> configurations = getValues();
final int index = configurations.indexOf(value);
if (index > 0 && index <= configurations.size() - 1) {
ChooseRunConfigurationPopup.ItemWrapper<?> aboveConfiguration = configurations.get(index - 1);
if (aboveConfiguration != null && aboveConfiguration.isDynamic() != value.isDynamic()) {
return new ListSeparator();
}
final ConfigurationType currentType = value.getType();
final ConfigurationType aboveType = aboveConfiguration == null ? null : aboveConfiguration.getType();
if (aboveType != currentType && currentType != null) {
return new ListSeparator(); // new ListSeparator(currentType.getDisplayName());
}
}
return null;
}
@Override
public boolean isSpeedSearchEnabled() {
return true;
}
@Override
public int getDefaultOptionIndex() {
final RunnerAndConfigurationSettings currentConfiguration = RunManager.getInstance(myProject).getSelectedConfiguration();
if (currentConfiguration == null && myDefaultConfiguration != -1) {
return myDefaultConfiguration;
}
return currentConfiguration instanceof RunnerAndConfigurationSettingsImpl ? getValues()
.indexOf(ChooseRunConfigurationPopup.ItemWrapper.wrap(myProject, currentConfiguration)) : -1;
}
@Override
public PopupStep<?> onChosen(ChooseRunConfigurationPopup.ItemWrapper wrapper, boolean finalChoice) {
if (myAction.myEditConfiguration) {
final Object o = wrapper.getValue();
if (o instanceof RunnerAndConfigurationSettingsImpl) {
return doFinalStep(() -> myAction.editConfiguration(myProject, (RunnerAndConfigurationSettings)o));
}
}
if (finalChoice && wrapper.available(myAction.getExecutor())) {
return doFinalStep(() -> {
if (myAction.getExecutor() == myAction.myAlternativeExecutor) {
PropertiesComponent.getInstance().setValue(myAction.myAddKey, Boolean.toString(true));
}
wrapper.perform(myProject, myAction.getExecutor(), DataManager.getInstance().getDataContext());
});
}
else {
return wrapper.getNextStep(myProject, myAction);
}
}
@Override
public boolean isFinal(ChooseRunConfigurationPopup.ItemWrapper wrapper) {
return myAction.myEditConfiguration
|| wrapper.available(myAction.getExecutor())
|| wrapper.getNextStep(myProject, myAction) == FINAL_CHOICE;
}
@Override
public boolean hasSubstep(ChooseRunConfigurationPopup.ItemWrapper selectedValue) {
return selectedValue.hasActions();
}
@Override
public @NotNull String getTextFor(ChooseRunConfigurationPopup.ItemWrapper value) {
//noinspection DialogTitleCapitalization
return value.getText();
}
@Override
public Icon getIconFor(ChooseRunConfigurationPopup.ItemWrapper value) {
return value.getIcon();
}
}
static final class ConfigurationActionsStep extends BaseListPopupStep<ActionWrapper> {
private final @NotNull RunnerAndConfigurationSettings mySettings;
private final @NotNull Project myProject;
ConfigurationActionsStep(final @NotNull Project project,
ChooseRunConfigurationPopup action,
final @NotNull RunnerAndConfigurationSettings settings, final boolean dynamic) {
super(null, buildActions(project, action, settings, dynamic));
myProject = project;
mySettings = settings;
}
public @NotNull RunnerAndConfigurationSettings getSettings() {
return mySettings;
}
public @NlsContexts.ListItem String getName() {
return Executor.shortenNameIfNeeded(mySettings.getName());
}
public Icon getIcon() {
return RunManagerEx.getInstanceEx(myProject).getConfigurationIcon(mySettings);
}
@Override
public ListSeparator getSeparatorAbove(ActionWrapper value) {
return value.addSeparatorAbove() ? new ListSeparator() : null;
}
private static ActionWrapper[] buildActions(final @NotNull Project project,
final ChooseRunConfigurationPopup action,
final @NotNull RunnerAndConfigurationSettings settings,
final boolean dynamic) {
final List<ActionWrapper> result = new ArrayList<>();
final ExecutionTarget active = ExecutionTargetManager.getActiveTarget(project);
for (final ExecutionTarget eachTarget : ExecutionTargetManager.getTargetsToChooseFor(project, settings.getConfiguration())) {
result.add(new ActionWrapper(eachTarget.getDisplayName(), eachTarget.getIcon()) {
{
setChecked(eachTarget.equals(active));
}
@Override
public void perform() {
final RunManager manager = RunManager.getInstance(project);
if (dynamic) {
manager.setTemporaryConfiguration(settings);
}
manager.setSelectedConfiguration(settings);
ExecutionTargetManager.setActiveTarget(project, eachTarget);
ExecutionUtil.runConfiguration(settings, action.getExecutor());
}
});
}
boolean isFirst = true;
final List<Executor> allExecutors = new ArrayList<>();
for (Executor executor : Executor.EXECUTOR_EXTENSION_NAME.getExtensionList()) {
if (executor instanceof ExecutorGroup) {
allExecutors.addAll(((ExecutorGroup<?>)executor).childExecutors());
}
else {
allExecutors.add(executor);
}
}
for (final Executor executor : allExecutors) {
if (ExecutorRegistryImpl.RunnerHelper.canRun(project, executor, settings.getConfiguration())) {
result.add(new ActionWrapper(executor.getActionName(), executor.getIcon(), isFirst) {
@Override
public void perform() {
final RunManager manager = RunManager.getInstance(project);
if (dynamic) {
manager.setTemporaryConfiguration(settings);
}
if (!manager.isRiderRunWidgetActive()) manager.setSelectedConfiguration(settings);
ExecutorRegistryImpl.RunnerHelper.run(project, settings.getConfiguration(), settings, DataContext.EMPTY_CONTEXT, executor);
}
});
isFirst = false;
}
}
result.add(new ActionWrapper(ExecutionBundle.message("choose.run.popup.edit"), AllIcons.Actions.EditSource, true) {
@Override
public void perform() {
if (dynamic) {
RunManager.getInstance(project).setTemporaryConfiguration(settings);
}
action.editConfiguration(project, settings);
}
});
if (settings.isTemporary() || dynamic) {
result.add(new ActionWrapper(ExecutionBundle.message("choose.run.popup.save"), AllIcons.Actions.MenuSaveall) {
@Override
public void perform() {
final RunManager manager = RunManager.getInstance(project);
if (dynamic) {
manager.setTemporaryConfiguration(settings);
}
manager.makeStable(settings);
}
});
}
result.add(new ActionWrapper(ExecutionBundle.message("choose.run.popup.delete"), AllIcons.Actions.Cancel) {
@Override
public void perform() {
deleteConfiguration(project, settings, action.myPopup);
}
});
return result.toArray(new ActionWrapper[0]);
}
@Override
public PopupStep<?> onChosen(ActionWrapper selectedValue, boolean finalChoice) {
return doFinalStep(() -> selectedValue.perform());
}
@Override
public Icon getIconFor(ActionWrapper aValue) {
return aValue.getIcon();
}
@Override
public @NotNull String getTextFor(ActionWrapper value) {
return value.getText();
}
}
abstract static class ActionWrapper extends ChooseRunConfigurationPopup.Wrapper {
private final @Nls String myName;
private final Icon myIcon;
ActionWrapper(@Nls String name, Icon icon) {
this(name, icon, false);
}
ActionWrapper(@Nls String name, Icon icon, boolean addSeparatorAbove) {
super(addSeparatorAbove);
myName = name;
myIcon = icon;
}
public abstract void perform();
@Override
public String getText() {
return myName;
}
@Override
public Icon getIcon() {
return myIcon;
}
}
}
@@ -1,67 +1,58 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.execution.actions;
import com.intellij.CommonBundle;
import com.intellij.execution.*;
import com.intellij.execution.actions.ChooseRunConfigurationManager.ConfigurationListPopupStep;
import com.intellij.execution.actions.ChooseRunConfigurationManager.FolderWrapper;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.execution.executors.ExecutorGroup;
import com.intellij.execution.impl.*;
import com.intellij.execution.runners.ExecutionUtil;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.icons.AllIcons;
import com.intellij.execution.impl.RunDialog;
import com.intellij.execution.impl.RunManagerImpl;
import com.intellij.ide.DataManager;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DoNotAskOption;
import com.intellij.openapi.ui.MessageDialogBuilder;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.ListPopupStep;
import com.intellij.openapi.ui.popup.ListSeparator;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.util.NlsActions;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.popup.NumericMnemonicItem;
import com.intellij.ui.popup.WizardPopup;
import com.intellij.ui.popup.list.ListPopupImpl;
import com.intellij.ui.popup.list.PopupListElementRenderer;
import com.intellij.ui.speedSearch.SpeedSearch;
import com.intellij.util.SmartList;
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.*;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;
import java.util.Objects;
import static java.util.Objects.requireNonNull;
/**
* Use {@link ChooseRunConfigurationManager} instead.
*/
@ApiStatus.Internal
public final class ChooseRunConfigurationPopup implements ExecutorProvider {
private final Project myProject;
private final @NotNull String myAddKey;
final @NotNull String myAddKey;
private final @NotNull Executor myDefaultExecutor;
private final @Nullable Executor myAlternativeExecutor;
final @Nullable Executor myAlternativeExecutor;
private Executor myCurrentExecutor;
private boolean myEditConfiguration;
private RunListPopup myPopup;
boolean myEditConfiguration;
RunListPopup myPopup;
public ChooseRunConfigurationPopup(@NotNull Project project,
@NotNull String addKey,
@@ -75,7 +66,7 @@ public final class ChooseRunConfigurationPopup implements ExecutorProvider {
@RequiresBackgroundThread
@NotNull ListPopupStep<?> buildStep(@NotNull DataContext dataContext) {
List<ChooseRunConfigurationPopup.ItemWrapper<?>> settingsList = createSettingsList(myProject, this, dataContext, true);
List<ChooseRunConfigurationPopup.ItemWrapper<?>> settingsList = ChooseRunConfigurationManager.createSettingsList(myProject, this, dataContext, true);
return new ConfigurationListPopupStep(this, myProject, myDefaultExecutor.getActionName(), settingsList);
}
@@ -195,7 +186,7 @@ public final class ChooseRunConfigurationPopup implements ExecutorProvider {
}
}
private void editConfiguration(@NotNull Project project, @NotNull RunnerAndConfigurationSettings configuration) {
void editConfiguration(@NotNull Project project, @NotNull RunnerAndConfigurationSettings configuration) {
final Executor executor = getExecutor();
PropertiesComponent.getInstance().setValue("run.configuration.edit.ad", Boolean.toString(true));
if (RunDialog.editConfiguration(project, configuration, ExecutionBundle.message("dialog.title.edit.configuration.settings"), executor)) {
@@ -204,42 +195,14 @@ public final class ChooseRunConfigurationPopup implements ExecutorProvider {
}
}
/**
* @deprecated Use {@link ChooseRunConfigurationManager#deleteConfiguration(Project, RunnerAndConfigurationSettings, JBPopup)}
*/
@Deprecated
public static void deleteConfiguration(@NotNull Project project,
@NotNull RunnerAndConfigurationSettings configurationSettings,
@Nullable JBPopup popupToCancel) {
RunManagerConfig runManagerConfig = RunManagerImpl.getInstanceImpl(project).getConfig();
boolean confirmed;
if (runManagerConfig.isDeletionFromPopupRequiresConfirmation()) {
if (popupToCancel != null) {
popupToCancel.cancel();
}
confirmed = MessageDialogBuilder.yesNo(CommonBundle.message("title.confirmation"),
ExecutionBundle.message("are.you.sure.you.want.to.delete.0", configurationSettings.getName()))
.doNotAsk(new DoNotAskOption.Adapter() {
@Override
public void rememberChoice(boolean isSelected, int exitCode) {
runManagerConfig.setDeletionFromPopupRequiresConfirmation(!isSelected);
}
@Override
public @NotNull String getDoNotShowMessage() {
return ExecutionBundle.message("don.t.ask.again");
}
@Override
public boolean shouldSaveOptionsOnCancel() {
return true;
}
})
.ask(project);
}
else {
confirmed = true;
}
if (confirmed) {
RunManager.getInstance(project).removeConfiguration(configurationSettings);
}
ChooseRunConfigurationManager.deleteConfiguration(project, configurationSettings, popupToCancel);
}
@Override
@@ -251,6 +214,17 @@ public final class ChooseRunConfigurationPopup implements ExecutorProvider {
return new MyAbstractAction(listPopup, number, executor);
}
/**
* @deprecated Use {@link ChooseRunConfigurationManager#createSettingsList(RunManagerImpl, ExecutorProvider, boolean, boolean, DataContext)}
*/
@Deprecated
public static @NotNull List<ChooseRunConfigurationPopup.ItemWrapper<?>> createSettingsList(@NotNull Project project,
@NotNull ExecutorProvider executorProvider,
@NotNull DataContext dataContext,
boolean isCreateEditAction) {
return ChooseRunConfigurationManager.createSettingsList(project, executorProvider, dataContext, isCreateEditAction);
}
@ApiStatus.Internal
public abstract static class Wrapper implements NumericMnemonicItem {
private int myMnemonic = -1;
@@ -288,6 +262,7 @@ public final class ChooseRunConfigurationPopup implements ExecutorProvider {
myMnemonic = mnemonic;
}
@SuppressWarnings("SameParameterValue")
protected void setMnemonicsEnabled(boolean mnemonicsEnabled) {
myMnemonicsEnabled = mnemonicsEnabled;
}
@@ -415,7 +390,7 @@ public final class ChooseRunConfigurationPopup implements ExecutorProvider {
@Override
public PopupStep<?> getNextStep(final @NotNull Project project, final @NotNull ChooseRunConfigurationPopup action) {
return new ConfigurationActionsStep(project, action, requireNonNull(getValue()), isDynamic());
return new ChooseRunConfigurationManager.ConfigurationActionsStep(project, action, requireNonNull(getValue()), isDynamic());
}
};
}
@@ -426,289 +401,6 @@ public final class ChooseRunConfigurationPopup implements ExecutorProvider {
}
}
private static final class ConfigurationListPopupStep extends BaseListPopupStep<ItemWrapper<?>> {
private final Project myProject;
private final ChooseRunConfigurationPopup myAction;
private int myDefaultConfiguration = -1;
private ConfigurationListPopupStep(final @NotNull ChooseRunConfigurationPopup action,
final @NotNull Project project,
final @NotNull @Nls String title,
@NotNull List<ItemWrapper<?>> list) {
super(title, list);
myProject = project;
myAction = action;
if (-1 == getDefaultOptionIndex()) {
myDefaultConfiguration = getDynamicIndex();
}
boolean hasMnemonics = ContainerUtil.exists(getValues(), wrapper -> wrapper.getMnemonic() != -1);
if (hasMnemonics) getValues().forEach(wrapper -> wrapper.setMnemonicsEnabled(true));
}
private int getDynamicIndex() {
int i = 0;
for (ItemWrapper<?> wrapper : getValues()) {
if (wrapper.isDynamic()) {
return i;
}
i++;
}
return -1;
}
@Override
public boolean isAutoSelectionEnabled() {
return false;
}
@Override
public ListSeparator getSeparatorAbove(ItemWrapper value) {
if (value.addSeparatorAbove()) return new ListSeparator();
List<ItemWrapper<?>> configurations = getValues();
final int index = configurations.indexOf(value);
if (index > 0 && index <= configurations.size() - 1) {
ItemWrapper<?> aboveConfiguration = configurations.get(index - 1);
if (aboveConfiguration != null && aboveConfiguration.isDynamic() != value.isDynamic()) {
return new ListSeparator();
}
final ConfigurationType currentType = value.getType();
final ConfigurationType aboveType = aboveConfiguration == null ? null : aboveConfiguration.getType();
if (aboveType != currentType && currentType != null) {
return new ListSeparator(); // new ListSeparator(currentType.getDisplayName());
}
}
return null;
}
@Override
public boolean isSpeedSearchEnabled() {
return true;
}
@Override
public int getDefaultOptionIndex() {
final RunnerAndConfigurationSettings currentConfiguration = RunManager.getInstance(myProject).getSelectedConfiguration();
if (currentConfiguration == null && myDefaultConfiguration != -1) {
return myDefaultConfiguration;
}
return currentConfiguration instanceof RunnerAndConfigurationSettingsImpl ? getValues()
.indexOf(ItemWrapper.wrap(myProject, currentConfiguration)) : -1;
}
@Override
public PopupStep<?> onChosen(final ItemWrapper wrapper, boolean finalChoice) {
if (myAction.myEditConfiguration) {
final Object o = wrapper.getValue();
if (o instanceof RunnerAndConfigurationSettingsImpl) {
return doFinalStep(() -> myAction.editConfiguration(myProject, (RunnerAndConfigurationSettings)o));
}
}
if (finalChoice && wrapper.available(myAction.getExecutor())) {
return doFinalStep(() -> {
if (myAction.getExecutor() == myAction.myAlternativeExecutor) {
PropertiesComponent.getInstance().setValue(myAction.myAddKey, Boolean.toString(true));
}
wrapper.perform(myProject, myAction.getExecutor(), DataManager.getInstance().getDataContext());
});
}
else {
return wrapper.getNextStep(myProject, myAction);
}
}
@Override
public boolean isFinal(ItemWrapper wrapper) {
return myAction.myEditConfiguration
|| wrapper.available(myAction.getExecutor())
|| wrapper.getNextStep(myProject, myAction) == FINAL_CHOICE;
}
@Override
public boolean hasSubstep(ItemWrapper selectedValue) {
return selectedValue.hasActions();
}
@Override
public @NotNull String getTextFor(ItemWrapper value) {
//noinspection DialogTitleCapitalization
return value.getText();
}
@Override
public Icon getIconFor(ItemWrapper value) {
return value.getIcon();
}
}
private static final class ConfigurationActionsStep extends BaseListPopupStep<ActionWrapper> {
private final @NotNull RunnerAndConfigurationSettings mySettings;
private final @NotNull Project myProject;
private ConfigurationActionsStep(final @NotNull Project project,
ChooseRunConfigurationPopup action,
final @NotNull RunnerAndConfigurationSettings settings, final boolean dynamic) {
super(null, buildActions(project, action, settings, dynamic));
myProject = project;
mySettings = settings;
}
public @NotNull RunnerAndConfigurationSettings getSettings() {
return mySettings;
}
public @NlsContexts.ListItem String getName() {
return Executor.shortenNameIfNeeded(mySettings.getName());
}
public Icon getIcon() {
return RunManagerEx.getInstanceEx(myProject).getConfigurationIcon(mySettings);
}
@Override
public ListSeparator getSeparatorAbove(ActionWrapper value) {
return value.addSeparatorAbove() ? new ListSeparator() : null;
}
private static ActionWrapper[] buildActions(final @NotNull Project project,
final ChooseRunConfigurationPopup action,
final @NotNull RunnerAndConfigurationSettings settings,
final boolean dynamic) {
final List<ActionWrapper> result = new ArrayList<>();
final ExecutionTarget active = ExecutionTargetManager.getActiveTarget(project);
for (final ExecutionTarget eachTarget : ExecutionTargetManager.getTargetsToChooseFor(project, settings.getConfiguration())) {
result.add(new ActionWrapper(eachTarget.getDisplayName(), eachTarget.getIcon()) {
{
setChecked(eachTarget.equals(active));
}
@Override
public void perform() {
final RunManager manager = RunManager.getInstance(project);
if (dynamic) {
manager.setTemporaryConfiguration(settings);
}
manager.setSelectedConfiguration(settings);
ExecutionTargetManager.setActiveTarget(project, eachTarget);
ExecutionUtil.runConfiguration(settings, action.getExecutor());
}
});
}
boolean isFirst = true;
final List<Executor> allExecutors = new ArrayList<>();
for (Executor executor: Executor.EXECUTOR_EXTENSION_NAME.getExtensionList()) {
if (executor instanceof ExecutorGroup) {
allExecutors.addAll(((ExecutorGroup<?>)executor).childExecutors());
}
else {
allExecutors.add(executor);
}
}
for (final Executor executor : allExecutors) {
if (ExecutorRegistryImpl.RunnerHelper.canRun(project, executor, settings.getConfiguration())) {
result.add(new ActionWrapper(executor.getActionName(), executor.getIcon(), isFirst) {
@Override
public void perform() {
final RunManager manager = RunManager.getInstance(project);
if (dynamic) {
manager.setTemporaryConfiguration(settings);
}
if (!manager.isRiderRunWidgetActive()) manager.setSelectedConfiguration(settings);
ExecutorRegistryImpl.RunnerHelper.run(project, settings.getConfiguration(), settings, DataContext.EMPTY_CONTEXT, executor);
}
});
isFirst = false;
}
}
result.add(new ActionWrapper(ExecutionBundle.message("choose.run.popup.edit"), AllIcons.Actions.EditSource, true) {
@Override
public void perform() {
if (dynamic) {
RunManager.getInstance(project).setTemporaryConfiguration(settings);
}
action.editConfiguration(project, settings);
}
});
if (settings.isTemporary() || dynamic) {
result.add(new ActionWrapper(ExecutionBundle.message("choose.run.popup.save"), AllIcons.Actions.MenuSaveall) {
@Override
public void perform() {
final RunManager manager = RunManager.getInstance(project);
if (dynamic) {
manager.setTemporaryConfiguration(settings);
}
manager.makeStable(settings);
}
});
}
result.add(new ActionWrapper(ExecutionBundle.message("choose.run.popup.delete"), AllIcons.Actions.Cancel) {
@Override
public void perform() {
deleteConfiguration(project, settings, action.myPopup);
}
});
return result.toArray(new ActionWrapper[0]);
}
@Override
public PopupStep<?> onChosen(final ActionWrapper selectedValue, boolean finalChoice) {
return doFinalStep(() -> selectedValue.perform());
}
@Override
public Icon getIconFor(ActionWrapper aValue) {
return aValue.getIcon();
}
@Override
public @NotNull String getTextFor(ActionWrapper value) {
return value.getText();
}
}
private abstract static class ActionWrapper extends Wrapper {
private final @Nls String myName;
private final Icon myIcon;
private ActionWrapper(@Nls String name, Icon icon) {
this(name, icon, false);
}
private ActionWrapper(@Nls String name, Icon icon, boolean addSeparatorAbove) {
super(addSeparatorAbove);
myName = name;
myIcon = icon;
}
public abstract void perform();
@Override
public String getText() {
return myName;
}
@Override
public Icon getIcon() {
return myIcon;
}
}
private static final class MyAbstractAction extends AbstractAction implements DumbAware {
private final ListPopupImpl myListPopup;
private final int myNumber;
@@ -808,7 +500,7 @@ public final class ChooseRunConfigurationPopup implements ExecutorProvider {
final Object o = getListModel().get(index);
if (o instanceof ItemWrapper && ((ItemWrapper<?>)o).canBeDeleted()) {
RunnerAndConfigurationSettings runConfig = (RunnerAndConfigurationSettings)((ItemWrapper<?>)o).getValue();
deleteConfiguration(myProject, requireNonNull(runConfig), ChooseRunConfigurationPopup.this.myPopup);
ChooseRunConfigurationManager.deleteConfiguration(myProject, requireNonNull(runConfig), ChooseRunConfigurationPopup.this.myPopup);
getListModel().deleteItem(o);
List<Object> values = getListStep().getValues();
@@ -828,376 +520,4 @@ public final class ChooseRunConfigurationPopup implements ExecutorProvider {
return true;
}
}
private static final class FolderWrapper extends ItemWrapper<String> {
private final Project myProject;
private final ExecutorProvider myExecutorProvider;
private final List<? extends RunnerAndConfigurationSettings> myConfigurations;
private FolderWrapper(Project project, ExecutorProvider executorProvider, @Nullable String value, List<? extends RunnerAndConfigurationSettings> configurations) {
super(value);
myProject = project;
myExecutorProvider = executorProvider;
myConfigurations = configurations;
}
@Override
public void perform(@NotNull Project project, @NotNull Executor executor, @NotNull DataContext context) {
RunManager runManager = RunManager.getInstance(project);
RunnerAndConfigurationSettings selectedConfiguration = runManager.getSelectedConfiguration();
if (myConfigurations.contains(selectedConfiguration)) {
runManager.setSelectedConfiguration(selectedConfiguration);
ExecutionUtil.runConfiguration(requireNonNull(selectedConfiguration), myExecutorProvider.getExecutor());
}
}
@Override
public @NotNull Icon getIcon() {
return AllIcons.Nodes.Folder;
}
@Override
public String getText() {
return getValue();
}
@Override
public @Nullable ConfigurationType getType() {
return Registry.is("run.popup.move.folders.to.top") || myConfigurations.isEmpty()
? null
: myConfigurations.get(0).getType();
}
@Override
public boolean hasActions() {
return true;
}
@Override
public PopupStep<?> getNextStep(Project project, ChooseRunConfigurationPopup action) {
List<ConfigurationActionsStep> steps = new ArrayList<>();
for (RunnerAndConfigurationSettings settings : myConfigurations) {
steps.add(new ConfigurationActionsStep(project, action, settings, false));
}
return new FolderStep(myProject, myExecutorProvider, null, steps, action);
}
}
private static final class FolderStep extends BaseListPopupStep<ConfigurationActionsStep> {
private final Project myProject;
private final ChooseRunConfigurationPopup myPopup;
private final ExecutorProvider myExecutorProvider;
private FolderStep(Project project, ExecutorProvider executorProvider, @NlsSafe String folderName, List<ConfigurationActionsStep> children,
ChooseRunConfigurationPopup popup) {
super(folderName, children, new ArrayList<>());
myProject = project;
myExecutorProvider = executorProvider;
myPopup = popup;
}
@Override
public PopupStep<?> onChosen(final ConfigurationActionsStep selectedValue, boolean finalChoice) {
if (finalChoice) {
if (myPopup.myEditConfiguration) {
final RunnerAndConfigurationSettings settings = selectedValue.getSettings();
return doFinalStep(() -> myPopup.editConfiguration(myProject, settings));
}
return doFinalStep(() -> {
RunnerAndConfigurationSettings settings = selectedValue.getSettings();
RunManager.getInstance(myProject).setSelectedConfiguration(settings);
ExecutionUtil.runConfiguration(settings, myExecutorProvider.getExecutor());
});
} else {
return selectedValue;
}
}
@Override
public Icon getIconFor(ConfigurationActionsStep aValue) {
return aValue.getIcon();
}
@Override
public @NotNull String getTextFor(ConfigurationActionsStep value) {
return value.getName();
}
@Override
public boolean hasSubstep(ConfigurationActionsStep selectedValue) {
return !selectedValue.getValues().isEmpty();
}
}
/**
* @deprecated Use {@link #createSettingsList(Project, ExecutorProvider, DataContext, boolean)}
*/
@Deprecated(forRemoval = true)
public static @NotNull List<ItemWrapper<?>> createSettingsList(@NotNull Project project,
@NotNull ExecutorProvider executorProvider,
boolean isCreateEditAction) {
return createSettingsList(project, executorProvider, DataManager.getInstance().getDataContext(), isCreateEditAction);
}
public static @NotNull List<ItemWrapper<?>> createSettingsList(@NotNull Project project,
@NotNull ExecutorProvider executorProvider,
@NotNull DataContext dataContext,
boolean isCreateEditAction) {
RunManager runManager = RunManager.getInstanceIfCreated(project);
if (runManager == null) {
return Collections.emptyList();
}
//noinspection TestOnlyProblems
return createSettingsList((RunManagerImpl)runManager, executorProvider, isCreateEditAction,
Registry.is("run.popup.move.folders.to.top", false), dataContext);
}
public static List<ItemWrapper<?>> createFlatSettingsList(@NotNull Project project) {
return RunManagerImplKt.createFlatSettingsList(project);
}
@TestOnly
public static @NotNull List<ItemWrapper<?>> createSettingsList(@NotNull RunManagerImpl runManager,
@NotNull ExecutorProvider executorProvider,
boolean isCreateEditAction,
boolean isMoveFoldersToTop,
@NotNull DataContext dataContext) {
List<ItemWrapper<?>> result = new ArrayList<>();
if (isCreateEditAction) {
result.add(createEditAction());
}
Project project = runManager.getProject();
final RunnerAndConfigurationSettings selectedConfiguration = runManager.getSelectedConfiguration();
if (selectedConfiguration != null) {
addActionsForSelected(selectedConfiguration, project, result);
}
Map<RunnerAndConfigurationSettings, ItemWrapper<?>> wrappedExisting = new LinkedHashMap<>();
List<FolderWrapper> folderWrappers = new SmartList<>();
for (Map<String, List<RunnerAndConfigurationSettings>> folderToConfigurations : runManager.getConfigurationsGroupedByTypeAndFolder(false).values()) {
if (isMoveFoldersToTop) {
for (Map.Entry<String, List<RunnerAndConfigurationSettings>> entry : folderToConfigurations.entrySet()) {
final String folderName = entry.getKey();
List<RunnerAndConfigurationSettings> configurations = entry.getValue();
if (folderName != null) {
folderWrappers.add(createFolderItem(project, executorProvider, selectedConfiguration, folderName, configurations));
}
else {
for (RunnerAndConfigurationSettings configuration : configurations) {
wrapAndAdd(project, configuration, selectedConfiguration, wrappedExisting);
}
}
}
}
else {
// add only folders
for (Map.Entry<String, List<RunnerAndConfigurationSettings>> entry : folderToConfigurations.entrySet()) {
final String folderName = entry.getKey();
if (folderName != null) {
result.add(createFolderItem(project, executorProvider, selectedConfiguration, folderName, entry.getValue()));
}
}
// add configurations
List<RunnerAndConfigurationSettings> configurations = folderToConfigurations.get(null);
if (!ContainerUtil.isEmpty(configurations)) {
for (RunnerAndConfigurationSettings configuration : configurations) {
result.add(wrapAndAdd(project, configuration, selectedConfiguration, wrappedExisting));
}
}
}
}
if (isMoveFoldersToTop) {
result.addAll(folderWrappers);
}
if (!DumbService.isDumb(project)) {
populateWithDynamicRunners(result, wrappedExisting, project, RunManagerEx.getInstanceEx(project), selectedConfiguration, dataContext);
}
if (isMoveFoldersToTop) {
result.addAll(wrappedExisting.values());
}
return result;
}
private static @NotNull ItemWrapper<?> wrapAndAdd(@NotNull Project project,
@NotNull RunnerAndConfigurationSettings configuration,
@Nullable RunnerAndConfigurationSettings selectedConfiguration,
@NotNull Map<RunnerAndConfigurationSettings, ItemWrapper<?>> wrappedExisting) {
ItemWrapper<?> wrapped = ItemWrapper.wrap(project, configuration);
if (configuration == selectedConfiguration) {
wrapped.setMnemonic(1);
}
wrappedExisting.put(configuration, wrapped);
return wrapped;
}
private static @NotNull FolderWrapper createFolderItem(@NotNull Project project,
@NotNull ExecutorProvider executorProvider,
@Nullable RunnerAndConfigurationSettings selectedConfiguration,
@NotNull String folderName,
@NotNull List<? extends RunnerAndConfigurationSettings> configurations) {
boolean isSelected = selectedConfiguration != null && configurations.contains(selectedConfiguration);
String value = folderName;
if (isSelected) {
value += " (mnemonic is to \"" + selectedConfiguration.getName() + "\")";
}
FolderWrapper result = new FolderWrapper(project, executorProvider, value, configurations);
if (isSelected) {
result.setMnemonic(1);
}
return result;
}
private static void addActionsForSelected(@NotNull RunnerAndConfigurationSettings selectedConfiguration,
@NotNull Project project,
@NotNull List<ItemWrapper<?>> result) {
boolean isFirst = true;
final ExecutionTarget activeTarget = ExecutionTargetManager.getActiveTarget(project);
for (ExecutionTarget eachTarget : ExecutionTargetManager.getTargetsToChooseFor(project, selectedConfiguration.getConfiguration())) {
ItemWrapper<ExecutionTarget> itemWrapper = new ItemWrapper<>(eachTarget, isFirst) {
@Override
public Icon getIcon() {
return requireNonNull(getValue()).getIcon();
}
@Override
public String getText() {
return requireNonNull(getValue()).getDisplayName();
}
@Override
public void perform(final @NotNull Project project, final @NotNull Executor executor, @NotNull DataContext context) {
ExecutionTargetManager.setActiveTarget(project, requireNonNull(getValue()));
ExecutionUtil.doRunConfiguration(selectedConfiguration, executor, null, null, context);
}
@Override
public boolean available(Executor executor) {
return true;
}
};
itemWrapper.setChecked(eachTarget.equals(activeTarget));
result.add(itemWrapper);
isFirst = false;
}
}
private static @NotNull ItemWrapper<Void> createEditAction() {
ItemWrapper<Void> result = new ItemWrapper<>(null) {
@Override
public Icon getIcon() {
return AllIcons.Actions.EditSource;
}
@Override
public String getText() {
return UIUtil.removeMnemonic(ActionsBundle.message("action.editRunConfigurations.text"));
}
@Override
public void perform(final @NotNull Project project, final @NotNull Executor executor, @NotNull DataContext context) {
if (new EditConfigurationsDialog(project) {
@Override
protected void init() {
setOKButtonText(executor.getActionName());
myExecutor = executor;
super.init();
}
}.showAndGet()) {
ApplicationManager.getApplication().invokeLater(() -> {
RunnerAndConfigurationSettings configuration = RunManager.getInstance(project).getSelectedConfiguration();
if (configuration != null) {
ExecutionUtil.doRunConfiguration(configuration, executor, null, null, context);
}
}, project.getDisposed());
}
}
@Override
public boolean available(Executor executor) {
return true;
}
};
result.setMnemonic(0);
return result;
}
private static void populateWithDynamicRunners(List<ItemWrapper<?>> result,
Map<RunnerAndConfigurationSettings, ItemWrapper<?>> existing,
Project project,
RunManager manager,
RunnerAndConfigurationSettings selectedConfiguration,
@NotNull DataContext dataContext) {
final ConfigurationContext context = ConfigurationContext.getFromContext(dataContext, ActionPlaces.UNKNOWN);
List<ConfigurationFromContext> producers = PreferredProducerFind.getConfigurationsFromContext(context.getLocation(),
context, false, true);
if (producers == null) return;
producers = ContainerUtil.sorted(producers, ConfigurationFromContext.NAME_COMPARATOR);
final RunnerAndConfigurationSettings[] preferred = {null};
int i = 2; // selectedConfiguration == null ? 1 : 2;
for (final ConfigurationFromContext fromContext : producers) {
final RunnerAndConfigurationSettings configuration = fromContext.getConfigurationSettings();
if (existing.containsKey(configuration)) {
ItemWrapper<?> wrapper = existing.get(configuration);
if (wrapper.getMnemonic() != 1) {
wrapper.setMnemonic(i);
i++;
}
}
else {
if (selectedConfiguration != null && configuration.equals(selectedConfiguration)) continue;
if (preferred[0] == null) {
preferred[0] = configuration;
}
ItemWrapper<?> wrapper = new ItemWrapper<Object>(configuration) {
@Override
public Icon getIcon() {
return RunManagerEx.getInstanceEx(project).getConfigurationIcon(configuration);
}
@Override
public String getText() {
return Executor.shortenNameIfNeeded(configuration.getName()) + configuration.getConfiguration().getPresentableType();
}
@Override
public boolean available(Executor executor) {
return ProgramRunner.getRunner(executor.getId(), configuration.getConfiguration()) != null;
}
@Override
public void perform(@NotNull Project project, @NotNull Executor executor, @NotNull DataContext context) {
manager.setTemporaryConfiguration(configuration);
RunManager.getInstance(project).setSelectedConfiguration(configuration);
ExecutionUtil.doRunConfiguration(configuration, executor, null, null, context);
}
@Override
public PopupStep<?> getNextStep(final @NotNull Project project, final @NotNull ChooseRunConfigurationPopup action) {
return new ConfigurationActionsStep(project, action, configuration, isDynamic());
}
@Override
public boolean hasActions() {
return true;
}
};
wrapper.setDynamic(true);
wrapper.setMnemonic(i);
result.add(wrapper);
i++;
}
}
}
}
@@ -28,7 +28,7 @@ open class ChooseRunConfigurationPopupAction : AnAction(), DumbAware {
popup.show(step)
}
override fun getActionUpdateThread() = ActionUpdateThread.BGT
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
override fun update(e: AnActionEvent) {
e.presentation.isEnabledAndVisible = e.getData(CommonDataKeys.PROJECT)?.isDisposed == false && defaultExecutor != null
@@ -5,6 +5,7 @@ import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.Executor;
import com.intellij.execution.RunManager;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.actions.ChooseRunConfigurationManager;
import com.intellij.execution.actions.ChooseRunConfigurationPopup;
import com.intellij.execution.actions.ExecutorProvider;
import com.intellij.execution.configurations.ConfigurationFactory;
@@ -260,7 +261,7 @@ final class ProjectStartupConfigurable implements SearchableConfigurable, Config
final Executor executor = DefaultRunExecutor.getRunExecutorInstance();
final List<ChooseRunConfigurationPopup.ItemWrapper<?>> wrappers = new ArrayList<>();
wrappers.add(createNewWrapper(button));
var allSettings = ChooseRunConfigurationPopup.createSettingsList(myProject, new ExecutorProvider() {
var allSettings = ChooseRunConfigurationManager.createSettingsList(myProject, new ExecutorProvider() {
@Override
public Executor getExecutor() {
return executor;
@@ -8413,21 +8413,6 @@ f:com.intellij.ide.actions.searcheverywhere.RecentFilesSEContributor$Factory
- com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributorFactory
- <init>():V
- createContributor(com.intellij.openapi.actionSystem.AnActionEvent):com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor
f:com.intellij.ide.actions.searcheverywhere.RunConfigurationsSEContributor
- com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor
- <init>(com.intellij.openapi.project.Project,java.awt.Component,java.util.function.Supplier):V
- fetchElements(java.lang.String,com.intellij.openapi.progress.ProgressIndicator,com.intellij.util.Processor):V
- getElementsRenderer():javax.swing.ListCellRenderer
- getGroupName():java.lang.String
- getSearchProviderId():java.lang.String
- getSortWeight():I
- getSupportedCommands():java.util.List
- processSelectedItem(com.intellij.execution.actions.ChooseRunConfigurationPopup$ItemWrapper,I,java.lang.String):Z
- showInFindResults():Z
f:com.intellij.ide.actions.searcheverywhere.RunConfigurationsSEContributor$Factory
- com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributorFactory
- <init>():V
- createContributor(com.intellij.openapi.actionSystem.AnActionEvent):com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor
f:com.intellij.ide.actions.searcheverywhere.SEResultsEqualityProvider$Companion
- f:composite(java.util.Collection):com.intellij.ide.actions.searcheverywhere.SEResultsEqualityProvider
- f:getEP_NAME():com.intellij.openapi.extensions.ExtensionPointName
@@ -1,7 +1,7 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.ide.actions.runAnything;
import com.intellij.execution.actions.ChooseRunConfigurationPopup;
import com.intellij.execution.actions.ChooseRunConfigurationManager;
import com.intellij.execution.actions.ChooseRunConfigurationPopup.ItemWrapper;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.actionSystem.DataContext;
@@ -40,9 +40,9 @@ public final class RunAnythingRunConfigurationProvider extends com.intellij.ide.
private static Collection<ItemWrapper> sort(@NotNull Project project, @NotNull String pattern) {
MinusculeMatcher matcher = NameUtil.buildMatcher("*" + pattern).build();
List<ItemWrapper<?>> list = ChooseRunConfigurationPopup.createFlatSettingsList(project);
List<ItemWrapper<?>> list = ChooseRunConfigurationManager.createFlatSettingsList(project);
TreeMap<Integer, ItemWrapper> map = new TreeMap<>(Comparator.reverseOrder());
for (ItemWrapper wrapper : list) {
for (ItemWrapper<?> wrapper : list) {
String name = wrapper.getText();
FList<TextRange> fragments = matcher.matchingFragments(name);
if (fragments != null) {
@@ -4,6 +4,7 @@ package com.intellij.ide.actions.searcheverywhere;
import com.intellij.execution.Executor;
import com.intellij.execution.ExecutorRegistry;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.actions.ChooseRunConfigurationManager;
import com.intellij.execution.actions.ChooseRunConfigurationPopup;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.executors.DefaultRunExecutor;
@@ -27,6 +28,7 @@ import com.intellij.util.Processor;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -39,6 +41,7 @@ import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
@ApiStatus.Internal
public final class RunConfigurationsSEContributor implements SearchEverywhereContributor<ChooseRunConfigurationPopup.ItemWrapper> {
private final SearchEverywhereCommandInfo RUN_COMMAND =
@@ -113,7 +116,7 @@ public final class RunConfigurationsSEContributor implements SearchEverywhereCon
pattern = filterString(pattern);
MinusculeMatcher matcher = NameUtil.buildMatcher(pattern).build();
for (ChooseRunConfigurationPopup.ItemWrapper wrapper : ChooseRunConfigurationPopup.createFlatSettingsList(myProject)) {
for (ChooseRunConfigurationPopup.ItemWrapper<?> wrapper : ChooseRunConfigurationManager.createFlatSettingsList(myProject)) {
if (matcher.matches(wrapper.getText()) && !consumer.process(wrapper)) {
return;
}
@@ -1131,7 +1131,7 @@ run.anything.recent.project.command.placeholder=open <project name>
run.anything.actions.undefined=Undefined
run.anything.notification.warning.content=Command ''{0}'' failed to execute.
run.anything.notification.warning.title=Failed Command Execution
run.anything.run.configurations.group.title=Run configurations
run.anything.run.configurations.group.title=Run Configurations
run.anything.help.list.empty.secondary.text=Select command
run.anything.main.list.empty.primary.text=Run command or configuration
run.anything.main.list.empty.secondary.text=Type "?" to see all commands