Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

OK, a little background: I use a Mac, and I do as much as possible in the CLI.

In particular, I frequently pop in a USB stick, cp or mv a file over, and then immediately wish to eject (unmount and disconnect) it. This can usually be accomplished in a handful of keystrokes, except for unmounting it, which requires (in 10.7) going to an empty desktop space (usually two spaces away at least), selecting the disk, and pressing "command-e". Frankly, this unmount procedure is, by several orders of magnitude, the most time-consuming and tedious part of the process.

It would be far more natural and efficient to simply be able to type, say:

ej<tab> J<tab>

Say my USB stick mounts at /Volumes/Jefferson. What I would expect to get from my 6 keystrokes is the following:

eject /Volumes/Jefferson

This should run the command:

diskutil unmount /Volumes/Jefferson

So, I wrote a nice little function:

eject() {
    diskutil unmount /Volumes/$1

And a completion function to go with it:

compdef '_files -g "/Volumes/*"' eject  

There is a problem with this, however. The _files function generates complete paths. Now, I could change the line in my "eject" function to diskutil unmount $1, and things would work, but then I have no ability to type the first letter of the mount point name, since the path starts with /Volumes/. For instance, if I type J<tab, I will get autocompletion for the files in the PWD. I would have to type /Volumes/J<tab> to get the desired completion.

So, is there a completion function which grabs filenames from a predefined, specific location, rather than generating complete paths?

I'd really like to get this down to 6 keystrokes.

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted
_files -W /Volumes

See the documentation of _path_files.

share|improve this answer
Perfect! I knew that had to be built in. Thanks so much! –  marshaul Feb 17 '13 at 15:03
So, how do I get it to autoload this completion function? I tried putting the compdef line in the file _eject located in my fpath. I tried it with and without an autoload line. I looked at several guides about completion functions and nobody covered how to do a real simple example like this, and nothing I tried based on any of their examples worked. –  marshaul Feb 17 '13 at 15:34
@marshaul You need to have #compdef eject as the first line of the file, then the real code. See under autoloaded files in the manual. If you didn't add the line at first, you may need to delete the cache in ~/.zcompdump and restart zsh. –  Gilles Feb 17 '13 at 18:27
AH! Deleting ~/.zcompdump did the trick. Thanks again! –  marshaul Feb 17 '13 at 18:38
add comment

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.