Args
Declarative CLI definition with options, subcommands, and help generation.
(import (sigil args))Defining Options
Options are records describing CLI flags and value parameters.
;; Boolean flag
(option name: 'verbose short: #\v long: "verbose"
description: "Enable verbose output")
;; Option with value and default
(option name: 'output short: #\o long: "output"
value: "FILE" default: "out.txt"
description: "Output file path")
;; Required option with parser
(option name: 'count long: "count"
value: "N" parse: string->number required: #t)
;; Environment variable fallback
(option name: 'token long: "token" value: "TOKEN"
env: "MY_APP_TOKEN")
;; Restricted choices
(option name: 'level long: "level" value: "LEVEL"
choices: '("debug" "info" "warn"))
;; Multi-value (repeatable)
(option name: 'include short: #\I long: "include"
value: "PATH" multi: #t)
;; Negatable flag (supports --no-color)
(option name: 'color long: "color" negatable: #t default: #t)Option fields: name: (symbol, required), short: (char), long: (string), description: (string), value: (string placeholder — omit for boolean flags), default:, required: (boolean), parse: (string converter), env: (env var name), choices: (list of valid strings), multi: (boolean), negatable: (boolean).
Defining Commands
Commands group options together with a handler or subcommands.
(command
name: "my-tool"
description: "A useful CLI tool"
options: (list
(option name: 'verbose short: #\v long: "verbose")
(option name: 'output short: #\o long: "output" value: "FILE"))
handler: (lambda (opts args)
(let ((verbose (alist-get 'verbose opts))
(output (alist-get 'output opts)))
(process-files args output verbose))))
;; With subcommands
(command
name: "my-tool"
subcommands: (list
(command name: "build" description: "Build project"
options: (list (option name: 'config short: #\c value: "NAME"))
handler: (lambda (opts args) ...))
(command name: "test" description: "Run tests"
handler: (lambda (opts args) ...))))Parsing Arguments
parse-args returns a parse-result record.
(let ((result (parse-args my-cmd '("-v" "--output" "out.txt" "file1" "file2"))))
(parse-result-opts result) ; => ((verbose . #t) (output . "out.txt"))
(parse-result-args result) ; => ("file1" "file2")
(parse-result-errors result) ; => () on success
(parse-result-subcommand result)) ; => matched command or #fSupported syntax:
-vshort flag,-vvvrepeated (counted),-vfcombined flags-o valueor-ovalueshort option with value--verboselong flag,--no-verbosenegated--output valueor--output=valuelong option with value--stops option parsing; everything after is positional
Running Commands
run-command parses arguments, handles errors, and dispatches to handlers. Automatically supports --help / -h.
(run-command my-cli (cdr (command-line)))- Prints help and exits 0 on
--help - Prints errors and exits 1 on parse failure
- Calls the handler with
(handler opts args) - Dispatches to subcommand handler when matched
Help Generation
;; Print help to stdout
(print-help my-cmd)
;; Get help as a string
(define help-text (generate-help my-cmd))Help output includes usage line, description, formatted options with defaults/choices/env vars, negatable syntax (--[no-]color), and subcommand list.
Common Patterns
Simple CLI Tool
(import (sigil args))
(define cli
(command
name: "greet"
description: "Print a greeting"
options: (list
(option name: 'name short: #\n long: "name"
value: "NAME" default: "World")
(option name: 'loud short: #\l long: "loud"
description: "Use uppercase"))
handler: (lambda (opts args)
(let ((greeting (format "Hello, ~a!" (alist-get 'name opts))))
(display (if (alist-get 'loud opts)
(string-upcase greeting)
greeting))
(newline)))))
(run-command cli (cdr (command-line)))Subcommand-Based Tool
(import (sigil args))
(define cli
(command
name: "todo"
description: "Task manager"
subcommands: (list
(command name: "add" description: "Add a task"
handler: (lambda (opts args)
(add-task (car args))))
(command name: "list" description: "List tasks"
options: (list
(option name: 'all short: #\a long: "all"
description: "Include completed"))
handler: (lambda (opts args)
(list-tasks all: (alist-get 'all opts)))))))
(run-command cli (cdr (command-line)))Option with Env Var Fallback
(option name: 'token long: "token" value: "TOKEN"
env: "API_TOKEN" required: #t
description: "API token (or set API_TOKEN)")
;; --token <val> takes priority, falls back to $API_TOKEN