Skip to content

Multi-field prefix match #95

@ghost

Description

As per discussion with @diml and @dbuenzli, let's outline the new behavior of unabbreviating things like l-a to list-available.

Cmdliner's custom trie already does a prefix match and allows one to type opam sw and have it run opam switch. Additionally, it's very useful to unabbreviate (expand) opam sw l-a to opam switch list-available.

Examples:

$ opam sw
==> opam switch

$ opam sw list-a
==> opam switch list-available

$ opam sw li-a
==> opam switch list-available

$ opam sw l-av
==> opam switch list-available

$ opam sw l-a
==> opam switch list-available

The implementation doesn't necessarily have to be limited to two fields and could support more, like dune d-s-e matched as dune do-something-else.

@dbuenzli wrote:

It's likely that another data structure should be provided, since maybe the trie prefix scheme should be kept for option names.

For command names this should then be plugged here:

cmdliner/src/cmdliner.ml

Lines 214 to 233 in 452760b

if String.length maybe > 1 && maybe.[0] = '-' then Ok (main, args) else
let index =
let add acc (choice, _ as c) =
let name = Cmdliner_info.term_name choice in
match Cmdliner_trie.add acc name c with
| `New t -> t
| `Replaced (c', _) -> invalid_arg (err_multi_cmd_def name c c')
in
List.fold_left add Cmdliner_trie.empty choices
in
match Cmdliner_trie.find index maybe with
| `Ok choice -> Ok (choice, args')
| `Not_found ->
let all = Cmdliner_trie.ambiguities index "" in
let hints = Cmdliner_suggest.value maybe all in
Error (Cmdliner_base.err_unknown ~kind:"command" maybe ~hints)
| `Ambiguous ->
let ambs = Cmdliner_trie.ambiguities index maybe in
let ambs = List.sort compare ambs in
Error (Cmdliner_base.err_ambiguous ~kind:"command" maybe ~ambs)

and an alternate enum converter:

val enum : (string * 'a) list -> 'a converter

should be provided for sub-commands (since currently you have to this manually using a positional argument see issue #24).

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions