extended cd
If you’ve spent a lot of time working in a UNIX-like shell environment, you’ve no doubt quickly become an expert at the cd command. It’s pretty much the first thing you learn to do in the shell. Then one day you learn the cd - option, to switch back to $OLDPWD (ie, the last place that you’d cd’ed to in that session), and at that point you were a cd master, showing off to all your friends and co-workers. From there on, you’re basically resolved to spend the next 30 years or so just cd’ing around from directory to directory, content, but never really loving cd. Until…
Until you install the extended cd function developed by kingsrook (which is available in our Downloads section). Extended cd defines a bash function, named “cd”, meaning that it replaces the shell’s built-in cd command. At first it might sound like a bad idea to replace the built-in cd command, but don’t worry – extended cd adds a number of great features to this most basic command, making your navigation through your system’s directory tree fast, easy, and everything you ever dreamed of (if you have very sad dreams, like me).
The first set of features in extended cd were inspired by that one trick you learned about built-in cd, which was passing an argument of “-” to switch back to the your last working directory (per environment variable $OLDPWD). Extended cd takes it a few steps further, by introducing the argument “_” (that’s an underscore, instead of a dash). If you run extended cd with only an underscore as it’s argument (ie, cd _), it will take you to the last directory you cd’ed into from ANY of your current or previous shell sessions on that computer. Actually, this could extend across multiple machines, if your home directory were shared across multiple computers, as it’s based on the cd history file (which is located at ~/.cd_history), which is maintained by the extended cd function.
So why is cd _ useful? My main use case for it would be when I first boot my PC, and I make several new PuTTY connections to a development server, and I want them all to be in the same working directory. I only have to type/tab out that path in the first one, then in the others I can just run a cd _ to go to that same directory (the most recent entry in the cd history file).
However, that’s only the beginning of what extended cd does with the underscore argument and the cd history file. To go a step beyond, you can add a number right after that underscore (as the same word or argument – no spaces between them), to go to the number’th most recent entry in your cd history. For example, to go to the 2nd most recent entry in your file, you’d run cd _2. For the third most recent, cd _3. (You may note that cd _1 would have the same effect as cd _).
You might ask, why is that useful? For me, it’s great in the situation when you’re popping back and forth between a few different directories, that aren’t necessarily close to one another, and you don’t want to have to re-type them, or find them in your shell command history. Or, if you know you’ve recently been in a directory, and you want to get back there, you can just start trying cd _# options, and you know you’ll quickly get back, with just a few keystrokes (i.e., try cd _2, if that’s not right, try cd _3, cd _4, cd _5, and soon enough, you’ll be there).
Now if you can’t remember when you’ve recently been in a directory, and you don’t feel like playing a guessing game to try to get there, you can use one more extended cd underscore variation, by adding a question mark after the underscore, as in: cd _?. When invoked like this, extended cd will print the contents of your cd history file, sorted with most recent entries last, printing the number of each entry before and after it, then will drop you at a prompt where you can enter the number of an entry to be switched directly to that directory. If you don’t want to see your full cd history file, you can also add a number after the question mark, to only see that many entries from the file (i.e., cd _?10 to see the 10 most recent entries from the file). Useful, eh? Here’s a “screenshot”:
dkelkhof@king:~> cd _?10
10 /home/dkelkhof/development/foobar_site/trunk/src/com/kingsrook/content/foobar 10
9 /home/dkelkhof/development/foobar_site/trunk/src/com 9
8 /home/dkelkhof/development/foobar_site/trunk/src/com/kingsrook/cgi/qdim/projects/foobar/tables/voucher 8
7 /home/dkelkhof/development/foobar_site/trunk/src/com/kingsrook 7
6 /home/dkelkhof/development/foobar_site/trunk/src/com/kingsrook/cgi/qdim/projects/foobar 6
5 /home/dkelkhof/development/foobar_site/trunk 5
4 /home/dkelkhof/development/foobar_site/trunk/src/com/kingsrook/content 4
3 /home/dkelkhof/development/infrastructure/trunk/CRONTAB 3
2 /home/dkelkhof/development/sas_applications/trunk/src/com/kingsrook/cgi/mcf/deployments 2
1 /home/dkelkhof/development/webapps/trunk 1
cd> 7
dkelkhof@mlrnd02:~/development/foobar_site/trunk/src/com/kingsrook>
The next bag of tricks in extended-cd are also built on that cd history file. This time, if you know part of a path that you have recently been to, but you don’t want to type/tab out the whole thing, you can pass it to extended cd preceded by a question mark. For example, to get back to the utilities directory in some project you know you’ve recently worked on, you can simply run cd ?utilities. If extended cd finds one or more matches in your cd history, it prints that same menu for you, showing the matches, prompting you to enter the one you want to go back to. Beautiful.
The magic of extended cd doesn’t end there: The next feature is great for when you’re working in a very deep directory path, and you want to go some distance up the the tree, but you don’t want to guess how many ../‘s you need to get there. What you can do in extended cd is use a third dot, followed by part of the directory name you want to end in, for example cd ...foo to move upward, however many directories are needed, until the basename of your working directory is (or contains) foo — a far shot better than cd ../../../../, then not being far enough, so doing another cd ../../../../, then going too far and having to go back down. (For reference, when working on java projects for kingsrook, I always find myself either doing cd ...ook to get back up to the top of our java packages, or cd ...src to get back to the root of our source code, or cd ...unk to get back to the root of my svn checkout).
The last feature available in extended cd mimics a shell trick I saw a college professor use once, where you can re-run your previous command after applying a basic find/replace to it, via ^find^replace. In this case, you can run cd ^foo^bar, and extended cd will take your current working path, apply the requested find/replace to it, and switch you the resulting path. This is nice if you’ve got two similar directory tress under different roots (for example, two svn working copies, let’s call them trunk and cool_branch), and you quickly want to jump from a given sub directory of one into the other (in our example, cd ^trunk^cool_branch might take you from ~/development/trunk/src/com/kingsrook/templates/site/macros/ to
~/development/cool_branch/src/com/kingsrook/templates/site/macros/ in one quick easy step).
Here’s a demo of the double-carat mode (both for general shell commands, and with extended cd):
## the shell's builtin for general commands: dkelkhof@king:~> ls -l foo ls: foo: No such file or directory dkelkhof@king:~> ^foo^bar ls -l bar -rw-rw-r-- 1 dkelkhof group 0 2011-06-24 16:11 bar ## extended cd's version: dkelkhof@king:~/development/trunk/src/com/kingsrook/> cd ^trunk^cool_branch dkelkhof@king:~/development/cool_branch/src/com/kingsrook/>
So that’s it – the full feature set of extended cd. It turns that most basic, boring bash builtin into something that can truly make your development faster, more fun, and almost futuristic. Oh, it also has a -help screen, shown here, which serves as a nice remind of everything we’ve gone through here:
dkelkhof@king:~> cd -help cd: usage: cd [-L|-P] [dir] For extended features, use the following for [dir] (not compatible with [-L|-P] flags): _ - Go to last entry in cd_history. _number - Go to <number>'th last entry in cd_history. _? - List cd_history, prompt to select directory. _?number - List last <number> cd_history entries, prompt to select directory. ?pattern - Pick directory from cd_history matching <pattern>. .?pattern - Pick directory from cd_history matching <pattern>, under cwd. ...pattern - Go up (multiple ../'s) to directory matching <pattern>. ^old^new - Go to pwd, with pattern <old> replaced with <new>
To install:
Unzip, place somewhere “handy”, and add a sourcing of it to your .bashrc
Tweet
