scalaintermediate
Command-Line Application
Build CLI applications with argument parsing, interactive prompts, and formatted output.
scalaPress ⌘/Ctrl + Shift + C to copy
import scala.io.StdIn
import scala.util.{Try, Success, Failure}
// Simple argument parser
case class Args(
command: String = "help",
flags: Map[String, String] = Map.empty,
positional: List[String] = Nil
)
object ArgParser:
def parse(args: Array[String]): Args =
if args.isEmpty then return Args()
val cmd = args.head
val rest = args.tail.toList
val (flags, positional) = parseFlags(rest)
Args(cmd, flags, positional)
private def parseFlags(args: List[String]): (Map[String, String], List[String]) =
val flags = scala.collection.mutable.Map.empty[String, String]
val pos = scala.collection.mutable.ListBuffer.empty[String]
var i = 0
val arr = args.toArray
while i < arr.length do
arr(i) match
case s if s.startsWith("--") && s.contains("=") =>
val Array(key, value) = s.drop(2).split("=", 2)
flags(key) = value
case s if s.startsWith("--") && i + 1 < arr.length =>
flags(s.drop(2)) = arr(i + 1)
i += 1
case s if s.startsWith("-") && s.length == 2 && i + 1 < arr.length =>
flags(s.drop(1)) = arr(i + 1)
i += 1
case s =>
pos += s
i += 1
(flags.toMap, pos.toList)
// REPL-style interactive app
object TodoApp:
private var todos = Vector.empty[String]
def run(): Unit =
println("Todo App — type 'help' for commands")
var running = true
while running do
print("> ")
val input = Option(StdIn.readLine()).getOrElse("quit")
input.trim.split("\\s+", 2).toList match
case "add" :: text :: Nil =>
todos = todos :+ text
println(s" Added: $text")
case "list" :: Nil =>
if todos.isEmpty then println(" No todos")
else todos.zipWithIndex.foreach { (todo, i) =>
println(f" ${i + 1}%3d. $todo")
}
case "done" :: num :: Nil =>
Try(num.toInt - 1) match
case Success(idx) if idx >= 0 && idx < todos.size =>
val removed = todos(idx)
todos = todos.patch(idx, Nil, 1)
println(s" Done: $removed")
case _ => println(s" Invalid number: $num")
case "clear" :: Nil =>
todos = Vector.empty
println(" Cleared all todos")
case "help" :: Nil =>
println(" Commands:")
println(" add <text> — Add a todo")
println(" list — List all todos")
println(" done <n> — Mark todo n as done")
println(" clear — Remove all todos")
println(" quit — Exit")
case "quit" :: Nil | "exit" :: Nil =>
running = false
println(" Bye!")
case cmd :: _ =>
println(s" Unknown: $cmd (try 'help')")
case Nil => ()
// Progress bar
def progressBar(current: Int, total: Int, width: Int = 40): String =
val pct = current.toDouble / total
val filled = (pct * width).toInt
val bar = "█" * filled + "░" * (width - filled)
f"[$bar] ${pct * 100}%5.1f%% ($current/$total)"
// Table formatter
def printTable(headers: List[String], rows: List[List[String]]): Unit =
val widths = headers.indices.map { i =>
(headers(i).length :: rows.map(r => r.lift(i).map(_.length).getOrElse(0))).max
}.toList
def formatRow(row: List[String]): String =
row.zip(widths).map((s, w) => s.padTo(w, ' ')).mkString(" | ")
val sep = widths.map("-" * _).mkString("-+-")
println(formatRow(headers))
println(sep)
rows.foreach(r => println(formatRow(r)))
@main def demo(args: String*): Unit =
// Arg parsing demo
val parsed = ArgParser.parse(args.toArray)
println(s"Command: ${parsed.command}")
println(s"Flags: ${parsed.flags}")
println(s"Args: ${parsed.positional}")
// Progress bar
println()
for i <- 0 to 10 do
print(s"\r${progressBar(i * 10, 100)}")
println()
// Table
println()
printTable(
List("Name", "Age", "City"),
List(
List("Alice", "30", "New York"),
List("Bob", "25", "San Francisco"),
List("Carol", "35", "London")
)
)Use Cases
- Command-line tool development
- Interactive REPL applications
- Formatted terminal output
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
pythonbeginner
CLI Tool with argparse
Build a professional CLI tool with subcommands, typed arguments, environment variable fallbacks, and help text.
Best for: Developer tooling
#cli#argparse
pythonintermediate
Click CLI Command Group
Build professional CLI tools with Click using command groups, options, arguments, and help text.
Best for: Developer tools
#cli#click
javaintermediate
CLI Argument Parser
Parse command-line arguments with flags, options, positional args, and help text without external libraries.
Best for: Command-line tool argument parsing
#java#cli
scalabeginner
Scala Hello World Application
Create a basic Scala application with main method, string interpolation, and val/var basics.
Best for: Getting started with Scala
#scala#basics