Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?


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?

share|improve this question
up vote 9 down vote accepted

I use the following function to say that a function or alias or wrapper script (e.g. s) is to be completed like an existing command (e.g. ssh):

compdefas () {
  local a
  compdef "$_comps[$a]" "${(@)*}=$a"
compdefas xterm cxterm uxterm xterm-color

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
share|improve this answer
Thanks - I assumed compdef was what I wanted to use. Out of interest, is there any reason you create a local variable and shift, rather than referencing $1 and $2 in your call to compdef? – Murali Suriar Jan 23 '11 at 23:50
@Murali: That's so I can write something like compdefas xterm cxterm uxterm xterm-color. – Gilles Jan 23 '11 at 23:53
interesting - so I've defined two wrappers, one for 'man' and one for 'ssh'. Using compdef, completion for my 'man' wrapper works, but completion for my 'ssh' wrapper doesn't. Have you run into any issues like this before? Is there something else I have to poke in order for _ssh to work with my alias/wrapper? – Murali Suriar Jan 24 '11 at 0:14

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.