[@@deriving subliner] and [%%subliner]

[@@deriving] plugin to generate Cmdliner sub-commands groups, and rewriter to generate Cmdliner evaluations.

Usage

To use [@@deriving subliner] or [%%subliner], add (preprocess (pps ppx_subliner)) to the library or executable configuration in dune file.

Syntax

Term

A Cmdliner term can be generated by tagging [@@deriving subliner] to a record type.

For record type params, function params_cmdliner_term with type unit -> params Cmdliner.Term.t will be generated. A command line argument will be generated for each field in the record. Term.t Attributes and Attributes for Types can be attached to fields or types to modify the behavior of the corresponding arguments.

type params = { my_arg : string } [@@deriving_inline subliner]
include
  sig
    [@@@ocaml.warning "-32"]
    val params_cmdliner_term : unit -> params Cmdliner.Term.t
  end[@@ocaml.doc "@inline"]
[@@@end]

The derived function can be used with [%subliner.term] extension and a handling function to generate Cmdliner evaluation. Cmd.info Attributes and Default Term.t Attribute can be attached to the extension to modify the behavior of the command line tools.

let handle { my_arg } = print_endline my_arg

[%%subliner.term eval.params <- handle]

Different evaluation functions can be used and optional parameters can be applied.

[%%subliner.term (eval_result ~catch:false).params <- handle_result]

Sub-commands

A group of Cmdliner sub-commands can be generated by tagging [@@deriving subliner] to a variant type and providing a handling function for that variant.

