/imperative-command-line-a

A simple imperative-style command-line parser

Primary LanguageScheme

[[toc:]]

== Description

This is the command-line parser from Mowedline, now an independent
project.  It is a simple imperative-style command-line parser, and the
"-a" suffix on its name is there to suggest that this module represents
only one of many possible imperative-style command-line frameworks.

An "imperative" command-line style is one in which the command-line
arguments represent procedures and parameters, to be called in
left-to-right order, a kind of DSL, or mini-language.  Contrast this style
with other command-line styles where the options represent simple flags,
and order is not significant.  In an imperative-style command-line, the
options represent ''actions'' to take in the order given.

There are times though, when strict left-to-right order is not desired,
and to support these situations, imperative-command-line-a supports
''command groups''.  If you want to take certain options out of the
overall ordering, you use groups.  When the command-line is processed,
commands from different command groups are first parsed into separate
lists.  Then the commands in these lists are called, in the order of their
respective command groups in the {{(groups)}} parameter.  Command groups
are notably used to support "-help" and "-version" options, which may
appear anywhere in the command-line (barring positional errors).  A
command group could also be used to support order-independent flag options
that need to run before the imperative "actions".

Imperative-command-line-a provides one pre-made command-group,
{{special-options}}, which defines the commands "help" and "version".
These command line options are automatically available in your program,
unless you override them (for which see {{groups}} below).  The output of
these commands is configured in part by the parameters {{help-heading}}
and {{help-minimum-intercolumn-space}}.

Each defined command-line option takes a certain number of positional
parameters.  Your commands are not limited to a single parameter, but
variable numbers of parameters are not yet supported.  Since the
distinction between command and parameter is purely positional, the
conventional leading hyphens on option names are purely stylistic and may
be omitted.

This module has room to grow.  The initial set of features are those that
meet the requirements of Mowedline, but now that this is a separate
project, new uses and needs will undoubtedly arise, and future versions of
this egg will be more powerful, flexible, and easier to use.


== Authors

* John J Foerch


== Requirements

* [[miscmacros]]


== API

Any program that uses imperative-command-line-a will define at least one
command group.  Typically, you will use {{define-command-group}} to do
this.

<syntax>(define-command-group name command-def ...)</syntax>
<syntax>(define-command-group name #:title title command-def ...)</syntax>
<syntax>(define-command-group* name command-def ...)</syntax>
<syntax>(define-command-group* name #:title title command-def ...)</syntax>

{{define-command-group}} is the typical way to define a command group.  It
defines the symbol {{name}} as a command group constructed according to
the rest of the arguments.  It adds the new group to {{(groups)}}.

The starred form, {{define-command-group*}}, is the same, except that it
does not automatically add the new group to {{(groups)}}.

When no title is given, {{make-title}} is used to generate one
automatically based on {{name}}.  The title is used in the -help display.

Each command-def looks like {{((name . args) . body)}} or {{((name . args)
#:doc doc . body)}}.  The {{#:doc}} keyword may be used to store a short
docstring for the command, which will be printed in the -help display.

<procedure>(make-command-group title commands)</procedure>

You will not normally use this procedure directly.  It is part of the
expansion of {{define-command-group}} and {{define-command-group*}}.

<parameter>make-title</parameter>

Value is a procedure that converts a symbol to a string, suitable for use
in -help titling. The default upcases the string and replaces hyphen with
spacen.

<procedure>(abort-parse)</procedure>

Helper procedure for use in command bodies to stop calling of commands,
and inform the calling program that it should exit.  This is used by the
built-in special commands {{-help}} and {{-version}} to ensure that only
one command is called.

<procedure>(parse input)</procedure>

Parse the list of command-line arguments, input into commands and call
them.  Returns {{#t}} on successful completion of calling commands, {{#f}}
if parsing was aborted.

<parameter>groups</parameter>

The groups parameter holds the list of command-groups that {{parse}} draws
from.  By default, it starts with a single group, special-options, which
contains the commands -help and -version.  The syntax form
{{define-command-group}} adds to this list.  To remove the provided
special-options group, call {{(group '())}} to initialize the list before
defining any other command groups.

<parameter>help-heading</parameter>

The string value of help-heading is printed out by the provided -version
command, and as the first line of the provided -help command.  Be sure to
set this.

<parameter>help-minimum-intercolumn-space</parameter>

The provided -help command prints command call forms and docstrings in two
columns.  The help-minimum-intercolumn-space parameter gives the minimum
number of spaces by which to separate the two columns, defaulting to 3.


=== Commands API

You will generally not need to use this part of the API, unless you write
introspective commands, like your own -help.

<procedure>(make-command name args doc body)</procedure>
<procedure>(command-name cmd)</procedure>
<procedure>(command-args cmd)</procedure>
<procedure>(command-doc cmd)</procedure>
<procedure>(command-body cmd)</procedure>
<procedure>(command-name-string cmd)</procedure>


== Examples

<enscript highlight=scheme>
(use srfi-1
     (prefix imperative-command-line-a icla:))

(icla:help-heading
 "icla-example version 1.0, by Harry S Beethoven")

(icla:define-command-group general-options
 ((foo)
  doc: "print foo"
  (print "foo"))
 ((bar baz)
  (print baz)))

(icla:parse (command-line-arguments))
</enscript>


== License

BSD


== Version History

* 0.1 (February 13, 2013) initial release
* 0.2 (February 14, 2013) simpler 'parse' call-form
* 0.3 (February 18, 2013) 'parse' now calls the commands
* 0.4 (February 19, 2013) introducing define-command-group
* 0.5.0 (June 16, 2016) signal (exn icla parse) error for parse errors