Execution API docs (#1065)

This commit is contained in:
Karol Lewandowski 2023-06-15 10:51:07 +02:00 committed by GitHub
parent 812cdab1dc
commit 0e3dc47eeb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 486 additions and 396 deletions

View File

@ -0,0 +1,35 @@
@startuml
hide empty members
hide circle
package Configuration <<Rectangle>> {
interface RunProfile
interface RunConfiguration
interface RunProfileState
}
package Execution <<Rectangle>> {
abstract class Executor
interface ProgramRunner
class ExecutionEnvironment
class RunContentBuilder
abstract class ExecutionResult
interface ExecutionConsole
abstract class ProcessHandler
}
RunProfile <|.. RunConfiguration
RunProfile --> RunProfileState: creates
RunProfileState --> ExecutionResult: prepares
ExecutionResult o-- "1" ExecutionConsole
ExecutionResult o-- "1" ProcessHandler
ProgramRunner --> RunProfile: executes
ProgramRunner --> Executor
ProgramRunner --> ExecutionEnvironment
ProgramRunner -r-> RunContentBuilder
@enduml

View File

@ -0,0 +1,18 @@
@startuml
hide empty members
hide circle
interface RunProfile
interface ConfigurationType
abstract class ConfigurationFactory
interface RunConfiguration
abstract class SettingsEditor
ConfigurationType *-- "*" ConfigurationFactory
ConfigurationFactory --> RunConfiguration: creates
RunConfiguration o-- "0..*" SettingsEditor
RunConfiguration -l|> RunProfile
@enduml

View File

@ -23,7 +23,8 @@ public class DemoConfigurationFactory extends ConfigurationFactory {
@NotNull
@Override
public RunConfiguration createTemplateConfiguration(@NotNull Project project) {
public RunConfiguration createTemplateConfiguration(
@NotNull Project project) {
return new DemoRunConfiguration(project, this, "Demo");
}

View File

@ -1,5 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.sdk.runConfiguration;
import com.intellij.execution.ExecutionException;
@ -17,7 +16,9 @@ import org.jetbrains.annotations.Nullable;
public class DemoRunConfiguration extends RunConfigurationBase<DemoRunConfigurationOptions> {
protected DemoRunConfiguration(Project project, ConfigurationFactory factory, String name) {
protected DemoRunConfiguration(Project project,
ConfigurationFactory factory,
String name) {
super(project, factory, name);
}
@ -41,19 +42,18 @@ public class DemoRunConfiguration extends RunConfigurationBase<DemoRunConfigurat
return new DemoSettingsEditor();
}
@Override
public void checkConfiguration() {
}
@Nullable
@Override
public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment executionEnvironment) {
return new CommandLineState(executionEnvironment) {
public RunProfileState getState(@NotNull Executor executor,
@NotNull ExecutionEnvironment environment) {
return new CommandLineState(environment) {
@NotNull
@Override
protected ProcessHandler startProcess() throws ExecutionException {
GeneralCommandLine commandLine = new GeneralCommandLine(getOptions().getScriptName());
OSProcessHandler processHandler = ProcessHandlerFactory.getInstance().createColoredProcessHandler(commandLine);
GeneralCommandLine commandLine =
new GeneralCommandLine(getOptions().getScriptName());
OSProcessHandler processHandler = ProcessHandlerFactory.getInstance()
.createColoredProcessHandler(commandLine);
ProcessTerminatedListener.attach(processHandler);
return processHandler;
}

View File

@ -7,7 +7,8 @@ import com.intellij.openapi.components.StoredProperty;
public class DemoRunConfigurationOptions extends RunConfigurationOptions {
private final StoredProperty<String> myScriptName = string("").provideDelegate(this, "scriptName");
private final StoredProperty<String> myScriptName =
string("").provideDelegate(this, "scriptName");
public String getScriptName() {
return myScriptName.getValue(this);

View File

@ -1,43 +1,18 @@
// Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.sdk.runConfiguration;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.execution.configurations.ConfigurationTypeBase;
import com.intellij.icons.AllIcons;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.util.NotNullLazyValue;
import javax.swing.*;
public class DemoRunConfigurationType implements ConfigurationType {
public class DemoRunConfigurationType extends ConfigurationTypeBase {
static final String ID = "DemoRunConfiguration";
@NotNull
@Override
public String getDisplayName() {
return "Demo";
}
@Override
public String getConfigurationTypeDescription() {
return "Demo run configuration type";
}
@Override
public Icon getIcon() {
return AllIcons.General.Information;
}
@NotNull
@Override
public String getId() {
return ID;
}
@Override
public ConfigurationFactory[] getConfigurationFactories() {
return new ConfigurationFactory[]{new DemoConfigurationFactory(this)};
protected DemoRunConfigurationType() {
super(ID, "Demo", "Demo run configuration type",
NotNullLazyValue.createValue(() -> AllIcons.Nodes.Console));
addFactory(new DemoConfigurationFactory(this));
}
}

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.sdk.runConfiguration.DemoSettingsEditor">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="57eab" class="com.intellij.openapi.ui.LabeledComponent" binding="myScriptName" custom-create="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="-1" height="20"/>
</grid>
</constraints>
<properties>
<labelLocation value="West"/>
<text value="Script file"/>
</properties>
</component>
<vspacer id="93bd6">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
</form>

View File

@ -1,27 +1,36 @@
// Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.sdk.runConfiguration;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.util.ui.FormBuilder;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class DemoSettingsEditor extends SettingsEditor<DemoRunConfiguration> {
private JPanel myPanel;
private LabeledComponent<TextFieldWithBrowseButton> myScriptName;
private final JPanel myPanel;
private final TextFieldWithBrowseButton scriptPathField;
public DemoSettingsEditor() {
scriptPathField = new TextFieldWithBrowseButton();
scriptPathField.addBrowseFolderListener("Select Script File", null, null,
FileChooserDescriptorFactory.createSingleFileDescriptor());
myPanel = FormBuilder.createFormBuilder()
.addLabeledComponent("Script file", scriptPathField)
.getPanel();
}
@Override
protected void resetEditorFrom(DemoRunConfiguration demoRunConfiguration) {
myScriptName.getComponent().setText(demoRunConfiguration.getScriptName());
scriptPathField.setText(demoRunConfiguration.getScriptName());
}
@Override
protected void applyEditorTo(@NotNull DemoRunConfiguration demoRunConfiguration) {
demoRunConfiguration.setScriptName(myScriptName.getComponent().getText());
demoRunConfiguration.setScriptName(scriptPathField.getText());
}
@NotNull
@ -30,9 +39,4 @@ public class DemoSettingsEditor extends SettingsEditor<DemoRunConfiguration> {
return myPanel;
}
private void createUIComponents() {
myScriptName = new LabeledComponent<>();
myScriptName.setComponent(new TextFieldWithBrowseButton());
}
}

View File

@ -117,10 +117,9 @@
<toc-element topic="text_selection.md"/>
<toc-element topic="multiple_carets.md"/>
</toc-element>
<toc-element topic="basic_run_configurations.md" accepts-web-file-names="run_configurations.html">
<toc-element topic="run_configuration_management.md"/>
<toc-element topic="run_configuration_execution.md"/>
<toc-element topic="run_configurations.md"/>
<toc-element topic="execution.md" accepts-web-file-names="run_configuration_execution.html,basic_run-configurations.html,run-configuration-execution.html">
<toc-element topic="run_configurations.md" accepts-web-file-names="run-configuration-management.html"/>
<toc-element topic="run_configurations_tutorial.md"/>
</toc-element>
<toc-element topic="vcs_integration_for_plugins.md">
<toc-element toc-title="Diff"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

View File

@ -74,7 +74,7 @@ Read Action _(RA)_
&rarr; _Write Action_
Run Configuration _(RC)_
: A [Run Configuration](basic_run_configurations.md) allows running external processes from within the IDE.
: A [Run Configuration](run_configurations.md) allows running external processes from within the IDE.
## S

View File

@ -1,28 +0,0 @@
<!-- Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
# Run Configurations
<link-summary>Run configurations architecture overview.</link-summary>
<tldr>
**Product Help:** [Run/Debug Configuration](https://www.jetbrains.com/idea/help/run-debug-configuration.html)
</tldr>
*Run Configurations* allow users to run specific external processes from within the IDE, e.g., a script, an application, a server, etc.
You can provide the UI for the user to specify execution options, and an option to create a run configuration based on a specific location in the source code.
## Architectural Overview
Classes used to manipulate run configurations can be split into the following groups:
* [Run configuration management](run_configuration_management.md).
This includes creation, persistence, and modification.
* [Execution](run_configuration_execution.md).
This diagram shows the main classes:
![Architecture](classes.png)
See [Run Configurations Tutorial](run_configurations.md) for a fully working sample.

View File

@ -0,0 +1,129 @@
<!-- Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
# Execution
<link-summary>Run profile execution lifecycle and description of APIs used to execute processes.</link-summary>
The IntelliJ Platform Execution API allows [running external processes](https://www.jetbrains.com/help/idea/running-applications.html) from within the IDE, e.g., applications, tests, servers, scripts, etc.
These processes can be run from the [editor](editors.md), [project view](project_view.md), run toolbar, or custom [actions](action_system.md).
Executed processes can be stopped, restarted, and their output and logs can be viewed in the run console.
It is possible to manage and persist [Run Configurations](https://www.jetbrains.com/help/idea/run-debug-configuration.html) from the UI.
## Architecture Overview
The key Execution API classes are divided into two groups:
* [Configuration](#configuration-classes)
* [Execution](#execution-classes)
The following diagram shows the relations between the key classes:
![Execution Classes](execution_classes.svg)
### Configuration Classes
[`RunProfile`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunProfile.java) is a base interface for things that can be executed (e.g., an application started via a `main()` method, a test or test suite, a remote debug session to a specific host, etc.).
It is responsible for building a process that is run and creates a `RunProfileState`.
[`RunProfileState`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunProfileState.java) holds the information about the process ready to be started, like the command line, current working directory, and environment variables.
The existence of `RunProfileState` allows extensions and other components to patch the run profile and modify the parameters before the process gets executed.
See [standard run profile state classes](#run-profile-state).
[`RunConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java) is a specific type of run profile, which can be managed and persisted by users from UI.
See the [Run Configurations](run_configurations.md) section for more details.
### Execution Classes
[`Executor`](%gh-ic%/platform/execution/src/com/intellij/execution/Executor.java) describes a specific way of executing run profiles.
The three default executors provided by the IntelliJ Platform are:
* [`DefaultRunExecutor`](%gh-ic%/platform/execution/src/com/intellij/execution/executors/DefaultRunExecutor.java) (_Run_)
* [`DefaultDebugExecutor`](%gh-ic%/platform/xdebugger-api/src/com/intellij/execution/executors/DefaultDebugExecutor.java) (_Debug_)
* [`CoverageExecutor`](%gh-ic%/plugins/coverage-common/src/com/intellij/coverage/CoverageExecutor.java) _(Run with Coverage_)
Custom implementations are rarely required (it may be necessary, e.g., when a profiler integration is implemented).
Executor implementations are registered in the `com.intellij.executor` extension point (EP).
[`ProgramRunner`](%gh-ic%/platform/execution/src/com/intellij/execution/runners/ProgramRunner.java) is responsible for the [execution workflow](#execution-workflow) of a `RunProfile` with a certain `Executor`.
`ProgramRunner` implementations are registered in the `com.intellij.programRunner` EP.
[`ExecutionEnvironment`](%gh-ic%/platform/execution/src/com/intellij/execution/runners/ExecutionEnvironment.java) object aggregates all the objects and settings required to execute the process.
It is used by the `ProgramRunner.execute()` method.
[`RunContentBuilder`](%gh-ic%/platform/execution-impl/src/com/intellij/execution/runners/RunContentBuilder.java) is responsible for building the content of the <control>Run</control> or <control>Debug</control> tool window.
The content is built by the `ProgramRunner` executing the process.
[`ExecutionResult`](%gh-ic%/platform/execution/src/com/intellij/execution/ExecutionResult.java) is prepared by `RunProfileState` class before execution and contains `ExecutionConsole` and `ProcessHandler`.
[`ExecutionConsole`](%gh-ic%/platform/execution/src/com/intellij/execution/ui/ExecutionConsole.java) is a component displaying the result of executing the process.
It can be a console, a test results view, or another similar component.
[`ProcessHandler`](%gh-ic%/platform/util/src/com/intellij/execution/process/ProcessHandler.java) is an object attached to the executed process and allows controlling and accessing the information about the process.
See [standard process handler class](#process-handler).
## Execution Workflow
A standard execution of a process consists of the following steps:
1. Depending on the execution context:
1. For execution initiated by a user from UI: the user selects a `RunConfiguration` (e.g., by choosing one from the run configurations combo box) and an `Executor` (e.g., by pressing the <control>Run</control> toolbar button).
2. For programmatic execution: a `RunProfile` instance is created, and an `Executor` is provided.
Specific run executors can be accessed with `ExecutorRegistry.getInstance().getExecutorById()`.
{style="alpha-lower"}
2. The `ProgramRunner` that will execute the process is selected.
The first `ProgramRunner` that returns true from `ProgramRunner.canRun(executorId, runProfile)` is selected from all registered program runners.
3. The `ExecutionEnvironment` is created.
It aggregates all the information required to run the process as well as the selected `ProgramRunner`, `Executor`, and `RunProfile`.
4. `ProgramRunner.execute(executionEnvironment)` is called, and the actual process is executed.
A standard implementation of `ProgramRunner.execute()` goes through the following steps to execute the process:
1. `RunProfile.getState()` method is called to create a `RunProfileState` object, which describes a process about to be started.
The command line parameters, environment variables, and other information required to start the process are initialized at this stage.
2. `RunProfileState.execute(executor, programRunner)` is called.
It starts the process, attaches a `ProcessHandler` to its input and output streams, creates a console to display the process output, and returns an `ExecutionResult` object aggregating the `ExecutionConsole` and the `ProcessHandler`.
3. The `RunContentBuilder` object is created and invoked to display the execution console in a <control>Run</control> or <control>Debug</control> tool window tab.
**Example**:
[`RunAnythingCommandProvider.runCommand()`](%gh-ic%/platform/lang-impl/src/com/intellij/ide/actions/runAnything/activity/RunAnythingCommandProvider.java), which programmatically executes a command typed by a user in the <control>Run Anything</control> popup
## Standard Base Classes
### Run Profile State
The standard base class used as an implementation of `RunProfileState` is [`CommandLineState`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/CommandLineState.java).
It contains the logic for putting together a running process and a console into an `ExecutionResult` but doesn't know anything about how the process is actually started.
For starting the process, it's recommended to use the [`GeneralCommandLine`](%gh-ic%/platform/platform-util-io/src/com/intellij/execution/configurations/GeneralCommandLine.java) class, which takes care of setting up the command line parameters and executing the process.
Alternatively, if the process is a JVM-based one, use the [`JavaCommandLineState`](%gh-ic%/java/execution/impl/src/com/intellij/execution/configurations/JavaCommandLineState.java) base class.
It handles the JVM command line parameters and can take care of details like calculating the classpath for the JVM.
Note that using this class requires [dependency](plugin_dependencies.md) on [the Java plugin](idea.md#java).
### Process Handler
The standard class for monitoring the execution of a process and capturing its output is [`OSProcessHandler`](%gh-ic%/platform/platform-util-io/src/com/intellij/execution/process/OSProcessHandler.java).
Once an instance of `OSProcessHandler` is created from either a `GeneralCommandLine` or a `Process` object, call the `startNotify()` method to capture its output.
To display the exit status of the process in the console, attach a [`ProcessTerminatedListener`](%gh-ic%/platform/ide-core/src/com/intellij/execution/process/ProcessTerminatedListener.java) to the `OSProcessHandler`.
### Displaying Process Output
When a process execution is handled with `CommandLineState`, a console view will be automatically created and attached to the process's output.
Alternatively, it can be handled with the following steps:
1. [`TextConsoleBuilderFactory.createBuilder(project).getConsole()`](%gh-ic%/platform/execution/src/com/intellij/execution/filters/TextConsoleBuilderFactory.java) creates a [`ConsoleView`](%gh-ic%/platform/execution/src/com/intellij/execution/ui/ConsoleView.java) instance.
2. `ConsoleView.attachToProcess()` attaches it to the output of a process.
If the running process uses [ANSI escape codes to color its output](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors), use the [`ColoredProcessHandler`](%gh-ic%/platform/platform-util-io/src/com/intellij/execution/process/ColoredProcessHandler.java) class to display the colors in the IDE console.
#### Console Filters
Console [`Filter`](%gh-ic%/platform/execution/src/com/intellij/execution/filters/Filter.java) allows converting certain strings found in the process output to clickable hyperlinks.
To attach a filter to the console, use `CommandLineState.addConsoleFilters()` or [`TextConsoleBuilder.addFilter()`](%gh-ic%/platform/execution/src/com/intellij/execution/filters/TextConsoleBuilder.java) if the console is created manually.
Two standard filter implementations are [`RegexpFilter`](%gh-ic%/platform/lang-api/src/com/intellij/execution/filters/RegexpFilter.java) and [`UrlFilter`](%gh-ic%/platform/execution-impl/src/com/intellij/execution/filters/UrlFilter.java).
Console filters can be also provided by implementing [`ConsoleFilterProvider`](%gh-ic%/platform/lang-api/src/com/intellij/execution/filters/ConsoleFilterProvider.java) and registering it in `com.intellij.consoleFilterProvider` EP.
## Listening for Execution Events
Implement [`ExecutionListener`](%gh-ic%/platform/execution/src/com/intellij/execution/ExecutionListener.java) and subscribe to [`ExecutionManager#EXECUTION_TOPIC`](%gh-ic%/platform/execution/src/com/intellij/execution/ExecutionManager.kt).
The listener allows for listening to several phases of the process execution lifecycle.

View File

@ -0,0 +1,163 @@
<!-- Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
# Run Configurations
<link-summary>Implementing run configurations management support.</link-summary>
<tldr>
**Product Help:** [Run/Debug Configuration](https://www.jetbrains.com/idea/help/run-debug-configuration.html)
</tldr>
A run configuration is a specific type of [run profile](execution.md#configuration-classes).
Run configurations can be managed from the UI and persisted between IDE restarts.
They allow users to specify execution options like a working directory, environment variables, program arguments, and other parameters required to run a process.
Run configurations can be started from the <control>Run</control> toolbar, the editor, and executed programmatically from actions or other components.
## Architecture Overview
The following diagram shows the key run configurations classes:
![Run Configuration Classes](run_configuration_classes.svg)
Run Configuration API (except `SettingsEditor` class, which is a class shared by many IntelliJ Platform APIs) is a part of the [Execution API](execution.md).
### ConfigurationType
The entry point of a run configuration implementation is [`ConfigurationType`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationType.java).
It is responsible for the run configuration type and instances presentation and contains configuration factories.
A single configuration type can have multiple configuration factories, e.g., the Docker configuration type can create run configurations for:
* Dockerfile
* Docker Image
* Docker-compose
To see the list of configuration types available in the IDE, go to <ui-path>Run \| Edit Configurations</ui-path> and click the <control>Add</control> button (<control>+</control> icon).
`ConfigurationType` implementations are registered in the `com.intellij.configurationType` extension point (EP).
Standard base classes for configuration type implementations are:
* [`SimpleConfigurationType`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/runConfigurationType.kt) - used for configuration types that have a single configuration factory.
Actually, this configuration type is also a configuration factory, and there is no need for setting up a factory.
* [`ConfigurationTypeBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/runConfigurationType.kt) - used for configuration types that have multiple configuration factories.
Factories should be added in the constructor by calling the `addFactory()` method.
### ConfigurationFactory
[`ConfigurationFactory`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) classes are responsible for creating [run configuration](#runconfiguration) instances.
The only method required to be implemented is `createTemplateConfiguration()`, which is called once for each project to create the run configuration template.
The actual run configurations are created in the `createConfiguration()` method by cloning the template.
Configuration factory presentation is inherited from the containing configuration type.
If customization is needed, override the presentation methods in the factory class.
### RunConfiguration
[`RunConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java) extends [`RunProfile`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunProfile.java) and represents a named profile that can be run by the [Execution API](execution.md).
When implementing a run configuration class, consider using one of the standard base classes:
* [`RunConfigurationBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfigurationBase.java) - a general-purpose base class that contains the most basic implementation of a run configuration.
* [`LocatableConfigurationBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/LocatableConfigurationBase.java) - a base class for [configurations that can be created from context](#creating-a-run-configuration-from-context).
* [`ModuleBasedConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ModuleBasedConfiguration.java) - a base class for a configuration that is associated with a specific [module](module.md) (e.g., Java run configurations use the selected module to determine the run classpath).
### SettingsEditor
A run configuration may allow editing its general settings and settings specific to a [program runner](execution.md#execution-classes).
If it is required, a `RunConfiguration` implementation should return a [`SettingsEditor`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/SettingsEditor.java) instance from:
* `getConfigurationEditor()` for editing run configuration settings
* `getRunnerSettingsEditor()` for editing settings for a specific program runner
A `SettingsEditor` implementation must provide the following methods:
* `getComponent()` - creates a UI component for displaying settings controls
* `applyEditorTo()` - copies the current editor UI state into the target settings object
* `resetEditorFrom()` - resets the current editor UI state to the initial settings state
In the case of run configuration settings, the settings object is `RunConfiguration` itself.
Settings specific to a program runner must implement [`ConfigurationPerRunnerSettings`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationPerRunnerSettings.java).
If a settings editor is complex, consider splitting it into multiple editors.
These editors should be added to the [`SettingsEditorGroup`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/SettingsEditorGroup.java) object, which is a `SettingsEditor`'s implementation itself and must be returned from `getConfigurationEditor()` or `getRunnerSettingsEditor()`.
Each editor added to the group is displayed in a separate tab.
See [`ApplicationConfiguration.getConfigurationEditor()`](%gh-ic%/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java) as a reference.
If the settings editor requires validation, implement [`CheckableRunConfigurationEditor`](%gh-ic%/platform/lang-api/src/com/intellij/execution/impl/CheckableRunConfigurationEditor.java).
## Persistence
Run configuration settings are persistent.
They are stored in the file system and loaded back after the IDE restart.
Persisting and loading settings are performed by `writeExternal()` and `readExternal()` methods of `RunConfiguration` class correspondingly.
The actually stored configurations are represented by instances of the [`RunnerAndConfigurationSettings`](%gh-ic%/platform/execution/src/com/intellij/execution/RunnerAndConfigurationSettings.java) class, which combines a run configuration with runner-specific settings and stores general run configuration flags and properties.
## Creating a Run Configuration Programmatically
If a plugin requires creating run configurations programmatically, .e.g, from a custom action, perform the following steps:
1. [`RunManager.createConfiguration()`](%gh-ic%/platform/execution/src/com/intellij/execution/RunManager.kt) - creates an instance of `RunnerAndConfigurationSettings`.
2. [`RunManager.addConfiguration()`](%gh-ic%/platform/execution/src/com/intellij/execution/RunManager.kt) - makes the created configuration persistent by adding it to either the list of shared configurations stored in a project or to the list of local configurations stored in the workspace file.
## Creating a Run Configuration from Context
Run configurations can be created and run from context, e.g., by right-clicking an application main method, a test class/method, etc., directly in the editor or the project view.
This is achieved by implementing [`LazyRunConfigurationProducer`](%gh-ic%/platform/lang-api/src/com/intellij/execution/actions/LazyRunConfigurationProducer.kt) and registering it in `com.intellij.runConfigurationProducer` EP.
The extension requires implementing the following methods:
* `getConfigurationFactory()` - returns the factory creating run configurations of the type specified in the extension class implementation.
* `setupConfigurationFromContext()` - receives a blank configuration of the specified type and a [`ConfigurationContext`](%gh-ic%/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java) containing information about a source code location (accessible by calling `getLocation()` or `getPsiLocation()`).
The implementation needs to check whether the location is applicable to the configuration type (e.g. if it's in a file of the supported language).
If it is, put the correct context-specific settings into the run configuration and return true.
Return false otherwise.
* `isConfigurationFromContext()` - checks if a configuration was created from the specified context.
This method allows reusing an existing run configuration, which applies to the current context, instead of creating a new one and possibly ignoring the user's customizations in the existing one.
To support the automatic naming of configurations created from context, the configuration should extend [`LocatableConfigurationBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/LocatableConfigurationBase.java).
It supports generating a name for a configuration from its settings and tracking whether the user changed the name.
## Running Configurations from the Gutter
If a run configuration is closely related to a PSI element (e.g., runnable method, test, etc.), it is possible to allow running configurations by [clicking the editor gutter icon](https://www.jetbrains.com/help/idea/running-applications.html#run-from-editor).
It is achieved by implementing [`RunLineMarkerContributor`](%gh-ic%/platform/execution-impl/src/com/intellij/execution/lineMarker/RunLineMarkerContributor.java), which provides information like the icon, tooltip content, and available actions for a given PSI element.
The standard method for providing the information is `getInfo()`.
If computing the information is slow, implement `getSlowInfo()`, which is used by the editor highlighting mechanism to gather information in batch, and apply all the information at once to avoid icons blinking.
To provide the standard executor actions like _Run_, _Debug_, etc., use [`ExecutorAction.getActions()`](%gh-ic%/platform/execution-impl/src/com/intellij/execution/ExecutorRegistryImpl.java).
## Starting a Run Configuration Programmatically
The easiest way to run an existing run configuration is using [`ProgramRunnerUtil.executeConfiguration(RunnerAndConfigurationSettings, Executor)`](%gh-ic%/platform/execution-impl/src/com/intellij/execution/ProgramRunnerUtil.java).
`RunnerAndConfigurationSettings` can be retrieved with, e.g., `RunManager.getConfigurationSettings(ConfigurationType)`.
The executor can be retrieved with a static method if a required executor exposes one or with [`ExecutorRegistry.getExecutorById()`](%gh-ic%/platform/execution/src/com/intellij/execution/ExecutorRegistry.java).
## Refactoring Support
Some run configurations contain references to classes, files, or directories in their settings, and these settings usually need to be updated when the corresponding element is renamed or moved.
To support that, a run configuration needs to implement the [`RefactoringListenerProvider`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RefactoringListenerProvider.java) interface.
The `RefactoringListenerProvider.getRefactoringElementListener()`'s implementation should check whether the refactored element is referred from the run configuration.
If it is, return a [`RefactoringElementListener`](%gh-ic%/platform/analysis-api/src/com/intellij/refactoring/listeners/RefactoringElementListener.java) that updates the run configuration according to the new name and location of the element.
## Modifying Existing Run Configurations
Plugins can modify existing run configurations before they are run, e.g., by adding additional process parameters.
However, there is no single platform-wide extension point, and different IDEs provide different configuration base classes and extension points, allowing for their modifications.
To see what is possible in your case, check the [`RunConfigurationExtensionBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configuration/RunConfigurationExtensionBase.java) inheritors.
Examples:
* [`RunConfigurationExtension`](%gh-ic%/java/execution/impl/src/com/intellij/execution/RunConfigurationExtension.java) implementations registered in `com.intellij.runConfigurationExtension` EP allow for modifying Java run configurations extending [`RunConfigurationBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfigurationBase.java).
* [`PythonRunConfigurationExtension`](%gh-ic%/python/src/com/jetbrains/python/run/PythonRunConfigurationExtension.java) implementations registered in `Pythonid.runConfigurationExtension` EP allow for modifying configuration extending [`AbstractPythonRunConfiguration`](%gh-ic%/python/src/com/jetbrains/python/run/AbstractPythonRunConfiguration.java)
etc.
## Referencing Environment Variables in Run Configurations
Run configurations can define user environment variables specific to a given run configuration and include system environment variables.
Sometimes, it is convenient to reference existing variables in newly created variables, e.g., if a user creates an `EXTENDED_PATH` variable and builds it from a custom entry and the system `PATH` variable, they should reference it in the value by surrounding it with the `$` character: `/additional/entry:$PATH$`.
To substitute variable references with the actual references, it is required to call [`EnvironmentUtil.inlineParentOccurrences()`](%gh-ic%/platform/util/src/com/intellij/util/EnvironmentUtil.java) (available since 2023.2).
## Before Run Tasks
Sometimes, it is necessary to perform specific tasks before a configuration is actually run, e.g., build the project, run a build tool preparation task, launch a web browser, etc.
Plugins can provide custom tasks that can be added by users to a created run configuration.
To provide a custom task, implement [`BeforeRunTaskProvider`](%gh-ic%/platform/execution/src/com/intellij/execution/BeforeRunTaskProvider.java) and register it in `com.intellij.stepsBeforeRunProvider` EP.
The provider implementation is responsible for creating a task instance for a given run configuration and executing the task.

View File

@ -5,7 +5,7 @@
<link-summary>Introduction to the IntelliJ Platform Persistence Model.</link-summary>
The IntelliJ Platform Persistence Model is used to store a variety of information.
For example, [Run Configurations](basic_run_configurations.md) and [Settings](settings.md) are stored using the Persistence Model.
For example, [Run Configurations](run_configurations.md) and [Settings](settings.md) are stored using the Persistence Model.
There are two distinct approaches, depending on the type of data being persisted:
* [Persisting State of Components](persisting_state_of_components.md)

View File

@ -1,68 +0,0 @@
<!-- Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
# Execution
<link-summary>Run configuration execution lifecycle and description of APIs used to execute processes.</link-summary>
The standard execution of a run action goes through the following steps:
* The user selects a *run configuration* (for example, by choosing one from the run configurations combo box) and an *executor* (for example, by pressing a toolbar button created by the executor).
* The *program runner* that will actually execute the process is selected by polling all registered program runners and asking whether they can run the specified run profile with the specified executor ID.
* The [`ExecutionEnvironment`](%gh-ic%/platform/execution/src/com/intellij/execution/runners/ExecutionEnvironment.java) object is created.
This object aggregates all the settings required to execute the process and the selected [`ProgramRunner`](%gh-ic%/platform/execution/src/com/intellij/execution/runners/ProgramRunner.java).
* `ProgramRunner.execute()` is called, receiving the executor and the execution environment.
Implementations of `ProgramRunner.execute()` go through the following steps to execute the process:
* `RunProfile.getState()` method is called to create a [`RunProfileState`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunProfileState.java) object, describing a process about to be started.
At this stage, the command line parameters, environment variables, and other information required to start the process are initialized.
* `RunProfileState.execute()` is called.
It starts the process, attaches a `ProcessHandler` to its input and output streams, creates a console to display the process output, and returns an [`ExecutionResult`](%gh-ic%/platform/execution/src/com/intellij/execution/ExecutionResult.java) object aggregating the console and the process handler.
* The `RunContentBuilder` object is created and invoked to display the execution console in a tab of the Run or Debug tool window.
## Executor
The [`Executor`](%gh-ic%/platform/execution/src/com/intellij/execution/Executor.java) interface describes a specific way of executing any possible run configuration.
The three default executors provided by the IntelliJ Platform by default are _Run_, _Debug_, and _Run with Coverage_. Each executor gets its own toolbar button, which starts the selected run configuration using this executor, and its own context menu item for starting a configuration using this executor.
As a plugin developer, you usually don't need to implement the `Executor` interface.
However, it can be useful, for example, if you're implementing a profiler integration and want to provide the possibility to execute any configuration with profiling.
## Running a Process
The `RunProfileState` interface comes up in every run configuration implementation as the return value `RunProfile.getState()`.
It describes a process that is ready to be started and holds information like the command line, current working directory, and environment variables for the process to be started. (The existence of `RunProfileState` as a separate step in the execution flow allows run configuration extensions and other components to patch the configuration and modify the parameters before it gets executed.)
The standard base class used as implementation of `RunProfileState` is [`CommandLineState`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/CommandLineState.java).
It contains the logic for putting together a running process and a console into an [`ExecutionResult`](%gh-ic%/platform/execution/src/com/intellij/execution/ExecutionResult.java), but doesn't know anything how the process is actually started.
For starting the process, it's best to use the [`GeneralCommandLine`](%gh-ic%/platform/platform-util-io/src/com/intellij/execution/configurations/GeneralCommandLine.java) class, which takes care of setting up the command line parameters and executing the process.
Alternatively, if the process you need to run is a JVM-based one, you can use the [`JavaCommandLineState`](%gh-ic%/java/execution/impl/src/com/intellij/execution/configurations/JavaCommandLineState.java) base class.
It knows about the JVM command line parameters and can take care of details like calculating the classpath for the JVM.
To monitor the execution of a process and capture its output, the [`OSProcessHandler`](%gh-ic%/platform/platform-util-io/src/com/intellij/execution/process/OSProcessHandler.java) class is usually used.
Once you've created an instance of `OSProcessHandler` from either a command line or a Process object, you need to call the `startNotify()` method to capture its output.
You may also want to attach a [`ProcessTerminatedListener`](%gh-ic%/platform/ide-core/src/com/intellij/execution/process/ProcessTerminatedListener.java) to the `OSProcessHandler` so that the exit status of the process will be displayed in the console.
## Displaying Process Output
If you're using `CommandLineState`, a console view will be automatically created and attached to the process's output.
Alternatively, you can arrange this yourself:
* `TextConsoleBuilderFactory.createBuilder(project).getConsole()` creates a [`ConsoleView`](%gh-ic%/platform/execution/src/com/intellij/execution/ui/ConsoleView.java) instance
* `ConsoleView.attachToProcess()` attaches it to the output of a process.
If the running process uses ANSI escape codes to color its output, the [`ColoredProcessHandler`](%gh-ic%/platform/platform-util-io/src/com/intellij/execution/process/ColoredProcessHandler.java) class will parse it and display the colors in the IntelliJ console.
Console [`Filter`](%gh-ic%/platform/execution/src/com/intellij/execution/filters/Filter.java) allows you to convert certain strings found in the process output to clickable hyperlinks.
To attach a filter to the console, use `CommandLineState.addConsoleFilters()` or, if you're creating a console manually, `TextConsoleBuilder.addFilter()`.
Two common filter implementations you may want to reuse are [`RegexpFilter`](%gh-ic%/platform/lang-api/src/com/intellij/execution/filters/RegexpFilter.java) and [`UrlFilter`](%gh-ic%/platform/execution-impl/src/com/intellij/execution/filters/UrlFilter.java).
## Starting a Run Configuration from Code
If you have an existing run configuration that you need to execute, the easiest way to do so is to use [`ProgramRunnerUtil.executeConfiguration()`](%gh-ic%/platform/execution-impl/src/com/intellij/execution/ProgramRunnerUtil.java).
The method takes a [`Project`](%gh-ic%/platform/core-api/src/com/intellij/openapi/project/Project.java), a [`RunnerAndConfigurationSettings`](%gh-ic%/platform/execution/src/com/intellij/execution/RunnerAndConfigurationSettings.java), as well as an [`Executor`](%gh-ic%/platform/execution/src/com/intellij/execution/Executor.java).
To get the `RunnerAndConfigurationSettings` for an existing configuration, you can use, for example, `RunManager.getConfigurationSettings(ConfigurationType)`.
As the last parameter, you normally pass either `DefaultRunExecutor.getRunExecutorInstance()` or `DefaultDebugExecutor.getDebugExecutorInstance()`.

View File

@ -1,115 +0,0 @@
<!-- Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
# Run Configuration Management
<link-summary>Implementing run configurations management support.</link-summary>
<tldr>
**Product Help:** [Run/Debug Configuration](https://www.jetbrains.com/idea/help/run-debug-configuration.html)
</tldr>
This document describes the primary classes to work with run configurations and everyday use cases.
## Configuration Type
The starting point for implementing any run configuration type is the [`ConfigurationType`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationType.java) interface.
The list of available configuration types is shown when a user opens the _'Edit run configurations'_ dialog and executes _'Add'_ action:
![Create](create-1.png)
Every type there is represented as an instance of [`ConfigurationType`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationType.java) and registered like below:
```xml
<configurationType
implementation="org.jetbrains.plugins.gradle.service.execution.GradleExternalTaskConfigurationType"/>
```
The easiest way to implement this interface is to use the [`ConfigurationTypeBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/runConfigurationType.kt) base class.
To use it, you need to inherit from it and to provide the configuration type parameters (ID, name, description, and icon) as constructor parameters.
In addition to that, you need to call the [`addFactory()`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/runConfigurationType.kt) method to add a configuration factory.
## Configuration Factory
All run configurations are created by the [`ConfigurationFactory`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) registered for a particular `ConfigurationType`.
It's possible that one `ConfigurationType` has more than one `ConfigurationFactory`:
![Configuration Factory](create-3.png)
The key API of `ConfigurationFactory`, and the only method that you're required to implement, is the [`createTemplateConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) method.
This method is called once per project to create the template run configuration.
All real run configurations (loaded from the workspace or created by the user) are called by cloning the template through the [`createConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) method.
You can customize additional aspects of your configuration factory by overriding the [`getIcon`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java), [`getAddIcon`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java), [`getName`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) and the default settings methods.
These additional overrides are optional.
## Run Configuration
The run configuration itself is represented by the [`RunConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java) interface.
A _'run configuration'_ here is some named profile which can be executed, e.g., the application started via `main()` class, test, remote debug to particular machine/port, etc.
Here is an example of a Java run configuration defined for a particular project:
![Run Configuration](create-2.png)
When implementing a run configuration, you may want to use one of the common base classes:
* [`RunConfigurationBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfigurationBase.java) is a general-purpose superclass that contains the most basic implementation of a run configuration.
* [`LocatableConfigurationBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/LocatableConfigurationBase.java) is a common base class that should be used for configurations that can be created from context by a `RunConfigurationProducer`.
It supports automatically generating a name for a configuration from its settings and keeping track of whether the name was changed by the user.
* [`ModuleBasedConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ModuleBasedConfiguration.java) is a base class for a configuration that is associated with a specific module (for example, Java run configurations use the selected module to determine the run classpath).
## Settings Editor
That common run configuration settings might be modified via:
[`RunConfiguration`-specific UI](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java)
That is handled by [`SettingsEditor`](%gh-ic%/platform/ide-core/src/com/intellij/openapi/options/SettingsEditor.java):
* `getComponent()` method is called by the IDE and shows run configuration specific UI.
* `resetFrom()` is called to discard all non-confirmed user changes made via that UI.
* `applyTo()` is called to confirm the changes, i.e. copy current UI state into the target settings object.
## Persistence
That run configuration settings are persistent, i.e., they are stored at the file system and loaded back on the IDE startup.
That is performed via [`writeExternal()`](%gh-ic%/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) and [`readExternal()`](%gh-ic%/platform/util/src/com/intellij/openapi/util/JDOMExternalizable.java) methods of [`RunConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java) class correspondingly.
The actual configurations stored by the IntelliJ Platform are represented by instances of the [`RunnerAndConfigurationSettings`](%gh-ic%/platform/execution/src/com/intellij/execution/RunnerAndConfigurationSettings.java) class, which combines a run configuration with runner-specific settings, as well as keeping track of certain run configuration flags such as "temporary" or "singleton".
Dealing with instances of this class becomes necessary when you need to create run configurations from code.
This is accomplished with the following two steps:
* `RunManager.createConfiguration()` creates an instance of `RunnerAndConfigurationSettings`.
* `RunManager.addConfiguration()` makes it persistent by adding it to either the list of shared configurations stored in a project or to the list of local configurations stored in the workspace file.
## Refactoring Support
Most run configurations contain references to classes, files, or directories in their settings, and these settings usually need to be updated when the corresponding element is renamed or moved.
To support that, your run configuration needs to implement the [`RefactoringListenerProvider`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RefactoringListenerProvider.java) interface.
In your implementation of `getRefactoringElementListener()`, you need to check whether the refactored element is the one that your run configuration refers to.
If it is, you return a [`RefactoringElementListener`](%gh-ic%/platform/analysis-api/src/com/intellij/refactoring/listeners/RefactoringElementListener.java) that updates your configuration according to the new name and location of the element.
## Creating Configurations from Context
Many plugins support automatic creation of run configurations from context so that the user can click, for example, on an application or test class and automatically run it using the correct run configuration type.
To support that, you need to provide an implementation of the [`RunConfigurationProducer`](%gh-ic%/platform/lang-api/src/com/intellij/execution/actions/RunConfigurationProducer.java) interface and to register it as `<runConfigurationProducer>` in your <path>[plugin.xml](plugin_configuration_file.md)</path>.
This API was redesigned in IntelliJ IDEA 13; the previous [`RuntimeConfigurationProducer`](%gh-ic%/platform/lang-api/src/com/intellij/execution/junit/RuntimeConfigurationProducer.java) is a much more confusing version of the same API.
The two main methods that you need to implement are:
* `setupConfigurationFromContext()` receives a blank configuration of your type and a `ConfigurationContext` containing information about a source code location (accessible by calling `getLocation()` or `getPsiLocation()`).
Your implementation needs to check whether the location is applicable for your configuration type (for example, if it's in a file of the language you're supporting).
If not, you need to return false, and if it is, you need to put the correct context-specific settings into the run configuration and return true.
* `isConfigurationFromContext()` checks if your type's specified configuration was created from the specified context.
Implementing this method allows you to reuse an existing run configuration, which applies to the current context instead of creating a new one and possibly ignoring the user's customizations in the existing one.
Note that, to support the automatic naming of configurations created from context, your configuration should use [`LocatableConfigurationBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/LocatableConfigurationBase.java) as the base class.
## Running from the Gutter
Take a look at [`RunLineMarkerContributor`](%gh-ic%/platform/execution-impl/src/com/intellij/execution/lineMarker/RunLineMarkerContributor.java) and its implementations.

View File

@ -12,6 +12,12 @@ See [GitHub Changelog](https://github.com/JetBrains/intellij-sdk-docs/commits/ma
## 2023
### June
{#june-23}
Execution
: Rework [](execution.md), [](run_configurations.md), and [](run_configurations_tutorial.md) pages.
### April
{#april-23}

View File

@ -1,92 +0,0 @@
# Run Configurations Tutorial
<!-- Copyright 2000-2023 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<link-summary>Adding custom run configuration tutorial.</link-summary>
<tldr>
**Product Help:** [Run/Debug Configuration](https://www.jetbrains.com/idea/help/run-debug-configuration.html)
</tldr>
These series of steps show how to register and implement a simple Run Configuration.
Run Configurations are used to run internal and external processes from within IntelliJ Platform based products.
Consider the **runConfiguration** sample plugin available in the [code samples](%gh-sdk-samples%/run_configuration).
See [Code Samples](code_samples.md) on how to set up and run the plugin.
## Pre-Requirements
Create an empty plugin project.
See the [](creating_plugin_project.md) section for details.
## Register a New ConfigurationType
Add new `com.intellij.configurationType` extension to the [plugin.xml](%gh-sdk-samples%/run_configuration/src/main/resources/META-INF/plugin.xml)
```xml
<extensions defaultExtensionNs="com.intellij">
<configurationType
implementation="org.jetbrains.sdk.runConfiguration.DemoRunConfigurationType"/>
</extensions>
```
## Implement ConfigurationType
Implement [`ConfigurationType`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationType.java) interface registered in the Step 1.
```java
```
{src="run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfigurationType.java" include-symbol="DemoRunConfigurationType"}
## Implement a ConfigurationFactory
Implement a new [`ConfigurationFactory`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) through which custom run configurations will be created.
```java
```
{src="run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoConfigurationFactory.java" include-symbol="DemoConfigurationFactory"}
Implement corresponding configuration options class extending [`RunConfigurationOptions`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfigurationOptions.kt) to store settings.
```java
```
{src="run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfigurationOptions.java" include-symbol="DemoRunConfigurationOptions"}
## Implement a Run Configuration
To make your changes visible from the UI, implement a new Run Configuration.
**Note:** In most of the cases you can derive a custom Run Configuration class from the [`RunConfigurationBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfigurationBase.java).
If you need to implement specific settings externalization rules and I/O behaviour, use [`RunConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java) interface.
```java
```
{src="run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfiguration.java" include-symbol="DemoRunConfiguration"}
## Create and Implement Run Configuration UI Form
Make sure _UI Designer_ plugin is [enabled](https://www.jetbrains.com/help/idea/managing-plugins.html).
Create a new [UI form](https://www.jetbrains.com/help/idea/designing-gui-major-steps.html) that defines, how an inner part of the new Run Configuration should look like.
Default Run Configuration will be looking like this:
![Default Run Configuration Look](ui_form.png)
## Bind the UI Form
The UI Form should be bound with a Java class responsible for handling UI components logic.
```java
```
{src="run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoSettingsEditor.java" include-symbol="DemoSettingsEditor"}
## Compile and Run the Plugin
Refer to [Running and Debugging a Plugin](creating_plugin_project.md#executing-the-plugin).
After going through the steps described above you can create a custom Run Configuration from your plugin.
![New Run Configuration Type](new_run_configuration.png)

View File

@ -0,0 +1,87 @@
<!-- Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
# Run Configurations Tutorial
<link-summary>Implementing a custom run configuration tutorial.</link-summary>
<tldr>
**Product Help:** [Run/Debug Configuration](https://www.jetbrains.com/idea/help/run-debug-configuration.html)
</tldr>
This step-by-step guide shows how to register and implement a simple [run configuration](run_configurations.md).
Run configurations are used to run internal and external processes from within IntelliJ Platform based products.
The full implementation is available in the [code samples](%gh-sdk-samples%/run_configuration).
## Pre-Requirements
Create an empty plugin project.
See the [](creating_plugin_project.md) section for details.
## Implement a ConfigurationType
Implement [`ConfigurationType`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationType.java):
```java
```
{src="run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfigurationType.java" include-symbol="DemoRunConfigurationType"}
## Register the ConfigurationType
Register implemented configuration type in `com.intellij.configurationType` extension point in the [plugin.xml](%gh-sdk-samples%/run_configuration/src/main/resources/META-INF/plugin.xml):
```xml
<extensions defaultExtensionNs="com.intellij">
<configurationType
implementation="org.jetbrains.sdk.runConfiguration.DemoRunConfigurationType"/>
</extensions>
```
## Implement a ConfigurationFactory
Implement a new [`ConfigurationFactory`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/ConfigurationFactory.java) through which custom run configurations will be created.
```java
```
{src="run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoConfigurationFactory.java" include-symbol="DemoConfigurationFactory"}
Implement corresponding configuration options class extending [`RunConfigurationOptions`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfigurationOptions.kt) to store settings.
```java
```
{src="run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfigurationOptions.java" include-symbol="DemoRunConfigurationOptions"}
## Implement a Run Configuration
To make your changes visible from the UI, implement a new run configuration.
> In most of the cases it is sufficient derive a custom run configuration class from the [`RunConfigurationBase`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfigurationBase.java).
> If implementing specific settings externalization rules and I/O behaviour is required, use [`RunConfiguration`](%gh-ic%/platform/execution/src/com/intellij/execution/configurations/RunConfiguration.java) interface.
>
{style="note"}
```java
```
{src="run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfiguration.java" include-symbol="DemoRunConfiguration"}
## Implement the Settings Editor
```java
```
{src="run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoSettingsEditor.java" include-symbol="DemoSettingsEditor"}
## Compile and Run the Plugin
<procedure>
1. [Execute](creating_plugin_project.md#executing-the-plugin) the plugin.
2. Go to <ui-path>Run \| Edit Configurations...</ui-path>, click to <control>Add</control> button (<control>+</control> icon), and select <control>Demo</control>.
3. In the <control>Script file</control> field provide the path to an example script (e.g. displaying "Hello world" message).
4. Click the <control>Apply</control> button and close the dialog.
5. In the run toolbar select created configuration and click the run button.
The script should be executed and its result should be displayed in the console.
</procedure>