#
tokens: 10184/50000 25/25 files
lines: off (toggle) GitHub
raw markdown copy
# Directory Structure

```
├── .github
│   ├── dependabot.yml
│   ├── readme
│   │   └── demo.gif
│   └── workflows
│       ├── build.yml
│       ├── release.yml
│       └── run-ui-tests.yml
├── .gitignore
├── .idea
│   └── gradle.xml
├── .run
│   ├── Run Plugin.run.xml
│   ├── Run Tests.run.xml
│   └── Run Verifications.run.xml
├── build.gradle.kts
├── CHANGELOG.md
├── gradle
│   ├── libs.versions.toml
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── qodana.yml
├── README.md
├── settings.gradle.kts
└── src
    ├── main
    │   ├── kotlin
    │   │   └── com
    │   │       └── github
    │   │           └── gschrader
    │   │               └── openinrunconfig
    │   │                   ├── actions
    │   │                   │   └── RunWithFilePathAction.kt
    │   │                   └── MyBundle.kt
    │   └── resources
    │       ├── messages
    │       │   └── MyBundle.properties
    │       └── META-INF
    │           └── plugin.xml
    └── test
        ├── kotlin
        │   └── com
        │       └── github
        │           └── gschrader
        │               └── openinrunconfig
        │                   └── MyPluginTest.kt
        └── testData
            └── rename
                ├── foo_after.xml
                └── foo.xml
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
.gradle
.idea
.intellijPlatform
.qodana
build

```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
# open-in-run-config-idea-plugin

