The Arch Wiki has this interesting bit of zsh configuration:

if [[ -f $DIRSTACKFILE ]] && [[ $#dirstack -eq 0 ]]; then
  dirstack=( ${(f)"$(< $DIRSTACKFILE)"} )
  [[ -d $dirstack[1] ]] && cd $dirstack[1]
chpwd() {
  print -l $PWD ${(u)dirstack} >$DIRSTACKFILE


setopt autopushd pushdsilent pushdtohome

## Remove duplicate entries
setopt pushdignoredups

## This reverts the +/- operators.
setopt pushdminus

Even though pushdignoredups is set, I find duplicate entries in the output of dirs, sometimes even the same entry repeated thrice. The Wiki does go on to say that this doesn't work well with multiple zsh sessions, and I do have multiple terminal tabs open with zsh running, so that may be the cause of the problem.

Can I modify this function somehow to keep only unique entries? Is this a convoluted way of achieving something that zsh provides easier ways to do?

How can I have a persistent dirstack, with only unique entries?

1 Answer 1


The simple typeset -U dirstack fails, as dirstack is doubtless too special for the usual unique limitation to apply (this typeset is however handy for things like the path array). On closer inspection the Arch Wiki code suffers from incomplete uniqueness, in that only dirstack only when being written out is made unique, and not with PWD, nor when reading the file in. So if PWD contains something also in dirstack, duplicates will be created and then read in. Thus, the quickest fix is to apply the unique expansion on the read:

  dirstack=( ${(uf)"$(< $DIRSTACKFILE)"} )

And perhaps also to the file write, which is more complicated, as it needs a unique dirstack minus whatever is in PWD plus PWD.

print -l $PWD ${(u)${dirstack:#$PWD}} >$DIRSTACKFILE
  • Dammit, this slipped my mind. Nice idea, but for some reason, the top directory is still repeated when I start a new tab.
    – muru
    Commented Apr 15, 2016 at 10:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .