···635635 cmdliner for the argument. *)
636636 module Completion : sig
637637638638- type complete = string -> (string * string) list
638638+ type 'ctx func = 'ctx option -> prefix:string -> (string * string) list
639639 (** The type for completion functions. Given a prefix should
640640 return a list of possible completions and a doc string. *)
641641642642+ type 'a complete = Complete : 'ctx Term.t option * 'ctx func -> 'a complete
643643+ (** The type for completing. A completion context specification
644644+ and a completion function. *)
645645+642646 type 'a t
643647 (** The type for completing values parsed into values of type ['a]. *)
644648645649 val make :
646646- ?complete:complete -> ?dirs:bool -> ?files:bool -> ?restart:bool ->
647647- unit -> 'a t
648648- (** [make ()] is a completion specification with given properties.
649649- See accesors for semantics. Note that the properties are
650650+ ?context:'ctx Term.t -> ?func:'ctx func -> ?dirs:bool ->
651651+ ?files:bool -> ?restart:bool -> unit -> 'a t
652652+ (** [make ()] is a completion specification with:
653653+654654+ [context] is a command line is command line completion
655655+ context. During completion the command line fragment of the
656656+ context is parsed, if successful the result is given to the
657657+ completion function. Note that [context] must be part of the
658658+ term of the command in which you use that completion otherwhise
659659+ the context will always be [None] in the function.
660660+661661+ See accessors for semantics. Note that the properties are
650662 not mutually exclusive. *)
651663652652- val complete : 'a t -> complete
653653- (** [complete c] is a function to perform completion. *)
664664+ val complete : 'a t -> 'a complete
665665+ (** [complete c] is a the context and function to perform completion. *)
654666655667 val dirs : 'a t -> bool
656668 (** [dirs c] indicates the argument should be completed with directories. *)
+8-4
vendor/opam/cmdliner/src/cmdliner_arg.ml
···336336 let parser s = try Ok (bool_of_string s) with
337337 | Invalid_argument _ -> Error (err_invalid_enum "" s alts)
338338 in
339339- let complete _prefix = List.map (fun s -> s, "") alts in
340340- let completion = Completion.make ~complete () in
339339+ let completion =
340340+ let func _ctx ~prefix:_ = List.map (fun s -> s, "") alts in
341341+ Completion.make ~func ()
342342+ in
341343 Conv.make ~docv:"BOOL" ~parser ~pp:Format.pp_print_bool ~completion ()
342344343345let char =
···395397 try Fmt.string ppf (List.assoc v sl_inv)
396398 with Not_found -> invalid_arg (err_incomplete_enum (List.map fst sl))
397399 in
398398- let complete _prefix = List.map (fun (s, _) -> s, "") sl in
399399- let completion = Completion.make ~complete () in
400400+ let completion =
401401+ let func _ctx ~prefix:_ = List.map (fun (s, _) -> s, "") sl in
402402+ Completion.make ~func ()
403403+ in
400404 Conv.make ~docv ~parser ~pp ~completion ()
401405402406let path =
+7-5
vendor/opam/cmdliner/src/cmdliner_arg.mli
···1010type 'a conv
11111212module Completion : sig
1313- type complete = string -> (string * string) list
1313+ type 'ctx func = 'ctx option -> prefix:string -> (string * string) list
1414+ type 'a complete =
1515+ | Complete : 'ctx Cmdliner_term.t option * 'ctx func -> 'a complete
1616+1417 type 'a t
1518 val make :
1616- ?complete:complete -> ?dirs:bool -> ?files:bool -> ?restart:bool -> unit ->
1717- 'a t
1919+ ?context: 'ctx Cmdliner_term.t -> ?func:'ctx func -> ?dirs:bool ->
2020+ ?files:bool -> ?restart:bool -> unit -> 'a t
18211919- val context : 'a t -> 'a Cmdliner_term.t option
2020- val complete : 'a t -> complete
2222+ val complete : 'a t -> 'a complete
2123 val dirs : 'a t -> bool
2224 val files : 'a t -> bool
2325 val restart : 'a t -> bool
+20-16
vendor/opam/cmdliner/src/cmdliner_cline.ml
···30303131exception Completion_requested of Cmdliner_def.Complete.t
32323333-let comp_request ?after_dashdash ~prefix kind =
3434- let comp = Cmdliner_def.Complete.make ?after_dashdash ~prefix kind in
3333+let comp_request ?after_dashdash cline ~prefix kind =
3434+ let comp = Cmdliner_def.Complete.make ?after_dashdash cline ~prefix kind in
3535 raise (Completion_requested comp)
36363737(* Command lines *)
···124124 | true, [] -> [short_opt]
125125 | true, l -> if List.mem short_opt l then l else short_opt :: l
126126127127-let parse_opt_value ~for_completion arg_info name value args =
127127+let parse_opt_value ~for_completion cline arg_info name value args =
128128 (* Either we got a value glued in [value] or we need to get one in args *)
129129 match Cmdliner_def.Arg_info.opt_kind arg_info with
130130 | Flag -> (* Flags have no values but we may get dash sharing in [value] *)
···144144 | v :: rest when for_completion && has_complete_prefix v ->
145145 let v = get_token_to_complete v in
146146 if is_opt v then (* not an option value *) None, args else
147147- comp_request ~prefix:v (Opt_value arg_info)
147147+ comp_request cline ~prefix:v (Opt_value arg_info)
148148 | v :: rest ->
149149 if is_opt v then None, args else Some v, rest
150150151151-let try_complete_opt_value arg_info name value args =
151151+let try_complete_opt_value cline arg_info name value args =
152152 (* At that point we found a matching option name so this should be mostly
153153 about completing a glued option value, but there are twists. *)
154154 match Cmdliner_def.Arg_info.opt_kind arg_info with
···162162 (* This is actually a parse error, flags have no value. We
163163 make it an option completion but the completions will
164164 eventually be empty (the prefix won't match) *)
165165- comp_request ~prefix:(name ^ v) Opt_name
165165+ comp_request cline ~prefix:(name ^ v) Opt_name
166166 | None ->
167167 (* We have in fact a fully completed flag turn it into an
168168 option completion. *)
169169- comp_request ~prefix:name Opt_name
169169+ comp_request cline ~prefix:name Opt_name
170170 end
171171 | _ ->
172172 begin match value with
173173- | Some prefix -> comp_request ~prefix (Opt_value arg_info)
173173+ | Some prefix -> comp_request cline ~prefix (Opt_value arg_info)
174174 | None ->
175175 (* We have a fully completed option name, we don't try to
176176 lookup what happens in the next argument which should
177177 hold the value if any, we just turn it into an option
178178 completion. *)
179179- comp_request ~prefix:name Opt_name
179179+ comp_request cline ~prefix:name Opt_name
180180 end
181181182182let parse_opt_args
···201201 | Ok arg_info ->
202202 let value, args =
203203 if is_completion
204204- then try_complete_opt_value arg_info name value args
205205- else parse_opt_value ~for_completion arg_info name value args
204204+ then try_complete_opt_value cline arg_info name value args
205205+ else parse_opt_value ~for_completion cline arg_info name value args
206206 in
207207 let arg : arg = O ((k, name, value) :: opt_arg cline arg_info) in
208208 let cline = Cmdliner_def.Arg_info.Map.add arg_info arg cline in
209209 loop errs (k + 1) cline pargs args
210210 | Error `Not_found when for_completion ->
211211 if not is_completion
212212- then (* XXX unclear *) loop errs (k + 1) cline (s :: pargs) args else
212212+ (* Drop the data, if the user thought this was an opt with
213213+ an argument this may confuse positional args but there's
214214+ not much we can do. *)
215215+ then loop errs (k + 1) cline pargs args else
213216 let prefix = name ^ Option.value ~default:"" value in
214214- comp_request ~prefix Opt_name
217217+ comp_request cline ~prefix Opt_name
215218 | Error `Not_found when peek_opts ->
216219 loop errs (k + 1) cline pargs args
217220 | Error `Not_found ->
···268271 | `Range args -> args
269272 | `Complete prefix ->
270273 let kind = Cmdliner_def.Complete.Opt_name_or_pos_value a in
271271- comp_request ~after_dashdash:has_dashdash ~prefix kind
274274+ comp_request ~after_dashdash:has_dashdash cline ~prefix kind
272275 in
273276 let max_spec = max stop max_spec in
274277 let cline = Cmdliner_def.Arg_info.Map.add a (P args : arg) cline in
···283286 match take_range ~for_completion (max_spec + 1) last pargs with
284287 | `Range args -> args
285288 | `Complete prefix ->
286286- comp_request ~after_dashdash:has_dashdash ~prefix Opt_name
289289+ comp_request ~after_dashdash:has_dashdash cline ~prefix Opt_name
287290 in
288291 if misses <> [] then begin
289292 let _ : string list = consume_excess () in
···317320 match maybe_token_to_complete ~for_completion:true arg with
318321 | None -> assert false
319322 | Some prefix ->
320320- comp_request ~after_dashdash:has_dashdash ~prefix Opt_name
323323+ comp_request
324324+ ~after_dashdash:has_dashdash cline ~prefix Opt_name
321325 end
322326 | Error (errs, cline, has_dashdash, pargs) ->
323327 let _ : _ result =
+10-7
vendor/opam/cmdliner/src/cmdliner_completion.ml
···3030 if not (Cmdliner_def.Arg_info.Set.is_empty set) then begin
3131 let arg_infos = Cmdliner_def.Cmd_info.args info in
3232 pp_group ppf "Options";
3333- Cmdliner_def.Arg_info.Set.iter (pp_opt ~err_ppf ~subst ~prefix ppf) arg_infos
3333+ Cmdliner_def.Arg_info.Set.iter (pp_opt ~err_ppf ~subst ~prefix ppf)
3434+ arg_infos
3435 end
35363636-let pp_arg_values ~after_dashdash ~prefix ppf comp =
3737+let pp_arg_values ~after_dashdash ~prefix items ppf comp =
3738 if after_dashdash && Cmdliner_def.Arg_completion.restart comp
3839 then pp_line ppf "restart" else
3939- let items = Cmdliner_def.Arg_completion.complete comp prefix in
4040+ let items = items () in
4041 let comp_files = Cmdliner_def.Arg_completion.files comp in
4142 let comp_dirs = Cmdliner_def.Arg_completion.dirs comp in
4243 if items <> [] || comp_files || comp_dirs then begin
···58595960let vnum = 1 (* Protocol version number *)
60616161-let output ~out_ppf ~err_ppf ei cmd_args_info cmd comp =
6262+let output ~out_ppf ~err_ppf ei cmd_args_info cmd comp ~items =
6263 let subst = Cmdliner_def.Eval.doclang_subst ei in
6364 let after_dashdash = Cmdliner_def.Complete.after_dashdash comp in
6465 let prefix = Cmdliner_def.Complete.prefix comp in
6666+ let maybe_opt = prefix = "" || prefix.[0] = '-' in
6567 let pp_arg_value ppf arg_info =
6668 begin match Cmdliner_def.Arg_info.Set.find_opt arg_info cmd_args_info with
6769 | None -> ()
6868- | Some (Completion comp) -> pp_arg_values ~after_dashdash ~prefix ppf comp
7070+ | Some (Completion comp) ->
7171+ pp_arg_values ~after_dashdash ~prefix items ppf comp
6972 end;
7073 in
7174 let pp ppf () =
···7376 | Opt_value arg_info -> pp_arg_value ppf arg_info
7477 | Opt_name_or_pos_value arg_info ->
7578 pp_arg_value ppf arg_info;
7676- if not after_dashdash
7979+ if not after_dashdash && maybe_opt
7780 then pp_opt_names ~err_ppf ~subst ~prefix ppf cmd
7881 | Opt_name ->
7979- if not after_dashdash
8282+ if not after_dashdash && maybe_opt
8083 then pp_opt_names ~err_ppf ~subst ~prefix ppf cmd;
8184 end;
8285 if Cmdliner_def.Complete.subcmds comp
+4-1
vendor/opam/cmdliner/src/cmdliner_completion.mli
···88 err_ppf:Format.formatter ->
99 Cmdliner_def.Eval.t ->
1010 Cmdliner_def.Arg_info.Set.t ->
1111- 'a Cmdliner_cmd.t -> Cmdliner_def.Complete.t -> unit
1111+ 'a Cmdliner_cmd.t ->
1212+ Cmdliner_def.Complete.t ->
1313+ items:(unit -> (string * string) list) ->
1414+ unit
+27-16
vendor/opam/cmdliner/src/cmdliner_def.ml
···202202 [ `Error of bool * string
203203 | `Help of Cmdliner_manpage.format * string option ]
204204205205- type complete = string -> (string * string) list
206206- type 'a completion =
207207- { context : 'a term option;
208208- complete : complete;
205205+ type 'ctx func = 'ctx option -> prefix:string -> (string * string) list
206206+ type 'a complete = Complete : 'ctx term option * 'ctx func -> 'a complete
207207+ and 'a completion =
208208+ { complete : 'a complete;
209209 dirs : bool;
210210 files : bool;
211211 restart : bool }
···351351 | Opt_name
352352353353 type t =
354354- { prefix : string;
354354+ { context : Cline.t;
355355+ prefix : string;
355356 after_dashdash : bool;
356357 subcmds : bool; (* Note this is adjusted in Cmdliner_eval *)
357357- kind : kind }
358358+ kind : kind;
359359+ values : (string * string) list }
358360359359- let make ?(after_dashdash = false) ?(subcmds = false) ~prefix kind =
360360- { prefix; after_dashdash; subcmds; kind }
361361+ let make ?(after_dashdash = false) ?(subcmds = false) context ~prefix kind =
362362+ { context; prefix; after_dashdash; subcmds; kind; values = [] }
361363362364 let add_subcmds c = { c with subcmds = true }
365365+ let add_values c values = { c with values }
366366+ let context c = c.context
363367 let prefix c = c.prefix
364368 let after_dashdash c = c.after_dashdash
365369 let subcmds c = c.subcmds
···377381end
378382379383module Arg_completion = struct
380380- type complete = Arg_info.complete
384384+ type 'ctx func = 'ctx Arg_info.func
385385+386386+ type 'a complete = 'a Arg_info.complete =
387387+ | Complete : 'ctx Term.t option * 'ctx func -> 'a complete
388388+381389 type 'a t = 'a Arg_info.completion
382390383391 let make
384384- ?(complete = Fun.const []) ?(dirs = false) ?(files = false)
392392+ ?context ?(func = fun _ ~prefix:_ -> []) ?(dirs = false) ?(files = false)
385393 ?(restart = false) () : 'a t
386394 =
387387- {context = None; complete; dirs; files; restart}
395395+ { complete = Complete (context, func); dirs; files; restart }
388396389389- let none = make ()
390390- let some (c : 'a t) =
391391- { c with context = Option.map Term.some c.context }
397397+ let none : 'a t =
398398+ { complete = Complete (None, fun _ ~prefix:_ -> []);
399399+ dirs = false; files = false; restart = false }
392400393393- let context (c : 'a t) = c.context
401401+ let some c : 'a option t = match c.Arg_info.complete with
402402+ | Complete (ctx, func) -> { c with complete = Complete (ctx, func) }
403403+394404 let complete (c : 'a t) = c.complete
395405 let dirs (c : 'a t) = c.dirs
396406 let files (c : 'a t) = c.files
···412422 { docv; parser; pp; completion }
413423414424 let of_conv
415415- conv ?(completion = conv.completion) ?(docv = conv.docv)
425425+ conv
426426+ ?(completion = conv.completion) ?(docv = conv.docv)
416427 ?(parser = conv.parser) ?(pp = conv.pp) ()
417428 =
418429 { docv; parser; pp; completion }
+12-9
vendor/opam/cmdliner/src/cmdliner_def.mli
···205205 type t
206206207207 val make :
208208- ?after_dashdash:bool -> ?subcmds:bool -> prefix:string -> kind -> t
208208+ ?after_dashdash:bool -> ?subcmds:bool -> Cline.t -> prefix:string ->
209209+ kind -> t
209210211211+ val context : t -> Cline.t
210212 val add_subcmds : t -> t
211213 val prefix : t -> string
212214 val after_dashdash : t -> bool
···228230229231(** Completion strategies *)
230232module Arg_completion : sig
231231- type complete = string -> (string * string) list
233233+234234+ type 'ctx func = 'ctx option -> prefix:string -> (string * string) list
235235+ type 'a complete = Complete : 'ctx Term.t option * 'ctx func -> 'a complete
232236 type 'a t = 'a Arg_info.completion
233237 val make :
234234- ?complete:complete -> ?dirs:bool -> ?files:bool -> ?restart:bool ->
235235- unit -> 'a t
238238+ ?context:'ctx Term.t -> ?func:'ctx func -> ?dirs:bool -> ?files:bool ->
239239+ ?restart:bool -> unit -> 'a t
236240237237- val context : 'a t -> 'a Term.t option
238241 val none : 'a t
239242 val some : 'a t -> 'a option t
240240- val complete : 'a t -> complete
243243+ val complete : 'a t -> 'a complete
241244 val dirs : 'a t -> bool
242245 val files : 'a t -> bool
243246 val restart : 'a t -> bool
···252255 ?completion:'a Arg_completion.t -> docv:string -> parser:'a parser ->
253256 pp:'a fmt -> unit -> 'a t
254257255255- val of_conv : 'a t ->
256256- ?completion:'a Arg_completion.t -> ?docv:string -> ?parser:'a parser ->
257257- ?pp:'a fmt -> unit -> 'a t
258258+ val of_conv :
259259+ 'a t -> ?completion:'a Arg_completion.t -> ?docv:string ->
260260+ ?parser:'a parser -> ?pp:'a fmt -> unit -> 'a t
258261259262 val docv : 'a t -> string
260263 val parser : 'a t -> 'a parser
+41-7
vendor/opam/cmdliner/src/cmdliner_eval.ml
···88type 'a eval_exit = [ `Ok of 'a | `Exit of Cmdliner_def.Exit.code ]
991010type 'a complete =
1111- Cmdliner_def.Arg_info.Set.t * 'a Cmdliner_cmd.t * Cmdliner_def.Complete.t
1111+ Cmdliner_def.Eval.t * Cmdliner_def.Arg_info.Set.t * 'a Cmdliner_cmd.t *
1212+ Cmdliner_def.Complete.t
12131314type eval_result_error =
1415 [ Cmdliner_term.term_escape
···4445 | exn when catch ->
4546 let bt = Printexc.get_raw_backtrace () in
4647 Error (`Exn (exn, bt))
4848+4949+let run_parser_for_completion_context ei cline ctx =
5050+ let parser = Cmdliner_term.parser ctx in
5151+ match (parser ei cline :> ('a, eval_result_error) result) with
5252+ | Ok ctx -> Some ctx
5353+ | Error _ -> None
5454+ | exception exn -> None
5555+47564857let try_eval_stdopts ~catch ei cl help version : 'a eval_result option =
4958 match run_parser ~catch ei cl (Cmdliner_term.parser help) with
···96105 Cmdliner_msg.pp_version help_ppf ei; Ok `Version
97106 | `Parse err ->
98107 Cmdliner_msg.pp_usage_and_err err_ppf ei ~err; Error `Parse
9999- | `Complete (cmd_args_info, cmd, comp) ->
108108+ | `Complete (ei, cmd_args_info, cmd, comp) ->
109109+ (* TODO quick hack this should not happen here *)
110110+ let items () =
111111+ let prefix = Cmdliner_def.Complete.prefix comp in
112112+ let arg_info = match Cmdliner_def.Complete.kind comp with
113113+ | Opt_value arg_info -> Some arg_info
114114+ | Opt_name_or_pos_value arg_info -> Some arg_info
115115+ | _ -> None
116116+ in
117117+ match arg_info with
118118+ | None -> []
119119+ | Some arg_info ->
120120+ match Cmdliner_def.Arg_info.Set.find_opt
121121+ arg_info cmd_args_info with
122122+ | None -> []
123123+ | Some (Completion c) ->
124124+ match Cmdliner_def.Arg_completion.complete c with
125125+ | Complete (ctx, func) ->
126126+ let cline = Cmdliner_def.Complete.context comp in
127127+ let ctx = match ctx with
128128+ | None -> None
129129+ | Some ctx ->
130130+ run_parser_for_completion_context ei cline ctx
131131+ in
132132+ func ctx ~prefix
133133+ in
100134 Cmdliner_completion.output
101101- ~out_ppf:help_ppf ~err_ppf ei cmd_args_info cmd comp; Ok `Help
135135+ ~out_ppf:help_ppf ~err_ppf ei cmd_args_info cmd comp ~items; Ok `Help
102136 | `Help (fmt, cmd_name) ->
103137 do_help ~env help_ppf err_ppf ei fmt cmd_name; Ok `Help
104138 | `Exn (e, bt) ->
···220254 | Error (`Parse (try_stdopts, msg)) ->
221255 (* Command lookup error, we may still prioritize stdargs *)
222256 begin match cline with
223223- | `Complete comp -> Error (`Complete (cmd_args_info, cmd, comp))
257257+ | `Complete comp -> Error (`Complete (ei, cmd_args_info, cmd, comp))
224258 | `Error (_, cl) | `Ok cl ->
225259 let stdopts =
226260 if try_stdopts then try_eval_stdopts ~catch ei cl help version else
···235269 begin match cline with
236270 | `Complete comp ->
237271 let comp = Cmdliner_def.Complete.add_subcmds comp in
238238- Error (`Complete (cmd_args_info, cmd, comp))
272272+ Error (`Complete (ei, cmd_args_info, cmd, comp))
239273 | `Ok _ | `Error _ -> assert false
240274 end
241275 | Ok parser ->
242276 begin match cline with
243243- | `Complete comp -> Error (`Complete (cmd_args_info, cmd, comp))
277277+ | `Complete comp -> Error (`Complete (ei, cmd_args_info, cmd, comp))
244278 | `Error (e, cl) ->
245279 begin match try_eval_stdopts ~catch ei cl help version with
246280 | Some e -> e
···282316 let v, ret = match cline with
283317 | `Complete comp ->
284318 let cmd = Cmdliner_cmd.make cmd_info t in
285285- None, (Error (`Complete (cmd_arg_infos, cmd, comp)))
319319+ None, (Error (`Complete (ei, cmd_arg_infos, cmd, comp)))
286320 | `Error (e, cl) ->
287321 begin match try_eval_stdopts ~catch:true ei cl help version with
288322 | Some e -> None, e
+6-3
vendor/opam/cmdliner/test/test_cmd.ml
···3737 error `Term [] @@ __POS_OF__
3838 "Usage: \u{001B}[01mtest_group\u{001B}[m [\u{001B}[01m--help\u{001B}[m] \u{001B}[04mCOMMAND\u{001B}[m …\n\
3939 test_group: required \u{001B}[04mCOMMAND\u{001B}[m name is \u{001B}[31mmissing\u{001B}[m, must be one of \u{001B}[01mbirds\u{001B}[m, \u{001B}[01mcamels\u{001B}[m,\n\
4040- \ \u{001B}[01mfishs\u{001B}[m or \u{001B}[01mmammals\u{001B}[m\n";
4040+ \ \u{001B}[01mfishs\u{001B}[m, \u{001B}[01mlookup\u{001B}[m or \u{001B}[01mmammals\u{001B}[m\n";
4141 error `Term ["bla"] @@ __POS_OF__ "Usage: \u{001B}[01mtest_group\u{001B}[m [\u{001B}[01m--help\u{001B}[m] \u{001B}[04mCOMMAND\u{001B}[m …\n\
4242- test_group: \u{001B}[31munknown\u{001B}[m command \u{001B}[01mbla\u{001B}[m. Must be one of \u{001B}[01mbirds\u{001B}[m, \u{001B}[01mcamels\u{001B}[m, \u{001B}[01mfishs\u{001B}[m or\n\
4343- \ \u{001B}[01mmammals\u{001B}[m\n";
4242+ test_group: \u{001B}[31munknown\u{001B}[m command \u{001B}[01mbla\u{001B}[m. Must be one of \u{001B}[01mbirds\u{001B}[m, \u{001B}[01mcamels\u{001B}[m, \u{001B}[01mfishs\u{001B}[m, \u{001B}[01mlookup\u{001B}[m\n\
4343+ \ or \u{001B}[01mmammals\u{001B}[m\n";
4444 error `Parse ["birds"; "-k"] @@ __POS_OF__
4545"Usage: \u{001B}[01mtest_group birds\u{001B}[m [\u{001B}[01m--help\u{001B}[m] [\u{001B}[04mCOMMAND\u{001B}[m] …\n\
4646test_group: option \u{001B}[01m-k\u{001B}[m \u{001B}[31mneeds an argument\u{001B}[m\n";
···64646565 fishs [OPTION]… [NAME]
6666 Operate on fishs.
6767+6868+ lookup [--kind=ENUM] [OPTION]… NAME
6969+ Lookup animal by name.
67706871 mammals [OPTION]…
6972 Operate on mammals.
···4545"Usage: \u{001B}[01mtest_group birds\u{001B}[m [\u{001B}[01m--help\u{001B}[m] [\u{001B}[04mCOMMAND\u{001B}[m] …\n\
4646test_group: \u{001B}[31munknown\u{001B}[m command \u{001B}[01mfl\u{001B}[m. Did you mean \u{001B}[01mfly\u{001B}[m?\n";
4747 error_nolegacy `Term ["mam"] @@ __POS_OF__ "Usage: \u{001B}[01mtest_group\u{001B}[m [\u{001B}[01m--help\u{001B}[m] \u{001B}[04mCOMMAND\u{001B}[m …\n\
4848- test_group: \u{001B}[31munknown\u{001B}[m command \u{001B}[01mmam\u{001B}[m. Must be one of \u{001B}[01mbirds\u{001B}[m, \u{001B}[01mcamels\u{001B}[m, \u{001B}[01mfishs\u{001B}[m or\n\
4949- \ \u{001B}[01mmammals\u{001B}[m\n";
4848+ test_group: \u{001B}[31munknown\u{001B}[m command \u{001B}[01mmam\u{001B}[m. Must be one of \u{001B}[01mbirds\u{001B}[m, \u{001B}[01mcamels\u{001B}[m, \u{001B}[01mfishs\u{001B}[m, \u{001B}[01mlookup\u{001B}[m\n\
4949+ \ or \u{001B}[01mmammals\u{001B}[m\n";
5050 ()
51515252let test_cmd =
+33-1
vendor/opam/cmdliner/test/testing_cmdliner.ml
···162162 Cmd.make (Cmd.info "camels" ~deprecated ~doc:"Operate on camels." ~man) @@
163163 let+ bactrian and+ herd in ()
164164 in
165165+ let lookup =
166166+ let kind_opt =
167167+ let kinds = ["bird", `Bird; "fish", `Fish] in
168168+ let doc =
169169+ "$(docv) restricts the animal kind. Must be " ^ Arg.doc_alts_enum kinds
170170+ in
171171+ Arg.(value & opt (some (enum kinds)) None & info ["k"; "kind"] ~doc)
172172+ in
173173+ let name_conv =
174174+ let bird_names = ["sparrow"; "parrot"; "pigeon"] in
175175+ let fish_names = ["salmon"; "trout"; "piranha"] in
176176+ let completion =
177177+ let select ~prefix n =
178178+ if String.starts_with ~prefix n then Some (n, "") else None
179179+ in
180180+ let func kind ~prefix = match Option.join kind with
181181+ | None -> List.filter_map (select ~prefix) (bird_names @ fish_names)
182182+ | Some `Bird -> List.filter_map (select ~prefix) bird_names
183183+ | Some `Fish -> List.filter_map (select ~prefix) fish_names
184184+ in
185185+ Arg.Completion.make ~context:kind_opt ~func ()
186186+ in
187187+ Arg.Conv.of_conv Arg.string ~completion ()
188188+ in
189189+ Cmd.make (Cmd.info "lookup" ~doc:"Lookup animal by name.") @@
190190+ let+ kind_opt
191191+ and+ name =
192192+ let doc = "$(docv) is the animal name to lookup" and docv = "NAME" in
193193+ Arg.(required & pos 0 (some name_conv) None & info [] ~doc ~docv)
194194+ in
195195+ ()
196196+ in
165197 Cmd.group (Cmd.info "test_group" ~version:"X.Y.Z" ~man) @@
166166- [birds; mammals; fishs; camels]
198198+ [birds; mammals; fishs; camels; lookup]