I have a couple of shell functions defined in my .zshrc
which save on typing and allow integration with screen. For example:
function s()
{
screen -t "$1" ssh "$@"
}
However, when I use these shell functions, I can't take advantage of zsh's built in command completion features. (In the case of SSH, automatically completing hostnames based on known_hosts and ssh_config). What's the preferred way to hook in to the existing completion mechanisms for commands I've created wrappers for?
EDIT:
Thanks to Gilles for his answer below. Using compdef appears to be the way to do this, but interestingly it doesn't seem to work uniformly. In this case, I have the following setup:
function s()
{
screen -t "$1" ssh "$@"
}
function m()
{
screen -t "man.$1" man "$1"
}
compdef $_comps[man] m
compdef $_comps[ssh] s
Completion for my wrapper function 'm' works as expected, however completion for my function 's' does not; rather than attempting to complete hostnames, it appears to fall back to default autocompletion by providing me a list of files when I hit 'tab'. Is there some oddity in the way that SSH completion is handled which means I need to do something further?
Best Answer
To request that a command be completed like another command that is already known to the completion system, you can use the
compdef my_command=known_command
form ofcompdef
.Under the hood, this is basically equivalent to
_comps[s]=$_comps[ssh]
.Some completion commands apply to a family of functions and read the first word of the command line to determine which particular command to complete. For example, the commands
ssh
,scp
,sftp
and a few more are all completed by the function_ssh
. In that case, you need to tell the completion function which “service” your function is like (by default, the service is the executable name, here your function's name).