Examples
Prompt
This example shows a simple UI you can easily build with Terminus. This is the kind of thing you might create for a command line tool. Make sure the emulated terminal has focus (i.e. click in the black rectangle) and then use up and down arrows to select an option. Reload the page to start again.
Here's the code for this example, running on the JVM backend. (The JS code is slightly different due to differences in how input is handled.)
import terminus.effect.Eof
enum KeyCode {
case Down
case Up
case Enter
}
// Clear the text we've written
def clear(): Program[Unit] = {
Terminal.cursor.move(1, -4)
Terminal.erase.down()
Terminal.cursor.column(1)
}
// Write an option the user can choose. The currently selected option is highlighted.
def writeChoice(description: String, selected: Boolean): Program[Unit] =
if selected then
Terminal.display.bold(Terminal.write(s"> ${description}\r\n"))
else Terminal.write(s" ${description}\r\n")
// Write the UI
def write(selected: Int): Program[Unit] = {
Terminal.write("How cool is this?\r\n")
writeChoice("Very cool", selected == 0)
writeChoice("Way cool", selected == 1)
writeChoice("So cool", selected == 2)
Terminal.flush()
}
def read(): Program[KeyCode] = {
Terminal.read() match {
case Eof =>
throw new Exception("Received an EOF")
case char: Char =>
char match {
case 10 | 13 => KeyCode.Enter
case '\u001b' =>
Terminal.read() match {
// Normal mode
case '[' =>
Terminal.read() match {
case 'A' => KeyCode.Up
case 'B' => KeyCode.Down
case other => read()
}
// Application mode
case 'O' =>
Terminal.read() match {
case 'A' => KeyCode.Up
case 'B' => KeyCode.Down
case other => read()
}
case other => read()
}
case other => read()
}
}
}
def loop(idx: Int): Program[Int] = {
write(idx)
read() match {
case KeyCode.Up =>
clear()
loop(if idx == 0 then 2 else idx - 1)
case KeyCode.Down =>
clear()
loop(if idx == 2 then 0 else idx + 1)
case KeyCode.Enter => idx
}
}
@main def prompt(): Unit = {
val idx =
Terminal.run(
Terminal.raw { loop(0) }
)
println(s"Selected $idx")
}