AtlatestRepositorysigil-args
1# Args
2
3> Declarative CLI definition with options, subcommands, and help generation.
4
5```scheme
6(import (sigil args))
7```
8
9## Defining Options
11Options are records describing CLI flags and value parameters.
13```scheme
14;; Boolean flag
15(option name: 'verbose short: #\v long: "verbose"
16 description: "Enable verbose output")
18;; Option with value and default
19(option name: 'output short: #\o long: "output"
20 value: "FILE" default: "out.txt"
21 description: "Output file path")
23;; Required option with parser
24(option name: 'count long: "count"
25 value: "N" parse: string->number required: #t)
27;; Environment variable fallback
28(option name: 'token long: "token" value: "TOKEN"
29 env: "MY_APP_TOKEN")
31;; Restricted choices
32(option name: 'level long: "level" value: "LEVEL"
33 choices: '("debug" "info" "warn"))
35;; Multi-value (repeatable)
36(option name: 'include short: #\I long: "include"
37 value: "PATH" multi: #t)
39;; Negatable flag (supports --no-color)
40(option name: 'color long: "color" negatable: #t default: #t)
41```
43Option 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).
45## Defining Commands
47Commands group options together with a handler or subcommands.
49```scheme
50(command
51 name: "my-tool"
52 description: "A useful CLI tool"
53 options: (list
54 (option name: 'verbose short: #\v long: "verbose")
55 (option name: 'output short: #\o long: "output" value: "FILE"))
56 handler: (lambda (opts args)
57 (let ((verbose (alist-get 'verbose opts))
58 (output (alist-get 'output opts)))
59 (process-files args output verbose))))
61;; With subcommands
62(command
63 name: "my-tool"
64 subcommands: (list
65 (command name: "build" description: "Build project"
66 options: (list (option name: 'config short: #\c value: "NAME"))
67 handler: (lambda (opts args) ...))
68 (command name: "test" description: "Run tests"
69 handler: (lambda (opts args) ...))))
70```
72## Parsing Arguments
74`parse-args` returns a `parse-result` record.
76```scheme
77(let ((result (parse-args my-cmd '("-v" "--output" "out.txt" "file1" "file2"))))
78 (parse-result-opts result) ; => ((verbose . #t) (output . "out.txt"))
79 (parse-result-args result) ; => ("file1" "file2")
80 (parse-result-errors result) ; => () on success
81 (parse-result-subcommand result)) ; => matched command or #f
82```
84Supported syntax:
85- `-v` short flag, `-vvv` repeated (counted), `-vf` combined flags
86- `-o value` or `-ovalue` short option with value
87- `--verbose` long flag, `--no-verbose` negated
88- `--output value` or `--output=value` long option with value
89- `--` stops option parsing; everything after is positional
91## Running Commands
93`run-command` parses arguments, handles errors, and dispatches to handlers. Automatically supports `--help` / `-h`.
95```scheme
96(run-command my-cli (cdr (command-line)))
97```
99- Prints help and exits 0 on `--help`
100- Prints errors and exits 1 on parse failure
101- Calls the handler with `(handler opts args)`
102- Dispatches to subcommand handler when matched
104## Help Generation
106```scheme
107;; Print help to stdout
108(print-help my-cmd)
110;; Get help as a string
111(define help-text (generate-help my-cmd))
112```
114Help output includes usage line, description, formatted options with defaults/choices/env vars, negatable syntax (`--[no-]color`), and subcommand list.
116## Common Patterns
118### Simple CLI Tool
120```scheme
121(import (sigil args))
123(define cli
124 (command
125 name: "greet"
126 description: "Print a greeting"
127 options: (list
128 (option name: 'name short: #\n long: "name"
129 value: "NAME" default: "World")
130 (option name: 'loud short: #\l long: "loud"
131 description: "Use uppercase"))
132 handler: (lambda (opts args)
133 (let ((greeting (format "Hello, ~a!" (alist-get 'name opts))))
134 (display (if (alist-get 'loud opts)
135 (string-upcase greeting)
136 greeting))
137 (newline)))))
139(run-command cli (cdr (command-line)))
140```
142### Subcommand-Based Tool
144```scheme
145(import (sigil args))
147(define cli
148 (command
149 name: "todo"
150 description: "Task manager"
151 subcommands: (list
152 (command name: "add" description: "Add a task"
153 handler: (lambda (opts args)
154 (add-task (car args))))
155 (command name: "list" description: "List tasks"
156 options: (list
157 (option name: 'all short: #\a long: "all"
158 description: "Include completed"))
159 handler: (lambda (opts args)
160 (list-tasks all: (alist-get 'all opts)))))))
162(run-command cli (cdr (command-line)))
163```
165### Option with Env Var Fallback
167```scheme
168(option name: 'token long: "token" value: "TOKEN"
169 env: "API_TOKEN" required: #t
170 description: "API token (or set API_TOKEN)")
171;; --token <val> takes priority, falls back to $API_TOKEN
172```