···628628629629 (** Argument completion.
630630631631- This modules provides a type to describe how argument values
632632- described by {{!Arg.type-conv}argument converters} can be completed.
633633- They define which completion directives from the
634634- {{!page-cli.completion_protocol}protocol} get emitted by
635635- cmdliner for the argument. *)
631631+ This module provides a type to describe how positional and
632632+ optional argument values described by {{!Arg.type-conv}argument
633633+ converters} can be completed. It defines which completion
634634+ directives from the {{!page-cli.completion_protocol}protocol}
635635+ get emitted by your tool for the argument.
636636+637637+ {b Note.} Subcommand and option name
638638+ completion is done automatically by the library itself.
639639+ {{!Cmdliner.Arg.predef}Prefined argument converters} already
640640+ have completions built-in whenever appropriate. *)
636641 module Completion : sig
637642638638- 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. *)
643643+ (** {1:directives Completion directives} *)
641644642642- 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+ type 'a directive
646646+ (** The type for a completion directive for values of type ['a]. *)
645647646646- type 'a t
647647- (** The type for completing values parsed into values of type ['a]. *)
648648+ val value : ?doc:string -> 'a -> 'a directive
649649+ (** [value v ~doc] indicates that the token to complete could be
650650+ replaced by the value [v] as serialized by the argument's
651651+ formatter {!Conv.pp}. [doc] is ANSI styled UTF-8 text
652652+ documenting the value, defaults to [""]. *)
648653649649- val make :
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:
654654+ val string : ?doc:string -> string -> 'a directive
655655+ (** [string s ~doc] indicates that the token to complete could be
656656+ replaced by the string [s]. [doc] is ANSI styled UTF-8 text
657657+ documenting the value, defaults to [""]. *)
653658654654- [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.
659659+ val files : 'a directive
660660+ (** [files] indicates that the token to complete could be replaced
661661+ with files that the shell deems suitable. *)
660662661661- See accessors for semantics. Note that the properties are
662662- not mutually exclusive. *)
663663+ val dirs : 'a directive
664664+ (** [dirs] indicates that the token to complete could be replaced with
665665+ directories that the shell deems suitable. *)
663666664664- val complete : 'a t -> 'a complete
665665- (** [complete c] is a the context and function to perform completion. *)
666666-667667- val dirs : 'a t -> bool
668668- (** [dirs c] indicates the argument should be completed with directories. *)
669669-670670- val files : 'a t -> bool
671671- (** [files c] indicates the argument should be completed with files. *)
672672-673673- val restart : 'a t -> bool
674674- (** [restart c] indicates that shell should restart the completion
667667+ val restart : 'a directive
668668+ (** [restart] indicates that the shell should restart the completion
675669 after the positional disambiguation token [--].
676670677671 This is typically used for tools that end-up invoking other
···681675 your program you'd eschew [restart] on the first postional
682676 argument but add it to the remaining ones.
683677684684- {b Warning.} Other completion properties are ignored when you
685685- use this. Also note that [restart] directives are emitted only
686686- after a [--] token and it's likely that it will work with
687687- completion scripts only if the [TOOL] is specified after the
688688- token. Educate your users to use the [--] (e.g. mention them
689689- in user {{!page-cookbook.manpage_synopsis}user defined
690690- synopses}) it's good cli specification hygiene anyways. *)
678678+ {b Warning.} A [restart] directive is eventually emited only
679679+ if the completion is requested after a [--] token. In this
680680+ case other completions returned alongside by {!func} are
681681+ ignored. Educate your users to use the [--], for example
682682+ mention them in {{!page-cookbook.manpage_synopsis}user defined
683683+ synopses}. It is good cli specification hygiene anyways as it
684684+ properly delineates argument scopes. *)
685685+686686+ val raw : string -> 'a directive
687687+ (** [raw s] takes over the whole {{!page-cli.completion_protocol}protocol}
688688+ output (including subcommand and option name completion) with [s],
689689+ you are in charge. Any other directive in the result of {!func}
690690+ is ignored.
691691+692692+ {b Warning.} The protocol is unstable, it is not advised to
693693+ output it yourself. *)
694694+695695+ (** {1:completion Completion} *)
696696+697697+ type ('ctx, 'a) func =
698698+ 'ctx option -> token:string -> ('a directive list, string) result
699699+ (** The type for completion functions.
700700+701701+ Given an optional context determined from a partial command
702702+ line parse and a token to complete it returns a list of
703703+ completion directives or an error which is reported to
704704+ end-users via the protocol. *)
705705+706706+ type 'a complete =
707707+ | Complete : 'ctx Term.t option * ('ctx, 'a) func -> 'a complete (** *)
708708+ (** The type for completing.
709709+710710+ A completion context specification which captures a partial
711711+ command line parse (for example the path to a configuration
712712+ file) and a completion function. *)
713713+714714+ type 'a t
715715+ (** The type for completing values parsed into values of type ['a]. *)
716716+717717+ val make : ?context:'ctx Term.t -> ('ctx, 'a) func -> 'a t
718718+ (** [make ~context func] uses [func] to complete.
719719+720720+ [context] defines a commmand line fragment that is evaluated
721721+ before performing the completion. It the evaluation is
722722+ successful the result is given to the completion function otherwise
723723+ [None] is given.
724724+725725+ {b Warning.} [context] must be part of the term of the command
726726+ in which you use the completion otherwise the context will
727727+ always be [None] in the function. *)
728728+729729+ val complete : 'a t -> 'a complete
730730+ (** [complete c] completes with [c]. *)
731731+732732+ val complete_files : 'a t
733733+ (** [complete_files] holds a context insensitive function that
734734+ always returns [Ok \[]{!files}[\]]. *)
735735+736736+ val complete_dirs : 'a t
737737+ (** [complete_dirs] holds a context insensitive function that
738738+ always returns [Ok \[]{!dirs}[\]]. *)
739739+740740+ val complete_paths : 'a t
741741+ (** [complete_paths] holds a context insensitive function that
742742+ always returns [Ok \[]{!files}[;]{!dirs}{[\]]. *)
743743+744744+ val complete_restart : 'a t
745745+ (** [complete_dirs] holds a context insensitive function that
746746+ always returns [Ok \[]{!restart}[\]]. *)
691747 end
692748693749 (** Argument converters.
+19-11
vendor/opam/cmdliner/src/cmdliner_arg.ml
···6767(* Arguments *)
68686969let no_completion =
7070- Cmdliner_def.Arg_info.Completion Cmdliner_def.Arg_completion.none
7070+ Cmdliner_def.Arg_info.Completion Cmdliner_def.Arg_completion.complete_none
71717272let ( & ) f x = f x
7373let parse_error e = Error (`Parse e)
···331331332332(* Predefined converters. *)
333333334334+let add_prefix_completion ~token name =
335335+ if Cmdliner_base.string_starts_with ~prefix:token name
336336+ then Some (Completion.string name) else None
337337+334338let bool =
335339 let alts = ["true"; "false"] in
336340 let parser s = try Ok (bool_of_string s) with
337341 | Invalid_argument _ -> Error (err_invalid_enum "" s alts)
338342 in
339343 let completion =
340340- let func _ctx ~prefix:_ = List.map (fun s -> s, "") alts in
341341- Completion.make ~func ()
344344+ let func _ctx ~token =
345345+ Ok (List.filter_map (add_prefix_completion ~token) alts)
346346+ in
347347+ Completion.make func
342348 in
343349 Conv.make ~docv:"BOOL" ~parser ~pp:Format.pp_print_bool ~completion ()
344350···398404 with Not_found -> invalid_arg (err_incomplete_enum (List.map fst sl))
399405 in
400406 let completion =
401401- let func _ctx ~prefix:_ = List.map (fun (s, _) -> s, "") sl in
402402- Completion.make ~func ()
407407+ let func _ctx ~token =
408408+ Ok (List.filter_map (fun (n, _) -> add_prefix_completion ~token n) sl)
409409+ in
410410+ Completion.make func
403411 in
404412 Conv.make ~docv ~parser ~pp ~completion ()
405413406414let path =
407415 let parser s = Ok s in
408416 let pp ppf s = Fmt.string ppf (Filename.quote s) in
409409- let completion = Completion.make ~dirs:true ~files:true () in
417417+ let completion = Completion.complete_paths in
410418 Conv.make ~docv:"PATH" ~parser ~pp ~completion ()
411419412420let filepath =
413421 let parser s = Ok s in
414422 let pp ppf s = Fmt.string ppf (Filename.quote s) in
415415- let completion = Completion.make ~files:true () in
423423+ let completion = Completion.complete_files in
416424 Conv.make ~docv:"FILE" ~parser ~pp ~completion ()
417425418426let dirpath =
419427 let parser s = Ok s in
420428 let pp ppf s = Fmt.string ppf (Filename.quote s) in
421421- let completion = Completion.make ~dirs:true () in
429429+ let completion = Completion.complete_dirs in
422430 Conv.make ~docv:"DIR" ~parser ~pp ~completion ()
423431424432let file =
···427435 if Sys.file_exists s then Ok s else
428436 Error (err_no "file or directory" s)
429437 in
430430- let completion = Completion.make ~dirs:true ~files:true () in
438438+ let completion = Completion.complete_files in
431439 Conv.make ~docv:"PATH" ~parser ~pp:Fmt.string ~completion ()
432440433441let dir =
···436444 then (if Sys.is_directory s then Ok s else Error (err_not_dir s))
437445 else Error (err_no "directory" s)
438446 in
439439- let completion = Completion.make ~dirs:true () in
447447+ let completion = Completion.complete_dirs in
440448 Conv.make ~docv:"DIR" ~parser ~pp:Fmt.string ~completion ()
441449442450let non_dir_file =
···446454 then (if not (Sys.is_directory s) then Ok s else Error (err_is_dir s))
447455 else Error (err_no "file" s)
448456 in
449449- let completion = Completion.make ~files:true () in
457457+ let completion = Completion.complete_files in
450458 Conv.make ~docv:"FILE" ~parser ~pp:Fmt.string ~completion ()
451459452460let split_and_parse sep parse s = (* raises [Failure] *)
+20-10
vendor/opam/cmdliner/src/cmdliner_arg.mli
···1010type 'a conv
11111212module Completion : sig
1313- type 'ctx func = 'ctx option -> prefix:string -> (string * string) list
1313+ type 'a directive
1414+1515+ val value : ?doc:string -> 'a -> 'a directive
1616+ val string : ?doc:string -> string -> 'a directive
1717+ val files : 'a directive
1818+ val dirs : 'a directive
1919+ val restart : 'a directive
2020+ val raw : string -> 'a directive
2121+2222+ type ('ctx, 'a) func =
2323+ 'ctx option -> token:string -> ('a directive list, string) result
2424+1425 type 'a complete =
1515- | Complete : 'ctx Cmdliner_term.t option * 'ctx func -> 'a complete
2626+ | Complete : 'ctx Cmdliner_term.t option * ('ctx, 'a) func -> 'a complete
16271728 type 'a t
1818- val make :
1919- ?context: 'ctx Cmdliner_term.t -> ?func:'ctx func -> ?dirs:bool ->
2020- ?files:bool -> ?restart:bool -> unit -> 'a t
2929+3030+ val make : ?context:'ctx Cmdliner_term.t -> ('ctx, 'a) func -> 'a t
21312232 val complete : 'a t -> 'a complete
2323- val dirs : 'a t -> bool
2424- val files : 'a t -> bool
2525- val restart : 'a t -> bool
2626- val none : 'a t
2727- val some : 'a t -> 'a option t
3333+ val complete_none : 'a t
3434+ val complete_files : 'a t
3535+ val complete_dirs : 'a t
3636+ val complete_paths : 'a t
3737+ val complete_restart : 'a t
2838end
29393040module Conv : sig
+1
vendor/opam/cmdliner/src/cmdliner_base.ml
···7777 type 'a t = Format.formatter -> 'a -> unit
7878 let str = Format.asprintf
7979 let pf = Format.fprintf
8080+ let nop ppf _ = ()
8081 let sp = Format.pp_print_space
8182 let cut = Format.pp_print_cut
8283 let string = Format.pp_print_string
+1
vendor/opam/cmdliner/src/cmdliner_base.mli
···2222 type 'a t = Format.formatter -> 'a -> unit
2323 val str : ('a, Format.formatter, unit, string) format4 -> 'a
2424 val pf : Format.formatter -> ('a, Format.formatter, unit) format -> 'a
2525+ val nop : 'a t
2526 val sp : unit t
2627 val comma : unit t
2728 val cut : unit t
+96-69
vendor/opam/cmdliner/src/cmdliner_completion.ml
···33 SPDX-License-Identifier: ISC
44 ---------------------------------------------------------------------------*)
5566-(* Output protocol
66+(* Output protocol *)
7788- This is a bit ugly we have logic and rendering intermingled. *)
88+let cons_if b v l = if b then v :: l else l
99+1010+type dir =
1111+[ `Dirs | `Error of string | `Files | `Group of string * (string * string) list
1212+| `Restart ]
9131010-let pp_line ppf s = Cmdliner_base.Fmt.(string ppf s; cut ppf ())
1111-let pp_group ppf s = pp_line ppf "group"; pp_line ppf s
1212-let pp_item ppf ~prefix (name, doc) =
1313- if Cmdliner_base.string_starts_with ~prefix name then begin
1414+let pp_protocol ppf dirs =
1515+ let pp_line ppf s = Cmdliner_base.Fmt.(string ppf s; cut ppf ()) in
1616+ let vnum = 1 (* Protocol version number *) in
1717+ let pp_item ppf (name, doc) =
1418 pp_line ppf "item";
1519 pp_line ppf name;
1616- Cmdliner_base.Fmt.(pf ppf "@[%a@]@," text doc);
2020+ Cmdliner_base.Fmt.(pf ppf "@[%a@]@," styled_text doc);
1721 pp_line ppf "item-end";
1818- end
2222+ in
2323+ let pp_dir ppf = function
2424+ | `Dirs -> pp_line ppf "dirs"
2525+ | `Files -> pp_line ppf "files"
2626+ | `Error msg -> failwith "TODO"
2727+ | `Restart -> pp_line ppf "restart"
2828+ | `Group (name, items) ->
2929+ pp_line ppf "group";
3030+ pp_line ppf name;
3131+ Cmdliner_base.Fmt.(list ~sep:nop pp_item) ppf items;
3232+ in
3333+ Cmdliner_base.Fmt.pf ppf "@[<v>%d@,%a@]" vnum
3434+ Cmdliner_base.Fmt.(list ~sep:nop pp_dir) dirs
19352020-let pp_opt ~err_ppf ~subst ~prefix ppf arg_info _ =
2121- (* XXX should we rather list a single name ? *)
2222- let names = Cmdliner_def.Arg_info.opt_names arg_info in
2323- let subst = Cmdliner_def.Arg_info.doclang_subst ~subst arg_info in
2424- let doc = Cmdliner_def.Arg_info.styled_doc ~errs:err_ppf ~subst arg_info in
2525- List.iter (fun name -> pp_item ppf ~prefix (name, doc)) names
2626-2727-let pp_opt_names ~err_ppf ~subst ~prefix ppf cmd =
2828- let info = Cmdliner_cmd.get_info cmd in
2929- let set = Cmdliner_def.Cmd_info.args info in
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)
3434- arg_infos
3535- end
3636-3737-let pp_arg_values ~after_dashdash ~prefix items ppf comp =
3838- if after_dashdash && Cmdliner_def.Arg_completion.restart comp
3939- then pp_line ppf "restart" else
4040- let items = items () in
4141- let comp_files = Cmdliner_def.Arg_completion.files comp in
4242- let comp_dirs = Cmdliner_def.Arg_completion.dirs comp in
4343- if items <> [] || comp_files || comp_dirs then begin
4444- pp_group ppf "Values";
4545- List.iter (pp_item ppf ~prefix) items;
4646- if comp_files then pp_line ppf "files";
4747- if comp_dirs then pp_line ppf "dirs"
4848- end
4949-5050-let pp_subcmds ~err_ppf ~subst ~prefix ppf cmd =
5151- pp_group ppf "Subcommands";
5252- let complete_cmd cmd =
3636+let add_subcommands_group ~err_ppf ~subst cmd comp directives =
3737+ if not (Cmdliner_def.Complete.subcmds comp) then directives else
3838+ let prefix = Cmdliner_def.Complete.prefix comp in
3939+ let maybe_item cmd =
5340 let name = Cmdliner_def.Cmd_info.name cmd in
4141+ if not (Cmdliner_base.string_starts_with ~prefix name) then None else
5442 (* FIXME subst is wrong here. *)
5543 let doc = Cmdliner_def.Cmd_info.styled_doc ~errs:err_ppf ~subst cmd in
5656- pp_item ppf ~prefix (name, doc)
4444+ Some (name, doc)
4545+ in
4646+ let subcmds = Cmdliner_cmd.get_children_infos cmd in
4747+ (`Group ("Subcommands", List.filter_map maybe_item subcmds)) :: directives
4848+4949+let add_options_group ~err_ppf ~subst cmd comp directives =
5050+ let prefix = Cmdliner_def.Complete.prefix comp in
5151+ let maybe_items arg_info =
5252+ let names = Cmdliner_def.Arg_info.opt_names arg_info in
5353+ let subst = Cmdliner_def.Arg_info.doclang_subst ~subst arg_info in
5454+ let doc = Cmdliner_def.Arg_info.styled_doc ~errs:err_ppf ~subst arg_info in
5555+ let add_name n =
5656+ if not (Cmdliner_base.string_starts_with ~prefix n) then None else
5757+ Some (n, doc)
5858+ in
5959+ List.filter_map add_name names
5760 in
5858- List.iter complete_cmd (Cmdliner_cmd.get_children_infos cmd)
6161+ let maybe_opt = prefix = "" || prefix.[0] = '-' in
6262+ if Cmdliner_def.Complete.after_dashdash comp || not maybe_opt
6363+ then directives else
6464+ let info = Cmdliner_cmd.get_info cmd in
6565+ let set = Cmdliner_def.Cmd_info.args info in
6666+ if Cmdliner_def.Arg_info.Set.is_empty set then directives else
6767+ let options = Cmdliner_def.Arg_info.Set.elements set in
6868+ `Group ("Options", List.concat (List.map maybe_items options)) :: directives
59696060-let vnum = 1 (* Protocol version number *)
7070+let add_argument_value_directives directives comp =
7171+ let Directives ds = Cmdliner_def.Complete.directives comp in
7272+ match ds with
7373+ | Error msg -> `Directives [`Error msg]
7474+ | Ok ds ->
7575+ let rec loop values ~files ~dirs ~restart ~raw = function
7676+ | [] ->
7777+ begin match raw with
7878+ | Some r -> `Raw r
7979+ | None ->
8080+ if Cmdliner_def.Complete.after_dashdash comp && restart
8181+ then `Directives [`Restart] else
8282+ let dd =
8383+ cons_if dirs `Dirs @@
8484+ cons_if files `Files @@
8585+ cons_if (values <> []) (`Group ("Values", List.rev values)) []
8686+ in
8787+ `Directives (List.rev_append dd directives)
8888+ end
8989+ | d :: ds ->
9090+ match d with
9191+ | Cmdliner_def.Arg_completion.String (s, doc) ->
9292+ loop ((s, doc) :: values) ~files ~dirs ~restart ~raw ds
9393+ | Value (_, _) -> failwith "TODO"
9494+ | Files -> loop values ~files:true ~dirs ~restart ~raw ds
9595+ | Dirs -> loop values ~files ~dirs:true ~restart ~raw ds
9696+ | Restart -> loop values ~files ~dirs ~restart:true ~raw ds
9797+ | Raw r -> loop values ~files ~dirs ~restart ~raw:(Some r) ds
9898+ in
9999+ loop [] ~files:false ~dirs:false ~restart:false ~raw:None ds
611006262-let output ~out_ppf ~err_ppf ei cmd_args_info cmd comp ~items =
101101+let output ~out_ppf ~err_ppf ei cmd_args_info cmd comp =
63102 let subst = Cmdliner_def.Eval.doclang_subst ei in
6464- let after_dashdash = Cmdliner_def.Complete.after_dashdash comp in
6565- let prefix = Cmdliner_def.Complete.prefix comp in
6666- let maybe_opt = prefix = "" || prefix.[0] = '-' in
6767- let pp_arg_value ppf arg_info =
6868- begin match Cmdliner_def.Arg_info.Set.find_opt arg_info cmd_args_info with
6969- | None -> ()
7070- | Some (Completion comp) ->
7171- pp_arg_values ~after_dashdash ~prefix items ppf comp
7272- end;
103103+ let dirs = add_subcommands_group ~err_ppf ~subst cmd comp [] in
104104+ let res = match Cmdliner_def.Complete.kind comp with
105105+ | Opt_value _arg_info (* XXX need to handle Value *) ->
106106+ add_argument_value_directives dirs comp
107107+ | Opt_name_or_pos_value arg_info (* XXX need to handle Value *) ->
108108+ let dirs = add_options_group ~err_ppf ~subst cmd comp dirs in
109109+ add_argument_value_directives dirs comp
110110+ | Opt_name ->
111111+ `Directives (add_options_group ~err_ppf ~subst cmd comp dirs)
73112 in
7474- let pp ppf () =
7575- begin match Cmdliner_def.Complete.kind comp with
7676- | Opt_value arg_info -> pp_arg_value ppf arg_info
7777- | Opt_name_or_pos_value arg_info ->
7878- pp_arg_value ppf arg_info;
7979- if not after_dashdash && maybe_opt
8080- then pp_opt_names ~err_ppf ~subst ~prefix ppf cmd
8181- | Opt_name ->
8282- if not after_dashdash && maybe_opt
8383- then pp_opt_names ~err_ppf ~subst ~prefix ppf cmd;
8484- end;
8585- if Cmdliner_def.Complete.subcmds comp
8686- then pp_subcmds ~err_ppf ~subst ~prefix ppf cmd
8787- in
8888- Cmdliner_base.Fmt.pf out_ppf "@[<v>%d@,%a@]@?" vnum pp ()
113113+ match res with
114114+ | `Raw raw -> Cmdliner_base.Fmt.pf out_ppf "%s@?" raw
115115+ | `Directives dirs -> Cmdliner_base.Fmt.pf out_ppf "%a@?" pp_protocol dirs
-1
vendor/opam/cmdliner/src/cmdliner_completion.mli
···1010 Cmdliner_def.Arg_info.Set.t ->
1111 'a Cmdliner_cmd.t ->
1212 Cmdliner_def.Complete.t ->
1313- items:(unit -> (string * string) list) ->
1413 unit
+93-62
vendor/opam/cmdliner/src/cmdliner_def.ml
···202202 [ `Error of bool * string
203203 | `Help of Cmdliner_manpage.format * string option ]
204204205205- 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 }
205205+ type 'a completion_directive =
206206+ | String of string * string | Value of 'a * string | Files | Dirs | Restart
207207+ | Raw of string
212208209209+ type ('ctx, 'a) completion_func =
210210+ 'ctx option -> token:string -> ('a completion_directive list, string) result
211211+212212+ type 'a complete =
213213+ | Complete : 'ctx term option * ('ctx, 'a) completion_func -> 'a complete
214214+215215+ and 'a completion = { complete : 'a complete }
213216 and e_completion = Completion : 'a completion -> e_completion
214217 and arg_set = e_completion Map.t
215215-216218 and cmd =
217219 { name : string; (* name of the cmd. *)
218220 version : string option; (* version (for --version). *)
···342344 | _ -> None
343345end
344346345345-(* Completion *)
346346-347347-module Complete = struct
348348- type kind =
349349- | Opt_value of Arg_info.t
350350- | Opt_name_or_pos_value of Arg_info.t
351351- | Opt_name
352352-353353- type t =
354354- { context : Cline.t;
355355- prefix : string;
356356- after_dashdash : bool;
357357- subcmds : bool; (* Note this is adjusted in Cmdliner_eval *)
358358- kind : kind;
359359- values : (string * string) list }
360360-361361- let make ?(after_dashdash = false) ?(subcmds = false) context ~prefix kind =
362362- { context; prefix; after_dashdash; subcmds; kind; values = [] }
363363-364364- let add_subcmds c = { c with subcmds = true }
365365- let add_values c values = { c with values }
366366- let context c = c.context
367367- let prefix c = c.prefix
368368- let after_dashdash c = c.after_dashdash
369369- let subcmds c = c.subcmds
370370- let kind c = c.kind
371371-end
372372-373347(* Terms *)
374348375349module Term = struct
···381355end
382356383357module Arg_completion = struct
384384- type 'ctx func = 'ctx Arg_info.func
358358+ type 'a directive = 'a Arg_info.completion_directive =
359359+ | String of string * string | Value of 'a * string
360360+ | Files | Dirs | Restart | Raw of string
361361+362362+ let value ?(doc = "") v = Value (v, doc)
363363+ let string ?(doc = "") s = String (s, doc)
364364+ let files = Files
365365+ let dirs = Dirs
366366+ let restart = Restart
367367+ let raw s = Raw s
368368+369369+ type ('ctx, 'a) func =
370370+ 'ctx option -> token:string -> ('a directive list, string) result
385371386372 type 'a complete = 'a Arg_info.complete =
387387- | Complete : 'ctx Term.t option * 'ctx func -> 'a complete
373373+ | Complete : 'ctx Term.t option * ('ctx, 'a) func -> 'a complete
388374389375 type 'a t = 'a Arg_info.completion
390376391391- let make
392392- ?context ?(func = fun _ ~prefix:_ -> []) ?(dirs = false) ?(files = false)
393393- ?(restart = false) () : 'a t
394394- =
395395- { complete = Complete (context, func); dirs; files; restart }
377377+ let make ?context func : 'a t = { complete = Complete (context, func) }
378378+ let complete (c : 'a t) = c.complete
379379+380380+ let complete_files : 'a t =
381381+ { complete = Complete (None, fun _ ~token:_ -> Ok [Files]) }
382382+383383+ let complete_dirs : 'a t =
384384+ { complete = Complete (None, fun _ ~token:_ -> Ok [Dirs]) }
385385+386386+ let complete_paths : 'a t =
387387+ { complete = Complete (None, fun _ ~token:_ -> Ok [Files; Dirs]) }
388388+389389+ let complete_restart : 'a t =
390390+ { complete = Complete (None, fun _ ~token:_ -> Ok [Restart]) }
396391397397- let none : 'a t =
398398- { complete = Complete (None, fun _ ~prefix:_ -> []);
399399- dirs = false; files = false; restart = false }
392392+ let complete_none : 'a t =
393393+ { complete = Complete (None, fun _ ~token:_ -> Ok []) }
400394401401- let some c : 'a option t = match c.Arg_info.complete with
402402- | Complete (ctx, func) -> { c with complete = Complete (ctx, func) }
395395+ let directive_some : 'a directive -> 'a option directive = function
396396+ | Value (v, doc) -> Value (Some v, doc)
397397+ | (String _ | Files | Dirs | Restart | Raw _ as v) -> v
403398404404- let complete (c : 'a t) = c.complete
405405- let dirs (c : 'a t) = c.dirs
406406- let files (c : 'a t) = c.files
407407- let restart (c : 'a t) = c.restart
399399+ let complete_some (c : 'a t) : 'a option t = match c.complete with
400400+ | Complete (ctx, func) ->
401401+ let func ctx ~token =
402402+ let some_result directives = List.map directive_some directives in
403403+ Result.map some_result (func ctx ~token)
404404+ in
405405+ { complete = Complete (ctx, func) }
408406end
409407410408(* Converters *)
···418416 pp : 'a fmt;
419417 completion : 'a Arg_completion.t; }
420418421421- let make ?(completion = Arg_completion.none) ~docv ~parser ~pp () =
419419+ let make ?(completion = Arg_completion.complete_none) ~docv ~parser ~pp () =
422420 { docv; parser; pp; completion }
423421424422 let of_conv
···434432 let completion c = c.completion
435433436434 let some ?(none = "") conv =
437437- let parser s = match parser conv s with
438438- | Ok v -> Ok (Some v) | Error _ as e -> e
439439- in
435435+ let parser s = Result.map Option.some (parser conv s) in
440436 let pp ppf v = match v with
441437 | None -> Format.pp_print_string ppf none
442438 | Some v -> pp conv ppf v
443439 in
444444- let completion = Arg_completion.some (completion conv) in
440440+ let completion = Arg_completion.complete_some (completion conv) in
445441 { conv with parser; pp; completion }
446442447443 let some' ?none conv =
448448- let parser s = match parser conv s with
449449- | Ok v -> Ok (Some v) | Error _ as e -> e
450450- in
444444+ let parser s = Result.map Option.some (parser conv s) in
451445 let pp ppf = function
452446 | None -> (match none with None -> () | Some v -> (pp conv) ppf v)
453447 | Some v -> pp conv ppf v
454448 in
455455- let completion = Arg_completion.some conv.completion in
456456- { conv with parser; pp; completion }
449449+ let completion = Arg_completion.complete_some conv.completion in
450450+ { conv with parser; pp; completion }
451451+end
452452+453453+454454+455455+(* Completion *)
456456+457457+module Complete = struct
458458+ type kind =
459459+ | Opt_value of Arg_info.t
460460+ | Opt_name_or_pos_value of Arg_info.t
461461+ | Opt_name
462462+463463+ type directives =
464464+ Directives : ('a Arg_completion.directive list, string) result -> directives
465465+466466+ type t =
467467+ { context : Cline.t;
468468+ prefix : string;
469469+ after_dashdash : bool;
470470+ subcmds : bool; (* Note this is adjusted in Cmdliner_eval *)
471471+ kind : kind;
472472+ directives : directives }
473473+474474+ let make ?(after_dashdash = false) ?(subcmds = false) context ~prefix kind =
475475+ { context; prefix; after_dashdash; subcmds; kind;
476476+ directives = Directives (Ok []) }
477477+478478+ let add_subcmds c = { c with subcmds = true }
479479+ let add_directives directives c =
480480+ { c with directives = Directives directives }
481481+482482+ let context c = c.context
483483+ let prefix c = c.prefix
484484+ let after_dashdash c = c.after_dashdash
485485+ let subcmds c = c.subcmds
486486+ let kind c = c.kind
487487+ let directives c = c.directives
457488end
+56-32
vendor/opam/cmdliner/src/cmdliner_def.mli
···117117 val styled_doc :
118118 errs:Format.formatter -> subst:Cmdliner_manpage.subst -> t -> string
119119120120+ module Map : Map.S with type key := t
121121+120122 type 'a completion
121123 type e_completion = Completion : 'a completion -> e_completion
122122- module Map : Map.S with type key := t
124124+123125 module Set : sig
124126 type arg := t
125127 type t
···195197 val doclang_subst : t -> Cmdliner_manpage.subst
196198end
197199198198-(** Complete instruction. *)
199199-module Complete : sig
200200- type kind =
201201- | Opt_value of Arg_info.t
202202- | Opt_name_or_pos_value of Arg_info.t
203203- | Opt_name
204204-205205- type t
206206-207207- val make :
208208- ?after_dashdash:bool -> ?subcmds:bool -> Cline.t -> prefix:string ->
209209- kind -> t
210210-211211- val context : t -> Cline.t
212212- val add_subcmds : t -> t
213213- val prefix : t -> string
214214- val after_dashdash : t -> bool
215215- val subcmds : t -> bool
216216- val kind : t -> kind
217217-end
218218-219200(** Terms, typed cli fragment definitions. *)
220201module Term : sig
221202 type escape =
···230211231212(** Completion strategies *)
232213module Arg_completion : sig
214214+ type 'a directive =
215215+ | String of string * string | Value of 'a * string
216216+ | Files | Dirs | Restart | Raw of string
233217234234- type 'ctx func = 'ctx option -> prefix:string -> (string * string) list
235235- type 'a complete = Complete : 'ctx Term.t option * 'ctx func -> 'a complete
218218+ val value : ?doc:string -> 'a -> 'a directive
219219+ val string : ?doc:string -> string -> 'a directive
220220+ val files : 'a directive
221221+ val dirs : 'a directive
222222+ val restart : 'a directive
223223+ val raw : string -> 'a directive
224224+225225+ type ('ctx, 'a) func =
226226+ 'ctx option -> token:string -> ('a directive list, string) result
227227+228228+ type 'a complete =
229229+ | Complete : 'ctx Term.t option * ('ctx, 'a) func -> 'a complete
230230+236231 type 'a t = 'a Arg_info.completion
237237- val make :
238238- ?context:'ctx Term.t -> ?func:'ctx func -> ?dirs:bool -> ?files:bool ->
239239- ?restart:bool -> unit -> 'a t
240232241241- val none : 'a t
242242- val some : 'a t -> 'a option t
233233+ val make : ?context:'ctx Term.t -> ('ctx, 'a) func -> 'a t
243234 val complete : 'a t -> 'a complete
244244- val dirs : 'a t -> bool
245245- val files : 'a t -> bool
246246- val restart : 'a t -> bool
235235+ val complete_none : 'a t
236236+ val complete_files : 'a t
237237+ val complete_dirs : 'a t
238238+ val complete_paths : 'a t
239239+ val complete_restart : 'a t
247240end
248241249242(** Textual OCaml value converters *)
···267260 val some : ?none:string -> 'a t -> 'a option t
268261 val some' : ?none:'a -> 'a t -> 'a option t
269262end
263263+264264+265265+(** Complete instruction. *)
266266+module Complete : sig
267267+ type kind =
268268+ | Opt_value of Arg_info.t
269269+ | Opt_name_or_pos_value of Arg_info.t
270270+ | Opt_name
271271+272272+ type directives =
273273+ Directives : ('a Arg_completion.directive list, string) result -> directives
274274+275275+ type t
276276+277277+ val make :
278278+ ?after_dashdash:bool -> ?subcmds:bool -> Cline.t -> prefix:string ->
279279+ kind -> t
280280+281281+ val context : t -> Cline.t
282282+283283+284284+ val add_subcmds : t -> t
285285+ val add_directives :
286286+ ('a Arg_completion.directive list, string) result -> t -> t
287287+288288+ val prefix : t -> string
289289+ val after_dashdash : t -> bool
290290+ val subcmds : t -> bool
291291+ val kind : t -> kind
292292+ val directives : t -> directives
293293+end
+16-15
vendor/opam/cmdliner/src/cmdliner_eval.ml
···107107 Cmdliner_msg.pp_usage_and_err err_ppf ei ~err; Error `Parse
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
110110+ let comp =
111111+ let token = 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 -> []
118118+ | None -> comp
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
122122+ | None -> comp
123123+ | Some (Completion c) -> (* FIXME we want converter here *)
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+ let dirs = func ctx ~token in
133133+ Cmdliner_def.Complete.add_directives dirs comp
133134 in
134135 Cmdliner_completion.output
135135- ~out_ppf:help_ppf ~err_ppf ei cmd_args_info cmd comp ~items; Ok `Help
136136+ ~out_ppf:help_ppf ~err_ppf ei cmd_args_info cmd comp; Ok `Help
136137 | `Help (fmt, cmd_name) ->
137138 do_help ~env help_ppf err_ppf ei fmt cmd_name; Ok `Help
138139 | `Exn (e, bt) ->
+4-6
vendor/opam/cmdliner/test/test_completion.ml
···216216 Options\n\
217217 item\n\
218218 -k\n\
219219- \u{001B}[04mENUM\u{001B}[m restricts the animal kind. Must be either \u{001B}[01mbird\u{001B}[m or\n\
220220- \u{001B}[01mfish\u{001B}[m\n\
219219+ \u{001B}[04mENUM\u{001B}[m restricts the animal kind. Must be either \u{001B}[01mbird\u{001B}[m or \u{001B}[01mfish\u{001B}[m\n\
221220 item-end\n\
222221 item\n\
223222 --kind\n\
224224- \u{001B}[04mENUM\u{001B}[m restricts the animal kind. Must be either \u{001B}[01mbird\u{001B}[m or\n\
225225- \u{001B}[01mfish\u{001B}[m\n\
223223+ \u{001B}[04mENUM\u{001B}[m restricts the animal kind. Must be either \u{001B}[01mbird\u{001B}[m or \u{001B}[01mfish\u{001B}[m\n\
226224 item-end\n";
227225 complete ["lookup"; "-kfish"; "--__complete=s"] @@ __POS_OF__
228226 "1\n\
···256254 Arg.(required & pos 0 (some tool) None & info [])
257255 and+ args =
258256 let arg =
259259- let completion = Arg.Completion.make ~restart:true () in
257257+ let completion = Arg.Completion.complete_restart in
260258 Arg.Conv.of_conv ~docv:"ARG" Arg.string ~completion ()
261259 in
262260 Arg.(value & pos_right 0 arg [] & info [])
···309307 let cmd =
310308 Cmd.make (Cmd.info "test_restart") @@
311309 let arg ~docv =
312312- let completion = Arg.Completion.make ~restart:true () in
310310+ let completion = Arg.Completion.complete_restart in
313311 Arg.Conv.of_conv ~docv:"TOOL" Arg.string ~completion ()
314312 in
315313 let+ verb = Arg.(value & flag & info ["verbose"])
+8-7
vendor/opam/cmdliner/test/testing_cmdliner.ml
···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
177177+ let select ~token:prefix n =
178178+ if String.starts_with ~prefix n
179179+ then Some (Arg.Completion.string n) else None
179180 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
181181+ let func kind ~token = match Option.join kind with
182182+ | None -> Ok (List.filter_map (select ~token) (bird_names @ fish_names))
183183+ | Some `Bird -> Ok (List.filter_map (select ~token) bird_names)
184184+ | Some `Fish -> Ok (List.filter_map (select ~token) fish_names)
184185 in
185185- Arg.Completion.make ~context:kind_opt ~func ()
186186+ Arg.Completion.make ~context:kind_opt func
186187 in
187188 Arg.Conv.of_conv Arg.string ~completion ()
188189 in