6. Directory Stacks — Zsh 5.9.999.3-test documentation

# 6. Directory Stacks

If you use csh, you may know about directory stacks. The `pushd` command puts the current directory on the stack, and changes to a new directory; the `popd` command pops a directory off the stack and changes to it.

Example 6.1: pushd and the directory stack

    phoenix% cd
    phoenix% PROMPT='Z %~> '
    Z ~> pushd /tmp
    /tmp ~
    Z /tmp> pushd /usr/etc
    /usr/etc /tmp ~
    Z /usr/etc> pushd /usr/bin
    /usr/bin /usr/etc /tmp ~
    Z /usr/bin> popd
    /usr/etc /tmp ~
    Z /usr/etc> popd
    /tmp ~
    Z /tmp> pushd /etc
    /etc /tmp ~
    Z /etc> popd
    /tmp ~

`zsh`’s directory stack commands work similarly. One difference is the way `pushd` is handled if no arguments are given. As in csh, this exchanges the top two elements of the directory stack:

Example 6.2: pushd swaps top two

    Z /tmp> dirs
    /tmp ~
    Z /tmp> pushd
    ~ /tmp

unless the stack only has one entry:

Example 6.3: pushd with one entry

    Z ~> popd
    /tmp
    Z /tmp> dirs
    /tmp
    Z /tmp> pushd
    ~ /tmp
    Z ~>

or unless the `PUSHD_TO_HOME` option is set:

Example 6.4: PUSHD_TO_HOME option

    Z ~> setopt pushdtohome
    Z ~> pushd
    ~ ~ /tmp

As an alternative to using directory stacks in this manner, we can get something like a directory history by setting a few more options and parameters:

Example 6.5: Directory history with AUTOPUSHD

    ~> DIRSTACKSIZE=8
    ~> setopt autopushd pushdminus pushdsilent pushdtohome
    ~> alias dh='dirs -v'
    ~> cd /tmp
    /tmp> cd /usr
    /usr> cd bin
    /usr/bin> cd ../pub
    /usr/pub> dh
    0       /usr/pub
    1       /usr/bin
    2       /usr
    3       /tmp
    4       ~
    /usr/pub> cd -3
    /tmp> dh
    0       /tmp
    1       /usr/pub
    2       /usr/bin
    3       /usr
    4       ~
    /tmp> ls ~2/df
    /usr/bin/df
    /tmp> cd -4
    ~>

Note that `~2` expanded to the second directory in the history list, and that `cd -3` recalled the third directory in the list.

You may be wondering what all those options do. `AUTO_PUSHD` made `cd` act like `pushd`. (`alias cd=pushd` is not sufficient, for various reasons.) `PUSHD_MINUS` swapped the meaning of `cd +1` and `cd -1`; we want them to mean the opposite of what they mean in csh, because it makes more sense in this scheme, and it’s easier to type:

Example 6.6: PUSHD_MINUS with cd +n

    ~> dh
    0       ~
    1       /tmp
    2       /usr/pub
    3       /usr/bin
    4       /usr
    ~> unsetopt pushdminus
    ~> cd +1
    /tmp> dh
    0       /tmp
    1       ~
    2       /usr/pub
    3       /usr/bin
    4       /usr
    /tmp> cd +2
    /usr/pub>

`PUSHD_SILENT` keeps the shell from printing the directory stack each time we do a `cd`, and `PUSHD_TO_HOME` we mentioned earlier:

Example 6.7: PUSHD_SILENT hides stack

    /usr/pub> unsetopt pushdsilent
    /usr/pub> cd /etc
    /etc /usr/pub /tmp ~ /usr/bin /usr
    /etc> cd
    ~ /etc /usr/pub /tmp ~ /usr/bin /usr
    ~> unsetopt pushdtohome
    ~> cd
    /etc ~ /usr/pub /tmp ~ /usr/bin /usr
    /etc>

`DIRSTACKSIZE` keeps the directory stack from getting too large, much like HISTSIZE:

Example 6.8: DIRSTACKSIZE limits stack

    /etc> setopt pushdsilent
    /etc> cd /
    /> cd /
    /> cd /
    /> cd /
    /> cd /
    /> cd /
    /> cd /
    /> cd /
    /> dh
    0       /
    1       /
    2       /
    3       /
    4       /
    5       /
    6       /
    7       /