I spent some time recently revamping my zsh setup, something I haven’t really spent any dedicated time with since about 2006. In transitioning to oh my zsh I discovered fasd, a command line productivity booster. Essentially it tracks the files and directories you work with in your terminal, and ranks them by “frecency”, both frequency and recency. You can then reference them with short, usually single character aliases and fuzzy matching.

Examples here will assume the suggested default aliases from the github readme. A couple parts are only available with zsh, but most of fasd is perfectly usable with bash as well.

Starting with the simple stuff, after using fasd for awhile my list of used directories:

$ d
1          /home/dev/src/infra/ansible/roles/dotfiles/files
1          /home/dev/src/infra/ansible/roles/dotfiles/templates
1          /home/dev/src/rmrf/resources/_gen
1          /home/dev/src/rmrf/resources/_gen/assets
1          /home/dev/src/rmrf/resources/_gen/assets/scss
1          /home/dev/src/rmrf/static
1          /home/dev/src/rmrf/static/images
3.24483    /home/dev/src/rmrf/content/posts/2020
4.09525    /home/dev/src/rmrf/content
4.09525    /home/dev/src/rmrf/content/posts/2019
4.7887     /home/dev/src/rmrf/content/posts
5.19762    /home/dev/src/rmrf/themes/LoveIt
8          /home/dev/go/src/github.com
8.1905     /home/dev/src/rmrf/content/posts/2020/buying-used-thinkpad-t470s
10         /home/dev/go/src/github.com/dgoodwin
10.1831    /home/dev/src/rmrf/themes
10.3952    /home/dev/go/src/github.com/dgoodwin/gophoto
22.3022    /home/dev/go/src/github.com/dgoodwin/argocd-appgenerator
64.766     /home/dev/src/infra/ansible
155.377    /home/dev/src/rmrf

Using the z alias you can easily jump around the above directories with fuzzy matching.

$ z ansible

~/src/infra/ansible master*
$ z resources scss

~/src/rmrf/resources/_gen/assets/scss master*
$ z rmrf pos

~/src/rmrf/content/posts master*
$ z the

~/src/rmrf/themes master*
$ z goph

~/go/src/github.com/dgoodwin/gophoto master*

I’d been adding explicit aliases to cd to deep directories I need often, and that feels pretty silly now.

Similarly for files:

$ f
1          /home/dev/src/infra/ansible/roles/dotfiles/files/gitconfig
1          /home/dev/src/rmrf/.gitignore
1          /home/dev/.tmux.conf
1          /usr/share/doc/tmux-powerline/README.rst
1          /usr/share/tmux/powerline.conf
2          /home/dev/src/rmrf/publish.sh
2          /home/dev/.ssh/authorized_keys
2          /home/dev/.zshrc.bak
2.5        /home/dev/src/infra/ansible/roles/dotfiles/files/zshrc
4          /home/dev/bin/kind
4          /home/dev/src/infra/ansible/roles/fedora_workstation/tasks/main.yml
4.09525    /home/dev/src/rmrf/config.toml
13.7549    /home/dev/src/infra/ansible/main-playbook.yml
14.8834    /home/dev/src/infra/ansible/hosts
17.4       /home/dev/src/rmrf/content/posts/2020/fasd.md

$ ls -la `f zsh sys`
-rw-r--r--. 1 dev dev 18 Feb 28 19:34 /home/dev/.zshrc-system

There’s also a nifty tab word completion available for zsh users by using a ,:

$ ls ,src,cont<TAB>

After pressing tab above, I’m prompted to TAB and choose between /home/dev/src/rmrf/content and /home/dev/go/src/github.com/dgoodwin/argocd-appgenerator/controllers which both matched. If only one entry matched it’s just automatically completed.

Similarly there’s an interactive chooser:

$ ls `sd src cont`
2       12         /home/dev/go/src/github.com/dgoodwin/argocd-appgenerator/controllers
1       31.1857    /home/dev/src/rmrf/content
> 2
applicationgenerator_controller.go  suite_test.go

I’ve been missing out on this for a long time and it’s hard to imagine life without if once you get used to it.

If you spend any time at all in the terminal, fasd really is worth installing and spending a few minutes learning. Install instructions and docs available on github.