Skip to content

Commit

Permalink
Allow documentation for positional args (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
gridbugs authored Nov 28, 2024
1 parent 8f99bbe commit 61621f1
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 95 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Allow documentation for positional args (#4)
- Improve filename completion (#3)
- Stop printing spec errors (#2, fixes #1)

Expand Down
12 changes: 6 additions & 6 deletions examples/fake_git.ml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ let checkout =

let commit =
let open Arg_parser in
let+ _amend = flag [ "amend"; "a" ]
let+ _amend = flag [ "amend"; "a" ] ~desc:"Ammend a commit"
and+ _branch = named_opt [ "b"; "branch" ] branch_conv
and+ _message = named_opt [ "m"; "message" ] string
and+ _message = named_opt [ "m"; "message" ] string ~desc:"The commit message"
and+ _files = pos_all file in
()
;;
Expand All @@ -55,10 +55,10 @@ let () =
let open Command in
group
~desc:"Fake version control"
[ subcommand "config" (singleton Arg_parser.unit)
; subcommand "checkout" (singleton checkout)
; subcommand "commit" (singleton commit)
; subcommand "log" (singleton log)
[ subcommand "config" (singleton Arg_parser.unit ~desc:"Configure the tool.")
; subcommand "checkout" (singleton checkout ~desc:"Check out a revision.")
; subcommand "commit" (singleton commit ~desc:"Commit your changes.")
; subcommand "log" (singleton log ~desc:"List recent commits.")
; subcommand
"bisect"
(group
Expand Down
2 changes: 1 addition & 1 deletion examples/sum.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ open Climate

let main =
let open Arg_parser in
let+ args = pos_all int in
let+ args = pos_all int ~desc:"The ints to be summed" in
print_endline (Printf.sprintf "%d" (List.fold_left args ~init:0 ~f:( + )))
;;

Expand Down
4 changes: 2 additions & 2 deletions examples/sum2.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ open Climate

let main =
let open Arg_parser in
let+ a = pos_req 0 int
and+ b = pos_req 1 int in
let+ a = pos_req 0 int ~value_name:"LHS" ~desc:"The left hand side of the operation"
and+ b = pos_req 1 int ~value_name:"RHS" ~desc:"The right hand side of the operation" in
print_endline (Printf.sprintf "%d" (a + b))
;;

Expand Down
41 changes: 23 additions & 18 deletions src/climate/climate.ml
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ module Arg_parser = struct

let flag = flag_gen ~allow_many:false

let pos_single_gen i conv ~value_name ~required ~completion =
let pos_single_gen i conv ~desc ~value_name ~required ~completion =
let i =
match Nonnegative_int.of_int i with
| Some _ -> i
Expand All @@ -465,7 +465,8 @@ module Arg_parser = struct
i
~value_name:(Option.value value_name ~default:conv.default_value_name)
~required
~completion:(conv_untyped_completion_opt_with_default conv completion))
~completion:(conv_untyped_completion_opt_with_default conv completion)
~desc)
; arg_compute =
(fun context ->
Raw_arg_table.get_pos context.raw_arg_table i
Expand All @@ -478,32 +479,33 @@ module Arg_parser = struct
}
;;

let pos_opt ?value_name ?completion i conv =
pos_single_gen i conv ~value_name ~required:false ~completion
let pos_opt ?desc ?value_name ?completion i conv =
pos_single_gen i conv ~desc ~value_name ~required:false ~completion
;;

let pos_with_default ?value_name ?completion i conv ~default =
pos_opt ?value_name ?completion i conv
let pos_with_default ?desc ?value_name ?completion i conv ~default =
pos_opt ?desc ?value_name ?completion i conv
|> map ~f:(function
| Some x -> x
| None -> default)
;;

let pos_req ?value_name ?completion i conv =
pos_single_gen i conv ~value_name ~required:true ~completion
let pos_req ?desc ?value_name ?completion i conv =
pos_single_gen i conv ~desc ~value_name ~required:true ~completion
|> map ~f:(function
| Some x -> x
| None -> raise Parse_error.(E (Pos_req_missing i)))
;;

let pos_left_gen i conv ~value_name ~required ~completion =
let pos_left_gen i conv ~desc ~value_name ~required ~completion =
{ arg_spec =
Spec.create_positional
(Spec.Positional.all_below_exclusive
i
~value_name:(Option.value value_name ~default:conv.default_value_name)
~required
~completion:(conv_untyped_completion_opt_with_default conv completion))
~completion:(conv_untyped_completion_opt_with_default conv completion)
~desc)
; arg_compute =
(fun context ->
let left, _ =
Expand All @@ -518,17 +520,18 @@ module Arg_parser = struct
}
;;

let pos_left ?value_name ?completion i conv =
pos_left_gen i conv ~value_name ~required:false ~completion
let pos_left ?desc ?value_name ?completion i conv =
pos_left_gen i conv ~desc ~value_name ~required:false ~completion
;;

let pos_right_inclusive ?value_name ?completion i_inclusive conv =
let pos_right_inclusive ?desc ?value_name ?completion i_inclusive conv =
{ arg_spec =
Spec.create_positional
(Spec.Positional.all_above_inclusive
i_inclusive
~value_name:(Option.value value_name ~default:conv.default_value_name)
~completion:(conv_untyped_completion_opt_with_default conv completion))
~completion:(conv_untyped_completion_opt_with_default conv completion)
~desc)
; arg_compute =
(fun context ->
let _, right =
Expand All @@ -543,12 +546,12 @@ module Arg_parser = struct
}
;;

let pos_right ?value_name ?completion i_exclusive conv =
pos_right_inclusive ?value_name ?completion (i_exclusive + 1) conv
let pos_right ?desc ?value_name ?completion i_exclusive conv =
pos_right_inclusive ?desc ?value_name ?completion (i_exclusive + 1) conv
;;

let pos_all ?value_name ?completion conv =
pos_right_inclusive ?value_name ?completion 0 conv
let pos_all ?desc ?value_name ?completion conv =
pos_right_inclusive ?desc ?value_name ?completion 0 conv
;;

let validate t = Spec.validate t.arg_spec
Expand Down Expand Up @@ -580,6 +583,8 @@ module Arg_parser = struct
Format.fprintf ppf "%s" description;
Format.pp_print_newline ppf ();
Format.pp_print_newline ppf ());
if not (Spec.Positional.is_empty arg_spec.positional)
then Spec.positional_help ppf arg_spec;
if not (Spec.Named.is_empty arg_spec.named) then Spec.named_help ppf arg_spec;
if not (List.is_empty child_subcommands)
then (
Expand Down
22 changes: 16 additions & 6 deletions src/climate/climate.mli
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ module Arg_parser : sig
(** [pos_opt i conv] declares an optional anonymous positional
argument at position [i] (starting at 0). *)
val pos_opt
: ?value_name:string
: ?desc:string
-> ?value_name:string
-> ?completion:'a Completion.t
-> int
-> 'a conv
Expand All @@ -183,7 +184,8 @@ module Arg_parser : sig
(** [pos_with_default i conv] declares an optional anonymous positional
argument with a default value at position [i] (starting at 0). *)
val pos_with_default
: ?value_name:string
: ?desc:string
-> ?value_name:string
-> ?completion:'a Completion.t
-> int
-> 'a conv
Expand All @@ -193,19 +195,26 @@ module Arg_parser : sig
(** [pos_req i conv] declares a required anonymous positional
argument at position [i] (starting at 0). *)
val pos_req
: ?value_name:string
: ?desc:string
-> ?value_name:string
-> ?completion:'a Completion.t
-> int
-> 'a conv
-> 'a t

(** Parses all positional arguments. *)
val pos_all : ?value_name:string -> ?completion:'a Completion.t -> 'a conv -> 'a list t
val pos_all
: ?desc:string
-> ?value_name:string
-> ?completion:'a Completion.t
-> 'a conv
-> 'a list t

(** [pos_left i conv] parses all positional arguments at positions less than
i. *)
val pos_left
: ?value_name:string
: ?desc:string
-> ?value_name:string
-> ?completion:'a Completion.t
-> int
-> 'a conv
Expand All @@ -214,7 +223,8 @@ module Arg_parser : sig
(** [pos_right i conv] parses all positional arguments at positions greater
than i. *)
val pos_right
: ?value_name:string
: ?desc:string
-> ?value_name:string
-> ?completion:'a Completion.t
-> int
-> 'a conv
Expand Down
Loading

0 comments on commit 61621f1

Please sign in to comment.