WELCOME TO YAROSLAV`S LINUX PAGE
+ -=:Dynamic DIRSTACK.:=- +
 

I would love to continue expressing my gratitude to bash, and as a follow-up to my article "BASH history forever" here is my new bash hack. I could have simply appended it to the tail of "Share your bash tips?" article on Debian-Administration site, but I've decided to add it as an independent entity since it exceeds a bit a size of 2-3 liner.

Traditional question: You're using bash, aren't you? You probably love it, especially if you use bash_completion script. But I started to hate plane completion whenever I need to run back and forth between a finite set of paths, which might be quite different one from another. There are possible solutions on how to make switching between directories more effective:

  • "cd -" is lovely but works just for 1 previous directory
  • open new terminals/tabs for every such location and jump between those. That might be the best way to do that, but usually I forget about it and end up running between directories using completion
  • persistent and thus static list of existing directories approach -- simply would not work for me since I have way too many directories with very similar names but I work with different groups of them from session to session
  • pushd/popd. Getting closer but you need to push/pop manually. so you need to foresee that you would come back to this directory again
  • recently discovered by me an alternative implementation of directories history on your beloved Debian Administration. That implementation has its own pros (saved history... though I guess they would overlap a lot if I save from multiple shells), but seems to be missing nice bash completion addendum. Besides that I use more of a heap approach to keep visited directories, so "forward history" is not deleted if you jump to some previously left directory. I complement it with somewhat intelligent bash completion scripts which come especially handy with 'menu-complete' command. Also you simply might like mine better

For my own solution I decided to craft cd command which would keep the stack of recently visited directories, so I could jump into any of them in a matter of few keystrokes. Since long ago I have been using alias for cd which also listed me a content of the directory which I changed to.

See how it works now ( is for regular compeltion, for menu-completion):

$> cd /home/yoh/deb/debs/fail2ban/trunk
total 4
4 debian/

belka:~/deb/debs/fail2ban/trunk
$> d
     0  /home/yoh/deb/debs/fail2ban/trunk
     1  /home/yoh/progr/papers/bib
     2  /research/fingertap/exper4/YH20060927-YH
     3  /research/fingertap/exper4
     4  /research/fingertap
     5  /research
     6  /home/yoh/deb/debs/fail2ban/trunk
     7  /home/yoh

belka:~/deb/debs/fail2ban/trunk
$> cd ..
total 56
4 branches/             4 logwatch/           4 trunk/
8 build-area/           4 patches/            4 trunk-0.6/
4 build-area.sarge/     4 submitted_patches/  4 trunk-0.6.badsvnupgrade/
4 fail2ban-0.6.2/       4 tags/
4 fail2ban-0.6.2.orig/  4 tarballs/

belka:~/deb/debs/fail2ban
$> d
     0  /home/yoh/deb/debs/fail2ban
     1  /home/yoh/progr/papers/bib
     2  /research/fingertap/exper4/YH20060927-YH
     3  /research/fingertap/exper4
     4  /research/fingertap
     5  /research
     6  /home/yoh/deb/debs/fail2ban/trunk
     7  /home/yoh

belka:~/deb/debs/fail2ban
$> jcd 2

belka:/research/fingertap/exper4/YH20060927-YH
$> d
     0  /research/fingertap/exper4/YH20060927-YH
     1  /home/yoh/progr/papers/bib
     2  /research/fingertap/exper4/YH20060927-YH
     3  /research/fingertap/exper4
     4  /research/fingertap
     5  /research
     6  /home/yoh/deb/debs/fail2ban/trunk
     7  /home/yoh

belka:/research/NeuroImage
$> jcd tr <TAB>
$> jcd /home/yoh/deb/debs/fail2ban/trunk

belka:~/deb/debs/fail2ban/trunk
$> jcd exp<F1>
$> jcd exp <F1>
$> jcd /research/fingertap/exper4 <F1>
$> jcd /research/fingertap/exper4/YH20060927-YH

belka:/research/fingertap/exper4/YH20060927-YH
$> jcd trunk

belka:~/deb/debs/fail2ban/trunk
$>

To summarize:

  • cd -- changes to the directory and if that one is not on DIRSTACK -- adds it. Completion for cd might include directories on the DIRSTACK as well (if they match the entered pattern of cause) but due to a glitch (repetition of the same directories) I commented it out by default
  • d -- list DIRSTACK with full names and numbers attached, for easy jcd-ing or pcd-ing
  • jcd -- jump to either specific number in the DIRSTACK or first occurrence of provided pattern. Calling to bash function 'complete' would complete to the first matching entry within DIRSTACK (N.B. matching by the grep regexp). Calling to 'complete-menu' will cycle through matching entries. DIRSTACK remains intact (besides entry 0 which corresponds to CWD).
  • pcd -- is popcd, so it extract the entry from the DIRSTACK, but since on next cd command current directory would be added to the stack, that directory would simply appear on top of the stack. Otherwise it is analogous to jcd
  • Of cause you are still free to use pushd and popd commands ;)

Ok - and now the file .bashrc_dyndirstack which you would like to source from your .bashrc.

If you have any comments - I would really appreciate them