For variant type params, function params_cmdliner_group_cmds with type (params -> 'a) -> 'a Cmdliner.Cmd.t list will be generated. The input function takes a handling function to process parsed input. A sub-command will be generated for each constructor in the variant. Cmd.info Attributes can be attached to constructors to modify the behavior of the corresponding sub-commands.

Each constructor of the variant can have no parameters, one parameter, or a tuple of multiple parameters, or be an inline record.

If a constructor has a parameter with type p, function p_cmdliner_term with type unit -> p Cmdliner.Term.t is required. The function can be either obtained by tagging a supported record with [@@deriving subliner], [@@deriving cmdliner] or constructed manually. If a constructor has multiple parameters, all parameter types must have the corresponding functions.

type foo = { my_arg : string }
val foo_cmdliner_term : unit -> foo Cmdliner.Term,t

type params =
  | Foo of foo
  | Bar
  | Foobar of { my_arg : string }
[@@deriving_inline subliner]
include
  sig
    [@@@ocaml.warning "-32"]
    val params_cmdliner_group_cmds : (params -> 'a) -> 'a Cmdliner.Cmd.t list
  end[@@ocaml.doc "@inline"]
[@@@end]

The derived function can be used with [%%subliner.cmds] extension to generate Cmdliner evaluation. Cmd.info Attributes and Default Term.t Attribute can be attached to the extension to modify the behavior of the command line tools.

let handle = function
  | Foo { my_arg } -> print_endline ("Foo " ^ my_arg)
  | Bar -> print_endline "Bar"

[%%subliner.cmds eval.params <- handle]

Different evaluation functions can be used and optional parameters can be applied.

[%%subliner.cmds (eval_result ~catch:false).params <- handle_result]

Enumeration

A Cmdliner argument converter of enumeration can be generated by tagging [@@deriving subliner_enum] to a variant type without any payload.

For variant type enum, function enum_cmdliner_conv with type unit -> enum Cmdliner.Arg.conv will be generated. Enumeration Attribute can be attached to constructors to modify the behavior of the corresponding enumeration.

type enum = Foo | Bar
[@@deriving_inline subliner_enum]
include
  sig
    [@@@ocaml.warning "-32"]
    val enum_cmdliner_conv : unit -> enum Cmdliner.Arg.conv
  end[@@ocaml.doc "@inline"]
[@@@end]

The derived function can be used inside [@@deriving subliner].

type params = { enum : enum [@conv enum_cmdliner_conv ()] }

Supported Attributes

All attributes may be prefixed with subliner. to avoid conflicts with other extensions.

Term.t Attributes

[@term t Term.t]

Use the user provided Term.t for this field as it is. All other attributes will be ignored.

type params = { foo : t [@term cmdliner_term ()] }

[@names string list]

Set the names of the named argument. If not provided, kebab case of the field name will be used (i.e. filed foo_bar will have name "foo-bar" by default).

type params = { foo : string [@names [ "my-arg-name"; "n" ]] }

[@doc string]

Set the man page description of the argument. If not provided, the doc string will be used.

type params = { foo : string [@doc "This is the documentation"] }

[@opt_all]

Allow the optional argument to appear more than once ( see opt_all for more details). This attribute must be used with a list, or used with [@last] attribute at the same time.

Conflict with [@pos int], [@pos_all], [@pos_right int], [@pos_left int].

type params = { foo : string list [@opt_all] }

[@pos int], [@pos_all], [@pos_right int], [@pos_left int]

Set the argument to be positional. [@pos_all], [@pos_right int] and [@pos_left int] must be used with a list type or used with [@last] attribute at the same time.

[@rev] can be used with [@pos int], [@pos_right int] and [@pos_left int] to compute the argument position in reverse order.

Conflict with [@opt_all].

type params = { foo : string list [@pos_right 1] }

[@non_empty]

Enforce a list argument to be non-empty.

Conflict with [@default t], [@last].

type params = { foo : string list [@non_empty] }

[@last]

Only evaluates the last element of the list.

[@last.sep char] can be used with this attribute to set the separator of the list.

Conflict with [@non_empty].

type params = { foo : string [@last] [@last.sep ';'] }

[@default t]

Set the default value of the argument.

Conflict with [@non_empty].

type params = { foo : string [@default "My default string"] }

[@env string]

Set the the name of an environment variable which is looked up for defining the argument if it is absent.

[@env.deprecated string], [@env.docs string] and [@env.doc string] can be used with this attribute. For their exact usages, please refer to the documentation of Cmdliner.Cmd.Env.info.

type params = { foo : string [@env "MY_ENV_VAR"] }

Other

[@deprecated string], [@absent string], [@docs string] and [@docv string] are also supported. For their exact usages, please refer to the documentation of Cmdliner.Arg.info.

Cmd.info Attributes

[@name string]

Set the name of the command. If not provided, the kebab case of the constructor name will be used (i.e. constructor Foo_bar will have name "foo-bar" by default) for sub-commands, and the executable name will be used for command line tools.

type params = Foo [@name "my-cmd-name"]

[@doc string]

Set the one line description of the command. If not provided, the doc string will be used.

type params = Foo (** This is a short description of My_cmd. *)

Other

[@version string], [@deprecated string], [@docs string], [@sdocs string], [@exits Cmd.Exit.info list], [@envs Cmd.Env.info list], [@man Manpage.block list] and [@man_xrefs Manpage.xref list] are also supported. For their exact usages, please refer to the documentation of Cmdliner.Cmd.info.

Enumeration Attribute

[@name string]

[@names string list]

Set the names of the enumeration. If not provided, the kebab case of the constructor name will be used (i.e. constructor Foo_bar will have name "foo-bar" by default).

type enum = Foo_bar [@names [ "my-enum-name"; "e" ]]

Default Term.t Attribute

For sub-command evaluation, [@@default] can be used to change the command line syntax to parse if no sub command is specified. By default, it will show the default help page.

let default = Cmdliner.Term.(ret (const (`Error (true, "Some error messages"))))

[%%subliner.cmds eval.params <- handle]
[@@default default]

Attributes for Types

The following attributes must be attached to types directly.

(* correct *)
type params = { foo : (string [@attr]) }

(* wrong, the attribute is attached to the field instead of the type *)

type params = { foo : string [@attr] }

[@conv t Arg.conv]

Use the user provided Arg.conv for this type as it is. All other attributes will be ignored.

type params = { foo : (t [@conv cmdliner_conv]) list }

[@file], [@dir], [@non_dir_file]

Check whether the provided name for file, dir or non-dir file exists. Only one of these attributes can be specified at the same time.

type params = { foo : (string [@non_dir_file]) }

[@sep char]

Set the separate of lists, arrays or tuples. This attribute can be used on nested structures.

type params = { rgb : (((int * int * int)[@sep '#']) list[@sep ';']) }