autopushd in zsh – make cd behave like pushd always

I’ve just been exposed to one of those delightful little hacks that are both forehead-slappingly simple/obvious and yet so powerful and clearly “right” that I just know I’m going to be using it for the next n years. Allow me to share.

In every Unix shell I’ve ever seen, one uses the “cd” command to change directory, moving around the directory structure.

cd has no memory of where you were before. Some shells add a stack-based history via the commands “pushd” and “popd” (which I only discovered in 2004). If you pushd to a directory (eg pushd /some/distant/directory), you can subsequently get back to where you were before very easily by just entering popd; furthermore, such calls can be nested arbitrarily deeply (that’s what the stack is for). This is, on occasion, tremendously helpful, and can save a lot of typing/thinking.

The insight: why bother with cd, then? Why not just always pushd around the place? That way, you’ve always got the possibility of using popd to get back to where you were before easily and quickly. There are two possible reasons why not. First the stack takes up some space in memory. Feh, no problem – it’s not that big, and I never have a shell open long enough for it to become a problem. Second, pushd is a few more keystrokes than cd, and my habits have cd hardwired into them.

Thus, the hack: alias cd to pushd. But wait! Don’t do that!

Since I use zsh, I don’t even need to alias it. I can use the zsh config option “autopushd” to make cd always behave like pushd. Hell, yeah! I just add the following to ~/.zshrc:

setopt autopushd

and hey pesto:

# Start by going to some fairly deeply nested directory
[gimbo@mane ~] cd work/teach/cs-238/current 

# Now I cd (but really pushd) to some other, also deeply nested, directory
[gimbo@mane current] cd ~/work/research/mphil/tools/HetCATS/CspCASL
[gimbo@mane current] pwd
/home/gimbo/work/research/mphil/tools/HetCATS/CspCASL

# In the words of Baloo: take me home, daddy!  (This next line doesn't work without the autopushd trickery)
[gimbo@mane current] popd
~/work/teach/cs-238/current ~
[gimbo@mane current] pwd
/home/gimbo/work/teach/cs-238/current

Update 2007-02-24: Will has just pointed out to me that “cd -” will take you back to where you were before, so repeatedly issuing cd - allows you to flip between two places easily – which is of course a common use case. Neato!

[gimbo@orb ~] cd /tmp 
[gimbo@orb /tmp] cd -
~
[gimbo@orb ~] cd -
/tmp
[gimbo@orb /tmp]

2 Responses to “autopushd in zsh – make cd behave like pushd always”

  1. Tom Murray
    February 11th, 2009 | 10:56 pm

    Cool! Thanks a lot. Need to use bash now at work and was really missing zsh’s autopushd.

  2. John
    June 15th, 2010 | 1:47 am

    With the fish shell, you can use alt-forward-arrow and alt-backward-arrow to move back and forward through your directory history.