Zsh offers a lot of significant improvements over traditional shell experience. Some of those can also be implemented in bash, but others are not. For a long time I've thought that advanced file path expansion is something that can't be done in bash. Today I prove myself wrong.

Background

When the Tab key is pressed, zsh expands incomplete file path assuming any of its elements might be incomplete, while bash expands only the last piece. For example: cd /u/s/app<Tab> will produce nothing in bash, but will be expanded to cd /usr/share/applications in zsh.

This feature is a huge time saver, but it does not justify switching the shell completely (for me). So I've been looking for a way to enable the same behavior in bash.

The solution had to be:

All I've been able to find was this StackOverflow thread. Accepted answer suggests using a new bash function that is later bound to Tab keypress. The function provided is a quick hack that was not tested thoroughly and has problems with spaces in file path. The author recommends to use his function along with the default completer, not instead of it, so it was not what I needed.

Workaround

Typing cd /u*/s*/app*<Tab> is somewhat better but not as streamlined an experience as the one zsh offers.

This turned out to be an inspiration for the proper completer function though.

Better solution

I have coded a small function that adds wildcards to each element in the path and executes normal bash completion procedures with modified input. After a bit of documentation digging I've been able to inject this function into normal bash completion process. I'm pretty happy with path expansion now.

To enable the described behavior source this file from your ~/.bashrc and run _bcpp --defaults. Supported features are:

Watch a demo screencast to see this feature in action:

asciicast