How to get the shell functions to make use of existing autocompletion in zsh

autocompletezsh

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 of compdef.

compdef s=ssh
compdef {cxterm,uxterm,xterm-color}=xterm

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

_s () {
  local service=ssh
  _ssh "$@"
}
compdef _s s
Related Question