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.
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
cd /u/s/app<Tab> will produce nothing in bash, but will be expanded
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:
- Portable between Linux and Windows (msys);
- Implemented in configuration files or short scripts that can be carried
around easily. No third-party tools like
fzfthat would require system-wide installation or other tricks to enable.
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.
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.
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:
- Special characters in completed path are automatically escaped if present
- Tilde expressions are properly expanded (as per bash documentation)
- If user had started writing the path in quotes, no character escaping is applied. Instead the quote is closed with a matching character after expanding the path.
- If bash-completion package is already in use, this code will safely override
_filedirfunction. No extra configuration is required.
Watch a demo screencast to see this feature in action: