I have a simple IntelliJ IDEA kotlin project with standard directory layout, i.e.:
src/
main/
kotlin/
ClassA.kts
ClassB.kts
resources/
test/
kotlin/
TestClassA.kts
TestClassB.kts
In this project I want to use kotlin scripts (.kts files) and I want to use IntelliJ to edit and execute these scripts.
Inside the scripts I need to use classes, functions etc. defined in main
, like ClassA
(using stuff from test
would also be nice). To aid in writing the scripts, I would like to get code completion and other coding assistance from IntelliJ.
Questions:
.kts
files?I use IntelliJ IDEA 2022.3.1 / kotlin plugin 223-1.7.21-release-272-IJ8214.52.
See also the IntelliJ issue tracker: https://youtrack.jetbrains.com/issue/KT-55833/Kotlin-scripting-should-have-more-documentation-and-it-should-be-easier-to-execute-scripts-from-the-command-line
The point of .main.kts
is that it's simple and doesn't require a build system. So depending on a project which is built with Maven/Gradle/Bazel is only possible through dependencies.
"IntelliJ IDEA kotlin project" sounds like you might not even have a build system which pretty much rules out running from command line, even if direct linking was possible. In the next sections I'll assume Gradle, because that's what I'm familiar with, but equivalents could work otherwise in other systems.
Before I go down the rabbit hole, I would like to call XYProblem, just because you might not need a .kts, a simple main.kt
with fun main()
could work as well. And then running with java -jar
on the resulting app or gradlew :module:run --args "..."
would just work normally without any special treatment. Oddly enough just today I read this article which describes in detail how to make a small easily-runnable Kotlin app.
One option is that you use @file:Import
, but I haven't gotten it to work, and it seems others neither.
<rabbithole>
So the only workable idea I have for this is that you have your library publish a jar to local repository (Gradle mavenLocal()
) or import from a local build folder (flatDir or with maven { url = file://
). Note that these are Gradle APIs, which means that Gradle can publish to these in some way.
At this point we have a .jar file of your library in src/main/kotlin
on the local file system. .main.kts
files can import JARs from Maven repositories (example). If you're lucky this built-in @file:Repository
also supports local file://
URIs, so it "just works".
Note: location of .main.kts
files don't matter, only their file name, which makes a huge difference.
The developer experience with this solution would be:
src/main/kotlin
src/test/kotlin
app.main.kts
after build</rabbithole>
, notice that the above is pretty much the same as having a main.kt
file in your app, with the difference that main.kt
is fully supported and you can do things like pre-compilation, minification, packaging.
You can find some .main.kts
examples here: https://github.com/TWiStErRob/TWiStErRob-env/search?q=filename%3Amain.kts, but they're not using local code, all single-file only with mavenCentral()
dependencies.