6

I am a quite a happy zsh user and especially appreciate its completion subsystem. Recently I am trying to enhance some completion commands especially those I use often (ex. rm). In zsh the following command:

rm <TAB>

makes zsh complete with the current directory's files as expected. What I am trying to do is make zsh complete the following variant:

rm -r <TAB>

with only directories.

Any zsh Guru that knows how to parameter completion so that it takes in consideration the (-r) parameter?

tshepang
  • 12,111
  • 21
  • 91
  • 136
user2414029
  • 71
  • 1
  • 5
  • I'm not a guru, but I'll note that rmdir is already set up this way in zsh. :-) – mjk Sep 19 '13 at 21:09
  • @mjk: but AFIAK `rmdir` removes only empty directories which is not the same functionality `rm -r` provides. – mschilli Sep 22 '13 at 11:13

1 Answers1

5

This can be achieved by editing the zsh completion function for rm to the desired behaviour.

The Z-shell completion functions are all defined somewhere on your system. On OSX, it's under /usr/local/zsh/5.0.2/share/zsh/functions. Linux probably has it somewhere similar.

The completion function for rm is defined in a file called _rm. It's rather small. (If you're interested, the completion for rmdir is defined in _directories).

To set the completion for rm -r, we need to modify the line that looks similar to this:

'(-r -R --recursive)'{-r,-R,--recursive}'[remove directories and their contents recursively]'

We add to the end of this line, inside the quote:

:*:file:_directories

I'm pretty sure that this informs zsh that the completion when the -r argument is given should consist of files, and the way we obtain those files is by using the _directories function (which only returns directories).

(I'm not 100% sure, because zsh is a beast I'm still wrapping my little mind around).

Here's a sample usage:

enter image description here


Here's a diff of the changes, to make it extra clear :)

<   '(-r -R --recursive)'{-r,-R,--recursive}'[remove directories and their contents recursively]:*:file:_directories'
---
>   '(-r -R --recursive)'{-r,-R,--recursive}'[remove directories and their contents recursively]'
simont
  • 68,704
  • 18
  • 117
  • 136
  • 1
    +1 & bounty for that great detailed answer. It worked perfectly fine on gentoo linux (the file was located under `/usr/share/zsh/5.0.2/functions/Completion/Unix/_rm`). – mschilli Sep 22 '13 at 11:10