diff --git a/README.md b/README.md index 94a08be20..3f19dc075 100755 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ class Hello : CliktCommand() { override fun run() { for (i in 1..count) { - TermUi.echo("Hello $name!") + echo("Hello $name!") } } } diff --git a/build.gradle b/build.gradle index dba6d03db..f53d3307a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.2.51' + ext.kotlin_version = '1.2.61' repositories { mavenCentral() @@ -30,8 +30,8 @@ subprojects { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" testImplementation 'junit:junit:4.12' - testImplementation 'io.kotlintest:kotlintest-assertions:3.1.7' - testImplementation 'com.github.stefanbirkner:system-rules:1.17.0' + testImplementation 'io.kotlintest:kotlintest-assertions:3.1.9' + testImplementation 'com.github.stefanbirkner:system-rules:1.18.0' testImplementation 'com.google.jimfs:jimfs:1.1' } diff --git a/docs/advanced.md b/docs/advanced.md index bcef037b2..584e7f162 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -29,7 +29,7 @@ class Repo : NoRunCliktCommand() { class Commit: CliktCommand() { val message by option("-m").default("") override fun run() { - TermUi.echo("Committing with message: $message") + echo("Committing with message: $message") } } @@ -75,13 +75,13 @@ class Tool : CliktCommand() { class Foo: CliktCommand() { override fun run() { - TermUi.echo("Running Foo") + echo("Running Foo") } } class Bar: CliktCommand() { override fun run() { - TermUi.echo("Running Bar") + echo("Running Bar") } } @@ -111,7 +111,7 @@ class Hello : CliktCommand() { } val name by option() - override fun run() = TermUi.echo("Hello $name!") + override fun run() = echo("Hello $name!") } ``` @@ -119,3 +119,38 @@ class Hello : CliktCommand() { $ ./hello --NAME=Foo Hello Foo! ``` + +## Replacing stdin and stdout + +By default, functions like [`CliktCommand.main`](api/clikt/com.github.ajalt.clikt.core/-clikt-command/main.html) +and [`option().prompt()`](api/clikt/com.github.ajalt.clikt.parameters.options/prompt.html) +read from `System.in` and write to `System.out`. If you want to use +clikt in an environment where the standard streams aren't available, you +can set your own implementation of [`CliktConsole`](api/clikt/com.github.ajalt.clikt.output/-clikt-console/index.html) +when [customizing the command context](commands.md#customizing-contexts). + +```kotlin +object MyConsole : CliktConsole { + override fun promptForLine(prompt: String, hideInput: Boolean): String? { + MyOutputStream.write(prompt) + return if (hideInput) MyInputStream.readPassword() + else MyInputStream.readLine() + } + + override fun print(text: String, error: Boolean) { + if (error) MyOutputStream.writeError(prompt) + else MyOutputStream.write(prompt) + } + + override val lineSeparator: String get() = "\n" +} + +class CustomCLI : CliktCommand() { + init { context { this.console = MyConsole } } + override fun run() {} +} +``` + +If you are using +[`TermUI`](api/clikt/com.github.ajalt.clikt.output/-term-ui/index.html) +directly, you can also pass your custom console as an argument. diff --git a/docs/arguments.md b/docs/arguments.md index 07ae9ce0c..3b7e05945 100644 --- a/docs/arguments.md +++ b/docs/arguments.md @@ -14,7 +14,7 @@ provided on the command line. class Hello : CliktCommand() { val name by argument() override fun run() { - TermUi.echo("Hello $name!") + echo("Hello $name!") } } ``` @@ -69,7 +69,7 @@ class Copy : CliktCommand() { val source by argument().file(exists = true).multiple() val dest by argument().file(fileOkay = false) override fun run() { - TermUi.echo("Copying files $source to $dest") + echo("Copying files $source to $dest") } } ``` @@ -98,7 +98,7 @@ class Touch : CliktCommand() { val verbose by option().flag() val files by argument().multiple() override fun run() { - if (verbose) TermUi.echo(files.joinToString("\n")) + if (verbose) echo(files.joinToString("\n")) } } ``` diff --git a/docs/commands.md b/docs/commands.md index 088863c37..43b0ddd0b 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -19,13 +19,13 @@ the help page is printed and `run` is not called. class Tool : CliktCommand() { val verbose by option().flag("--no-verbose") override fun run() { - TermUi.echo("Verbose mode is ${if (verbose) "on" else "off"}") + echo("Verbose mode is ${if (verbose) "on" else "off"}") } } class Execute : CliktCommand() { override fun run() { - TermUi.echo("executing") + echo("executing") } } @@ -66,7 +66,7 @@ class Tool : CliktCommand() { class Execute : CliktCommand(name = "RUN-ME") { override fun run() { - TermUi.echo("executing") + echo("executing") } } @@ -176,7 +176,7 @@ class Tool : CliktCommand() { class Execute : CliktCommand() { val config by requireObject>() override fun run() { - TermUi.echo("Verbose mode is ${config["VERBOSE"]}") + echo("Verbose mode is ${config["VERBOSE"]}") } } @@ -210,16 +210,16 @@ one. class Tool : CliktCommand(invokeWithoutSubcommand = true) { override fun run() { if (context.invokedSubcommand == null) { - TermUi.echo("invoked without a subcommand") + echo("invoked without a subcommand") } else { - TermUi.echo("about to run ${context.invokedSubcommand!!.commandName}") + echo("about to run ${context.invokedSubcommand!!.commandName}") } } } class Execute : CliktCommand() { override fun run() { - TermUi.echo("running subcommand") + echo("running subcommand") } } diff --git a/docs/documenting.md b/docs/documenting.md index f0ef564b8..b061d7966 100644 --- a/docs/documenting.md +++ b/docs/documenting.md @@ -21,7 +21,7 @@ class Hello : CliktCommand(help = """ val count by option("-c", "--count", help = "number of greetings").int().default(1) val name by argument() - override fun run() = repeat(count) { TermUi.echo("Hello $name!") } + override fun run() = repeat(count) { echo("Hello $name!") } } ``` diff --git a/docs/index.md b/docs/index.md index cd1563e02..d9dd8e784 100755 --- a/docs/index.md +++ b/docs/index.md @@ -1,3 +1,7 @@ +--- +title: 'Clikt: Simple, powerful command line parser for Kotlin' +--- +
wordmark
@@ -27,7 +31,7 @@ class Hello : CliktCommand() { override fun run() { for (i in 1..count) { - TermUi.echo("Hello $name!") + echo("Hello $name!") } } } diff --git a/docs/options.md b/docs/options.md index b4d5e9c6d..2de84b55d 100644 --- a/docs/options.md +++ b/docs/options.md @@ -13,7 +13,7 @@ will return the value of the last occurrence of the option. class Hello: CliktCommand() { val name by option(help="your name") override fun run() { - TermUi.echo("Hello, $name!") + echo("Hello, $name!") } } ``` @@ -38,7 +38,7 @@ You can also specify any number of names for an option manually: class Hello: CliktCommand() { val name by option("-n", "--name", help="your name") override fun run() { - TermUi.echo("Hello, $name!") + echo("Hello, $name!") } } ``` @@ -121,7 +121,7 @@ on the command line. You can instead return a default value with [`default`](api class Pow : CliktCommand() { val exp by option("-e", "--exp").double().default(1.0) override fun run() { - TermUi.echo("2 ^ $exp = ${Math.pow(2.0, exp)}") + echo("2 ^ $exp = ${Math.pow(2.0, exp)}") } } ``` @@ -167,9 +167,9 @@ class Geometry : CliktCommand() { val cube by option().int().triple() val tesseract by option().int().transformValues(4) { Quad(it[0], it[1], it[2], it[3]) } override fun run() { - TermUi.echo("Square has dimensions ${square?.toList()?.joinToString("x")}") - TermUi.echo("Cube has dimensions ${cube?.toList()?.joinToString("x")}") - TermUi.echo("Tesseract has dimensions ${tesseract?.toList()?.joinToString("x")}") + echo("Square has dimensions ${square?.toList()?.joinToString("x")}") + echo("Cube has dimensions ${cube?.toList()?.joinToString("x")}") + echo("Tesseract has dimensions ${tesseract?.toList()?.joinToString("x")}") } } ``` @@ -199,7 +199,7 @@ list will be empty (or you can specify a list to use). class Commit : CliktCommand() { val message by option("-m").multiple() override fun run() { - TermUi.echo(message.joinToString("\n")) + echo(message.joinToString("\n")) } } ``` @@ -235,7 +235,7 @@ previously. class Cli : CliktCommand() { val flag by option("--on", "-o").flag("--off", "-O", default = false) override fun run() { - TermUi.echo(flag) + echo(flag) } } ``` @@ -262,7 +262,7 @@ class Cli : CliktCommand() { val flagB by option("-b").flag() val foo by option("-f") override fun run() { - TermUi.echo("$flagA $flagB $foo") + echo("$flagA $flagB $foo") } } ``` @@ -284,7 +284,7 @@ on the command line. You can use [`counted`](api/clikt/com.github.ajalt.clikt.pa class Log : CliktCommand() { val verbosity by option("-v").counted() override fun run() { - TermUi.echo("Verbosity level: $verbosity") + echo("Verbosity level: $verbosity") } } ``` @@ -306,7 +306,7 @@ the names in the map replace any previously specified or inferred names. class Size : CliktCommand() { val size by option().switch("--large" to "large", "--small" to "small").default("unknown") override fun run() { - TermUi.echo("You picked size $size") + echo("You picked size $size") } } ``` @@ -327,7 +327,7 @@ values using [`choice`](api/clikt/com.github.ajalt.clikt.parameters.types/choice class Digest : CliktCommand() { val hash by option().choice("md5", "sha1") override fun run() { - TermUi.echo(hash) + echo(hash) } } ``` @@ -365,7 +365,7 @@ if one is not provided. Clikt can take care of this for you with the [`prompt`]( class Hello : CliktCommand() { val name by option().prompt() override fun run() { - TermUi.echo("Hello $name") + echo("Hello $name") } } ``` @@ -396,7 +396,7 @@ passwords. class Login : CliktCommand() { val password by option().prompt(requireConfirmation = true, hideInput = true) override fun run() { - TermUi.echo("Your hidden password: $password") + echo("Your hidden password: $password") } } ``` @@ -491,7 +491,7 @@ To set the envvar name manually, pass the name to [`option`](api/clikt/com.githu class Hello : CliktCommand() { val name by option(envvar = "MY_NAME") override fun run() { - TermUi.echo("Hello $name") + echo("Hello $name") } } ``` @@ -524,7 +524,7 @@ class Hello : CliktCommand() { } val name by option() override fun run() { - TermUi.echo("Hello $name") + echo("Hello $name") } } ``` @@ -552,7 +552,7 @@ colons (`:`). class Hello : CliktCommand() { val names by option(envvar = "NAMES").multiple() override fun run() { - for (name in names) TermUi.echo("Hello $name") + for (name in names) echo("Hello $name") } } ``` @@ -577,7 +577,7 @@ For example, you can make a Windows-style interface with slashes: class Hello: CliktCommand() { val name by option("/name", help="your name") override fun run() { - TermUi.echo("Hello, $name!") + echo("Hello, $name!") } } ``` @@ -596,7 +596,7 @@ options: class Hello: CliktCommand() { val name by option("-name", help="your name") override fun run() { - TermUi.echo("Hello, $name!") + echo("Hello, $name!") } } ``` diff --git a/docs/parameters.md b/docs/parameters.md index 8920a8716..b2305f08e 100644 --- a/docs/parameters.md +++ b/docs/parameters.md @@ -129,7 +129,7 @@ For example, you can create an option of type `BigDecimal` like this: ```kotlin class Cli: CliktCommand() { val opt by option().convert { it.toBigDecimal() } - override fun run() = TermUi.echo("opt=$opt") + override fun run() = echo("opt=$opt") } ``` @@ -154,7 +154,7 @@ class Cli: CliktCommand() { val opt by option(help="a real number").convert("FLOAT") { it.toBigDecimalOrNull() ?: fail("A real number is required") } - override fun run() = TermUi.echo("opt=$opt") + override fun run() = echo("opt=$opt") } ``` diff --git a/docs/quickstart.md b/docs/quickstart.md index f4f7e9e2c..1a6964a5f 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -14,7 +14,7 @@ The simplest command with no parameters would look like this: ```kotlin class Hello: CliktCommand() { override fun run() { - TermUi.echo("Hello World!") + echo("Hello World!") } } @@ -40,7 +40,7 @@ Options: ## Printing to Stdout and Stderr -Why does this example use [TermUi.echo](api/clikt/com.github.ajalt.clikt.output/-term-ui/echo.html) instead of +Why does this example use [echo](api/clikt/com.github.ajalt.clikt.core/-clikt-command/echo.html) instead of [println](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/println.html)? Although `println` works, it can cause problems with multi-platform support. [echo](api/clikt/com.github.ajalt.clikt.output/-term-ui/echo.html) automatically translates line breaks into the line @@ -62,13 +62,13 @@ class Database: CliktCommand() { class Init: CliktCommand(help="Initialize the database") { override fun run() { - TermUi.echo("Initialized the database.") + echo("Initialized the database.") } } class Drop: CliktCommand(help="Drop the database") { override fun run() { - TermUi.echo("Dropped the database.") + echo("Dropped the database.") } } @@ -110,7 +110,7 @@ class Hello : CliktCommand() { override fun run() { for (i in 1..count) { - TermUi.echo("Hello $name!") + echo("Hello $name!") } } } diff --git a/mkdocs.yml b/mkdocs.yml index 5a69b72fc..fc57a4cff 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -84,6 +84,7 @@ nav: - 'Advanced Patterns': - 'Command Aliases': advanced.md - 'Token Normalization': advanced/#token-normalization + - 'Replacing stdin and stdout': advanced/#replacing-stdin-and-stdout - 'Utilities': - 'Launching Editors': utilities.md - 'Input Prompts': utilities/#input-prompts