Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-field prefix match #95

Closed
ghost opened this issue Mar 3, 2018 · 1 comment
Closed

Multi-field prefix match #95

ghost opened this issue Mar 3, 2018 · 1 comment

Comments

@ghost
Copy link

ghost commented Mar 3, 2018

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).

@ghost ghost changed the title Multi-field un-abbreviation Multi-field unabbreviation Mar 4, 2018
@ghost ghost changed the title Multi-field unabbreviation Multi-field prefix match Jul 6, 2019
@ghost ghost closed this as completed Feb 23, 2021
@dbuenzli
Copy link
Owner

Not sure why this was closed but I'm not against :-) A few comments:

  1. I don't think the current behaviour of cmdliner which allows prefixes to be specified for commands and options was a good idea in the first place since it is not stable w.r.t. option and command additions despite the fact that it is a very natural destiny for cli programs.
  2. I have the impression that the kind of behaviour that was sought by this proposal is better solved at the shell UI layer where smarter, highly user dependent and statistically informed completion strategies can be achieved in a generic manner.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant