sigildocs

(sigil args)

(sigil args) - Command-Line Argument Parsing

Declarative CLI definition with options, subcommands, and help generation. Uses records for clean, composable command structures.

Quick Start

(import (sigil args))

(define my-cli
  (command
    name: "my-tool"
    description: "My awesome tool"
    options: (list
               (option name: 'verbose short: #\v long: "verbose"
                       description: "Enable verbose output")
               (option name: 'output short: #\o long: "output"
                       value: "FILE" default: "out.txt"))
    handler: (lambda (opts args)
               (let ((verbose (alist-get 'verbose opts))
                     (output (alist-get 'output opts)))
                 (process-files args output verbose)))))

(run-command my-cli (cdr (command-line)))

Subcommands

(define build-cmd
  (command name: "build" description: "Build project"
    handler: (lambda (opts args) ...)))

(define my-cli
  (command name: "my-tool"
    subcommands: (list build-cmd test-cmd)))

Advanced Features

;; Negatable flags: --verbose or --no-verbose
(option name: 'verbose long: "verbose" negatable: #t)

;; Environment variable fallback
(option name: 'token long: "token" value: "TOKEN" env: "MY_APP_TOKEN")

;; Choice validation
(option name: 'level long: "level" value: "LEVEL"
        choices: '("debug" "info" "warn" "error"))

;; Multi-value (repeatable) options
(option name: 'include short: #\I long: "include" value: "PATH" multi: #t)
;; -I foo -I bar => ((include . ("foo" "bar")))

Supported Syntax

-v              Short flag
-vvv            Repeated short flags (counted)
-o value        Short option with value
--verbose       Long flag
--no-verbose    Negated flag (if negatable: #t)
--output=value  Long option with =
--output value  Long option with space
--              Stop option parsing

Exports

optionprocedure

A command-line option definition for flags or value options.

(option (name 'verbose) (short #\v) (long "verbose")
        (description "Enable verbose output"))
(option (name 'output) (short #\o) (long "output")
        (value "FILE") (default "out.txt"))
option?procedure

Test if a value is a option struct.

option-nameprocedure

Symbol used as key in parsed options alist.

option-shortprocedure

Single character for short form (e.g., #\v for -v), or #f.

option-longprocedure

String for long form (e.g., "verbose" for --verbose), or #f.

Help text displayed in usage output.

option-valueprocedure

Value placeholder string (e.g., "FILE"), or #f for boolean flags.

Default value if option not provided.

If #t, option must be provided or parsing fails.

option-parseprocedure

Function to parse string value (e.g., string->number), or #f.

option-envprocedure

Environment variable name to use as fallback (e.g., "MY_APP_OUTPUT").

List of valid choices for validation (e.g., '("debug" "info" "warn")).

option-multiprocedure

If #t, option can be repeated and values accumulate into a list.

If #t, flag supports --no-X form to set value to #f.

If #t, flag supports --no-X form to set value to #f.

commandprocedure

A CLI command or subcommand definition.

(command
  (name "build")
  (description "Build the project")
  (options
    (option (name 'config) (short #\c) (value "NAME")))
  (handler (lambda (opts args) (run-build opts))))
command?procedure

Test if a value is a command struct.

command-nameprocedure

Command name string shown in help and used for matching.

Help text describing what this command does.

List of option records for this command.

Handler procedure (lambda (opts args) ...) called when command runs.

List of command records for nested subcommands.

List of command records for nested subcommands.

parse-resultprocedure

The result of parsing command-line arguments.

Check errors to determine if parsing succeeded. If empty, opts contains the parsed option values and args contains positional arguments.

parse-result?procedure

Test if a value is a parse-result struct.

Parsed options as ((name . value) ...) alist.

Positional arguments as a list of strings.

Error messages as a list of strings. Empty if parsing succeeded.

Matched subcommand command record, or #f if none.

Find a subcommand by name from a list of commands.

Returns the matching command record, or #f if not found.

(find-subcommand (command-subcommands cli) "build")
; => <command> record for "build" or #f
parse-argsprocedure

Parse command-line arguments according to a command spec.

Returns a <parse-result> record with parsed options, positional arguments, any errors, and the matched subcommand (if any).

(let ((result (parse-args my-cmd '("-v" "--output" "file.txt" "arg1"))))
  (parse-result-opts result)  ; => ((verbose . #t) (output . "file.txt"))
  (parse-result-args result)) ; => ("arg1")

Main parsing loop options - List of option specs to match against subcommands - List of subcommand specs argv - Remaining arguments to parse opts - Accumulated options alist args - Accumulated positional args errors - Accumulated errors stop? - #t if -- was seen (stop parsing options) subcmd - Matched subcommand (or #f)

Parse a long option: --name or --name=value or --no-name

Parse short option(s): -v, -vvv, -o value

Parse individual characters in short option string

Validate value against choices if specified

get-env-valueprocedure

Get value from environment variable if available

Finalize parsing: apply env fallback, defaults, check required, validate choices

generate-helpprocedure

Generate help text for a command.

Returns a formatted help string including usage, description, options, and subcommands.

(display (generate-help my-cmd))
run-commandprocedure

Parse arguments and run the appropriate command handler.

Handles parsing, error display, automatic --help/-h support, subcommand dispatch, and exit status.

(run-command my-cli (cdr (command-line)))

(No description)

(No description)