Apologies in advance if this has been answered before, I was not able to find it searching.
In bash, I'm trying to figure out an elegant way to autocomplete a command line argument where a single word is broken down into segments, and completion is processed one segment at a time. An example would be something like a host name where you might have a <site><app><role><node>
format, where each segment might have a manageable number of options for each segment but an enormous number of options in the full search space. (e.g. 20 options per segment (80 total) would be manageable. 20^4 = 160,000 suggestions, which is madness)
Lets say that I want to auto complete an argument matching the pattern "{foo,bar}{qux,baz}". If I try complete -W "{foo,bar}{qux,baz}" asdf
, I can type asdf <tab><tab>
and I'll get a completion suggestion of barbaz barqux foobaz fooqux
. This is fine for the trivial case but becomes an unwieldy number of suggestions when the segments each have a large numbers of options (see 160,000 in the example above), plus I really only care about foo
or bar
at this point. I'd prefer an intermediate completion suggestion of foo bar
, and after I've picked foo
or bar
doing e.g. asdf foo<tab><tab>
would generate a completion suggestion of foobaz fooqux
(yes, I already know about -o nospace
)
I also tried complete -W "foo bar" -W "qux baz" asdf
, but it appears that the complete
is last-wins for -W since I only got baz qux
as suggestions.
Fully enumerating my options isn't really practical as it's a constantly changing list (although staying within the formulaic framework) that can't easily be automatically updated. Doing so would also generate the previously mentioned unwieldy number of suggestions that I'd like to avoid. (Not the 160,000 in the example's full search space, but enough to still be undesireable)
I may try solving the problem with a complete -F
function, but doing so seems non-trivial. I'm really hoping someone has a more elegant solution.
I should also point out that while my example had equal length segments, no overlap, and no numbers, the general case does not. I.e, a pattern of {foo,foobletch,qwerty}{xyzzy,bar,bar42}{qux,quxbaz,alskhgqlehgdghl}
should be handled.