sigildocs

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 #f

Supported syntax:

  • -v short flag, -vvv repeated (counted), -vf combined flags
  • -o value or -ovalue short option with value
  • --verbose long flag, --no-verbose negated
  • --output value or --output=value long 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