Add custom bash autocomplete function to quickly move into code projects
I keep my projects in a Projects directory on my Mac. It's also not unusual for me to switch back and forth between projects throughout the day. To do that, I have a couple different options:
cd ~/Projects/dashboard- cd
../../dashboard
Either I type a few extra characters or I have to think about where I am in relationship to where I want to go.
I thought to myself: wouldn't it be nice if I could:
- Type
goand be in my~/Projectsdirectory? - Better yet: Type
go dashboardand be in~/Projects/dashboard? - Or better yet: Type
go da, hit tab, and it autocompletes?
After a little bit of tinkering, here's the solution I came up with.
As an aside, Zsh is now the default on the Mac instead of Bash. Zsh is an extension of Bash, and while they're very similar, they do have differences. The functionality below was tested using Zsh.
Create custom cd function
Let's add a function called go to ~/.zprofile. Open ~/.zprofile for editing:
vi ~/.zprofileAnd then add the following:
go() {
cd ~/Projects/$1
}Save your changes by pressing ESC, type :wq, and press ENTER. If you restart Terminal, you'll see this actually gets us pretty close.
The $1 refers to whatever we add after go. It's our first argument so to speak. If you typed in go hello world, then $1 = hello and $2 = world.
We can now type go and press ENTER to change into ~/Projects. We can also type go dashboard to directly move into ~/Projects/dashboard. What we can't do is enter a partial directory like go da and press TAB to autocomplete from our projects.
Create autocomplete function
Let's add another function called _go_auto_complete to ~/.zprofile:
_go_auto_complete() {
local file
for file in ~/Projects/"$2"*; do
[[ -d $file ]] || continue
COMPREPLY+=( $(basename "$file") )
done
}local filecreates a local variable calledfilefor file in ~/Projects/loops over everything within Projects$2is our partial directory name (e.g.da) that we want to autocomplete*is a wildcard character to include anything that starts withda- I'll explain why it's
$2and not$1in the next section -d $fileensures we only autocomplete directories, not files- If
$fileis a directory, go to next line, elsecontinuewith next iteration COMPREPLYis an internal bash array that stores possible completions+=is how we append to that array$fileis the full path, but we only want the directory$(basename "$file")then ensures we only get the directory
Enable autocomplete function
We have a go function for us and a _go_auto_complete function for bash, but bash doesn't yet know of its existence. Let's solve that now.
Edit ~/.zshrc by running vi ~/.zshrc and include the following line:
complete -F _go_auto_complete gocompleteis a built-in bash command for auto completion-Findicates what we're providing is a function_go_auto_completeindicates what our autocompletion function is calledgoindicates to run this autocompletion function whenever we usego- That's why we used
$2in the last section, because$1would refer togo
Save your file, restart your Terminal, and add a few directories to ~/Projects (or wherever you keep them) and watch them autocomplete.
By the way, we put this command in the ~/.zshrc file because every time we open Terminal (aka start a shell session), all commands in this file get executed, ensuring our autocomplete is always ready to go– pun intended.
If you have any questions or comments, feel free to leave them below.
Featured image by Pablo Martinez.