diff --git a/buildUML/reference_guide/execution_classes.puml b/buildUML/reference_guide/execution_classes.puml new file mode 100644 index 000000000..ab5d67be6 --- /dev/null +++ b/buildUML/reference_guide/execution_classes.puml @@ -0,0 +1,35 @@ +@startuml + +hide empty members +hide circle + +package Configuration <> { + interface RunProfile + interface RunConfiguration + interface RunProfileState +} + +package Execution <> { + 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 diff --git a/buildUML/reference_guide/run_configuration_classes.puml b/buildUML/reference_guide/run_configuration_classes.puml new file mode 100644 index 000000000..25d1a48e9 --- /dev/null +++ b/buildUML/reference_guide/run_configuration_classes.puml @@ -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 diff --git a/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoConfigurationFactory.java b/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoConfigurationFactory.java index af3199185..cf345d4d5 100644 --- a/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoConfigurationFactory.java +++ b/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoConfigurationFactory.java @@ -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"); } diff --git a/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfiguration.java b/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfiguration.java index bc0324eb0..e9b608d08 100644 --- a/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfiguration.java +++ b/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfiguration.java @@ -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 { - 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 myScriptName = string("").provideDelegate(this, "scriptName"); + private final StoredProperty myScriptName = + string("").provideDelegate(this, "scriptName"); public String getScriptName() { return myScriptName.getValue(this); diff --git a/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfigurationType.java b/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfigurationType.java index 47f9b06be..4db55fefe 100644 --- a/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfigurationType.java +++ b/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoRunConfigurationType.java @@ -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)); } } diff --git a/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoSettingsEditor.form b/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoSettingsEditor.form deleted file mode 100644 index 3c3160f08..000000000 --- a/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoSettingsEditor.form +++ /dev/null @@ -1,29 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoSettingsEditor.java b/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoSettingsEditor.java index 7a6f85757..b02f8bbe3 100644 --- a/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoSettingsEditor.java +++ b/code_samples/run_configuration/src/main/java/org/jetbrains/sdk/runConfiguration/DemoSettingsEditor.java @@ -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 { - private JPanel myPanel; - private LabeledComponent 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 { return myPanel; } - private void createUIComponents() { - myScriptName = new LabeledComponent<>(); - myScriptName.setComponent(new TextFieldWithBrowseButton()); - } - } diff --git a/ijs.tree b/ijs.tree index a7ce06b40..11d0e134d 100644 --- a/ijs.tree +++ b/ijs.tree @@ -117,10 +117,9 @@ - - - - + + + diff --git a/images/basics/img/classes.png b/images/basics/img/classes.png deleted file mode 100644 index 4acc1811a..000000000 Binary files a/images/basics/img/classes.png and /dev/null differ diff --git a/images/basics/img/create-1.png b/images/basics/img/create-1.png deleted file mode 100644 index 850e0a17d..000000000 Binary files a/images/basics/img/create-1.png and /dev/null differ diff --git a/images/basics/img/create-2.png b/images/basics/img/create-2.png deleted file mode 100644 index a18b047d1..000000000 Binary files a/images/basics/img/create-2.png and /dev/null differ diff --git a/images/basics/img/create-3.png b/images/basics/img/create-3.png deleted file mode 100644 index 89e651a20..000000000 Binary files a/images/basics/img/create-3.png and /dev/null differ diff --git a/images/reference_guide/img/execution_classes.svg b/images/reference_guide/img/execution_classes.svg new file mode 100644 index 000000000..4f9610f65 --- /dev/null +++ b/images/reference_guide/img/execution_classes.svg @@ -0,0 +1,2 @@ + +ConfigurationExecutionRunProfileRunConfigurationRunProfileStateExecutorProgramRunnerExecutionEnvironmentRunContentBuilderExecutionResultExecutionConsoleProcessHandlercreatesprepares11executes diff --git a/images/reference_guide/img/run_configuration_classes.svg b/images/reference_guide/img/run_configuration_classes.svg new file mode 100644 index 000000000..b3970d2b3 --- /dev/null +++ b/images/reference_guide/img/run_configuration_classes.svg @@ -0,0 +1,2 @@ + +RunProfileConfigurationTypeConfigurationFactoryRunConfigurationSettingsEditor*creates0..* diff --git a/images/tutorials/run_configurations/img/new_run_configuration.png b/images/tutorials/run_configurations/img/new_run_configuration.png deleted file mode 100644 index b4fb191fb..000000000 Binary files a/images/tutorials/run_configurations/img/new_run_configuration.png and /dev/null differ diff --git a/images/tutorials/run_configurations/img/ui_form.png b/images/tutorials/run_configurations/img/ui_form.png deleted file mode 100644 index c84436544..000000000 Binary files a/images/tutorials/run_configurations/img/ui_form.png and /dev/null differ diff --git a/topics/appendix/glossary.md b/topics/appendix/glossary.md index b4afc59c2..7af7264b1 100644 --- a/topics/appendix/glossary.md +++ b/topics/appendix/glossary.md @@ -74,7 +74,7 @@ Read Action _(RA)_ → _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 diff --git a/topics/basics/basic_run_configurations.md b/topics/basics/basic_run_configurations.md deleted file mode 100644 index 30260d56d..000000000 --- a/topics/basics/basic_run_configurations.md +++ /dev/null @@ -1,28 +0,0 @@ - - -# Run Configurations - -Run configurations architecture overview. - - - -**Product Help:** [Run/Debug Configuration](https://www.jetbrains.com/idea/help/run-debug-configuration.html) - - - -*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. diff --git a/topics/basics/execution/execution.md b/topics/basics/execution/execution.md new file mode 100644 index 000000000..690ca85bb --- /dev/null +++ b/topics/basics/execution/execution.md @@ -0,0 +1,129 @@ + + +# Execution + +Run profile execution lifecycle and description of APIs used to execute processes. + +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 Run or Debug 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 Run 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 Run or Debug 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 Run Anything 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. diff --git a/topics/basics/execution/run_configurations.md b/topics/basics/execution/run_configurations.md new file mode 100644 index 000000000..20d25e803 --- /dev/null +++ b/topics/basics/execution/run_configurations.md @@ -0,0 +1,163 @@ + + +# Run Configurations + +Implementing run configurations management support. + + + +**Product Help:** [Run/Debug Configuration](https://www.jetbrains.com/idea/help/run-debug-configuration.html) + + + +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 Run 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 Run \| Edit Configurations and click the Add button (+ 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. diff --git a/topics/basics/persistence.md b/topics/basics/persistence.md index a726e9675..f4c94a7c2 100644 --- a/topics/basics/persistence.md +++ b/topics/basics/persistence.md @@ -5,7 +5,7 @@ Introduction to the IntelliJ Platform Persistence Model. 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) diff --git a/topics/basics/run_configurations/run_configuration_execution.md b/topics/basics/run_configurations/run_configuration_execution.md deleted file mode 100644 index dbfcd47ea..000000000 --- a/topics/basics/run_configurations/run_configuration_execution.md +++ /dev/null @@ -1,68 +0,0 @@ - - -# Execution - -Run configuration execution lifecycle and description of APIs used to execute processes. - -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()`. diff --git a/topics/basics/run_configurations/run_configuration_management.md b/topics/basics/run_configurations/run_configuration_management.md deleted file mode 100644 index 2677994ad..000000000 --- a/topics/basics/run_configurations/run_configuration_management.md +++ /dev/null @@ -1,115 +0,0 @@ - - -# Run Configuration Management - -Implementing run configurations management support. - - - -**Product Help:** [Run/Debug Configuration](https://www.jetbrains.com/idea/help/run-debug-configuration.html) - - - -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 - -``` - -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 `` in your [plugin.xml](plugin_configuration_file.md). -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. diff --git a/topics/intro/content_updates.md b/topics/intro/content_updates.md index fe4d63da5..0e2c77c07 100644 --- a/topics/intro/content_updates.md +++ b/topics/intro/content_updates.md @@ -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} diff --git a/topics/tutorials/run_configurations.md b/topics/tutorials/run_configurations.md deleted file mode 100644 index 4e48e3d3e..000000000 --- a/topics/tutorials/run_configurations.md +++ /dev/null @@ -1,92 +0,0 @@ -# Run Configurations Tutorial - - - -Adding custom run configuration tutorial. - - - -**Product Help:** [Run/Debug Configuration](https://www.jetbrains.com/idea/help/run-debug-configuration.html) - - - -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 - - - -``` - -## 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) diff --git a/topics/tutorials/run_configurations_tutorial.md b/topics/tutorials/run_configurations_tutorial.md new file mode 100644 index 000000000..be95f3a59 --- /dev/null +++ b/topics/tutorials/run_configurations_tutorial.md @@ -0,0 +1,87 @@ + + +# Run Configurations Tutorial + +Implementing a custom run configuration tutorial. + + + +**Product Help:** [Run/Debug Configuration](https://www.jetbrains.com/idea/help/run-debug-configuration.html) + + + +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 + + + +``` + +## 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 + + + +1. [Execute](creating_plugin_project.md#executing-the-plugin) the plugin. +2. Go to Run \| Edit Configurations..., click to Add button (+ icon), and select Demo. +3. In the Script file field provide the path to an example script (e.g. displaying "Hello world" message). +4. Click the Apply 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. + +