![Build](https://github.com/gschrader/open-in-run-config-idea-plugin/workflows/Build/badge.svg)
[![Version](https://img.shields.io/jetbrains/plugin/v/27881.svg)](https://plugins.jetbrains.com/plugin/27881)
[![Downloads](https://img.shields.io/jetbrains/plugin/d/27881.svg)](https://plugins.jetbrains.com/plugin/27881)

## Plugin Overview

<!-- Plugin description -->
The **Open in Run Config** plugin allows you to quickly run any Java application configuration with a selected file as a program argument. It's essentially a productivity tool that eliminates the need to manually edit run configurations when you want to pass a file path to your application.
<!-- Plugin description end -->

![demo](./.github/readme/demo.gif)

## What It Does

1. **Context Menu Integration**: Adds a "Project Application" action to the context menu when you right-click on a file in the Project view or other file browsers in IntelliJ IDEA.

2. **Configuration Selection**: When triggered, it shows a popup list of all available Java Application run configurations in your project.

3. **Automatic File Path Injection**: Once you select a run configuration, it:
  - Creates a temporary copy of the selected configuration
  - Automatically adds the selected file's path as a program argument
  - Runs the configuration immediately

4. **Smart Handling**:
  - Only works with Java Application configurations (not other types like JUnit, etc.)
  - Preserves all original configuration settings (working directory, environment variables, etc.)
  - Creates temporary configurations that don't clutter your permanent run configurations
  - Handles both cases where the configuration already has program arguments and where it doesn't

## Use Cases

This plugin is particularly useful when you have applications that:
- Process files (like parsers, converters, analyzers)
- Need file paths as command-line arguments
- Are frequently run with different input files

Instead of manually editing run configurations each time, you can simply right-click on any file and run your application with that file as input.

```

--------------------------------------------------------------------------------
/src/test/testData/rename/foo_after.xml:
--------------------------------------------------------------------------------

```
<root>
    <a2>Foo</a2>
</root>

```

--------------------------------------------------------------------------------
/src/test/testData/rename/foo.xml:
--------------------------------------------------------------------------------

```
<root>
    <a<caret>1>Foo</a1>
</root>

```

--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------

```kotlin
plugins {
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}

rootProject.name = "open-in-run-config-idea-plugin"

```

--------------------------------------------------------------------------------
/qodana.yml:
--------------------------------------------------------------------------------

```yaml
# Qodana configuration:
# https://www.jetbrains.com/help/qodana/qodana-yaml.html

version: "1.0"
linter: jetbrains/qodana-jvm-community:2024.3
projectJDK: "21"
profile:
  name: qodana.recommended
exclude:
  - name: All
    paths:
      - .qodana

```

--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------

```
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

```

--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------

```markdown
<!-- Keep a Changelog guide -> https://keepachangelog.com -->

# open-in-run-config-idea-plugin Changelog

## [Unreleased]
### Added
- Initial scaffold created from [IntelliJ Platform Plugin Template](https://github.com/JetBrains/intellij-platform-plugin-template)

```

--------------------------------------------------------------------------------
/src/test/kotlin/com/github/gschrader/openinrunconfig/MyPluginTest.kt:
--------------------------------------------------------------------------------

```kotlin
package com.github.gschrader.openinrunconfig

import com.intellij.testFramework.TestDataPath
import com.intellij.testFramework.fixtures.BasePlatformTestCase

@TestDataPath("\$CONTENT_ROOT/src/test/testData")
class MyPluginTest : BasePlatformTestCase() {
    fun testt() {
    }
}

```

--------------------------------------------------------------------------------
/src/main/resources/messages/MyBundle.properties:
--------------------------------------------------------------------------------

```
runWithFilePath=Project Application
selectConfiguration=Select Configuration to Run
noConfigurationsAvailable=No run configurations are available in this project.
configurationNotSupported=Configuration ''{0}'' does not support program parameters.
executionError=Error executing configuration: {0}

```

--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------

```yaml
# Dependabot configuration:
# https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
  # Maintain dependencies for Gradle dependencies
  - package-ecosystem: "gradle"
    directory: "/"
    schedule:
      interval: "daily"
  # Maintain dependencies for GitHub Actions
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "daily"

```

--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------

```
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="GradleMigrationSettings" migrationVersion="1" />
  <component name="GradleSettings">
    <option name="linkedExternalProjectsSettings">
      <GradleProjectSettings>
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="modules">
          <set>
            <option value="$PROJECT_DIR$" />
          </set>
        </option>
      </GradleProjectSettings>
    </option>
  </component>
</project>
```

--------------------------------------------------------------------------------
/src/main/kotlin/com/github/gschrader/openinrunconfig/MyBundle.kt:
--------------------------------------------------------------------------------

```kotlin
package com.github.gschrader.openinrunconfig

import com.intellij.DynamicBundle
import org.jetbrains.annotations.NonNls
import org.jetbrains.annotations.PropertyKey

@NonNls
private const val BUNDLE = "messages.MyBundle"

object MyBundle : DynamicBundle(BUNDLE) {

    @JvmStatic
    fun message(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) =
        getMessage(key, *params)

    @Suppress("unused")
    @JvmStatic
    fun messagePointer(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) =
        getLazyMessage(key, *params)
}

```

--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------

```toml
[versions]
# libraries
junit = "4.13.2"
opentest4j = "1.3.0"

# plugins
changelog = "2.2.1"
intelliJPlatform = "2.5.0"
kotlin = "2.1.20"
kover = "0.9.1"
qodana = "2024.3.4"

[libraries]
junit = { group = "junit", name = "junit", version.ref = "junit" }
opentest4j = { group = "org.opentest4j", name = "opentest4j", version.ref = "opentest4j" }

[plugins]
changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" }
intelliJPlatform = { id = "org.jetbrains.intellij.platform", version.ref = "intelliJPlatform" }
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" }
qodana = { id = "org.jetbrains.qodana", version.ref = "qodana" }

```

--------------------------------------------------------------------------------
/.run/Run Tests.run.xml:
--------------------------------------------------------------------------------

```
<component name="ProjectRunConfigurationManager">
  <configuration default="false" name="Run Tests" type="GradleRunConfiguration" factoryName="Gradle">
    <log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
    <ExternalSystemSettings>
      <option name="executionName" />
      <option name="externalProjectPath" value="$PROJECT_DIR$" />
      <option name="externalSystemIdString" value="GRADLE" />
      <option name="scriptParameters" value="" />
      <option name="taskDescriptions">
        <list />
      </option>
      <option name="taskNames">
        <list>
          <option value="check" />
        </list>
      </option>
      <option name="vmOptions" value="" />
    </ExternalSystemSettings>
    <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
    <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
    <DebugAllEnabled>false</DebugAllEnabled>
    <RunAsTest>true</RunAsTest>
    <method v="2" />
  </configuration>
</component>

```

--------------------------------------------------------------------------------
/.run/Run Plugin.run.xml:
--------------------------------------------------------------------------------

```
<component name="ProjectRunConfigurationManager">
  <configuration default="false" name="Run Plugin" type="GradleRunConfiguration" factoryName="Gradle">
    <log_file alias="IDE logs" path="$PROJECT_DIR$/build/idea-sandbox/*/log/idea.log" show_all="true" />
    <ExternalSystemSettings>
      <option name="executionName" />
      <option name="externalProjectPath" value="$PROJECT_DIR$" />
      <option name="externalSystemIdString" value="GRADLE" />
      <option name="scriptParameters" value="" />
      <option name="taskDescriptions">
        <list />
      </option>
      <option name="taskNames">
        <list>
          <option value="runIde" />
        </list>
      </option>
      <option name="vmOptions" value="" />
    </ExternalSystemSettings>
    <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
    <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
    <DebugAllEnabled>false</DebugAllEnabled>
    <RunAsTest>false</RunAsTest>
    <method v="2" />
  </configuration>
</component>

```

--------------------------------------------------------------------------------
/.run/Run Verifications.run.xml:
--------------------------------------------------------------------------------

```
<component name="ProjectRunConfigurationManager">
  <configuration default="false" name="Run Verifications" type="GradleRunConfiguration" factoryName="Gradle">
    <log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
    <ExternalSystemSettings>
      <option name="executionName" />
      <option name="externalProjectPath" value="$PROJECT_DIR$" />
      <option name="externalSystemIdString" value="GRADLE" />
      <option name="scriptParameters" value="" />
      <option name="taskDescriptions">
        <list />
      </option>
      <option name="taskNames">
        <list>
          <option value="verifyPlugin" />
        </list>
      </option>
      <option name="vmOptions" value="" />
    </ExternalSystemSettings>
    <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
    <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
    <DebugAllEnabled>false</DebugAllEnabled>
    <RunAsTest>false</RunAsTest>
    <method v="2" />
  </configuration>
</component>
```

--------------------------------------------------------------------------------
/src/main/resources/META-INF/plugin.xml:
--------------------------------------------------------------------------------

```
<!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
<idea-plugin>
    <id>com.github.gschrader.openinrunconfig</id>
    <name>Open in Run Config</name>
    <vendor>gschrader</vendor>
    <description><![CDATA[
The <b>Open in Run Config</b> plugin allows you to quickly run any Java application configuration with a selected file as a program argument. It's essentially a productivity tool that eliminates the need to manually edit run configurations when you want to pass a file path to your application.
]]></description>

    <depends>com.intellij.modules.platform</depends>
    <depends>com.intellij.modules.java</depends>

    <resource-bundle>messages.MyBundle</resource-bundle>

    <actions>
        <action id="RunWithFilePathAction" 
                class="com.github.gschrader.openinrunconfig.actions.RunWithFilePathAction"
                text="Project Application"
                description="Run with the selected file path as program argument">
            
            <add-to-group group-id="UsageView.Popup" anchor="last"/>
            <add-to-group group-id="RevealGroup" anchor="last"/>
        </action>
    </actions>
</idea-plugin>

```

--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------

```
# IntelliJ Platform Artifacts Repositories -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html

pluginGroup = com.github.gschrader.openinrunconfig
pluginName = open-in-run-config
pluginRepositoryUrl = https://github.com/gschrader/open-in-run-config-idea-plugin
# SemVer format -> https://semver.org
pluginVersion = 0.0.4

# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
pluginSinceBuild = 242
pluginUntilBuild = 252.*

# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension
platformType = IC
platformVersion = 2024.2.5

# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
# Example: platformPlugins = com.jetbrains.php:203.4449.22, org.intellij.scala:2023.3.27@EAP
platformPlugins =
# Example: platformBundledPlugins = com.intellij.java
platformBundledPlugins = com.intellij.java, org.jetbrains.kotlin

# Gradle Releases -> https://github.com/gradle/gradle/releases
gradleVersion = 8.13

# Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib
kotlin.stdlib.default.dependency = false

# Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html
org.gradle.configuration-cache = true

# Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html
org.gradle.caching = true

```

--------------------------------------------------------------------------------
/.github/workflows/run-ui-tests.yml:
--------------------------------------------------------------------------------

```yaml
# GitHub Actions Workflow for launching UI tests on Linux, Windows, and Mac in the following steps:
# - Prepare and launch IDE with your plugin and robot-server plugin, which is needed to interact with the UI.
# - Wait for IDE to start.
# - Run UI tests with a separate Gradle task.
#
# Please check https://github.com/JetBrains/intellij-ui-test-robot for information about UI tests with IntelliJ Platform.
#
# Workflow is triggered manually.

name: Run UI Tests
on:
  workflow_dispatch

jobs:

  testUI:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            runIde: |
              export DISPLAY=:99.0
              Xvfb -ac :99 -screen 0 1920x1080x16 &
              gradle runIdeForUiTests &
          - os: windows-latest
            runIde: start gradlew.bat runIdeForUiTests
          - os: macos-latest
            runIde: ./gradlew runIdeForUiTests &

    steps:

      # Check out the current repository
      - name: Fetch Sources
        uses: actions/checkout@v4

      # Set up Java environment for the next steps
      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: zulu
          java-version: 21

      # Setup Gradle
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4

      # Run IDEA prepared for UI testing
      - name: Run IDE
        run: ${{ matrix.runIde }}

      # Wait for IDEA to be started
      - name: Health Check
        uses: jtalk/url-health-check-action@v4
        with:
          url: http://127.0.0.1:8082
          max-attempts: 15
          retry-delay: 30s

      # Run tests
      - name: Tests
        run: ./gradlew test

```

--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------

```
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem      https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem

@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute

echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar


@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*

:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega

```

--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------

```yaml
# GitHub Actions Workflow created for handling the release process based on the draft release prepared with the Build workflow.
# Running the publishPlugin task requires all following secrets to be provided: PUBLISH_TOKEN, PRIVATE_KEY, PRIVATE_KEY_PASSWORD, CERTIFICATE_CHAIN.
# See https://plugins.jetbrains.com/docs/intellij/plugin-signing.html for more information.

name: Release
on:
  release:
    types: [prereleased, released]

jobs:

  # Prepare and publish the plugin to JetBrains Marketplace repository
  release:
    name: Publish Plugin
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:

      # Free GitHub Actions Environment Disk Space
      - name: Maximize Build Space
        # jlumbroso/[email protected]:
        uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
        with:
          tool-cache: false
          large-packages: false

      # Check out the current repository
      - name: Fetch Sources
        uses: actions/checkout@v4
        with:
          ref: ${{ github.event.release.tag_name }}

      # Set up Java environment for the next steps
      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: zulu
          java-version: 21

      # Setup Gradle
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4

      # Set environment variables
      - name: Export Properties
        id: properties
        shell: bash
        run: |
          CHANGELOG="$(cat << 'EOM' | sed -e 's/^[[:space:]]*$//g' -e '/./,$!d'
          ${{ github.event.release.body }}
          EOM
          )"
          
          echo "changelog<<EOF" >> $GITHUB_OUTPUT
          echo "$CHANGELOG" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      # Update the Unreleased section with the current release note
      - name: Patch Changelog
        if: ${{ steps.properties.outputs.changelog != '' }}
        env:
          CHANGELOG: ${{ steps.properties.outputs.changelog }}
        run: |
          ./gradlew patchChangelog --release-note="$CHANGELOG"

      # Publish the plugin to JetBrains Marketplace
      - name: Publish Plugin
        env:
          PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
          CERTIFICATE_CHAIN: ${{ secrets.CERTIFICATE_CHAIN }}
          PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
          PRIVATE_KEY_PASSWORD: ${{ secrets.PRIVATE_KEY_PASSWORD }}
        run: ./gradlew publishPlugin

      # Upload artifact as a release asset
      - name: Upload Release Asset
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: gh release upload ${{ github.event.release.tag_name }} ./build/distributions/*

      # Create a pull request
      - name: Create Pull Request
        if: ${{ steps.properties.outputs.changelog != '' }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          VERSION="${{ github.event.release.tag_name }}"
          BRANCH="changelog-update-$VERSION"
          LABEL="release changelog"

          git config user.email "[email protected]"
          git config user.name "GitHub Action"

          git checkout -b $BRANCH
          git commit -am "Changelog update - $VERSION"
          git push --set-upstream origin $BRANCH
          
          gh label create "$LABEL" \
            --description "Pull requests with release changelog update" \
            --force \
            || true

          gh pr create \
            --title "Changelog update - \`$VERSION\`" \
            --body "Current pull request contains patched \`CHANGELOG.md\` file for the \`$VERSION\` version." \
            --label "$LABEL" \
            --head $BRANCH

```

--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------

```kotlin
import org.jetbrains.changelog.Changelog
import org.jetbrains.changelog.markdownToHTML
import org.jetbrains.intellij.platform.gradle.TestFrameworkType

plugins {
    id("java") // Java support
    alias(libs.plugins.kotlin) // Kotlin support
    alias(libs.plugins.intelliJPlatform) // IntelliJ Platform Gradle Plugin
    alias(libs.plugins.changelog) // Gradle Changelog Plugin
    alias(libs.plugins.qodana) // Gradle Qodana Plugin
    alias(libs.plugins.kover) // Gradle Kover Plugin
}

group = providers.gradleProperty("pluginGroup").get()
version = providers.gradleProperty("pluginVersion").get()

// Set the JVM language level used to build the project.
kotlin {
    jvmToolchain(21)
}

// Configure project's dependencies
repositories {
    mavenCentral()

    // IntelliJ Platform Gradle Plugin Repositories Extension - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-repositories-extension.html
    intellijPlatform {
        defaultRepositories()
    }
}

// Dependencies are managed with Gradle version catalog - read more: https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog
dependencies {
    testImplementation(libs.junit)
    testImplementation(libs.opentest4j)

    // IntelliJ Platform Gradle Plugin Dependencies Extension - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html
    intellijPlatform {
        create(providers.gradleProperty("platformType"), providers.gradleProperty("platformVersion"))

        // Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
        bundledPlugins(providers.gradleProperty("platformBundledPlugins").map { it.split(',') })

        // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file for plugin from JetBrains Marketplace.
        plugins(providers.gradleProperty("platformPlugins").map { it.split(',') })

        testFramework(TestFrameworkType.Platform)
    }
}

// Configure IntelliJ Platform Gradle Plugin - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-extension.html
intellijPlatform {
    pluginConfiguration {
        name = providers.gradleProperty("pluginName")
        version = providers.gradleProperty("pluginVersion")

        // Extract the <!-- Plugin description --> section from README.md and provide for the plugin's manifest
        description = providers.fileContents(layout.projectDirectory.file("README.md")).asText.map {
            val start = "<!-- Plugin description -->"
            val end = "<!-- Plugin description end -->"

            with(it.lines()) {
                if (!containsAll(listOf(start, end))) {
                    throw GradleException("Plugin description section not found in README.md:\n$start ... $end")
                }
                subList(indexOf(start) + 1, indexOf(end)).joinToString("\n").let(::markdownToHTML)
            }
        }

        val changelog = project.changelog // local variable for configuration cache compatibility
        // Get the latest available change notes from the changelog file
        changeNotes = providers.gradleProperty("pluginVersion").map { pluginVersion ->
            with(changelog) {
                renderItem(
                    (getOrNull(pluginVersion) ?: getUnreleased())
                        .withHeader(false)
                        .withEmptySections(false),
                    Changelog.OutputType.HTML,
                )
            }
        }

        ideaVersion {
            sinceBuild = providers.gradleProperty("pluginSinceBuild")
            untilBuild = providers.gradleProperty("pluginUntilBuild")
        }
    }

    signing {
        certificateChain = providers.environmentVariable("CERTIFICATE_CHAIN")
        privateKey = providers.environmentVariable("PRIVATE_KEY")
        password = providers.environmentVariable("PRIVATE_KEY_PASSWORD")
    }

    publishing {
        token = providers.environmentVariable("PUBLISH_TOKEN")
        // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3
        // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more:
        // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel
        channels = providers.gradleProperty("pluginVersion").map { listOf(it.substringAfter('-', "").substringBefore('.').ifEmpty { "default" }) }
    }

    pluginVerification {
        ides {
            recommended()
        }
    }
}

// Configure Gradle Changelog Plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin
changelog {
    groups.empty()
    repositoryUrl = providers.gradleProperty("pluginRepositoryUrl")
}

// Configure Gradle Kover Plugin - read more: https://github.com/Kotlin/kotlinx-kover#configuration
kover {
    reports {
        total {
            xml {
                onCheck = true
            }
        }
    }
}

tasks {
    wrapper {
        gradleVersion = providers.gradleProperty("gradleVersion").get()
    }

    publishPlugin {
        dependsOn(patchChangelog)
    }
}

intellijPlatformTesting {
    runIde {
        register("runIdeForUiTests") {
            task {
                jvmArgumentProviders += CommandLineArgumentProvider {
                    listOf(
                        "-Drobot-server.port=8082",
                        "-Dide.mac.message.dialogs.as.sheets=false",
                        "-Djb.privacy.policy.text=<!--999.999-->",
                        "-Djb.consents.confirmation.enabled=false",
                    )
                }
            }

            plugins {
                robotServerPlugin()
            }
        }
    }
}

```

--------------------------------------------------------------------------------
/src/main/kotlin/com/github/gschrader/openinrunconfig/actions/RunWithFilePathAction.kt:
--------------------------------------------------------------------------------

```kotlin
package com.github.gschrader.openinrunconfig.actions

import com.github.gschrader.openinrunconfig.MyBundle
import com.intellij.execution.CommonProgramRunConfigurationParameters
import com.intellij.execution.ProgramRunnerUtil
import com.intellij.execution.RunManager
import com.intellij.execution.application.ApplicationConfiguration
import com.intellij.execution.configurations.RunConfiguration
import com.intellij.execution.executors.DefaultRunExecutor
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.ui.popup.PopupStep
import com.intellij.openapi.ui.popup.util.BaseListPopupStep
import com.intellij.openapi.vfs.VirtualFile
import javax.swing.Icon

class RunWithFilePathAction : AnAction() {

    override fun actionPerformed(e: AnActionEvent) {
        val project = e.project ?: return
        val virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE) ?: return
        
        val runManager = RunManager.getInstance(project)
        val allSettings = runManager.allSettings
        val configurations = allSettings
            .filter { (it.configuration.type.id == "Application" || it.configuration.type.id == "JetRunConfigurationType") && !it.isTemporary }
            .map { it.configuration }
        
        if (configurations.isEmpty()) {
            Messages.showInfoMessage(
                project, 
                MyBundle.message("noConfigurationsAvailable"),
                MyBundle.message("runWithFilePath")
            )
            return
        }
        
        val popup = JBPopupFactory.getInstance().createListPopup(
            ConfigurationListPopupStep(configurations, virtualFile, project)
        )
        
        popup.showInBestPositionFor(e.dataContext)
    }
    
    override fun update(e: AnActionEvent) {
        val project = e.project
        val virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE)
        
        // Enable action only if we have a project
        e.presentation.isEnabledAndVisible = project != null && virtualFile != null
    }
    
    override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
    
    private class ConfigurationListPopupStep(
        private val configurations: List<RunConfiguration>,
        private val virtualFile: VirtualFile,
        private val project: Project
    ) : BaseListPopupStep<RunConfiguration>(MyBundle.message("selectConfiguration"), configurations) {
        
        override fun getTextFor(value: RunConfiguration): String = value.name
        
        override fun getIconFor(value: RunConfiguration): Icon? = value.icon
        
        override fun onChosen(selectedValue: RunConfiguration, finalChoice: Boolean): PopupStep<*>? {
            if (finalChoice) {
                runConfigurationWithFilePath(selectedValue, virtualFile, project)
            }
            return PopupStep.FINAL_CHOICE
        }
        
        private fun runConfigurationWithFilePath(configuration: RunConfiguration, file: VirtualFile, project: Project) {
            val runManager = RunManager.getInstance(project)
            
            try {
                // Create a temporary copy of the configuration
                val factory = configuration.factory ?: run {
                    Messages.showErrorDialog(
                        project,
                        MyBundle.message("configurationNotSupported", configuration.name),
                        MyBundle.message("runWithFilePath")
                    )
                    return
                }
                
                val tempSettings = runManager.createConfiguration(
                    "${configuration.name} (with ${file.name})",
                    factory
                )
                
                val tempConfiguration = tempSettings.configuration
                
                // Copy settings from original configuration to temporary one
                copyConfigurationSettings(configuration, tempConfiguration)
                
                // Add the file path as a program argument to the temporary configuration
                val filePath = file.path
                val success = addProgramArgument(tempConfiguration, filePath)
                
                if (!success) {
                    Messages.showWarningDialog(
                        project,
                        MyBundle.message("configurationNotSupported", configuration.name),
                        MyBundle.message("runWithFilePath")
                    )
                    return
                }
                
                // Set the configuration as temporary
                tempSettings.isTemporary = true
                
                // Add the temporary configuration to the run manager so it persists
                runManager.addConfiguration(tempSettings)
                
                // Set it as the selected configuration
                runManager.selectedConfiguration = tempSettings
                
                // Execute the temporary configuration
                val executor = DefaultRunExecutor.getRunExecutorInstance()
                ProgramRunnerUtil.executeConfiguration(tempSettings, executor)
                
            } catch (e: Exception) {
                Messages.showErrorDialog(
                    project,
                    MyBundle.message("executionError", e.message ?: "Unknown error"),
                    MyBundle.message("runWithFilePath")
                )
            }
        }
        
        private fun copyConfigurationSettings(source: RunConfiguration, target: RunConfiguration) {
            if (source is ApplicationConfiguration && target is ApplicationConfiguration) {
                target.programParameters = source.programParameters
                target.workingDirectory = source.workingDirectory
                target.mainClassName = source.mainClassName
                target.envs = HashMap(source.envs)
                target.isPassParentEnvs = source.isPassParentEnvs
                target.configurationModule.module = source.configurationModule.module
            }
        }

        private fun addProgramArgument(configuration: RunConfiguration, argument: String): Boolean {
            if (configuration is CommonProgramRunConfigurationParameters) {
                val currentParams = configuration.programParameters
                val newParams = if (currentParams.isNullOrEmpty()) {
                    "\"$argument\""
                } else {
                    "$currentParams \"$argument\""
                }
                configuration.programParameters = newParams
                return true
            }
            return false
        }
    }
} 
```

--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------

```yaml
# GitHub Actions Workflow is created for testing and preparing the plugin release in the following steps:
# - Validate Gradle Wrapper.
# - Run 'test' and 'verifyPlugin' tasks.
# - Run Qodana inspections.
# - Run the 'buildPlugin' task and prepare artifact for further tests.
# - Run the 'runPluginVerifier' task.
# - Create a draft release.
#
# The workflow is triggered on push and pull_request events.
#
# GitHub Actions reference: https://help.github.com/en/actions
#
## JBIJPPTPL

name: Build
on:
  # Trigger the workflow on pushes to only the 'main' branch (this avoids duplicate checks being run e.g., for dependabot pull requests)
  push:
    branches: [ main ]
  # Trigger the workflow on any pull request
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
  
jobs:

  # Prepare environment and build the plugin
  build:
    name: Build
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.properties.outputs.version }}
      changelog: ${{ steps.properties.outputs.changelog }}
      pluginVerifierHomeDir: ${{ steps.properties.outputs.pluginVerifierHomeDir }}
    steps:

      # Free GitHub Actions Environment Disk Space
      - name: Maximize Build Space
        # jlumbroso/[email protected]:
        uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
        with:
          tool-cache: false
          large-packages: false

      # Check out the current repository
      - name: Fetch Sources
        uses: actions/checkout@v4

      # Set up Java environment for the next steps
      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: zulu
          java-version: 21

      # Setup Gradle
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4

      # Set environment variables
      - name: Export Properties
        id: properties
        shell: bash
        run: |
          PROPERTIES="$(./gradlew properties --console=plain -q)"
          VERSION="$(echo "$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')"
          CHANGELOG="$(./gradlew getChangelog --unreleased --no-header --console=plain -q)"

          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "pluginVerifierHomeDir=~/.pluginVerifier" >> $GITHUB_OUTPUT
          
          echo "changelog<<EOF" >> $GITHUB_OUTPUT
          echo "$CHANGELOG" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      # Build plugin
      - name: Build plugin
        run: ./gradlew buildPlugin

      # Prepare plugin archive content for creating artifact
      - name: Prepare Plugin Artifact
        id: artifact
        shell: bash
        run: |
          cd ${{ github.workspace }}/build/distributions
          FILENAME=`ls *.zip`
          unzip "$FILENAME" -d content

          echo "filename=${FILENAME:0:-4}" >> $GITHUB_OUTPUT

      # Store already-built plugin as an artifact for downloading
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ steps.artifact.outputs.filename }}
          path: ./build/distributions/content/*/*

  # Run tests and upload a code coverage report
  test:
    name: Test
    needs: [ build ]
    runs-on: ubuntu-latest
    steps:

      # Free GitHub Actions Environment Disk Space
      - name: Maximize Build Space
        uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
        with:
          tool-cache: false
          large-packages: false

      # Check out the current repository
      - name: Fetch Sources
        uses: actions/checkout@v4

      # Set up Java environment for the next steps
      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: zulu
          java-version: 21

      # Setup Gradle
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4

      # Run tests
      - name: Run Tests
        run: ./gradlew check

      # Collect Tests Result of failed tests
      - name: Collect Tests Result
        if: ${{ failure() }}
        uses: actions/upload-artifact@v4
        with:
          name: tests-result
          path: ${{ github.workspace }}/build/reports/tests

      # Upload the Kover report to CodeCov
      - name: Upload Code Coverage Report
        uses: codecov/codecov-action@v5
        with:
          files: ${{ github.workspace }}/build/reports/kover/report.xml

  # Run Qodana inspections and provide report
  inspectCode:
    name: Inspect code
    needs: [ build ]
    runs-on: ubuntu-latest
    permissions:
      contents: write
      checks: write
      pull-requests: write
    steps:

      # Free GitHub Actions Environment Disk Space
      - name: Maximize Build Space
        uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
        with:
          tool-cache: false
          large-packages: false

      # Check out the current repository
      - name: Fetch Sources
        uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}  # to check out the actual pull request commit, not the merge commit
          fetch-depth: 0  # a full history is required for pull request analysis

      # Set up Java environment for the next steps
      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: zulu
          java-version: 21

      # Run Qodana inspections
      - name: Qodana - Code Inspection
        uses: JetBrains/[email protected]
        with:
          cache-default-branch-only: true

  # Run plugin structure verification along with IntelliJ Plugin Verifier
  verify:
    name: Verify plugin
    needs: [ build ]
    runs-on: ubuntu-latest
    steps:

      # Free GitHub Actions Environment Disk Space
      - name: Maximize Build Space
        uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
        with:
          tool-cache: false
          large-packages: false

      # Check out the current repository
      - name: Fetch Sources
        uses: actions/checkout@v4

      # Set up Java environment for the next steps
      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: zulu
          java-version: 21

      # Setup Gradle
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4

      # Cache Plugin Verifier IDEs
      - name: Setup Plugin Verifier IDEs Cache
        uses: actions/cache@v4
        with:
          path: ${{ needs.build.outputs.pluginVerifierHomeDir }}/ides
          key: plugin-verifier-${{ hashFiles('build/listProductsReleases.txt') }}

      # Run Verify Plugin task and IntelliJ Plugin Verifier tool
      - name: Run Plugin Verification tasks
        run: ./gradlew verifyPlugin -Dplugin.verifier.home.dir=${{ needs.build.outputs.pluginVerifierHomeDir }}

      # Collect Plugin Verifier Result
      - name: Collect Plugin Verifier Result
        if: ${{ always() }}
        uses: actions/upload-artifact@v4
        with:
          name: pluginVerifier-result
          path: ${{ github.workspace }}/build/reports/pluginVerifier

  # Prepare a draft release for GitHub Releases page for the manual verification
  # If accepted and published, release workflow would be triggered
  releaseDraft:
    name: Release draft
    if: github.event_name != 'pull_request'
    needs: [ build, test, inspectCode, verify ]
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:

      # Check out the current repository
      - name: Fetch Sources
        uses: actions/checkout@v4

      # Remove old release drafts by using the curl request for the available releases with a draft flag
      - name: Remove Old Release Drafts
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh api repos/{owner}/{repo}/releases \
            --jq '.[] | select(.draft == true) | .id' \
            | xargs -I '{}' gh api -X DELETE repos/{owner}/{repo}/releases/{}

      # Create a new release draft which is not publicly visible and requires manual acceptance
      - name: Create Release Draft
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh release create "v${{ needs.build.outputs.version }}" \
            --draft \
            --title "v${{ needs.build.outputs.version }}" \
            --notes "$(cat << 'EOM'
          ${{ needs.build.outputs.changelog }}
          EOM
          )"

```