Alright, maybe the title is a little pretentious, but hopefully this isn’t a total disappointment.
So if you have been on a linux or mac system as your main workstation for any amount of time, or
have recently moved to it, or even just considering adopting it now, you have had to spend some time
in the terminal
. Even little hacks that improve your terminal workflow can be a massive
productivity boost, and this is what we are going to talk about today.
This is obviously a VERY opinionated post, its really just a catalog of some software/tips/tricks/commands I have picked up over the years, YMMV.
First a quick list of all the main things we are going to talk about today:
- Default shell - zsh
- Shell Configuration Framework - Prezto
- Fuzzy Finder - FZF
- Quick Access to Files and Directories -Fasd
- Shell Extension - direnv
There is lots more, but this is a pretty good list to get started with. Now if you are a Homebrew user on a mac (or linux), you can install most of that with a single command:
brew install zsh nvim fzf iterm2 tmux direnv fasd
and then simply clone the prezto
repo from the link above. Now each one of those projects is
pretty awesome and powerful, so I highly recommend reading their documentation, quick shout out to
all the amazing open source folks out there who let us have stuff like this for free!! Please try to
find an author or two you really like and support them on Patreon. Some
of my favorite open source authors/projects are:
- Dominik Honnef - Works on Go Tooling
- Max Howell - Creator of Homebrew
- George Nachman - Man behind iTerm2
- Billie Cleek - Maintainer of the awesome vim-go plugin
There are tons of other folks, doing amazing work in the open source universe, lets show them our gratitude.
Alright back to our post, please note, there is really (equally?) good alternatives to pretty much all of these tools, but this post isn’t meant to do a compare/contrast (maybe we will someday), today we are simply going to look at some basic features these tools offer and how we can use them to improve our daily workflow.
Default Shell and Configuration
There is lots of reasons why you would want to consider switching your default terminal to ZSH, but I like it mostly for the plugin/theme support. I have gone back and forth between Oh My ZSH and Zprezto, Zprezto seems to (anecdotally) perform better for me.
Some examples of things ZSH + Zprezto do for you out of the box are:
- Setting up your SSH Agent
- Handy Git Aliases
- Some really cool autocompletion
- Integrating terminal with the MacOS finder
There is plenty more where that came from, to make full use of the power of ZSH and Zprezto please refer to their documentation. The community managed Reference Card is also pretty handy.
Fuzzy Finder
FZF is a magic tool, that adds fuzzy finding capabilities to any list on your terminal!!!
Let’s say you want to find a file, but don’t remember its full name (or are too lazy to type it) or
maybe you can never remember all the flags for the find
command or just not in the mood for a
complex grep pipeline. Well, FZF to the rescue!! If you installed FZF using the brew
command
above, simply run $(brew --prefix)/opt/fzf/install
to install all the goodies. Once you do that,
run fzf
on the command line and start typing some combination of letters in the filename your are
searching for. Isn’t this so much better than find . -type f | grep -E <some regex>
??
Only looking for files that end in .py
? Type fzf
and then .py$
, where $
indicates end of
line.
FZF by default only prints the file name, but lets say you want to do something more useful, like opening the file up in vim:
vim -o `fzf`
This will let you fuzzy find the file and then open it in vim directly!
Can’t remember some command you ran a while back to convert a certificate from pem
to crt
? Try
adding this as in your ~/.zshrc
h() {
print -z $( ([ -n "$ZSH_NAME" ] && fc -l 1 || history) | fzf +s --tac --height "50%" | sed -E 's/ *[0-9]*\*? *//' | sed -E 's/\\/\\\\/g')
}
Now reload your shell with say: exec $SHELL -l
, and run h
, yes CTRL+r
is so 2013 you can now fuzzy search through your
command history, see it in action below if you don’t believe me:
There is a lot more you can do with fzf
, see this article from Techmint.com for some good tips.
Navigating Directories
If you are like me you have tons of personal and
professional projects all stored in a neat (& deeply) nested folder structure, but switching projects
means remembering where each file/folder is, and sometimes typing out deeply nested directory locations.
This is where fasd
comes to our rescue, fasd
comes with some defaults built in already for
common tasks like navigating to a directory or open a file in vim. So instead of typing
cd /Users/faraaz/developer/samtek/blog/blog/content/post/
I can simply do:
j post
Or to open the file for this post in vim, I can do:
v command line
instead of:
vim ~/developer/samtek/blog/blog/content/post/command-line-fu.md
Maybe you don’t remember anything about the directory structure and want to interactively select the directory from a list of your most recently visited ones, try:
zz
Lets see this in action:
Neat, isn’t it!
Managing configuration
Now that we have learned how to improve the speed of common day to day activities on the terminal, lets take a look at another common problem. Most of us have project specific configuration. While some people might debate whether or not environment variables are the right place to store configuration, it has been recommended as a best practice for a while now (See: 12 Factor App) and let’s face it, its pretty handy.
Besides if you work in the cloud, you probably have access to a few different cloud provider
accounts. Access to these profiles can be managed by setting environment variables like AWS_PROFILE
or AZURE_DEFAULTS_GROUP
.
Alright, great! But how do I change these environment variables everytime I switch into a new
project (directory), you ask? Direnv was built precisely for this reason. It
has a very simple API, all you need (after you install/enable it) is a .envrc
file in your project
directory. Once you have allowed this file to load by running direnv allow
inside your project
directory, direnv automatically handles the loading and unloading of environment variables as you
cd
in and out of project directories. So lets say you have two projects, one personal and one work
related. Each of these projects uses a specific AWS account, named, personal and work, and you have
top level directories for these project, named, once again, personal and work. All you need to do is
set up your aws
cli/sdk/tool with named profiles and have the following .envrc
in your project directories.
cat ~/personal/.envrc
AWS_PROFILE=personal
cat ~/work/.envrc
AWS_PROFILE=work
Now as you cd
in and out of these directories, you will see direnv is doing its magic:
cd ~/personal
direnv: loading ~/personal/.envrc
env | grep -i aws_profile
AWS_PROFILE=personal
cd ..
direnv: unloading
Once again, this isn’t meant to be a full on tutorial on direnv, just enough to peak your interest. If you would like to learn more about what direnv can do, please see their documentation
There is so much more to talk about on command line productivity (tmux anyone?) but I just wanted to introduce some really essential tools to my workflow on a day to day basis, I am sure a lot of you have tips/tricks/tools you love as well, please do tell me about them. You can tweet me at @mfyk84 or hit me up on linkedin