diff --git a/_odoc-theme/manual.css b/_odoc-theme/manual.css index 92a1b438..5e17c4d3 100644 --- a/_odoc-theme/manual.css +++ b/_odoc-theme/manual.css @@ -3,8 +3,8 @@ @import url("theme.css"); /* Copyright (c) 2019 The odig programmers. All rights reserved. - Distributed under the ISC license, see terms at the end of the file. - odig v0.0.9 */ + SPDX-License-Identifier: ISC + odig v0.1.0 */ :root { --font-headings: "PT-Sans-Caption"; --font-body: "PT-Sans"; @@ -373,4 +373,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ +*/ \ No newline at end of file diff --git a/_odoc-theme/odoc.css b/_odoc-theme/odoc.css index 1dbc9da2..c6362b73 100644 --- a/_odoc-theme/odoc.css +++ b/_odoc-theme/odoc.css @@ -3,7 +3,7 @@ @import url("theme.css"); /* Copyright (c) 2019 The odig programmers. All rights reserved. - Distributed under the ISC license, see terms at the end of the file. */ + SPDX-License-Identifier: ISC */ /* Reset a few things. */ @@ -62,7 +62,7 @@ table { border-collapse: collapse; border-spacing: 0; } .odoc-nav { grid-area: nav; } .odoc-preamble { grid-area: header; } .odoc-content { grid-area: content; margin: 0 } -.odoc-toc +.odoc-tocs { grid-area: toc; margin-top: var(--size-line); border-top: solid thin var(--color-rule); } @@ -331,4 +331,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ +*/ \ No newline at end of file diff --git a/cmdliner/Cmdliner/Arg/Completion/index.html b/cmdliner/Cmdliner/Arg/Completion/index.html new file mode 100644 index 00000000..9d887053 --- /dev/null +++ b/cmdliner/Cmdliner/Arg/Completion/index.html @@ -0,0 +1,5 @@ + +
Arg.CompletionArgument completion.
This module provides a type to describe how positional and optional argument values of argument converters can be completed. It defines which completion directives from the protocol get emitted by your tool for the argument.
Note. Subcommand and option name are completed automatically by the library itself and prefined argument converters already have completions built-in whenever appropriate.
val value : ?doc:string -> 'a -> 'a directivevalue v ~doc indicates that the token to complete could be replaced by the value v as serialized by the argument's formatter Conv.pp. doc is ANSI styled UTF-8 text documenting the value, defaults to "".
val string : ?doc:string -> string -> 'a directivestring s ~doc indicates that the token to complete could be replaced by the string s. doc is ANSI styled UTF-8 text documenting the value, defaults to "".
val files : 'a directivefiles indicates that the token to complete could be replaced with files that the shell deems suitable.
val dirs : 'a directivedirs indicates that the token to complete could be replaced with directories that the shell deems suitable.
val restart : 'a directiverestart indicates that the shell should restart the completion after the positional disambiguation token --.
This is typically used for tools that end-up invoking other tools like sudo -- TOOL [ARG]…. For the latter a restart completion should be added on all positional arguments. If you allow TOOL to be only a restricted set of tools known to your program you'd eschew restart on the first postional argument but add it to the remaining ones.
Warning. A restart directive is eventually emited only if the completion is requested after a -- token. In this case other completions returned alongside by func are ignored. Educate your users to use the --, for example mention them in user defined synopses, it is good cli specification hygiene as it properly delineates argument scopes.
val message : string -> 'a directivemessage s is a multi-line, ANSI styled, UTF-8 message reported to end users.
val raw : string -> 'a directiveraw s takes over the whole protocol output (including subcommand and option name completion) with s, you are in charge. Any other directive in the result of func is ignored.
Warning. The protocol is unstable, it is not advised to output it yourself. However this can be useful to invoke another tool according to the protocol in the completion function and treat its result as the requested completion.
The type for completion functions.
Given an optional context determined from a partial command line parse and a token to complete it returns a list of completion directives or an error which is reported to end-users by using a protocol message.
The context is None if no context was given to make or if the context failed to parse on the current command line.
The type for completing.
A completion context specification which captures a partial command line parse (for example the path to a configuration file) and a completion function.
make ~context func uses func to complete.
context defines a commmand line fragment that is evaluated before performing the completion. It the evaluation is successful the result is given to the completion function. Otherwise None is given.
Warning. context must be part of the term of the command in which you use the completion otherwise the context will always be None in the function.
val complete_files : 'a tcomplete_files holds a context insensitive function that always returns Ok [files].
val complete_dirs : 'a tcomplete_dirs holds a context insensitive function that always returns Ok [dirs].
val complete_paths : 'a tArg.ConvArgument converters.
An argument converter transforms a string argument of the command line to an OCaml value. Predefined converters are provided for many types of the standard library.
type 'a parser = string -> ('a, string) resultThe type for parsing arguments to values of type 'a.
type 'a fmt = Stdlib.Format.formatter -> 'a -> unitThe type for formatting values of type 'a.
val make :
+ ?completion:'a Completion.t ->
+ docv:string ->
+ parser:'a parser ->
+ pp:'a fmt ->
+ unit ->
+ 'a tmake ~docv ~parser ~pp () is an argument converter with given properties. See corresponding accessors for semantics.
val of_conv :
+ ?completion:'a Completion.t ->
+ ?docv:string ->
+ ?parser:'a parser ->
+ ?pp:'a fmt ->
+ 'a t ->
+ 'a tof_conv conv () is a new converter with given unspecified properties defaulting to those of conv.
val docv : 'a t -> stringdocv c is c's documentation meta-variable. This value can be refered to as $(docv) in the documentation strings of arguments. It can be overriden by the info value of an argument.
val completion : 'a t -> 'a Completion.tcompletion c is c's completion.
Cmdliner.ArgTerms for command line arguments.
This module provides functions to define terms that evaluate to the arguments provided on the command line.
Basic constraints, like the argument type or repeatability, are specified by defining a value of type Arg.t. Further constraints can be specified during the conversion to a term.
An argument converter transforms a string argument of the command line to an OCaml value. Predefined converters are provided for many types of the standard library.
type 'a printer = Stdlib.Format.formatter -> 'a -> unitThe type for converted argument printers.
val conv :
- ?docv:string ->
- ((string -> ('a, [ `Msg of string ]) result) * 'a printer) ->
- 'a convconv ~docv (parse, print) is an argument converter parsing values with parse and printing them with print. docv is a documentation meta-variable used in the documentation to stand for the argument value, defaults to "VALUE".
conv' is like conv but the Error case has an unlabelled string.
conv_parser c is the parser of c.
val conv_docv : 'a conv -> stringval parser_of_kind_of_string :
- kind:string ->
- (string -> 'a option) ->
- string ->
- ('a, [ `Msg of string ]) resultparser_of_kind_of_string ~kind kind_of_string is an argument parser using the kind_of_string function for parsing and kind to report errors (e.g. could be "an integer" for an int parser.).
some' ?none c is like the converter c except it returns Some value. It is used for command line arguments that default to None when absent. If provided, none is used with conv's printer to document the value taken on absence; to document a more complex behaviour use the absent argument of info.
some ?none c is like some' but none is described as a string that will be rendered in bold.
Argument information defines the man page information of an argument and, for optional arguments, its names. An environment variable can also be specified to read the argument value from if the argument is absent from the command line and the variable is defined.
val info :
+Arg (cmdliner.Cmdliner.Arg) Module Cmdliner.Arg
Terms for command line arguments.
This module provides functions to define terms that evaluate to the arguments provided on the command line.
Basic constraints, like the argument type or repeatability, are specified by defining a value of type Arg.t. Further constraints can be specified during the conversion to a term.
Argument converters
module Completion : sig ... endArgument completion.
module Conv : sig ... endArgument converters.
type 'a conv = 'a Conv.tThe type for argument converters. See the predefined converters.
some' ?none c is like the converter c except it returns Some value. It is used for command line arguments that default to None when absent. If provided, none is used with c's formatter to document the value taken on absence; to document a more complex behaviour use the absent argument of info. If you cannot construct an 'a value use some.
some ?none c is like some' but none is described as a string that will be rendered in bold. Use the absent argument of info to document more complex behaviours.
Arguments
The type for information about command line arguments.
Argument information defines the man page information of an argument and, for optional arguments, its names. An environment variable can also be specified to read get the argument value from if the argument is absent from the command line and the variable is defined.
val info :
?deprecated:string ->
?absent:string ->
- ?docs:string ->
+ ?docs:Manpage.section_name ->
+ ?doc_envs:Cmd.Env.info list ->
?docv:string ->
?doc:string ->
?env:Cmd.Env.info ->
string list ->
- infoinfo docs docv doc env names defines information for an argument.
names defines the names under which an optional argument can be referred to. Strings of length 1 ("c") define short option names ("-c"), longer strings ("count") define long option names ("--count"). names must be empty for positional arguments.env defines the name of an environment variable which is looked up for defining the argument if it is absent from the command line. See environment variables for details.doc is the man page information of the argument. The documentation language can be used and the following variables are recognized:
"$(docv)" the value of docv (see below)."$(opt)", one of the options of names, preference is given to a long one."$(env)", the environment var specified by env (if any).
These functions can help with formatting argument values.
docv is for positional and non-flag optional arguments. It is a variable name used in the man page to stand for their value.docs is the title of the man page section in which the argument will be listed. For optional arguments this defaults to Manpage.s_options. For positional arguments this defaults to Manpage.s_arguments. However a positional argument is only listed if it has both a doc and docv specified.deprecated, if specified the argument is deprecated and the string is a message output on standard error when the argument is used.absent, if specified a documentation string that indicates what happens when the argument is absent. The document language can be used like in doc. This overrides the automatic default value rendering that is performed by the combinators.
f & v is f v, a right associative composition operator for specifying argument terms.
Optional arguments
The information of an optional argument must have at least one name or Invalid_argument is raised.
flag i is a bool argument defined by an optional flag that may appear at most once on the command line under one of the names specified by i. The argument holds true if the flag is present on the command line and false otherwise.
flag_all is like flag except the flag may appear more than once. The argument holds a list that contains one true value per occurrence of the flag. It holds the empty list if the flag is absent from the command line.
vflag v [v0,i0;…] is an 'a argument defined by an optional flag that may appear at most once on the command line under one of the names specified in the ik values. The argument holds v if the flag is absent from the command line and the value vk if the name under which it appears is in ik.
Note. Environment variable lookup is unsupported for for these arguments.
vflag_all v l is like vflag except the flag may appear more than once. The argument holds the list v if the flag is absent from the command line. Otherwise it holds a list that contains one corresponding value per occurrence of the flag, in the order found on the command line.
Note. Environment variable lookup is unsupported for for these arguments.
opt vopt c v i is an 'a argument defined by the value of an optional argument that may appear at most once on the command line under one of the names specified by i. The argument holds v if the option is absent from the command line. Otherwise it has the value of the option as converted by c.
If vopt is provided the value of the optional argument is itself optional, taking the value vopt if unspecified on the command line.
opt_all vopt c v i is like opt except the optional argument may appear more than once. The argument holds a list that contains one value per occurrence of the flag in the order found on the command line. It holds the list v if the flag is absent from the command line.
Positional arguments
The information of a positional argument must have no name or Invalid_argument is raised. Positional arguments indexing is zero-based.
Warning. The following combinators allow to specify and extract a given positional argument with more than one term. This should not be done as it will likely confuse end users and documentation generation. These over-specifications may be prevented by raising Invalid_argument in the future. But for now it is the client's duty to make sure this doesn't happen.
pos rev n c v i is an 'a argument defined by the nth positional argument of the command line as converted by c. If the positional argument is absent from the command line the argument is v.
If rev is true (defaults to false), the computed position is max-n where max is the position of the last positional argument present on the command line.
pos_all c v i is an 'a list argument that holds all the positional arguments of the command line as converted by c or v if there are none.
pos_left rev n c v i is an 'a list argument that holds all the positional arguments as converted by c found on the left of the nth positional argument or v if there are none.
If rev is true (defaults to false), the computed position is max-n where max is the position of the last positional argument present on the command line.
pos_right is like pos_left except it holds all the positional arguments found on the right of the specified positional argument.
Arguments as terms
required a is a term that fails if a's value is None and evaluates to the value of Some otherwise. Use this for required positional arguments (it can also be used for defining required optional arguments, but from a user interface perspective this shouldn't be done, it is a contradiction in terms).
non_empty a is term that fails if a's list is empty and evaluates to a's list otherwise. Use this for non empty lists of positional arguments.
last a is a term that fails if a's list is empty and evaluates to the value of the last element of the list otherwise. Use this for lists of flags or options where the last occurrence takes precedence over the others.
Predefined arguments
val man_format : Manpage.format Term.tman_format is a term that defines a --man-format option and evaluates to a value that can be used with Manpage.print.
Predefined converters
val bool : bool convbool converts values with bool_of_string.
val char : char convchar converts values by ensuring the argument has a single char.
val int : int convint converts values with int_of_string.
val nativeint : nativeint convnativeint converts values with Nativeint.of_string.
val int32 : int32 convint32 converts values with Int32.of_string.
val int64 : int64 convint64 converts values with Int64.of_string.
val float : float convfloat converts values with float_of_string.
val string : string convstring converts values with the identity function.
val enum : (string * 'a) list -> 'a convenum l p converts values such that unambiguous prefixes of string names in l map to the corresponding value of type 'a.
Warning. The type 'a must be comparable with Stdlib.compare.
val file : string convfile converts a value with the identity function and checks with Sys.file_exists that a file with that name exists.
val dir : string convdir converts a value with the identity function and checks with Sys.file_exists and Sys.is_directory that a directory with that name exists.
val non_dir_file : string convnon_dir_file converts a value with the identity function and checks with Sys.file_exists and Sys.is_directory that a non directory file with that name exists.
list sep c splits the argument at each sep (defaults to ',') character and converts each substrings with c.
array sep c splits the argument at each sep (defaults to ',') character and converts each substring with c.
pair sep c0 c1 splits the argument at the first sep character (defaults to ',') and respectively converts the substrings with c0 and c1.
t3 sep c0 c1 c2 splits the argument at the first two sep characters (defaults to ',') and respectively converts the substrings with c0, c1 and c2.
val t4 :
+ infoinfo docs docv doc env names defines information for an argument.
names defines the names under which an optional argument can be referred to. Strings of length 1 like "c") define short option names "-c", longer strings like "count") define long option names "--count". names must be empty for positional arguments.env defines the name of an environment variable which is looked up for defining the argument if it is absent from the command line. See environment variables for details.doc is the man page information of the argument. These functions can help with formatting argument values.docv is for positional and non-flag optional arguments. It is a variable name used in the man page to stand for their value. If unspecified is taken from the argument converter's, see Conv.docv.doc_envs is a list of environment variable that are added to the manual of the command when the argument is used.docs is the title of the man page section in which the argument will be listed. For optional arguments this defaults to Manpage.s_options. For positional arguments this defaults to Manpage.s_arguments. However a positional argument is only listed if it has both a doc and docv specified.deprecated, if specified the argument is deprecated. Use of the variable warns on stderr. This message which should be a capitalized sentence is preprended to doc and output on standard error when the environment variable ends up being used.absent, if specified a documentation string that indicates what happens when the argument is absent. The document language can be used like in doc. This overrides the automatic default value rendering that is performed by the combinators.
In doc, deprecated, absent the documentation markup language can be used with following variables:
"$(docv)" the value of docv (see below)."$(opt)", one of the options of names, preference is given to a long one."$(env)", the environment var specified by env (if any).
f & v is f v, a right associative composition operator for specifying argument terms.
Optional arguments
The information of an optional argument must have at least one name or Invalid_argument is raised.
flag i is a bool argument defined by an optional flag that may appear at most once on the command line under one of the names specified by i. The argument holds true if the flag is present on the command line and false otherwise.
flag_all is like flag except the flag may appear more than once. The argument holds a list that contains one true value per occurrence of the flag. It holds the empty list if the flag is absent from the command line.
vflag v [v0,i0;…] is an 'a argument defined by an optional flag that may appear at most once on the command line under one of the names specified in the ik values. The argument holds v if the flag is absent from the command line and the value vk if the name under which it appears is in ik.
Note. Automatic environment variable lookup is unsupported for for these arguments but an env in an info will be documented. Use an option and Term.env for manually looking something up.
vflag_all v l is like vflag except the flag may appear more than once. The argument holds the list v if the flag is absent from the command line. Otherwise it holds a list that contains one corresponding value per occurrence of the flag, in the order found on the command line.
Note. Automatic environment variable lookup is unsupported for for these arguments but an env in an info will be documented. Use an option and Term.env for manually looking something up.
opt vopt c v i is an 'a argument defined by the value of an optional argument that may appear at most once on the command line under one of the names specified by i. The argument holds v if the option is absent from the command line. Otherwise it has the value of the option as converted by c.
If vopt is provided the value of the optional argument is itself optional, taking the value vopt if unspecified on the command line. Warning using vopt is not recommended.
opt_all vopt c v i is like opt except the optional argument may appear more than once. The argument holds a list that contains one value per occurrence of the flag in the order found on the command line. It holds the list v if the flag is absent from the command line.
Positional arguments
The information of a positional argument must have no name or Invalid_argument is raised. Positional arguments indexing is zero-based.
Warning. The following combinators allow to specify and extract a given positional argument with more than one term. This should not be done as it will likely confuse end users and documentation generation. These over-specifications may be prevented by raising Invalid_argument in the future. But for now it is the client's duty to make sure this doesn't happen.
pos rev n c v i is an 'a argument defined by the nth positional argument of the command line as converted by c. If the positional argument is absent from the command line the argument is v.
If rev is true (defaults to false), the computed position is max-n where max is the position of the last positional argument present on the command line.
pos_all c v i is an 'a list argument that holds all the positional arguments of the command line as converted by c or v if there are none.
pos_left rev n c v i is an 'a list argument that holds all the positional arguments as converted by c found on the left of the nth positional argument or v if there are none.
If rev is true (defaults to false), the computed position is max-n where max is the position of the last positional argument present on the command line.
pos_right is like pos_left except it holds all the positional arguments found on the right of the specified positional argument.
Converting to terms
required a is a term that fails if a's value is None and evaluates to the value of Some otherwise. Use this in combination with Arg.some' for required positional arguments. Warning using this on optional arguments is not recommended.
non_empty a is term that fails if a's list is empty and evaluates to a's list otherwise. Use this for non empty lists of positional arguments.
last a is a term that fails if a's list is empty and evaluates to the value of the last element of the list otherwise. Use this for lists of flags or options where the last occurrence takes precedence over the others.
Predefined arguments
val man_format : Manpage.format Term.tman_format is a term that defines a --man-format option and evaluates to a value that can be used with Manpage.print.
Predefined converters
val bool : bool convbool converts values with bool_of_string.
val char : char convchar converts values by ensuring the argument has a single char.
val int : int convint converts values with int_of_string.
val nativeint : nativeint convnativeint converts values with Nativeint.of_string.
val int32 : int32 convint32 converts values with Int32.of_string.
val int64 : int64 convint64 converts values with Int64.of_string.
val float : float convfloat converts values with float_of_string.
val string : string convstring converts values with the identity function.
val enum : ?docv:string -> (string * 'a) list -> 'a convenum l p converts values such that string names in l map to the corresponding value of type 'a. docv is the converter's documentation meta-variable, it defaults to ENUM. A completion is added for the names.
Warning. The type 'a must be comparable with Stdlib.compare.
list sep c splits the argument at each sep (defaults to ',') character and converts each substrings with c.
array sep c splits the argument at each sep (defaults to ',') character and converts each substring with c.
pair sep c0 c1 splits the argument at the first sep character (defaults to ',') and respectively converts the substrings with c0 and c1.
t3 sep c0 c1 c2 splits the argument at the first two sep characters (defaults to ',') and respectively converts the substrings with c0, c1 and c2.
t4 sep c0 c1 c2 c3 splits the argument at the first three sep characters (defaults to ',') respectively converts the substrings with c0, c1, c2 and c3.
Documentation formatting helpers
doc_alts alts documents the alternative tokens alts according the number of alternatives. If quoted is:
None, the tokens are enclosed in manpage markup directives to render them in bold (manpage convention).Some true, the tokens are quoted with doc_quote.Some false, the tokens are written as is
The resulting string can be used in sentences of the form "$(docv) must be %s".
doc_alts_enum quoted alts is doc_alts quoted (List.map fst alts).
Deprecated
type env = Cmd.Env.infoSee Cmd.Env.info
val env_var :
- ?deprecated:string ->
- ?docs:string ->
- ?doc:string ->
- Cmd.Env.var ->
- Cmd.Env.infoSee Cmd.Env.info.
+ ('a * 'b * 'c * 'd) convt4 sep c0 c1 c2 c3 splits the argument at the first three sep characters (defaults to ',') respectively converts the substrings with c0, c1, c2 and c3.
val path : string convpath is like string but prints using Filename.quote and completes both files and directories.
val filepath : string convfilepath is like string but prints using Filename.quote and completes files.
val dirpath : string convdirpath is like string but prints using Filename.quote and completes directories.
Note. The following converters report errors whenever the requested file system object does not exist. This is only mildly useful since nothing guarantees they will still exist at the time you act upon them. So you will have to treat these error cases anyways in your tool function. It is also unhelpful if the file system object may be created by your tool. Rather use filepath and dirpath.
val file : string convfile converts a value with the identity function and checks with Sys.file_exists that a file with that name exists. The string "-" is parsed without checking: it represents stdio. It completes both files directories.
val dir : string convdir converts a value with the identity function and checks with Sys.file_exists and Sys.is_directory that a directory with that name exists. It completes directories.
val non_dir_file : string convnon_dir_file converts a value with the identity function and checks with Sys.file_exists and Sys.is_directory that a non directory file with that name exists. The string "-" is parsed without checking it represents stdio. It completes files.
doc_alts alts documents the alternative tokens alts according the number of alternatives. If quoted is:
None, the tokens are enclosed in manpage markup directives to render them in bold (manpage convention).Some true, the tokens are quoted with doc_quote.Some false, the tokens are written as isThe resulting string can be used in sentences of the form "$(docv) must be %s".
doc_alts_enum quoted alts is doc_alts quoted (List.map fst alts).
These identifiers are silently deprecated. For now there is no plan to remove them. But you should prefer to use the Conv interface in new code.
val conv' : ?docv:string -> ('a Conv.parser * 'a Conv.fmt) -> 'a convDeprecated. Use Conv.make instead.
val conv :
+ ?docv:string ->
+ ((string -> ('a, [ `Msg of string ]) result) * 'a Conv.fmt) ->
+ 'a convDeprecated. Use Conv.make instead.
Deprecated. Use Conv.parser.
val parser_of_kind_of_string :
+ kind:string ->
+ (string -> 'a option) ->
+ string ->
+ ('a, [ `Msg of string ]) resultDeprecated. parser_of_kind_of_string ~kind kind_of_string is an argument parser using the kind_of_string function for parsing and kind to report errors (e.g. could be "an integer" for an int parser.).
Cmd.EnvEnvironment variable and their information.
type info = Term.env_infoThe type for environment variable information.
info ~docs ~doc var describes an environment variable var such that:
doc is the man page information of the environment variable, defaults to "undocumented".docs is the title of the man page section in which the environment variable will be listed, it defaults to Cmdliner.Manpage.s_environment.deprecated, if specified the environment is deprecated and the string is a message output on standard error when the environment variable gets used to lookup the default value of an argument.In doc the documentation markup language can be used with following variables:
$(env), the value of var.info.Cmd.EnvEnvironment variable and their information.
val info :
+ ?deprecated:string ->
+ ?docs:Manpage.section_name ->
+ ?doc:string ->
+ var ->
+ infoinfo ~docs ~doc var describes an environment variable var such that:
doc is the man page information of the environment variable, defaults to "See option $(opt).".docs is the title of the man page section in which the environment variable will be listed, it defaults to Cmdliner.Manpage.s_environment.deprecated, if specified the environment variable is deprecated. Use of the variable warns on depstderr This message which should be a capitalized sentence is preprended to doc and output on standard error when the environment variable ends up being used.In doc and deprecated the documentation markup language can be used with following variables:
$(opt), if any the option name of the argument the variable is looked up for.$(env), the value of var.Cmd.info.Cmd.ExitExit codes and their information.
The type for exit codes.
Warning. You should avoid status codes strictly greater than 125 as those may be used by some shells.
val ok : codeok is 0, the exit status for success.
val some_error : codesome_error is 123, an exit status for indisciminate errors reported on stderr.
val cli_error : codecli_error is 124, an exit status for command line parsing errors.
val internal_error : codeinternal_error is 125, an exit status for unexpected internal errors.
exit_info ~docs ~doc min ~max describe the range of exit statuses from min to max (defaults to min). doc is the man page information for the statuses, defaults to "undocumented". docs is the title of the man page section in which the statuses will be listed, it defaults to Manpage.s_exit_status.
In doc the documentation markup language can be used with following variables:
$(status), the value of min.$(status_max), the value of max.Cmd.infoval defaults : info listdefaults are exit code information for ok, some_error cli_error and internal_error.
Cmd.ExitExit codes and their information.
The type for exit codes.
Warning. You should avoid status codes strictly greater than 125 as those may be used by some shells.
These are documented by defaults.
val ok : codeok is 0, the exit status for success.
val some_error : codesome_error is 123, an exit status for indiscriminate errors reported on stderr.
val cli_error : codecli_error is 124, an exit status for command line parsing errors.
val internal_error : codeinternal_error is 125, an exit status for unexpected internal errors.
val info :
+ ?docs:Manpage.section_name ->
+ ?doc:string ->
+ ?max:code ->
+ code ->
+ infoinfo ~docs ~doc min ~max describe the range of exit statuses from min to max (defaults to min).
doc is the man page information for the statuses, defaults to "undocumented". The documentation markup language can be used with following variables:
$(status), the value of min.$(status_max), the value of max.Cmd.infodocs is the title of the man page section in which the statuses will be listed, it defaults to Manpage.s_exit_status.val defaults : info listdefaults are exit code information for ok, some_error, cli_error and internal_error.
Cmdliner.CmdCommands.
Command line syntaxes are implicitely defined by Terms. A command value binds a syntax and its documentation to a command name.
A command can group a list of sub commands (and recursively). In this case your tool defines a tree of commands, each with its own command line syntax. The root of that tree is called the main command; it represents your tool and its name.
Command information defines the name and documentation of a command.
module Exit : sig ... endExit codes and their information.
module Env : sig ... endEnvironment variable and their information.
val info :
+Cmd (cmdliner.Cmdliner.Cmd) Module Cmdliner.Cmd
Commands.
Command line syntaxes are implicitely defined by Term.t values. A command value binds a term and its documentation to a command name.
A command can group a list of subcommands (and recursively). In this case your tool defines a tree of commands, each with its own command line syntax. The root of that tree is called the main command; it represents your tool and its name.
Command information
Command information defines the name and documentation of a command.
module Exit : sig ... endExit codes and their information.
module Env : sig ... endEnvironment variable and their information.
val info :
?deprecated:string ->
?man_xrefs:Manpage.xref list ->
?man:Manpage.block list ->
?envs:Env.info list ->
?exits:Exit.info list ->
- ?sdocs:string ->
- ?docs:string ->
+ ?sdocs:Manpage.section_name ->
+ ?docs:Manpage.section_name ->
?doc:string ->
?version:string ->
string ->
- infoinfo ?sdocs ?man ?docs ?doc ?version name is a term information such that:
name is the name of the command.version is the version string of the command line tool, this is only relevant for the main command and ignored otherwise.deprecated, if specified the command is deprecated and the string is a message output on standard error when the command is used.doc is a one line description of the command used for the NAME section of the command's man page and in command group listings.docs, for commands that are part of a group, the title of the section of the parent's command man page where it should be listed (defaults to Manpage.s_commands).sdocs defines the title of the section in which the standard --help and --version arguments are listed (defaults to Manpage.s_common_options).exits is a list of exit statuses that the command evaluation may produce, defaults to Exit.defaults.envs is a list of environment variables that influence the command's evaluation.man is the text of the man page for the command.man_xrefs are cross-references to other manual pages. These are used to generate a Manpage.s_see_also section.
doc, man, envs support the documentation markup language in which the following variables are recognized:
$(tname) the (term's) command's name.$(mname) the main command name.$(iname) the command invocation from main command to the command name.
Commands
v i t is a command with information i and command line syntax parsed by t.
group i ?default cmds is a command with information i that groups sub commands cmds. default is the command line syntax to parse if no sub command is specified on the command line. If default is None (default), the tool errors when no sub command is specified.
val name : 'a t -> stringname c is the name of c.
Evaluation
These functions are meant to be composed with Stdlib.exit. The following exit codes may be returned by all these functions:
Exit.cli_error if a parse error occurs.Exit.internal_error if the ~catch argument is true (default) and an uncaught exception is raised.- The value of
~term_err (defaults to Exit.cli_error) if a term error occurs.
These exit codes are described in Exit.defaults which is the default value of the ?exits argument of function info.
val eval :
+ infoinfo ?sdocs ?man ?docs ?doc ?version name is a term information such that:
name is the name of the command.version is the version string of the command line tool, this is only relevant for the main command and ignored otherwise.deprecated, if specified the command is deprecated. Use of the variable warns on stderr. This message which should be a capitalized sentence is preprended to doc and output on standard error when the environment variable ends up being used.doc is a one line description of the command used for the NAME section of the command's man page and in command group listings.docs, for commands that are part of a group, the title of the section of the parent's command man page where it should be listed (defaults to Manpage.s_commands).sdocs defines the title of the section in which the standard --help and --version arguments are listed (defaults to Manpage.s_common_options).exits is a list of exit statuses that the command evaluation may produce, defaults to Exit.defaults.envs is a list of environment variables that influence the command's evaluation.man is the text of the man page for the command.man_xrefs are cross-references to other manual pages. These are used to generate a Manpage.s_see_also section.
doc, deprecated, man, envs, exits support the documentation markup language in which the following variables are recognized:
$(tool) the main, topmost, command name.$(cmd) the command invocation from main command to the command name.$(cmd.name) the command's name.$(cmd.parent) the command's parent or the main command if none.
Previously some of these names were refered to as $(tname), $(mname) and $(iname), they still work but do not use them, they are obscure.
Commands
make i t is a command with information i and command line syntax parsed by t.
group i ?default cmds is a command with information i that groups subcommands cmds. default is the command line syntax to parse if no subcommand is specified on the command line. If default is None (default), the tool errors when no subcommand is specified.
val name : 'a t -> stringname c is the name of c.
Evaluation
Read Which Cmd evaluation function should I use? in the cookbook if you struggle to choose between this menagerie of evaluation functions.
These functions are meant to be composed with Stdlib.exit. The following exit codes may be returned by all these functions:
Exit.cli_error if a parse error occurs.Exit.internal_error if the ~catch argument is true (default) and an uncaught exception is raised.- The value of
~term_err (defaults to Exit.cli_error) if a term error occurs.
These exit codes are described in Exit.defaults which is the default value of the ?exits argument of the function info.
val eval :
?help:Stdlib.Format.formatter ->
?err:Stdlib.Format.formatter ->
?catch:bool ->
@@ -42,14 +42,14 @@
?argv:string array ->
?term_err:Exit.code ->
(Exit.code, string) result t ->
- Exit.codeeval_result' cmd is:
c if cmd evaluates to Ok c.Exit.some_error if cmd evaluates to Error msg. In this case msg is printed on err.
See eval_value for other arguments.
Low level evaluation
This interface gives more information on command evaluation results and lets you choose how to map evaluation results to exit codes.
type 'a eval_ok = [ | `Ok of 'a(*The term of the command evaluated to this value.
*)| `Version(*The version of the main cmd was requested.
*)| `Help(*Help was requested.
*)
]The type for successful evaluation results.
type eval_error = [ | `Parse(*A parse error occurred.
*)| `Term(*A term evaluation error occurred.
*)| `Exn(*An uncaught exception occurred.
*)
]The type for erroring evaluation results.
type 'a eval_exit = [ | `Ok of 'a(*The term of the command evaluated to this value.
*)| `Exit of Exit.code(*The evaluation wants to exit with this code.
*)
]val eval_value :
+ Exit.codeeval_result' cmd is:
c if cmd evaluates to Ok c.Exit.some_error if cmd evaluates to Error msg. In this case msg is printed on err.
See eval_value for other arguments.
Low level evaluation
This interface gives more information on command evaluation results and lets you choose how to map evaluation results to exit codes. All evaluation functions are wrappers around eval_value.
type 'a eval_ok = [ | `Ok of 'a(*The term of the command evaluated to this value.
*)| `Version(*The version of the main cmd was requested.
*)| `Help(*Help was requested.
*)
]The type for successful evaluation results.
type eval_error = [ | `Parse(*A parse error occurred.
*)| `Term(*A term evaluation error occurred.
*)| `Exn(*An uncaught exception occurred.
*)
]The type for erroring evaluation results.
val eval_value :
?help:Stdlib.Format.formatter ->
?err:Stdlib.Format.formatter ->
?catch:bool ->
?env:(string -> string option) ->
?argv:string array ->
'a t ->
- ('a eval_ok, eval_error) resulteval ~help ~err ~catch ~env ~argv cmd is the evaluation result of cmd with:
argv the command line arguments to parse (defaults to Sys.argv)env the function used for environment variable lookup (defaults to Sys.getenv).catch if true (default) uncaught exceptions are intercepted and their stack trace is written to the err formatterhelp is the formatter used to print help or version messages (defaults to Format.std_formatter)err is the formatter used to print error messages (defaults to Format.err_formatter).
val eval_value' :
+ ('a eval_ok, eval_error) resulteval ~help ~err ~catch ~env ~argv cmd is the evaluation result of cmd with:
argv the command line arguments to parse (defaults to Sys.argv)env the function used for environment variable lookup (defaults to Sys.getenv).catch if true (default) uncaught exceptions are intercepted and their stack trace is written to the err formatterhelp is the formatter used to print help, version messages or completions, (defaults to Format.std_formatter). Note that the completion protocol needs to output '\n' line ending, if you are outputing to a channel make sure it is in binary mode to avoid newline translation (this is done automatically before completion when help is Format.std_formatter).err is the formatter used to print error messages (defaults to Format.err_formatter).
type 'a eval_exit = [ | `Ok of 'a(*The term of the command evaluated to this value.
*)| `Exit of Exit.code(*The evaluation wants to exit with this code.
*)
]The type for evaluation exits.
val eval_value' :
?help:Stdlib.Format.formatter ->
?err:Stdlib.Format.formatter ->
?catch:bool ->
@@ -57,9 +57,9 @@
?argv:string array ->
?term_err:int ->
'a t ->
- 'a eval_exiteval_value' is like eval_value, but if the command term does not evaluate, returns an exit code like the evaluation function do (which can be Exit.ok in case help or version was requested).
val eval_peek_opts :
+ 'a eval_exiteval_value' is like eval_value, but if the command term does not evaluate to Ok (`Ok v), returns an exit code like the higher-level evaluation functions do (which can be Exit.ok in case help or version was requested).
val eval_peek_opts :
?version_opt:bool ->
?env:(string -> string option) ->
?argv:string array ->
'a Term.t ->
- 'a option * ('a eval_ok, eval_error) resulteval_peek_opts version_opt argv t evaluates t, a term made of optional arguments only, with the command line argv (defaults to Sys.argv). In this evaluation, unknown optional arguments and positional arguments are ignored.
The evaluation returns a pair. The first component is the result of parsing the command line argv stripped from any help and version option if version_opt is true (defaults to false). It results in:
Some _ if the command line would be parsed correctly given the partial knowledge in t.None if a parse error would occur on the options of t
The second component is the result of parsing the command line argv without stripping the help and version options. It indicates what the evaluation would result in on argv given the partial knowledge in t (for example it would return `Help if there's a help option in argv). However in contrasts to eval_value no side effects like error reporting or help output occurs.
Note. Positional arguments can't be peeked without the full specification of the command line: we can't tell apart a positional argument from the value of an unknown optional argument.
+ 'a option * ('a eval_ok, eval_error) resultWARNING. You are highly encouraged not to use this function it may be removed in the future.
eval_peek_opts version_opt argv t evaluates t, a term made of optional arguments only, with the command line argv (defaults to Sys.argv). In this evaluation, unknown optional arguments and positional arguments are ignored.
The evaluation returns a pair. The first component is the result of parsing the command line argv stripped from any help and version option if version_opt is true (defaults to false). It results in:
Some _ if the command line would be parsed correctly given the partial knowledge in t.None if a parse error would occur on the options of tThe second component is the result of parsing the command line argv without stripping the help and version options. It indicates what the evaluation would result in on argv given the partial knowledge in t (for example it would return `Help if there's a help option in argv). However in contrasts to eval_value no side effects like error reporting or help output occurs.
Note. Positional arguments can't be peeked without the full specification of the command line: we can't tell apart a positional argument from the value of an unknown optional argument.
Cmdliner.ManpageMan page specification.
Man page generation is automatically handled by Cmdliner, consult the details.
The Manpage.block type is used to define a man page's content. It's a good idea to follow the standard manual page structure.
References.
man-pages(7), Conventions for writing Linux man pages.type block = [ | `S of string| `P of string| `Pre of string| `I of string * string| `Noblank| `Blocks of block list ]The type for a block of man page text.
`S s introduces a new section s, see the standard section names.`P t is a new paragraph with text t.`Pre t is a new preformatted paragraph with text t.`I (l,t) is an indented paragraph with label l and text t.`Noblank suppresses the blank line introduced between two blocks.`Blocks bs splices the blocks bs.Except in `Pre, whitespace and newlines are not significant and are all collapsed to a single space. All block strings support the documentation markup language.
escape s escapes s so that it doesn't get interpreted by the documentation markup language.
The type for man page titles. Describes the man page title, section, center_footer, left_footer, center_header.
The type for man page cross-references.
`Main refers to the man page of the program itself.`Cmd cmd refers to the man page of the program's cmd command (which must exist).`Tool bin refers to the command line tool named bin.`Page (name, sec) refers to the man page name(sec).The following are standard man page section names, roughly ordered in the order they conventionally appear. See also man man-pages for more elaborations about what sections should contain.
The SYNOPSIS section. By default this section is automatically created by Cmdliner for you, unless it is the first section of your term's man page, in which case it will replace it with yours.
The DESCRIPTION section. This should be a description of what the tool does and provide a little bit of usage and documentation guidance.
The COMMON OPTIONS section. By default help and version options get listed here. For programs with multiple commands, optional arguments common to all commands can be added here.
The EXIT STATUS section. By default term status exit codes get listed here.
The ENVIRONMENT section. By default environment variables get listed here.
val s_environment_intro : blocks_environment_intro is the introduction content used by cmdliner when it creates the s_environment section.
s_none is a special section named "cmdliner-none" that can be used whenever you do not want something to be listed.
The print function can be useful if the client wants to define other man pages (e.g. to implement a help command).
The type for man page output specification.
`Auto, formats like `Pager or `Plain whenever the TERM environment variable is dumb or unset.`Pager, tries to write to a discovered pager, if that fails uses the `Plain format.`Plain, formats to plain text.`Groff, formats to groff commands.val print :
+Manpage (cmdliner.Cmdliner.Manpage) Module Cmdliner.Manpage
Man pages.
Man page generation is automatically handled by Cmdliner, see the details. The Manpage.block type is used to define a man page's content. It's a good idea to follow the standard manual page structure.
References.
man-pages(7), Conventions for writing Linux man pages.
Man pages
The type for section names (titles). See standard section names.
type block = [ | `S of section_name(*Start a new section with given name.
*)| `P of string(*Paragraph with given text.
*)| `Pre of string(*Preformatted paragraph with given text.
*)| `I of string * string(*Indented paragraph with given label and text.
*)| `Noblank(*Suppress blank line introduced between two blocks.
*)| `Blocks of block list(*Splice given blocks.
*)
]The type for a block of man page text.
Except in `Pre, whitespace and newlines are not significant and are all collapsed to a single space. All block strings support the documentation markup language.
escape s escapes s so that it doesn't get interpreted by the documentation markup language.
The type for man page titles. Describes the man page title, section, center_footer, left_footer, center_header.
type xref = [ | `Main(*Refer to the man page of the program itself.
*)| `Cmd of string(*Refer to the command cmd of the tool, which must exist.
*)| `Tool of string(*Tool refer to the given command line tool.
*)| `Page of string * int(*Refer to the manpage name(sec).
*)
]The type for man page cross-references.
Standard section names and content
The following are standard man page section names, roughly ordered in the order they conventionally appear. See also man man-pages for more elaborations about what sections should contain.
val s_name : section_nameThe NAME section. This section is automatically created by Cmdliner for your command.
val s_synopsis : section_nameThe SYNOPSIS section. By default this section is automatically created by Cmdliner for your command, unless it is the first section of your term's man page, in which case it will replace it with yours.
val s_description : section_nameThe DESCRIPTION section. This should be a description of what the tool does and provide a little bit of command line usage and documentation guidance.
val s_commands : section_nameThe COMMANDS section. By default subcommands get listed here.
val s_arguments : section_nameThe ARGUMENTS section. By default positional arguments get listed here.
val s_options : section_nameThe OPTIONS section. By default optional arguments get listed here.
val s_common_options : section_nameThe COMMON OPTIONS section. By default help and version options get listed here. For programs with multiple commands, optional arguments common to all commands can be added here.
val s_exit_status : section_nameThe EXIT STATUS section. By default term status exit codes get listed here.
val s_environment : section_nameThe ENVIRONMENT section. By default environment variables get listed here.
val s_environment_intro : blocks_environment_intro is the introduction content used by cmdliner when it creates the s_environment section.
val s_files : section_nameThe FILES section.
val s_bugs : section_nameThe BUGS section.
val s_examples : section_nameThe EXAMPLES section.
val s_authors : section_nameThe AUTHORS section.
val s_see_also : section_nameThe SEE ALSO section.
val s_none : section_names_none is a special section named "cmdliner-none" that can be used whenever you do not want something to be listed.
Output
The print function can be useful if the client wants to define other man pages (e.g. to implement a help command).
type format = [ | `Auto(*Format like `Pager or `Plain whenever the TERM environment variable is dumb or unset.
*)| `Pager| `Plain(*Format to plain text.
*)| `Groff(*Format to groff commands.
*)
]The type for man page output specification.
val print :
+ ?env:(string -> string option) ->
?errs:Stdlib.Format.formatter ->
?subst:(string -> string option) ->
format ->
Stdlib.Format.formatter ->
t ->
- unitprint ~errs ~subst fmt ppf page prints page on ppf in the format fmt. subst can be used to perform variable substitution,(defaults to the identity). errs is used to print formatting errors, it defaults to Format.err_formatter.
+ unitprint ~env ~errs ~subst fmt ppf page prints page on ppf in the format fmt.
env is used to lookup environment for driving paging when the format is `Pager. Defaults to Sys.getenv_opt.subst can be used to perform variable substitution (defaults to the identity).errs is used to print formatting errors, it defaults to Format.err_formatter.Term.Syntaxlet operators.
Term.Syntaxlet operators.
See how to use them in the blueprints.
Cmdliner.TermTerms.
A term is evaluated by a program to produce a result, which can be turned into an exit status. A term made of terms referring to command line arguments implicitly defines a command line syntax.
val const : 'a -> 'a tconst v is a term that evaluates to v.
f $ v is a term that evaluates to the result of applying the evaluation of v to the one of f.
module Syntax : sig ... endlet operators.
term_result ~usage t evaluates to
`Ok v if t evaluates to Ok v`Error `Term with the error message e and usage shown according to usage (defaults to false), if t evaluates to Error (`Msg e).See also term_result'.
term_result' is like term_result but with a string error case.
cli_parse_result t is a term that evaluates to:
`Ok v if t evaluates to Ok v.`Error `Parse with the error message e if t evaluates to Error (`Msg e).See also cli_parse_result'.
cli_parse_result' is like cli_parse_result but with a string error case.
val main_name : string tmain_name is a term that evaluates to the main command name; that is the name of the tool.
val choice_names : string list tchoice_names is a term that evaluates to the names of the commands that are children of the main command.
with_used_args t is a term that evaluates to t tupled with the arguments from the command line that where used to evaluate t.
The type for command return values. See ret.
ret v is a term whose evaluation depends on the case to which v evaluates. With :
`Ok v, it evaluates to v.`Error (usage, e), the evaluation fails and Cmdliner prints the error e and the term's usage if usage is true.`Help (format, name), the evaluation fails and Cmdliner prints a manpage in format format. If name is None this is the the main command's manpage. If name is Some c this is the man page of the sub command c of the main command.Note. While not deprecated you are encouraged not use this API.
This interface is deprecated in favor of Cmdliner.Cmd. Follow the compiler deprecation warning hints to transition.
Term information defines the name and man page of a term. For simple evaluation this is the name of the program and its man page. For multiple term evaluation, this is the name of a command and its man page.
val exit_info : ?docs:string -> ?doc:string -> ?max:int -> int -> exit_infoexit_info ~docs ~doc min ~max describe the range of exit statuses from min to max (defaults to min). doc is the man page information for the statuses, defaults to "undocumented". docs is the title of the man page section in which the statuses will be listed, it defaults to Manpage.s_exit_status.
In doc the documentation markup language can be used with following variables:
$(status), the value of min.$(status_max), the value of max.infoval default_exits : exit_info listdefault_exits is information for exit status exit_status_success added to default_error_exits.
val default_error_exits : exit_info listdefault_error_exits is information for exit statuses exit_status_cli_error and exit_status_internal_error.
val env_info : ?docs:string -> ?doc:string -> string -> env_infoenv_info ~docs ~doc var describes an environment variable var. doc is the man page information of the environment variable, defaults to "undocumented". docs is the title of the man page section in which the environment variable will be listed, it defaults to Cmdliner.Manpage.s_environment.
In doc the documentation markup language can be used with following variables:
$(env), the value of var.infoval info :
- ?man_xrefs:Manpage.xref list ->
- ?man:Manpage.block list ->
- ?envs:env_info list ->
- ?exits:exit_info list ->
- ?sdocs:string ->
- ?docs:string ->
- ?doc:string ->
- ?version:string ->
- string ->
- infoinfo sdocs man docs doc version name is a term information such that:
name is the name of the program or the command.version is the version string of the program, ignored for commands.doc is a one line description of the program or command used for the NAME section of the term's man page. For commands this description is also used in the list of commands of the main term's man page.docs, only for commands, the title of the section of the main term's man page where it should be listed (defaults to Manpage.s_commands).sdocs defines the title of the section in which the standard --help and --version arguments are listed (defaults to Manpage.s_options).exits is a list of exit statuses that the term evaluation may produce.envs is a list of environment variables that influence the term's evaluation.man is the text of the man page for the term.man_xrefs are cross-references to other manual pages. These are used to generate a Manpage.s_see_also section.doc, man, envs support the documentation markup language in which the following variables are recognized:
$(tname) the term's name.$(mname) the main term's name.val name : info -> stringname ti is the name of the term information.
The type for evaluation results.
`Ok v, the term evaluated successfully and v is the result.`Version, the version string of the main term was printed on the help formatter.`Help, man page about the term was printed on the help formatter.`Error `Parse, a command line parse error occurred and was reported on the error formatter.`Error `Term, a term evaluation error occurred and was reported on the error formatter (see Term.ret').`Error `Exn, an exception e was caught and reported on the error formatter (see the ~catch parameter of eval).val eval :
- ?help:Stdlib.Format.formatter ->
- ?err:Stdlib.Format.formatter ->
- ?catch:bool ->
- ?env:(string -> string option) ->
- ?argv:string array ->
- ('a t * info) ->
- 'a resulteval help err catch argv (t,i) is the evaluation result of t with command line arguments argv (defaults to Sys.argv).
If catch is true (default) uncaught exceptions are intercepted and their stack trace is written to the err formatter.
help is the formatter used to print help or version messages (defaults to Format.std_formatter). err is the formatter used to print error messages (defaults to Format.err_formatter).
env is used for environment variable lookup, the default uses Sys.getenv.
val eval_choice :
- ?help:Stdlib.Format.formatter ->
- ?err:Stdlib.Format.formatter ->
- ?catch:bool ->
- ?env:(string -> string option) ->
- ?argv:string array ->
- ('a t * info) ->
- ('a t * info) list ->
- 'a resulteval_choice help err catch argv (t,i) choices is like eval except that if the first argument on the command line is not an option name it will look in choices for a term whose information has this name and evaluate it.
If the command name is unknown an error is reported. If the name is unspecified the "main" term t is evaluated. i defines the name and man page of the program.
val eval_peek_opts :
- ?version_opt:bool ->
- ?env:(string -> string option) ->
- ?argv:string array ->
- 'a t ->
- 'a option * 'a resulteval_peek_opts version_opt argv t evaluates t, a term made of optional arguments only, with the command line argv (defaults to Sys.argv). In this evaluation, unknown optional arguments and positional arguments are ignored.
The evaluation returns a pair. The first component is the result of parsing the command line argv stripped from any help and version option if version_opt is true (defaults to false). It results in:
Some _ if the command line would be parsed correctly given the partial knowledge in t.None if a parse error would occur on the options of tThe second component is the result of parsing the command line argv without stripping the help and version options. It indicates what the evaluation would result in on argv given the partial knowledge in t (for example it would return `Help if there's a help option in argv). However in contrasts to eval and eval_choice no side effects like error reporting or help output occurs.
Note. Positional arguments can't be peeked without the full specification of the command line: we can't tell apart a positional argument from the value of an unknown optional argument.
Note. If you are using the following functions to handle the evaluation result of a term you should add default_exits to the term's information ~exits argument.
WARNING. You should avoid status codes strictly greater than 125 as those may be used by some shells.
exit_status_cli_error is 124, an exit status for command line parsing errors.
exit_status_internal_error is 125, an exit status for unexpected internal errors.
val exit_status_of_result : ?term_err:int -> unit result -> intexit_status_of_result ~term_err r is an exit(3) status code determined from r as follows:
exit_status_success if r is one of `Ok (), `Version, `Helpterm_err if r is `Error `Term, term_err defaults to 1.exit_status_cli_error if r is `Error `Parseexit_status_internal_error if r is `Error `Exnval exit_status_of_status_result : ?term_err:int -> int result -> intexit_status_of_status_result is like exit_status_of_result except for `Ok n where n is used as the status exit code.
val exit : ?term_err:int -> unit result -> unitexit ~term_err r is Stdlib.exit @@ exit_status_of_result ~term_err r
val exit_status : ?term_err:int -> int result -> unitexit_status ~term_err r is Stdlib.exit @@ exit_status_of_status_result ~term_err r
Cmdliner.TermTerms.
A term made of terms referring to command line arguments implicitly defines a command line syntax fragment. Terms are associated to command values Cmd.t which are evaluated to eventually produce an exit code.
Nowadays terms are best defined using the Cmdliner.Term.Syntax. See examples in the blueprints.
val const : 'a -> 'a tconst v is a term that evaluates to v.
app f v is a term that evaluates to the result applying the evaluation of v to the one of f.
module Syntax : sig ... endlet operators.
Cmd.t evaluationThese special terms allow to interact with the low-level evaluation process performed on commands.
term_result is such that:
term_result ~usage (Ok v) evaluates to Ok (`Ok v).term_result ~usage (Error (`Msg e)) evaluates to Error `Term with the error message e and usage shown according to usage (defaults to false)See also term_result'.
term_result' is like term_result but with a string error case.
cli_parse_result is such that:
cli_parse_result (Ok v) evaluates Ok (`Ok v)).} {- [cli_parse_result (Error (`Msg e))] evaluates Error `Parse.See also cli_parse_result'.
cli_parse_result' is like cli_parse_result but with a string error case.
val main_name : string tmain_name is a term that evaluates to the main command name; that is the name of the tool.
val choice_names : string list tchoice_names is a term that evaluates to the names of the commands that are children of the main command.
with_used_args t is a term that evaluates to t tupled with the arguments from the command line that where used to evaluate t.
The type for command return values. See ret.
ret v is a term whose evaluation depends on the case to which v evaluates. With :
`Ok v, it evaluates to v.`Error (usage, e), the evaluation fails and Cmdliner prints the error e and the term's usage if usage is true.`Help (format, name), the evaluation fails and Cmdliner prints a manpage in format format. If name is None this is the the main command's manpage. If name is Some c this is the man page of the subcommand c of the main command.val env : (string -> string option) tenv is the env argument given to command evaluation functions. If you need to refine the environment lookup done by Cmdliner's machinery you should use this rather than direct calls to Sys.getenv_opt.
CmdlinerDeclarative definition of command line interfaces.
Consult the tutorial, details about the supported command line syntax and examples of use.
Open the module to use it, it defines only three modules in your scope.
module Manpage : sig ... endMan page specification.
module Term : sig ... endTerms.
module Cmd : sig ... endCommands.
module Arg : sig ... endTerms for command line arguments.
CmdlinerDeclarative definition of command line interfaces.
Consult the tutorial, the cookbook, program blueprints and source structure, details about the supported command line syntax and examples of use.
Open the module to use it, it defines only these modules in your scope.
module Manpage : sig ... endMan pages.
module Term : sig ... endTerms.
module Cmd : sig ... endCommands.
module Arg : sig ... endTerms for command line arguments.
Cmdliner_argThis module is hidden.
Cmdliner_baseThis module is hidden.
Cmdliner_clineThis module is hidden.
Cmdliner_cmdThis module is hidden.
Cmdliner_completionThis module is hidden.
Cmdliner_defThis module is hidden.
Cmdliner_docgenThis module is hidden.
Cmdliner_evalThis module is hidden.
Cmdliner_manpageThis module is hidden.
Cmdliner_msgThis module is hidden.
Cmdliner_termThis module is hidden.
Cmdliner_trieThis module is hidden.
For tools evaluating a command without sub commands the most general form of invocation is:
tool [OPTION]… [ARG]…The tool automatically reponds to the --help option by printing the help. If a version string is provided in the command information, it also automatically responds to the --version option by printing this string on standard output.
Command line arguments are either optional or positional. Both can be freely interleaved but since Cmdliner accepts many optional forms this may result in ambiguities. The special token -- can be used to resolve them; anything that follows it is treated as a positional argument.
Tools evaluating commands with sub commands have this form of invocation
tool [COMMAND]… [OPTION]… [ARG]…Commands automatically respond to the --help option by printing their help. The sequence of COMMAND strings must be the first strings following the tool name – as soon as an optional argument is seen the search for a sub command stops. Command names may be specified by a prefixe as long as they are not ambiguous.
An optional argument is specified on the command line by a name possibly followed by a value.
The name of an option can be short or long.
-h, -q, -I.--help, --silent, --ignore-case.More than one name may refer to the same optional argument. For example in a given program the names -q, --quiet and --silent may all stand for the same boolean argument indicating the program to be quiet. Long names can be specified by any non ambiguous prefix.
The value of an option can be specified in three different ways.
-o a.out, --output a.out.-oa.out.--output=a.out.Glued forms are especially useful if the value itself starts with a dash as is the case for negative numbers, --min=-10.
An optional argument without a value is either a flag (see Cmdliner.Arg.flag, Cmdliner.Arg.vflag) or an optional argument with an optional value (see the ~vopt argument of Cmdliner.Arg.opt).
Short flags can be grouped together to share a single dash and the group can end with a short option. For example assuming -v and -x are flags and -f is a short option:
-vx will be parsed as -v -x.-vxfopt will be parsed as -v -x -fopt.-vxf opt will be parsed as -v -x -fopt.-fvx will be parsed as -f=vx.Positional arguments are tokens on the command line that are not option names and are not the value of an optional argument. They are numbered from left to right starting with zero.
Since positional arguments may be mistaken as the optional value of an optional argument or they may need to look like option names, anything that follows the special token "--" on the command line is considered to be a positional argument:
tool --option -- we -are --all positional --argu=mentsNon-required command line arguments can be backed up by an environment variable. If the argument is absent from the command line and that the environment variable is defined, its value is parsed using the argument converter and defines the value of the argument.
For Cmdliner.Arg.flag and Cmdliner.Arg.flag_all that do not have an argument converter a boolean is parsed from the lowercased variable value as follows:
"", "false", "no", "n" or "0" is false."true", "yes", "y" or "1" is true.Note that environment variables are not supported for Cmdliner.Arg.vflag and Cmdliner.Arg.vflag_all.
Using the cmdliner library puts the following constraints o
--cmdliner is reserved by the library.--help, (and --version if you specify a version string) is reserved by the library. Using it as a term or option name may result in undefined behaviour.Invalid_argument.This manual describes how your tool ends up interacting with shells when you use Cmdliner.
For tools evaluating a command without subcommands the most general form of invocation is:
tool [OPTION]… [ARG]…
The tool automatically reponds to the --help option by printing the help. If a version string is provided in the command information, it also automatically responds to the --version option by printing this string on standard output.
Command line arguments are either optional or positional. Both can be freely interleaved but since Cmdliner accepts many optional forms this may result in ambiguities. The special token -- can be used to resolve them: anything that follows it is treated as a positional argument.
Tools evaluating commands with subcommands have this form of invocation
tool [COMMAND]… [OPTION]… [ARG]…
Commands automatically respond to the --help option by printing their help. The sequence of COMMAND strings must be the first strings following the tool name – as soon as an optional argument is seen the search for a subcommand stops.
An optional argument is specified on the command line by a name possibly followed by a value.
The name of an option can be short or long.
-h, -q, -I.--help, --silent, --ignore-case.More than one name may refer to the same optional argument. For example in a given program the names -q, --quiet and --silent may all stand for the same boolean argument indicating the program to be quiet.
The value of an option can be specified in three different ways.
-o a.out, --output a.out.-oa.out.--output=a.out.Glued forms are especially useful if the value itself starts with a dash as is the case for negative numbers, --min=-10.
An optional argument without a value is either a flag (see Cmdliner.Arg.flag, Cmdliner.Arg.vflag) or an optional argument with an optional value (see the ~vopt argument of Cmdliner.Arg.opt).
Short flags can be grouped together to share a single dash and the group can end with a short option. For example assuming -v and -x are flags and -f is a short option:
-vx will be parsed as -v -x.-vxfopt will be parsed as -v -x -fopt.-vxf opt will be parsed as -v -x -fopt.-fvx will be parsed as -f=vx.Positional arguments are tokens on the command line that are not option names and are not the value of an optional argument. They are numbered from left to right starting with zero.
Since positional arguments may be mistaken as the optional value of an optional argument or they may need to look like option names, anything that follows the special token "--" on the command line is considered to be a positional argument:
tool --option -- but --now we -are --all positional --argu=ments
Using the cmdliner library puts the following constraints on your command line interface:
--cmdliner and --__complete are reserved by the library.--help, (and --version if you specify a version string) is reserved by the library. Using it as a term or option name may result in undefined behaviour.Invalid_argument.Non-required command line arguments can be backed up by an environment variable. If the argument is absent from the command line and the environment variable is defined, its value is parsed using the argument converter and defines the value of the argument.
For Cmdliner.Arg.flag and Cmdliner.Arg.flag_all that do not have an argument converter a boolean is parsed from the lowercased variable value as follows:
"", "false", "no", "n" or "0" is false."true", "yes", "y" or "1" is true.Note that environment variables are not supported for Cmdliner.Arg.vflag and Cmdliner.Arg.vflag_all.
Help and man pages are are generated when you call your tool or a subcommand with --help. By default, if the TERM environment variable is not dumb or unset, the tool tries to page the manual so that you can directly search it. Otherwise it outputs the manual as plain text.
Alternative help formats can be specified with the optional argument of --help, see your own tool --help for more information.
tool --help
+tool cmd --help
+tool --help=groff > tool.1The pager is selected by looking up, in order:
MANPAGER variable.PAGER variable.less.more.Regardless of the pager, it is invoked with LESS=FRX set in the environment unless, the LESS environment variable is set in your environment.
The manpages of a tool and its subcommands can be installed to a root man directory $MANDIR by invoking:
cmdliner install tool-manpages thetool $MANDIRThis looks up thetool in the PATH. Use an explicit file path like ./thetool to directly specify an executable.
If you are also installing completions rather use the install tool-support command, see this cookbook tip which also has instructions on how to install if you are using opam.
Cmdliner programs automatically get support for shell command line completion.
The completion process happens via a protocol which is interpreted by generic shell completion scripts that are installed by the library. For now the zsh and bash shells are supported.
Tool developers can easily install completion definitions that invoke these completion scripts. Tool end-users need to make sure these definitions are looked up by their shell.
If you are the user of a cmdliner based tool, the following shell-dependent steps need to be performed in order to benefit from command line completion.
zshThe FPATH environment variable must be setup to include the directory where the generic cmdliner completion function is installed before properly initializing the completion system.
For example, for now, if you are using opam. You should add something like this to your .zshrc:
FPATH="$(opam var share)/zsh/site-functions:${FPATH}"
+autoload -Uz compinit
+compinit -uAlso make sure this happens before opam's zsh init script inclusion, see this issue. Note that these instruction do not react dynamically to opam switches changes so you may see odd completion behaviours when you do so, see this this opam issue.
After this, to test everything is right, check that the _cmdliner_generic function can be looked by invoking it (this will result in an error).
> autoload _cmdliner_generic
+> _cmdliner_generic
+_cmdliner_generic:1: words: assignment to invalid subscript rangeIf the function cannnot be found make sure the cmdliner library is installed, that the generic scripts were installed and that the _cmdliner_generic file can be found in one of the directories mentioned in the FPATH variable.
With this setup, if you are using a cmdliner based tool named thetool that did not install a completion definition. You can always do it yourself by invoking:
autoload _cmdliner_generic
+compdef _cmdliner_generic thetoolbashThese instructions assume that you have bash-completion installed and setup in some way in your .bashrc.
The XDG_DATA_DIRS environment variable must be setup to include the share directory where the generic cmdliner completion function is installed.
For example, for now, if you are using opam. You should add something like this to your .bashrc:
XDG_DATA_DIRS="$(opam var share):${XDG_DATA_DIRS}"Note that these instruction do not react dynamically to opam switches changes so you may see odd completion behaviours when you do so, see this this opam issue.
After this, to test everything is right, check that the _cmdliner_generic function can be looked up:
> _completion_loader _cmdliner_generic
+> declare -F _cmdliner_generic &>/dev/null && echo "Found" || echo "Not found"
+Found!If the function cannot be found make sure the cmdliner library is installed, that the generic scripts were installed and that the _cmdliner_generic file can be looked up by _completion_loader.
With this setup, if you are using a cmdliner based tool named thetool that did not install a completion definition. You can always do it yourself by invoking:
_completion_loader _cmdliner_generic
+complete -F _cmdliner_generic thetoolNote. It seems _completion_loader was deprecated in bash-completion 2.12 in favour of _comp_load but many distributions are on < 2.12 and in 2.12 _completion_loader simply calls _comp_load.
Completion scripts need to be installed in subdirectories of a share directory which we denote by the $SHAREDIR variable below. In a package installation script this variable is typically defined by:
SHAREDIR="$DESTDIR/$PREFIX/share"The final destination directory in share depends on the shell:
zsh it is $SHAREDIR/zsh/site-functionsbash it is $SHAREDIR/bash-completion/completionsIf that is unsatisfying you can output the completion scripts directly where you want with the cmdliner generic-completion and cmdliner tool-completion commands.
The generic completion scripts must be installed by the cmdliner library. They should not be part of your tool install. If they are not installed you can inspect and install them with the following invocations, invoke with --help for more information.
cmdliner generic-completion zsh # Output generic zsh script on stdout
+cmdliner install generic-completion $SHAREDIR # All shells
+cmdliner install generic-completion --shell zsh $SHAREDIR # Only zshDirectories are created as needed. Use option --dry-run to see which paths would be written by an install invocation.
If your tool named thetool uses Cmdliner you should install completion definitions for them. They rely on the generic scripts to be installed. These tool specific scripts can be inspected and installed via these invocations:
cmdliner tool-completion zsh thetool # Output tool zsh script on stdout.
+cmdliner install tool-completion thetool $SHAREDIR # All shells
+cmdliner install tool-completion --shell zsh thetool $SHAREDIR # Only zshDirectories are created as needed. Use option --dry-run to see which paths would be written by an install invocation.
If you are also installing manpages rather use the install tool-support command, see this cookbook tip which also has instructions on how to install if you are using opam.
There is no standard that allows tools and shells to interact to perform shell command line completion. Completion is supposed to happen through idiosyncratic, ad-hoc, obscure and brain damaging shell-specific completion scripts.
To alleviate this, Cmdliner defines one generic script per shell and interacts with it using the protocol described below. The protocol can be used to implement generic completion scripts for other shells. The protocol is versioned but can change even between minor versions of Cmdliner. Generic scripts for popular shells can be inspected via the cmdliner generic-completion command.
The protocol betwen the shell completion script and a cmdliner based tool is as follows:
When completion is requested the script invokes the tool with a modified command line:
Sys.argv.(1)) must be the option --__complete.ARG on which the completion is requested must be replaced by exactly --__complete=ARG. Note that this can happen after the -- token, this is the reason why we have an explicit --__complete argument in Sys.argv.(1): it indicates the command line parser must operate in a special mode.completions rule of the grammar given below.The following ABNF grammar is described using the notations of RFC 5234 and RFC 7405. A few constraints are not expressed by the grammar:
completion rule, the byte stream may contain ANSI escape sequences introduced by the byte 0x1B.completions = version nl directives
+version = "1"
+directives = *(directive nl)
+directive = message / group / %s"files" / %s"dirs" / %"restart"
+message = %s"message" nl text nl %s"message-end"
+group = %s"group" nl group_name nl *item
+group_name = *pchar
+item = %s"item" nl completion nl item_doc nl %s"item-end"
+completion = *pchar
+item_doc = text
+text = *(pchar / nl)
+nl = %0A
+pchar = %20-%7E / %8A-%FFThe semantics of directives is as follows:
message directive defines a message to be reported to the user. It is multi-line ANSI styled text which cannot have a line that is exactly made of the text message-end as it is used to signal the end of the message. Messages should be reported in the order they are received.group directive defines an informational group_name followed by a possibly empty list of completion items that are part of the group. An item provides a completion value, this is a string that defines what the requested ARG value can be replaced with. It is followed by an item_doc, multi-line ANSI styled text which cannot have a line that is exactly made of the text item-end as it is used to signal the end of the item.file directive indicates that the script should add existing files staring with ARG to completion values.dir directive indicates that the script should add existing directories starting with ARG to completion values.restart directive indicates that the script should restart shell completion as if the command line was starting after the leftmost -- disambiguation token. The directive never gets emited if there is no -- on the command line.You can easily inspect the completions of any cmdliner based tool by invoking it like the protocol suggests. For example for the cmdliner tool itself:
cmdliner --__complete --__complete=Since Cmdliner 2.0 error messages printed on stderr use styled text with ANSI escapes unless one of the following conditions is met:
NO_COLOR environment variable is set and different from the empty string. Yes, even if you have NO_COLOR=false, that's what the particularly dumb https://no-color.org standard says.TERM environment variable is dumb.TERM environment variable is unset and Sys.backend_type is not Other "js_of_ocaml". Yes, browser consoles support ANSI escapes. Yes, you can run Cmdliner in your browser.Before Cmdliner 2.0, command names, long option names and Cmdliner.Arg.enum values could be specified by a prefix as long as the prefix was not ambiguous.
This turned out to be a mistake. It makes the user experience of the tool unstable as it evolves: former user established shortcuts or invocations in scripts may be broken by new command, option and enumerant additions.
Therefore this behaviour was unconditionally removed in Cmdliner 2.0. If you happen to have scripts that rely on it, you can invoke them with CMDLINER_LEGACY_PREFIXES=true set in the environment to recover the old behaviour. However the scripts should be fixed: this escape hatch will be removed in the future.
The CMDLINER_LEGACY_PREFIX=true escape hatch should not be used for interactive tool interaction. In particular the behaviour of Cmdliner completion support under this setting is undefined.
Cmdliner cookbookA few recipes and starting blueprints to describe your command lines with Cmdliner.
Note. Some of the code snippets here assume they are done after:
open Cmdliner
+open Cmdliner.Term.SyntaxCommand line interfaces are a rather crude and inexpressive user interaction medium. It is tempting to try to be nice to users in various ways but this often backfires in confusing context sensitive behaviours. Here are a few tips and Cmdliner features you should rather not use.
Command groups can have a default command, that is be of the form tool [CMD]. Except perhaps at the top level of your tool, it's better to avoid them. They increase command line parsing ambiguities.
In particular if the default command has positional arguments, users are forced to use the disambiguation token -- to specify them so that they can be distinguished from command names. For example:
tool -- file …One thing that is acceptable is to have a default command that simply shows documentation for the group of subcommands as this not interfere with tool operation.
Optional arguments with values can have a default value, that is be of the form --opt[=VALUE]. In general it is better to avoid them as they lead to context sensitive command lines specifications and surprises when users refine invocations. For examples suppose you have the synopsis
tool --opt[=VALUE] [FILE]Trying to refine the following invocation to add a FILE parameter is error prone and painful:
tool --optThere is more than one way but the easiest way is to specify:
tool --opt -- FILEwhich is not obvious unless you have tool's cli hard wired in your brain. This would have been a careless refinement if --opt did not have a default option value.
Cmdliner allows to define required optional arguments. Avoid doing this, it's a contradiction in the terms. In command line interfaces optional arguments are defined to be… optional, not doing so is surprising for your users. Use required positional arguments if arguments are required by your command invocation.
Required optional arguments can be useful though if your tool is not meant to be invoked manually but rather through scripts and has many required arguments. In this case they become a form of labelled arguments which can make invocations easier to understand.
Unless your tool is very simple, avoid making manpages the main documentation medium of your tool. The medium is rather limited and even though you can convert them to HTML, its cross references capabilities are rather limited which makes discussing your tool online more difficult.
Keep information in manpages to the minimum needed to operate your tool without having to leave the terminal too much and defer reference manuals, conceptual information and tutorials to a more evolved medium like HTML.
If you are porting your command line parsing to Cmdliner and that you have conventions that clash with Cmdliner's ones but you need to preserve backward compatibility, one way of proceeding is to pre-process Sys.argv into a new array of the right shape before giving it to command evaluation functions via the ?argv optional argument.
These are two common cases:
-warn-error. In this case simply prefix an additional - to these arguments when they occur in Sys.argv before the -- argument; after it, all arguments are positional and to be treated literally.--X. In this case simply chop the first - to make it a short option when they occur in Sys.argv before the -- argument; after it all arguments are positional and to be treated literally.In general Cmdliner wants you to see your tools as regular OCaml functions that you make available to the shell. This means adopting the following source structure:
(* Implementation of your command. Except for exit codes does not deal with
+ command line interface related matters and is independent from
+ Cmdliner. *)
+
+let exit_ok = 0
+let tool … = …; exit_ok
+
+(* Command line interface. Adds metadata to your [tool] function arguments
+ so that they can be parsed from the command line and documented. *)
+
+open Cmdliner
+open Cmdliner.Term.Syntax
+
+let cmd = … (* Has a term that invokes [tool] *)
+let main () = Cmd.eval' cmd
+let () = if !Sys.interactive then () else exit (main ())In particular it is good for your readers' understanding that your program has a single point where it Stdlib.exits. This structure is also useful for playing with your program in the OCaml toplevel (REPL), you can invoke its main function without having the risk of it exiting the toplevel.
If your tool named tool is growing into multiple commands which have a lot of definitions it is advised to:
Tool_cli.name in a separate module Cmd_name which exports its command as a val cmd : int Cmd.t value.Cmdliner.Cmd.group in a source file called tool_main.ml.For an hypothetic tool named tool with commands import, serve and user, this leads to the following set of files:
cmd_import.ml cmd_serve.ml cmd_user.ml tool_cli.ml tool_main.ml
+cmd_import.mli cmd_serve.mli cmd_user.mli tool_cli.mliThe .mli files simply export commands:
val cmd : int Cmdliner.Cmd.tAnd the tool_main.ml gathers them with a Cmdliner.Cmd.group:
let cmd =
+ let default = Term.(ret (const (`Help (`Auto, None)))) (* show help *) in
+ Cmd.group (Cmd.info "tool") ~default @@
+ [Cmd_import.cmd; Cmd_serve.cmd; Cmd_user.cmd]
+
+let main () = Cmd.value' cmd
+let () = if !Sys.interactive then () else exit (main ())The cmdliner tool can be used to install completion scripts and manpages for you tool and its subcommands by using the dedicated install tool-completion and install tool-manpages subcommands.
To install both directly (and possibly other support files in the future) it is more concise to use the install tool-support command. Invoke with --help for more information.
opamIf you are installing your package with opam for a tool named tool located in the build at the path $BUILD/tool, you can add the following instruction after your build instructions in the build: field of your opam file (also works if your build system is not using a .install file).
build: [
+ [ … ] # Your regular build instructions
+ ["cmdliner" "install" "tool-support"
+ "--update-opam-install=%{_:name}%.install"
+ "$BUILD/tool" "_build/cmdliner-install"]]You need to specify the path to the built executable, as it cannot be looked up in the PATH yet. Also more than one tool can be specified in a single invocation and there is a syntax for specifying the actual tool name if it is renamed on install; see --help for more details.
If cmdliner is only an optional dependency of your package use the opam filter {cmdliner:installed} after the closing bracket of the command invocation.
opam and duneFirst make sure your understand the above basic instructions for opam. You then need to figure out how to add the cmdliner install instruction to the build: field of the opam file after your dune build instructions. For a tool named tool the result should eventually look this:
build: [
+ [ … ] # Your regular dune build instructions
+ ["cmdliner" "install" "tool-support"
+ "--update-opam-install=%{_:name}%.install"
+ "_build/default/install/bin/tool" {os != "win32"}
+ "_build/default/install/bin/tool.exe" {os = "win32"}
+ "_build/cmdliner-install"]]By simply using Cmdliner you are already abiding to a great deal of command line interface conventions. Here are a few other ones that are not necessarily enforced by the library but that are good to adopt for your users.
"-" to specify stdio in file path argumentsWhenever a command line argument specifies a file path to read or write you should let the user specify - to denote standard in or standard out, if possible. If you worry about a file sporting this name, note that the user can always specify it using ./- for the argument.
Very often tools default to stdin or stdout when a file input or output is unspecified, here is typical argument definitions to support these conventions:
let infile =
+ let doc = "$(docv) is the file to read from. Use $(b,-) for $(b,stdin)" in
+ Arg.(value & opt string "-" & info ["i", "input-file"] ~doc ~docv:"FILE")
+
+let outfile =
+ let doc = "$(docv) is the file to write to. Use $(b,-) for $(b,stdout)" in
+ Arg.(value & opt string "-" & info ["o", "output-file"] ~doc ~docv:"FILE")Here is Stdlib based code to read to a string a file or standard input if - is specified:
let read_file file =
+ let read file ic = try Ok (In_channel.input_all ic) with
+ | Sys_error e -> Error (Printf.sprintf "%s: %s" file e)
+ in
+ let binary_stdin () = In_channel.set_binary_mode In_channel.stdin true in
+ try match file with
+ | "-" -> binary_stdin (); read file In_channel.stdin
+ | file -> In_channel.with_open_bin file (read file)
+ with Sys_error e -> Error eHere is Stdlib based code to write a string to a file or standard output if - is specified:
let write_file file s =
+ let write file s oc = try Ok (Out_channel.output_string oc s) with
+ | Sys_error e -> Error (Printf.sprintf "%s: %s" file e)
+ in
+ let binary_stdout () = Out_channel.(set_binary_mode stdout true) in
+ try match file with
+ | "-" -> binary_stdout (); write file s Out_channel.stdout
+ | file -> Out_channel.with_open_bin file (write file s)
+ with Sys_error e -> Error eCmdliner has support to back values defined by arguments with environment variables. The value specified via an environment variable should never take over an argument specified explicitely on the command line. The environment variable should be seen as providing the default value when the argument is absent.
This is exactly what Cmdliner's support for environment variables does, see How can environment variables define defaults?
Positional arguments are extracted from the command line using these combinators which use zero-based indexing. The following example extracts the first argument and if the argument is absent from the command line it evaluates to "Revolt!".
let msg =
+ let doc = "$(docv) is the message to utter." and docv = "MSG" in
+ Arg.(value & pos 0 string "Revolt!" & info [] ~doc ~docv)Optional arguments are extracted from the command line using these combinators. The actual option name is defined in the Cmdliner.Arg.info structure without dashes. One character strings define short options, others long options (see the parsed syntax).
The following defines the -l and --loud options. This is a simple command line argument without a value also known as a command line flag. The term loud evaluates to false when the argument is absent on the command line and true otherwise.
let loud =
+ let doc = "Say the message loudly." in
+ Arg.(value & flag & info ["l"; "loud"] ~doc)The following defines the -m and --message options. The term msg evalutes to "Revolt!" when the option is absent on the command line.
let msg =
+ let doc = "$(docv) is the message to utter." and docv = "MSG" in
+ Arg.(value & opt string "Revolt!" & info ["m"; "message"] ~doc ~docv)Some of the constraints on the presence of arguments occur when the specification of arguments is converted to terms. The following says that the first positional argument is required:
let msg =
+ let msg = "$(docv) is the message to utter." and docv = "MSG" in
+ Arg.(required & pos 0 (some string) None & info [] ~absent ~doc ~docv)The value msg ends up being a term of type string. If the argument is not provided, Cmdliner will automatically bail out during evaluation with an error message.
Note that while it is possible to define required positional argument it is discouraged.
Most positional and optional arguments have a default value. You can use a None for the default argument and the Cmdliner.Arg.some or Cmdliner.Arg.some' combinators on your argument converter which simply wrap its result in a Some.
let msg =
+ let msg = "$(docv) is the message to utter." in
+ let absent = "Random quote." in
+ Arg.(value & pos 0 (some string) None & info [] ~absent ~doc ~docv:"MSG")There is more than one way to document the value when it is absent. See How do I document absent argument behaviours?
There are three ways to document the behaviour when an argument is unspecified on the command line.
Cmdliner.Arg.some' and Cmdliner.Arg.some there is an optional none argument that allows you to specify the default value. If you can exhibit this value at definition point use Cmdliner.Arg.some', the underlying converter's printer will be used. If not you can specify it as a string rendered in bold via Cmdliner.Arg.some.~absent parameter of Cmdliner.Arg.info. Using this parameter overrides the two previous ways. See this example.Positional argument values and option values are completed according to the argument converter you use for defining the optional or positional argument.
A couple of predefined argument converter like Cmdliner.Arg.path, Cmdliner.Arg.filepath and Cmdliner.Arg.dirpath or Cmdliner.Arg.enum automatically handle this for you.
If you would like to perform custom or more elaborate context sensitive completions you can define your own argument converter with a completion defined with Cmdliner.Arg.Completion.make.
Here is an example where the first positional argument is completed with the filenames found in a directory specified via the --dir option (which defaults to the current working directory if unspecified).
let dir = Arg.(value & opt dirpath "." & info ["d"; "dir"])
+let dir_filenames_conv =
+ let complete dir ~token = match dir with
+ | None -> Error "Could not determine directory to lookup"
+ | Some dir ->
+ match Array.to_list (Sys.readdir dir) with
+ | exception Sys_error e -> Error (String.concat ": " [dir; e])
+ | fnames ->
+ let fnames = List.filter (String.starts_with ~prefix:token) fnames in
+ Ok (List.map Arg.Completion.string fnames)
+ in
+ let completion = Arg.Completion.make ~context:dir complete in
+ Arg.Conv.of_conv ~completion Arg.string
+
+let pos0 = Arg.(required & pos 0 (some dir_filenames_conv) None & info [])Note that when you use pos0 in a command line definition you also need to make sure dir is part of the term otherwise the context will always be None:
let+ pos0 and+ dir and+ … in …As mentioned in Environment variables as default modifiers, any non-required argument can be defined by an environment variable when absent. This works by specifying the env argument in the argument's Cmdliner.Arg.info information. For example:
let msg =
+ let doc = "$(docv) is the message to utter." and docv = "MSG" in
+ let env = Cmd.Env.info "MESSAGE" in
+ Arg.(value & pos 0 string "Revolt!" & info [] ~env ~doc ~docv)When the first positional argument is absent it takes the default value "Revolt!", unless the MESSAGE variable is defined in the environment in which case it takes its value.
Cmdliner handles the environment variable lookup for you. By using the msg term in your command definition all this gets automatically documented in the tool help.
Environment variable that are used to change argument defaults automatically get documented in a command's man page when you use the argument's term in the command's term.
However if your command implementation looks up other variables and you wish to document them in the command's man page, use the envs argument of Cmdliner.Cmd.info or the docs_env argument of Cmdliner.Arg.info.
This documents in the Cmdliner.Manpage.s_environment manual section of tool that EDITOR is looked up to find the tool to invoke to edit the files:
let editor_env = "EDITOR"
+let tool … = … Sys.getenv_opt editor_env
+let cmd =
+ let env = Cmd.Env.info editor_env ~doc:"The editor used to edit files." in
+ Cmd.make (Cmd.info "tool" ~envs:[env]) @@
+ …Exit codes are documentd by Cmdliner.Cmd.Exit.info values and must be given to the command's Cmdliner.Cmd.info value via the exits optional arguments. For example:
let conf_not_found = 1
+let tool … =
+let tool_cmd =
+ let exits =
+ Cmd.Exit.info conf_not_found "if no configuration could be found." ::
+ Cmd.Exit.defaults
+ in
+ Cmd.make (Cmd.info "mycmd" ~exits) @@
+ …While it is usually not advised to have a default command in a group, just showing docs is acceptable. A term can request Cmdliner's generated help by using Cmdliner.Term.ret:
let group_cmd =
+ let default = Term.(ret (const (`Help (`Auto, None)))) (* show help *) in
+ Cmd.group (Cmd.info "group") ~default @@
+ [first_cmd; second_cmd]Cmd evaluation function should I use?There are (too) many command evaluation functions. They have grown organically in a rather ad-hoc manner. Some of these are there for backwards compatibility reasons and advanced usage for complex tools.
Here are the main ones to use and why you may want to use them which essentially depends on how you want to handle errors and exit codes in your tool function.
Cmdliner.Cmd.eval. This forces your tool function to return (). The evaluation function always returns an exit code of 0 unless a command line parsing error occurs.Cmdliner.Cmd.eval'. Recommended. This forces your tool function to return an exit code exit which is returned by the evaluation function unless a command line parsing error occurs. This is the recommended function to use as it forces you to think about how to report errors and design useful exit codes for users.Cmdliner.Cmd.eval_result is akin to Cmdliner.Cmd.eval except it forces your function to return either Ok () or Error msg. The evaluation function returns with exit code 0 unless Error msg is computed in which case msg is printed on the error stream prefixed by the executable name and the evaluation function returns with exit code Cmdliner.Cmd.Exit.some_error.Cmdliner.Cmd.eval_result' is akin to Cmdliner.Cmd.eval_result, except the Ok case carries an exit code which is returned by the evaluation function.The command line interface manual has all the details and specific instructions for complementing your tool install. See also Installing completions and manpages.
In a shell the invocation cmdliner tool-commands $TOOL lists every command of the tool $TOOL.
Since Cmdliner 2.0, error message printed on stderr use styled text with ANSI escapes. Styled text is disabled if one of the conditions mentioned here is met.
If you want to be more aggressive in suppressing them you can use the err formatter argument of command evaluation functions with a suitable formatter on which a function like this one has been applied that automatically strips the styling.
In general it's not a good idea to hide stuff from your users but in case an item needs to be hidden you can use the special Cmdliner.Manpage.s_none section name. This ensures the item does not get listed in any section.
let secret = Arg.(value & flag & info ["super-secret"] ~docs:Manpage.s_none)Define the Cmdliner.Manpage.s_synopsis section in the manpage of your command. It takes over the one generated by Cmdliner. For example:
let man = [
+ `S Manpage.s_synopsis;
+ `P "$(cmd) $(b,--) $(i,TOOL) [$(i,ARG)]…"; `Noblank;
+ `P "$(cmd) $(i,COMMAND) …";
+ `S Manpage.s_description;
+ `P "Without a command $(cmd) invokes $(i,TOOL)"; ]The command line interface manual the details on how to install the manpages of your tool and its subcommands. See also Installing completions and manpages.
These blueprints when copied to a src.ml file can be compiled and run with:
ocamlfind ocamlopt -package cmdliner -linkgpkg src.ml
+./a.out --helpMore concrete examples can be found on the examples page and the tutorial may help too.
These examples follow a conventional Source code structure.
A minimal example.
let tool () = Cmdliner.Cmd.Exit.ok
+
+open Cmdliner
+open Cmdliner.Term.Syntax
+
+let cmd =
+ Cmd.make (Cmd.info "TODO" ~version:"v2.0.0") @@
+ let+ unit = Term.const () in
+ tool unit
+
+let main () = Cmd.eval' cmd
+let () = if !Sys.interactive then () else exit (main ())This is a tool that has a flag, an optional positional argument for specifying an input file. It also responds to the --version option.
let exit_todo = 1
+let tool ~flag ~infile = exit_todo
+
+open Cmdliner
+open Cmdliner.Term.Syntax
+
+let flag = Arg.(value & flag & info ["flag"] ~doc:"The flag")
+let infile =
+ let doc = "$(docv) is the input file. Use $(b,-) for $(b,stdin)." in
+ Arg.(value & pos 0 string "-" & info [] ~doc ~docv:"FILE")
+
+let cmd =
+ let doc = "The tool synopsis is TODO" in
+ let man = [
+ `S Manpage.s_description;
+ `P "$(cmd) does TODO" ]
+ in
+ let exits =
+ Cmd.Exit.info exit_todo ~doc:"When there is stuff todo" ::
+ Cmd.Exit.defaults
+ in
+ Cmd.make (Cmd.info "TODO" ~version:"v2.0.0" ~doc ~man ~exits) @@
+ let+ flag and+ infile in
+ tool ~flag ~infile
+
+let main () = Cmd.eval' cmd
+let () = if !Sys.interactive then () else exit (main ())This is a tool with two subcommands hey and ho. If your tools grows many subcommands you may want to follow these source code conventions.
let hey () = Cmdliner.Cmd.Exit.ok
+let ho () = Cmdliner.Cmd.Exit.ok
+
+open Cmdliner
+open Cmdliner.Term.Syntax
+
+let flag = Arg.(value & flag & info ["flag"] ~doc:"The flag")
+let infile =
+ let doc = "$(docv) is the input file. Use $(b,-) for $(b,stdin)." in
+ Arg.(value & pos 0 file "-" & info [] ~doc ~docv:"FILE")
+
+let hey_cmd =
+ let doc = "The hey command synopsis is TODO" in
+ Cmd.make (Cmd.info "hey" ~doc) @@
+ let+ unit = Term.const () in
+ ho ()
+
+let ho_cmd =
+ let doc = "The ho command synopsis is TODO" in
+ Cmd.make (Cmd.info "ho" ~doc) @@
+ let+ unit = Term.const () in
+ ho unit
+
+let cmd =
+ let doc = "The tool synopsis is TODO" in
+ Cmd.group (Cmd.info "TODO" ~version:"v2.0.0" ~doc) @@
+ [hey_cmd; ho_cmd]
+
+let main () = Cmd.eval' cmd
+let () = if !Sys.interactive then () else exit (main ())The examples are self-contained, cut and paste them in a file to play with them.
rm commandWe define the command line interface of an rm command with the synopsis:
rm [OPTION]… FILE…
The -f, -i and -I flags define the prompt behaviour of rm. It is represented in our program by the prompt type. If more than one of these flags is present on the command line the last one takes precedence.
To implement this behaviour we map the presence of these flags to values of the prompt type by using Cmdliner.Arg.vflag_all.
This argument will contain all occurrences of the flag on the command line and we just take the Cmdliner.Arg.last one to define our term value. If there is no occurrence the last value of the default list [Always] is taken. This means the default prompt behaviour is Always.
(* Implementation of the command, we just print the args. *)
+examples (cmdliner.examples) Examples
The examples are self-contained, cut and paste them in a file to play with them. See also the suggested source code structure and program blueprints.
A rm command
We define the command line interface of an rm command with the synopsis:
rm [OPTION]… FILE…
The -f, -i and -I flags define the prompt behaviour of rm. It is represented in our program by the prompt type. If more than one of these flags is present on the command line the last one takes precedence.
To implement this behaviour we map the presence of these flags to values of the prompt type by using Cmdliner.Arg.vflag_all.
This argument will contain all occurrences of the flag on the command line and we just take the Cmdliner.Arg.last one to define our term value. If there is no occurrence the last value of the default list [Always] is taken. This means the default prompt behaviour is Always.
(* Implementation of the command, we just print the args. *)
type prompt = Always | Once | Never
let prompt_str = function
| Always -> "always" | Once -> "once" | Never -> "never"
-let rm prompt recurse files =
+let rm ~prompt ~recurse files =
Printf.printf "prompt = %s\nrecurse = %B\nfiles = %s\n"
(prompt_str prompt) recurse (String.concat ", " files)
(* Command line interface *)
open Cmdliner
+open Cmdliner.Term.Syntax
let files = Arg.(non_empty & pos_all file [] & info [] ~docv:"FILE")
let prompt =
@@ -36,29 +37,30 @@ let recursive =
let doc = "Remove directories and their contents recursively." in
Arg.(value & flag & info ["r"; "R"; "recursive"] ~doc)
-let cmd =
+let rm_cmd =
let doc = "Remove files or directories" in
let man = [
`S Manpage.s_description;
- `P "$(tname) removes each specified $(i,FILE). By default it does not
+ `P "$(cmd) removes each specified $(i,FILE). By default it does not
remove directories, to also remove them and their contents, use the
option $(b,--recursive) ($(b,-r) or $(b,-R)).";
`P "To remove a file whose name starts with a $(b,-), for example
$(b,-foo), use one of these commands:";
- `Pre "$(mname) $(b,-- -foo)"; `Noblank;
- `Pre "$(mname) $(b,./-foo)";
- `P "$(tname) removes symbolic links, not the files referenced by the
+ `Pre "$(cmd) $(b,-- -foo)"; `Noblank;
+ `Pre "$(cmd) $(b,./-foo)";
+ `P "$(cmd.name) removes symbolic links, not the files referenced by the
links.";
`S Manpage.s_bugs; `P "Report bugs to <bugs@example.org>.";
`S Manpage.s_see_also; `P "$(b,rmdir)(1), $(b,unlink)(2)" ]
in
- let info = Cmd.info "rm" ~version:"v1.3.0" ~doc ~man in
- Cmd.v info Term.(const rm $ prompt $ recursive $ files)
+ Cmd.make (Cmd.info "rm" ~version:"v2.0.0" ~doc ~man) @@
+ let+ prompt and+ recursive and+ files in
+ rm ~prompt ~recurse:recursive files
-let main () = exit (Cmd.eval cmd)
-let () = main ()
A cp command
We define the command line interface of a cp command with the synopsis:
cp [OPTION]… SOURCE… DEST
The DEST argument must be a directory if there is more than one SOURCE. This constraint is too complex to be expressed by the combinators of Cmdliner.Arg.
Hence we just give DEST the Cmdliner.Arg.string type and verify the constraint at the beginning of the implementation of cp. If the constraint is unsatisfied we return an `Error result. By using Cmdliner.Term.ret on the lifted result cp_t of cp, Cmdliner handles the error reporting.
(* Implementation, we check the dest argument and print the args *)
+let main () = Cmd.eval rm_cmd
+let () = if !Sys.interactive then () else exit (main ())
A cp command
We define the command line interface of a cp command with the synopsis:
cp [OPTION]… SOURCE… DEST
The DEST argument must be a directory if there is more than one SOURCE. This constraint is too complex to be expressed by the combinators of Cmdliner.Arg.
Hence we just give DEST the Cmdliner.Arg.string type and verify the constraint at the beginning of the implementation of cp. If the constraint is unsatisfied we return an `Error result. By using Cmdliner.Term.ret on the command's term for cp, Cmdliner handles the error reporting.
(* Implementation, we check the dest argument and print the args *)
-let cp verbose recurse force srcs dest =
+let cp ~verbose ~recurse ~force srcs dest =
let many = List.length srcs > 1 in
if many && (not (Sys.file_exists dest) || not (Sys.is_directory dest))
then `Error (false, dest ^ ": not a directory") else
@@ -69,6 +71,7 @@ let cp verbose recurse force srcs dest =
(* Command line interface *)
open Cmdliner
+open Cmdliner.Term.Syntax
let verbose =
let doc = "Print file names as they are copied." in
@@ -92,21 +95,22 @@ let dest =
let docv = "DEST" in
Arg.(required & pos ~rev:true 0 (some string) None & info [] ~docv ~doc)
-let cmd =
+let cp_cmd =
let doc = "Copy files" in
let man_xrefs =
- [ `Tool "mv"; `Tool "scp"; `Page ("umask", 2); `Page ("symlink", 7) ]
+ [`Tool "mv"; `Tool "scp"; `Page ("umask", 2); `Page ("symlink", 7)]
in
- let man =
- [ `S Manpage.s_bugs;
- `P "Email them to <bugs@example.org>."; ]
+ let man = [
+ `S Manpage.s_bugs;
+ `P "Email them to <bugs@example.org>."; ]
in
- let info = Cmd.info "cp" ~version:"v1.3.0" ~doc ~man ~man_xrefs in
- Cmd.v info Term.(ret (const cp $ verbose $ recurse $ force $ srcs $ dest))
+ Cmd.make (Cmd.info "cp" ~version:"v2.0.0" ~doc ~man ~man_xrefs) @@
+ Term.ret @@
+ let+ verbose and+ recurse and+ force and+ srcs and+ dest in
+ cp ~verbose ~recurse ~force srcs dest
-
-let main () = exit (Cmd.eval cmd)
-let () = main ()
A tail command
We define the command line interface of a tail command with the synopsis:
tail [OPTION]… [FILE]…
The --lines option whose value specifies the number of last lines to print has a special syntax where a + prefix indicates to start printing from that line number. In the program this is represented by the loc type. We define a custom loc_arg argument converter for this option.
The --follow option has an optional enumerated value. The argument converter follow, created with Cmdliner.Arg.enum parses the option value into the enumeration. By using Cmdliner.Arg.some and the ~vopt argument of Cmdliner.Arg.opt, the term corresponding to the option --follow evaluates to None if --follow is absent from the command line, to Some Descriptor if present but without a value and to Some v if present with a value v specified.
(* Implementation of the command, we just print the args. *)
+let main () = Cmd.eval cp_cmd
+let () = if !Sys.interactive then () else exit (main ())
A tail command
We define the command line interface of a tail command with the synopsis:
tail [OPTION]… [FILE]…
The --lines option whose value specifies the number of last lines to print has a special syntax where a + prefix indicates to start printing from that line number. In the program this is represented by the loc type. We define a custom loc_arg argument converter for this option.
The --follow option has an optional enumerated value. The argument converter follow, created with Cmdliner.Arg.enum parses the option value into the enumeration. By using Cmdliner.Arg.some and the ~vopt argument of Cmdliner.Arg.opt, the term corresponding to the option --follow evaluates to None if --follow is absent from the command line, to Some Descriptor if present but without a value and to Some v if present with a value v specified.
(* Implementation of the command, we just print the args. *)
type loc = bool * int
type verb = Verbose | Quiet
@@ -118,7 +122,7 @@ let loc_str (rev, k) = if rev then str "%d" k else str "+%d"
let follow_str = function Name -> "name" | Descriptor -> "descriptor"
let verb_str = function Verbose -> "verbose" | Quiet -> "quiet"
-let tail lines follow verb pid files =
+let tail ~lines ~follow ~verb ~pid files =
Printf.printf
"lines = %s\nfollow = %s\nverb = %s\npid = %s\nfiles = %s\n"
(loc_str lines) (opt_str follow_str follow) (verb_str verb)
@@ -127,17 +131,18 @@ let tail lines follow verb pid files =
(* Command line interface *)
open Cmdliner
+open Cmdliner.Term.Syntax
let loc_arg =
- let parse s =
+ let parser s =
try
if s <> "" && s.[0] <> '+'
then Ok (true, int_of_string s)
else Ok (false, int_of_string (String.sub s 1 (String.length s - 1)))
- with Failure _ -> Error (`Msg "unable to parse integer")
+ with Failure _ -> Error "unable to parse integer"
in
- let print ppf p = Format.fprintf ppf "%s" (loc_str p) in
- Arg.conv ~docv:"N" (parse, print)
+ let pp ppf p = Format.fprintf ppf "%s" (loc_str p) in
+ Arg.Conv.make ~docv:"N" ~parser ~pp ()
let lines =
let doc = "Output the last $(docv) lines or use $(i,+)$(docv) to start \
@@ -171,24 +176,24 @@ let pid =
let files = Arg.(value & (pos_all non_dir_file []) & info [] ~docv:"FILE")
-let cmd =
+let tail_cmd =
let doc = "Display the last part of a file" in
let man = [
`S Manpage.s_description;
- `P "$(tname) prints the last lines of each $(i,FILE) to standard output. If
- no file is specified reads standard input. The number of printed
+ `P "$(cmd) prints the last lines of each $(i,FILE) to standard output.
+ If no file is specified reads standard input. The number of printed
lines can be specified with the $(b,-n) option.";
`S Manpage.s_bugs;
`P "Report them to <bugs@example.org>.";
`S Manpage.s_see_also;
`P "$(b,cat)(1), $(b,head)(1)" ]
in
- let info = Cmd.info "tail" ~version:"v1.3.0" ~doc ~man in
- Cmd.v info Term.(const tail $ lines $ follow $ verb $ pid $ files)
+ Cmd.make (Cmd.info "tail" ~version:"v2.0.0" ~doc ~man) @@
+ let+ lines and+ follow and+ verb and+ pid and+ files in
+ tail ~lines ~follow ~verb ~pid files
-
-let main () = exit (Cmd.eval cmd)
-let () = main ()
A darcs command
We define the command line interface of a darcs command with the synopsis:
darcs [COMMAND] …
The --debug, -q, -v and --prehook options are available in each command. To avoid having to pass them individually to each command we gather them in a record of type copts. By lifting the record constructor copts into the term copts_t we now have a term that we can pass to the commands to stand for an argument of type copts. These options are documented in a section called COMMON OPTIONS, since we also want to put --help and --version in this section, the term information of commands makes a judicious use of the sdocs parameter of Cmdliner.Term.info.
The help command shows help about commands or other topics. The help shown for commands is generated by Cmdliner by making an appropriate use of Cmdliner.Term.ret on the lifted help function.
If the program is invoked without a command we just want to show the help of the program as printed by Cmdliner with --help. This is done by the default_cmd term.
(* Implementations, just print the args. *)
+let main () = Cmd.eval tail_cmd
+let () = if !Sys.interactive then () else exit (main ())
A darcs command
We define the command line interface of a darcs command with the synopsis:
darcs [COMMAND] …
The --debug, -q, -v and --prehook options are available in each command. To avoid having to pass them individually to each command we gather them in a record of type copts. By lifting the record constructor copts into the term copts_t we now have a term that we can pass to the commands to stand for an argument of type copts. These options are documented in the section Cmdliner.Manpage.s_common_options.
The help command shows help about commands or other topics. The help shown for commands is generated by Cmdliner by making an appropriate use of Cmdliner.Term.ret on the lifted help function.
If the program is invoked without a command we just want to show the help of the program as printed by Cmdliner with --help. This is done by the default term.
(* Implementations, just print the args. *)
type verb = Normal | Quiet | Verbose
type copts = { debug : bool; verb : verb; prehook : string option }
@@ -215,16 +220,18 @@ let help copts man_format cmds topic = match topic with
| None -> `Help (`Pager, None) (* help about the program. *)
| Some topic ->
let topics = "topics" :: "patterns" :: "environment" :: cmds in
- let conv, _ = Cmdliner.Arg.enum (List.rev_map (fun s -> (s, s)) topics) in
- match conv topic with
- | `Error e -> `Error (false, e)
- | `Ok t when t = "topics" -> List.iter print_endline topics; `Ok ()
- | `Ok t when List.mem t cmds -> `Help (man_format, Some t)
- | `Ok t ->
+ let conv = Cmdliner.Arg.enum (List.rev_map (fun s -> (s, s)) topics) in
+ let parse = Cmdliner.Arg.Conv.parser conv in
+ match parse topic with
+ | Error e -> `Error (false, e)
+ | Ok t when t = "topics" -> List.iter print_endline topics; `Ok ()
+ | Ok t when List.mem t cmds -> `Help (man_format, Some t)
+ | Ok t ->
let page = (topic, 7, "", "", ""), [`S topic; `P "Say something";] in
`Ok (Cmdliner.Manpage.print man_format Format.std_formatter page)
open Cmdliner
+open Cmdliner.Term.Syntax
(* Help sections common to all commands *)
@@ -232,9 +239,9 @@ let help_secs = [
`S Manpage.s_common_options;
`P "These options are common to all commands.";
`S "MORE HELP";
- `P "Use $(mname) $(i,COMMAND) --help for help on a single command.";`Noblank;
- `P "Use $(mname) $(b,help patterns) for help on patch matching."; `Noblank;
- `P "Use $(mname) $(b,help environment) for help on environment variables.";
+ `P "Use $(tool) $(i,COMMAND) --help for help on a single command.";`Noblank;
+ `P "Use $(tool) $(b,help patterns) for help on patch matching."; `Noblank;
+ `P "Use $(tool) $(b,help environment) for help on environment variables.";
`S Manpage.s_bugs; `P "Check bug reports at http://bugs.example.org.";]
(* Options common to all commands *)
@@ -254,7 +261,7 @@ let copts_t =
Arg.(last & vflag_all [Normal] [quiet; verbose])
in
let prehook =
- let doc = "Specify command to run before this $(mname) command." in
+ let doc = "Specify command to run before this $(tool) command." in
Arg.(value & opt (some string) None & info ["prehook"] ~docs ~doc)
in
Term.(const copts $ debug $ verb $ prehook)
@@ -276,8 +283,9 @@ let initialize_cmd =
existing files and subdirectories become …";
`Blocks help_secs; ]
in
- let info = Cmd.info "initialize" ~doc ~sdocs ~man in
- Cmd.v info Term.(const initialize $ copts_t $ repodir)
+ Cmd.make (Cmd.info "initialize" ~doc ~sdocs ~man) @@
+ let+ copts_t and+ repodir in
+ initialize copts_t repodir
let record_cmd =
let pname =
@@ -303,12 +311,12 @@ let record_cmd =
let man =
[`S Manpage.s_description;
`P "Creates a patch from changes in the working tree. If you specify
- a set of files …";
+ a set of files…";
`Blocks help_secs; ]
in
- let info = Cmd.info "record" ~doc ~sdocs ~man in
- Cmd.v info
- Term.(const record $ copts_t $ pname $ author $ all $ ask_deps $ files)
+ Cmd.make (Cmd.info "record" ~doc ~sdocs ~man) @@
+ let+ copts_t and+ pname and+ author and+ all and+ ask_deps and+ files in
+ record copts_t pname author all ask_deps files
let help_cmd =
let topic =
@@ -321,16 +329,18 @@ let help_cmd =
`P "Prints help about darcs commands and other subjects…";
`Blocks help_secs; ]
in
- let info = Cmd.info "help" ~doc ~man in
- Cmd.v info
- Term.(ret (const help $ copts_t $ Arg.man_format $ Term.choice_names $
- topic))
+ Cmd.make (Cmd.info "help" ~doc ~man) @@
+ Term.ret @@
+ let+ copts_t and+ man_format = Arg.man_format
+ and+ choice_names = Term.choice_names and+ topic in
+ help copts_t man_format choice_names topic
let main_cmd =
let doc = "a revision control system" in
let man = help_secs in
- let info = Cmd.info "darcs" ~version:"v1.3.0" ~doc ~sdocs ~man in
+ let info = Cmd.info "darcs" ~version:"v2.0.0" ~doc ~sdocs ~man in
let default = Term.(ret (const (fun _ -> `Help (`Pager, None)) $ copts_t)) in
Cmd.group info ~default [initialize_cmd; record_cmd; help_cmd]
-let () = exit (Cmd.eval main_cmd)
+let main () = Cmd.eval main_cmd
+let () = if !Sys.interactive then () else exit (main ())Cmdliner provides a simple and compositional mechanism to convert command line arguments to OCaml values and pass them to your functions.
The library automatically handles syntax errors, help messages and UNIX man page generation. It supports programs with single or multiple commands (like git) and respect most of the POSIX and GNU conventions.
The following manuals are available.
Cmdliner Declarative definition of command line interfaces.| changes-files | |
| license-files | |
| readme-files |
Cmdliner provides a simple and compositional mechanism to convert command line arguments to OCaml values and pass them to your functions.
The library automatically handles command line completion, syntax errors, help messages and UNIX man page generation. It supports programs with single or multiple commands (like git) and respect most of the POSIX and GNU conventions.
The following manuals are available.
cmdlinerCmdliner Declarative definition of command line interfaces.Cmdliner.Arg Terms for command line arguments.Cmdliner.Cmd Commands.Cmdliner.Manpage Man pages.Cmdliner.Term Terms.| changes-files | |
| license-files | |
| readme-files |
Man page sections for a command are printed in the order specified by manual as given to Cmdliner.Cmd.info. Unless specified explicitly in the command's manual the following sections are automatically created and populated for you:
The various doc documentation strings specified by the command's term arguments get inserted at the end of the documentation section they respectively mention in their docs argument:
Cmdliner.Cmd.info.Cmdliner.Arg.info. Those are listed iff both the docv and doc string is specified by Cmdliner.Arg.info.Cmdliner.Arg.info.Cmdliner.Cmd.Exit.info.Cmdliner.Arg.env_var and Cmdliner.Cmd.Env.info.If a docs section name is mentioned and does not exist in the command's manual, an empty section is created for it, after which the doc strings are inserted, possibly prefixed by boilerplate text (e.g. for Cmdliner.Manpage.s_environment and Cmdliner.Manpage.s_exit_status).
If the created section is:
Cmdliner.Manpage.s_synopsis if there is no such section.Cmdliner.Manpage.s_commands section or the first subsequent existing standard section if it doesn't exist. Taking advantage of this behaviour is discouraged, you should declare manually your non standard section in the command's manual page.Finally note that the header of empty sections are dropped from the output. This allows you to share section placements among many commands and render them only if something actually gets inserted in it.
Manpage blocks and doc strings support the following markup language.
$(i,text) and $(b,text), where text is raw text respectively rendered in italics and bold.$(var) are substituted by marked up data. For example in a term's man page $(tname) is substituted by the term name in bold."\\$", "\\(", "\\)", "\\\\"). Escaping $ and \ is mandatory everywhere. Escaping ) is mandatory only in markup directives. Escaping ( is only here for your symmetric pleasure. Any other sequence of characters starting with a \ is an illegal character sequence.See also the section about man pages in the command line interface manual.
Man page sections for a command are printed in the order specified by the man value given to Cmdliner.Cmd.info. Unless specified explicitly in the man value the following sections are automatically created and populated for you:
The various doc documentation strings specified by the command's term arguments get inserted at the end of the documentation section they respectively mention in their docs argument:
Cmdliner.Cmd.info.Cmdliner.Arg.info. Those are listed iff both the docv and doc string is specified by Cmdliner.Arg.info.Cmdliner.Arg.info.Cmdliner.Cmd.Exit.info.Cmdliner.Cmd.Env.info.If a docs section name is mentioned and does not exist in the command's man value, an empty section is created for it, after which the doc strings are inserted, possibly prefixed by boilerplate text (e.g. for Cmdliner.Manpage.s_environment and Cmdliner.Manpage.s_exit_status).
If the created section is:
man value since the latter get the order number of the last previously specified standard section or the order of Cmdliner.Manpage.s_synopsis if there is no such section.Cmdliner.Manpage.s_commands section or the first subsequent existing standard section if it doesn't exist. Taking advantage of this behaviour is discouraged, you should declare manually your non standard section in the command's manual page.Finally note that the header of empty sections are dropped from the output. This allows you to share section placements among many commands and render them only if something actually gets inserted in it.
Manpage blocks and the doc strings of the various info values support the following markup language.
$(i,text) and $(b,text), where text is raw text respectively rendered in italics and bold.$(var) are substituted by marked up data. For example in a command man page $(cmd) is substituted by the command's invocation in bold."\\$", "\\(", "\\)", "\\\\". Escaping '$' and '\' is mandatory everywhere. Escaping ')' is mandatory only in markup directives. Escaping '(' is only here for your symmetric pleasure. Any other sequence of characters starting with a '\' is an illegal character sequence.With Cmdliner your tool's main function evaluates a command.
A command is a value of type Cmdliner.Cmd.t which gathers a command name and a term of type Cmdliner.Term.t. A term is an expression to be evaluated. The type parameter of the term (and the command) indicates the type of the result of the evaluation.
One way to create terms is by lifting regular OCaml values with Cmdliner.Term.const. Terms can be applied to terms evaluating to functional values with Cmdliner.Term.($).
For example, in a revolt.ml file, for the function:
let revolt () = print_endline "Revolt!"the term :
open Cmdliner
+tutorial (cmdliner.tutorial) Tutorial
See also the cookbook, blueprints and examples.
Commands and terms
With Cmdliner your tool's main function evaluates a command.
A command is a value of type Cmdliner.Cmd.t which gathers a command name and a term of type Cmdliner.Term.t. A term represents both a command line syntax fragment and an expression to be evaluated that implements your tool. The type parameter of the term (and the command) indicates the type of the result of the evaluation.
One way to create terms is by lifting regular OCaml values with Cmdliner.Term.const. Terms can be applied to terms evaluating to functional values with Cmdliner.Term.app.
For example, in a revolt.ml file, for the function:
let revolt () = print_endline "Revolt!"
the term :
open Cmdliner
-let revolt_t = Term.(const revolt $ const ())
is a term that evaluates to the result (and effect) of the revolt function. This term can be attached to a command:
let cmd = Cmd.v (Cmd.info "revolt") revolt_t
and evaluated with Cmdliner.Cmd.eval:
let () = exit (Cmd.eval cmd)
This defines a command line tool named "revolt" (this name will be used in error reporting and documentation generation), without command line arguments, that just prints "Revolt!" on stdout.
> ocamlfind ocamlopt -linkpkg -package cmdliner -o revolt revolt.ml
+let revolt_term = Term.app (Term.const revolt) (Term.const ())
is a term that evaluates to the result (and effect) of the revolt function. This term can be associated to a command:
let cmd_revolt = Cmd.make (Cmd.info "revolt") revolt_term
and evaluated with Cmdliner.Cmd.eval:
let main () = Cmd.eval cmd_revolt
+let () = if !Sys.interactive then () else exit (main ())
This defines a command line tool named "revolt" (this name will be used in error reporting and documentation generation), without command line arguments, that just prints "Revolt!" on stdout.
> ocamlfind ocamlopt -linkpkg -package cmdliner -o revolt revolt.ml
> ./revolt
-Revolt!
The combinators in the Cmdliner.Arg module allow to extract command line arguments as terms. These terms can then be applied to lifted OCaml functions to be evaluated.
Terms corresponding to command line argument data that are part of a term evaluation implicitly define a command line syntax. We show this on an concrete example.
In a chorus.ml file, consider the chorus function that prints repeatedly a given message :
let chorus count msg = for i = 1 to count do print_endline msg done
we want to make it available from the command line with the synopsis:
chorus [-c COUNT | --count=COUNT] [MSG]
where COUNT defaults to 10 and MSG defaults to "Revolt!". We first define a term corresponding to the --count option:
let count =
+Revolt!
Term syntax
There is a special syntax that uses OCaml's binding operators for writing terms which is less error prone when the number of arguments you want to give to your function grows. In particular it allows you to easily lift functions which have labels.
So in fact the program we have just shown above is usually rather written this way:
let revolt () = print_endline "Revolt!"
+
+open Cmdliner
+open Cmdliner.Term.Syntax
+
+let cmd_revolt =
+ Cmd.make (Cmd.info "revolt") @@
+ let+ () = Term.const () in
+ revolt ()
+
+let main () = Cmd.eval cmd_revolt
+let () = if !Sys.interactive then () else exit (main ())
Command line arguments as terms
The combinators in the Cmdliner.Arg module allow to extract command line arguments as terms. These terms can then be applied to lifted OCaml functions to be evaluated. A term that uses terms that correspond to command line argument implicitely defines a command line syntax fragment. We show this on an concrete example.
In a chorus.ml file, consider the chorus function that prints repeatedly a given message :
let chorus ~count msg = for i = 1 to count do print_endline msg done
we want to make it available from the command line with the synopsis:
chorus [-c COUNT | --count=COUNT] [MSG]
where COUNT defaults to 10 and MSG defaults to "Revolt!". We first define a term corresponding to the --count option:
open Cmdliner
+open Cmdliner.Term.Syntax
+
+let count =
let doc = "Repeat the message $(docv) times." in
- Arg.(value & opt int 10 & info ["c"; "count"] ~docv:"COUNT" ~doc)
This says that count is a term that evaluates to the value of an optional argument of type int that defaults to 10 if unspecified and whose option name is either -c or --count. The arguments doc and docv are used to generate the option's man page information.
The term for the positional argument MSG is:
let msg =
+ Arg.(value & opt int 10 & info ["c"; "count"] ~doc ~docv:"COUNT")
This says that count is a term that evaluates to the value of an optional argument of type int that defaults to 10 if unspecified and whose option name is either -c or --count. The arguments doc and docv are used to generate the option's man page information.
The term for the positional argument MSG is:
let msg =
let env =
let doc = "Overrides the default message to print." in
Cmd.Env.info "CHORUS_MSG" ~doc
in
let doc = "The message to print." in
- Arg.(value & pos 0 string "Revolt!" & info [] ~env ~docv:"MSG" ~doc)
which says that msg is a term whose value is the positional argument at index 0 of type string and defaults to "Revolt!" or the value of the environment variable CHORUS_MSG if the argument is unspecified on the command line. Here again doc and docv are used for the man page information.
The term for executing chorus with these command line arguments is :
let chorus_t = Term.(const chorus $ count $ msg)
We are now ready to define the main function of our tool:
let cmd =
- let doc = "print a customizable message repeatedly" in
+ Arg.(value & pos 0 string "Revolt!" & info [] ~env ~doc ~docv:"MSG")
which says that msg is a term whose value is the positional argument at index 0 of type string and defaults to "Revolt!" or the value of the environment variable CHORUS_MSG if the argument is unspecified on the command line. Here again doc and docv are used for the man page information.
We can now define a term and command for invoking the chorus function using the term syntax and the obscure but handy let-punning OCaml notation. This also shows that the value Cmdliner.Cmd.info can be given more information about the term we execute which is notably used to to generate the tool's man page.
let chorus_cmd =
+ let doc = "Print a customizable message repeatedly" in
let man = [
`S Manpage.s_bugs;
`P "Email bug reports to <bugs@example.org>." ]
in
- let info = Cmd.info "chorus" ~version:"%%VERSION%%" ~doc ~man in
- Cmd.v info chorus_t
+ Cmd.make (Cmd.info "chorus" ~version:"v2.0.0" ~doc ~man) @@
+ let+ count and+ msg in
+ chorus ~count msg
-let main () = exit (Cmd.eval cmd)
-let () = main ()
The info value created with Cmdliner.Cmd.info gives more information about the term we execute and is used to generate the tool's man page. Since we provided a ~version string, the tool will automatically respond to the --version option by printing this string.
A tool using Cmdliner.Cmd.eval always responds to the --help option by showing the tool's man page generated using the information you provided with Cmdliner.Cmd.info and Cmdliner.Arg.info. Here is the output generated by our example:
> ocamlfind ocamlopt -linkpkg -package cmdliner -o chorus chorus.ml
+let main () = Cmd.eval chorus_cmd
+let () = if !Sys.interactive then () else exit (main ())
Since we provided a ~version string, the tool will automatically respond to the --version option by printing this string.
Besides a tool using Cmdliner.Cmd.eval always responds to the --help option by showing the tool's man page generated using the information you provided with Cmdliner.Cmd.info and Cmdliner.Arg.info. Here is the manual generated by our example:
> ocamlfind ocamlopt -linkpkg -package cmdliner -o chorus chorus.ml
> ./chorus --help
NAME
chorus - Print a customizable message repeatedly
@@ -64,4 +80,4 @@ ENVIRONMENT
Overrides the default message to print.
BUGS
- Email bug reports to <bugs@example.org>.If a pager is available, this output is written to a pager. This help is also available in plain text or in the groff man page format by invoking the program with the option --help=plain or --help=groff.
For examples of more complex command line definitions look and run the examples.
Sub commands
Cmdliner also provides support for programs like git that have sub commands each with their own command line syntax and manual:
tool [COMMAND]… [OPTION]… ARG…
These sub commands are defined by grouping them under a parent command via the Cmdliner.Cmd.group function.
+ Email bug reports to <bugs@example.org>.If a pager is available, this output is written to a pager. This help is also available in plain text or in the groff man page format by invoking the program with the option --help=plain or --help=groff.
And with this you should master the basics of Cmdliner, for examples of more complex command line definitions consult the examples. For more tips, off-the-shelf recipes and conventions have look at the cookbook.
Browse by name, by tag, the standard library and the OCaml manual (online, latest version).
Generated for /home/runner/work/linol/linol/_opam/lib
Browse by name, by tag, the standard library and the OCaml manual (online, latest version).
Generated for /home/runner/work/linol/linol/_opam/lib