Don't let `cd` slow you down

I spend quite a bit of time moving around in the terminal. Naturally, tools like fasd, bd, fzf, etc are at the top of my ‘day-to-day usage list’. Unfortunately, zsh is nowhere among them. As much as I would love to use it, the majority of Linux distributions still don’t have it preinstalled. For me it’s a deal breaker. I honestly don’t want to get homesick every time I ssh into some remote machine I have no control over. The obvious shell of choice, given the circumstances, is Bash. Up until recently, there was one thing driving me nuts, though. Namely, absent zsh-style cd . But, with commacd in the game, it’s no longer a problem.

So, what is commacd exactly? Well, it’s basically just a bunch of aliases ( , , ,, , and (surprise, surprise!) ,,, ), designed to make navigation faster. The best way to explain each one of them is probably to go through some examples.

Let’s start with , . Think of it as a cd that matches directories by prefixes:

~ $ , des => cd Desktop # move through multiple directories ~ $ , /u/l/ce => cd /usr/local/Cellar # allow me to choose directory in case of ambiguous pattern (= multiple choices) ~ $ , d => 1 Desktop 2 Downloads : < type index of the directory to cd into> # given two directories jdk7 and jdk8 on the Desktop, cd into jdk8 without hitting interactive mode (the one shown above) ~/github $ , ~/d/j * 8 => cd ~/Desktop/jdk8 # cd into directory having 'esk' somewhere in its name ~/github $ , ~/ * esk => cd ~/Desktop

If you often find yourself using cd .. , cd ../.. , … (in one from or another), you might be interested in ,, . It has a number of different strategies that can make navigation backward a whole lot easier:

(no arguments) look for the project (checkout) directory (the one with .git/.hg/.svn in it) and then cd into it;

into it; (one argument) cd into the closest parent having its name begin with whatever the value you passed in;

into the closest parent having its name begin with whatever the value you passed in; (two arguments) replace all occurrences of the first value with the second one (in the current path).

# go all the way up to the project root (in this case, the one that has .git in it) ~/github/lorem/src/public $ ,, => cd ~/github/lorem # cd into to the first parent directory named g* ~/github/vimium/src/public $ ,, g => cd ~/github # substitute jekyll with ghost ~/github/jekyll/test $ ,, jekyll ghost => cd ~/github/ghost/test

The last one is ,,, (my favorite). Think of it as , but from the first (nearest) parent directory having non-empty expansion. It allows quickly jump between multiple directories sharing the same ancestor (not necessarily an immediate one).

# jump to some other project (in this case, located in ~/github) ~/github/rook/src/public $ ,,, m * binlog => cd ~/github/mysql-binlog-connector-java

Note that all three commands automatically emit pwd before the completion (just like cd - ), which makes it possible to combine them with other tools (without actually changing the working directory):

$ tail -f ` , /v/l/t/l ` /catalina.out => tail -f /var/lib/tomcat7/logs/catalina.out /opt/nginx $ ` ,,, ap/b ` /cassandra-cli => /opt/apache-cassandra-1.2.1/bin/cassandra-cli

You can also hit <Tab> whenever you want to check where are you about to jump to. Like this:

$ , /v/l<Tab> => ( shows 3 possible completions ) /var/lib/ /var/lock/ /var/log/ $ , /u/l/ce<Tab> => , /usr/local/Cellar/

To shrink path back use <Control>- .

And now, the final part - installation. commacd is written in pure Bash (no dependencies on Python/Ruby/Perl, no nothing). Getting it into your shell is as easy as:

curl https://raw.githubusercontent.com/shyiko/commacd/master/commacd.bash -o ~/.commacd.bash && echo "source ~/.commacd.bash" >> ~/.bashrc

After that, open a new terminal session and , ahead!

Want to help out? Report issues, suggest improvements/features or, even better, send in a pull request (see GitHub page). Every bit is helpful.