ZSH to auto-complete directories in command-line arguments

autocompleteosxzsh

Transferred from regular StackOverflow…

I'm a new ZSH convert on OSX (git status in the prompt was my main driver to make the leap). Everything seems to be working swimmingly but I'm missing something from BASH..

In BASH I would start to run a CLI PHP script that's built around Symfony's CLI tools.

Typically I would run the command like this:

$> php doctrine --configuration=../conf/doctrine.xml migrations:migrate

In BASH I would be able to use the TAB key while typing out the ../conf/doctrine.xml portion to complete the directories.

In ZSH hitting the TAB key while typing out the directory results in… nothing.

Is there a setting in ZSH or a configuration I can set to enable this behavior of attempting to complete almost anything that looks like a directory?

Best Answer

Zsh is attempting to be clever in choosing completions, but it's not clever enough to know that after doctrine --configuration=, it should complete a file name. Bash is either clever enough to parse this command correctly, or too stupid to complete anything but a file name here.

You can write a completion function for doctrine. This is a little advanced, though — completion functions tend to be a little arcane. You may find it easier to write a completer using zsh's alternative, older, simpler, but less powerful completion system, compctl (documented in the zshcompctl man page).

If you have a bash completion function for doctrine, you might be able to get zsh to read it by including autoload bashcompinit; bashcompinit in your ~/.zshrc. See Switching from bash on the zsh wiki.

You may find it useful to bind a few keys to _bash_complete-word. This widget (interactive command) performs completion of a few built-in types, depending on the last character in the key sequence that invoked the widget: / for directories, $ for parameter names, etc. For example, include bindkey '^X/' _bash_complete-word in your ~/.zshrc, and press Ctrl+X / to complete a file name in any context (you might need to temporarily insert a space before the file name, if the file name is preceded by punctuation that is not a word separator in the shell).