How to tap into the completion of another command programmatically?
Supposing my current directory has files a1
, a2
, and a3
, then how can I make my command invoke the autocompletion of ls a
to get back a1 a2 a3
?
Is this possible?
Clarification and justification:
I chose ls
because people can relate to it. It is a contrived example, but let me try to exemplify the value of this feature. I have a command called build
which, given a directory, can autocomplete to the targets that can be built in that directory. Those targets may not correspond to the files from that directory. The targets might be mined by the build
command from a build file that I don't want to be parsing. In other words:
build path/to/dir/
TABTAB
Might give:
path/to/dir/a_target
path/to/dir/b_target
build
is a pre-existing command, not something I can go ahead and modify to suit my purposes. And the manner in which it extracts its targets is something I certainly don't want to know.
Now suppose I have an entire repository of build
able projects, and most of my work and therefore most of my build
work happens in only one project. In other words, I always build
some target under my/project/directory
.
So far so good.
So I want to write a wrapper around the build command that doesn't require me to feed it the directory path each time I run it. I want it to know my preferred project directory (or directories, why not) and let me reference the targets without qualifying them:
So under the assumption that I have:
my/project/directory/a_target
my/project/directoryb_target
I want this:
mybuild
TABTAB
to give me:
a_target
b_target
Of course I will need to write completion code for mybuild
, but I want it to rely on the completion for build
, because I can't just go and ask the developers of build
to code a build listtargets
command just to make me happy. That feature is already there, in the completion for build
, and I need to tap into it.
(Of course, when I run mybuild a_target
, it will know to run build my/project/directory/a_target
, and that I know how to implement and is not in scope for this question.)
I hope this illustrates why I need to tap into the completion of the build
command and use it as a black box.
Bash has something similar to this called globbing.
So for example in your case you could run the command
Which would produce:
This is very useful where you have spaces in the names of your files as you can say
And it would work for
a1
as well asa 1
This is a bit of an odd thing to do, and the command you need to execute depends on the number of files in the directory - none, one, or more than one. But this command works for the example case:
The command being autocompleted is
so send that as a character stream, followed by two tab characters, into an interactive bash shell.
bash
produces the autocompletion output onstderr
, so redirect that tostdout
and pipe that throughhead
andtail
to select one line of output from the whole. That produces, in this case, the one-line outputBut, as others say, just using
might be easier!
Auto-completion is a feature provided by your shell (e.g. bash). The shell will try to offer auto-complete suggestions based on the context of the command you're trying to run and the environment. E.g. it knows that some commands will work on files and can offer some auto-completion based on file paths. But the command itself is not aware on how the arguments it has been run with have been specified, either by the user or with help of auto-completion.