diff --git a/jvm/main-kts/MainKts.md b/jvm/main-kts/MainKts.md new file mode 100644 index 0000000..2b7048f --- /dev/null +++ b/jvm/main-kts/MainKts.md @@ -0,0 +1,63 @@ + +# Kotlin Scripting Examples: `kotlin-main-kts` usages + +Scripts demonstrating the usage of the `kotlin-main-kts` script definition jar, distributied with the Kotlin compiler +and IntelliJ plugin. + +*See also [simplified implementation in this repository](../simple-main-kts/SimpleMainKts.md)* + +## Description + +The purpose of the `main-kts` is to allow writing simple but extendable utility scripts for the usage in the command +line, replacing the simple Kotlin programs with `main` function (hence the `main` in its name). + +### Usage + +For example a script (note that the file should have an extension corresponding to the script definition, in this case +`.smain.kts`): + +```kotlin +println("Hello, ${args[0]}") +``` + +could be executed with the command + +``` +kotlinc -cp script.main.kts +``` + +and starting from Kotlin version 1.3.70 it could even be used without explicit `kotlin-main-kts.jar` in the classpath, +provided that the compiler could find the required jars. In addition starting from 1.3.70 `kotlin` runner supports +scripts the same way as `kotlinc -script` combination: + +``` +kotlin script.main.kts +``` + +or even as simple as + +``` +./script.main.kts +``` + +provided that the shebang line is added to the script and works in the given OS shell. *(See examples below.)* + +### Caching + +The compiled scripts are cashed to the directory defined by an environmen variable `KOTLIN_MAIN_KTS_COMPILED_SCRIPTS_CACHE_DIR` +*(`$TEMP/main.kts.compiled.cache` by default)*, and if the script is not changed, the compiled one is executed from the cache. + +### IntelliJ support + +Starting from the Kotlin IntelliJ plugin version 1.3.70, the `.main.kts` scripts are supported automatically in the +IntelliJ IDEA, provided that they are placed outside of the regular source folders. E.g. if this project is imported into +the IntelliJ, the demo scripts in the [`scripts`](scripts) folders should be properly highlighted and support navigation, +including navigation into imported libraries. + +## Demo Scripts + +- [`kotlinx-html.main.kts`](scripts/kotlinx-html.main.kts) demonstrates usage of the +[`kotlinx-html` library](https://github.com/Kotlin/kotlinx.html) by JetBrains, to generate HTML output +- [`kotlin-shell.main.kts`](scripts/kotlin-shell.main.kts) demonstrates usage of the +[`kotlin-shell` library](https://github.com/jakubriegel/kotlin-shell) by Jakub Riegel, to execute OS shell commands +with easy interaction with Kotlin code diff --git a/jvm/main-kts/scripts/kotlin-shell.main.kts b/jvm/main-kts/scripts/kotlin-shell.main.kts new file mode 100755 index 0000000..a9452dc --- /dev/null +++ b/jvm/main-kts/scripts/kotlin-shell.main.kts @@ -0,0 +1,46 @@ +#!/usr/bin/env kotlin + +@file:Repository("https://dl.bintray.com/jakubriegel/kotlin-shell") +@file:DependsOn("eu.jrie.jetbrains:kotlin-shell-core:0.2.1") +@file:DependsOn("org.slf4j:slf4j-simple:1.7.28") +@file:CompilerOptions("-Xopt-in=kotlin.RequiresOptIn") +@file:OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class) + +import eu.jrie.jetbrains.kotlinshell.shell.* + +shell { + if (args.isEmpty()) { + "ls -l"() + } else { + var lines = 0 + var words = 0 + var chars = 0 + + var wasSpace = false + + pipeline { + "cat ${args[0]}".process() pipe + streamLambda { strm, _, _ -> + while (true) { + val byte = strm.read() + if (byte < 0) break + val ch = byte.toChar() + chars++ + if (ch == '\n') lines++ + val isSpace = ch == '\n' || ch == '\t' || ch == ' ' + if (!wasSpace && isSpace) { + wasSpace = true + } else if (wasSpace && !isSpace) { + words++ + wasSpace = false + } + } + } + } + + println("My wc:") + println("$lines $words $chars") + println("System wc:") + "wc ${args[0]}"() + } +} diff --git a/jvm/main-kts/scripts/kotlinx-html.main.kts b/jvm/main-kts/scripts/kotlinx-html.main.kts new file mode 100755 index 0000000..c4d069d --- /dev/null +++ b/jvm/main-kts/scripts/kotlinx-html.main.kts @@ -0,0 +1,15 @@ +#!/usr/bin/env kotlin + +@file:Repository("https://jcenter.bintray.com") +@file:DependsOn("org.jetbrains.kotlinx:kotlinx-html-jvm:0.6.11") + +import kotlinx.html.*; import kotlinx.html.stream.*; import kotlinx.html.attributes.* + +val addressee = args.firstOrNull() ?: "World" + +print(createHTML().html { + body { + h1 { +"Hello, $addressee!" } + } +}) +