o/uutalk - Useful Utilities
Today I want to talk about a few utilities to supercharge your shell workflows!
zsh- a modern shell replacement for Bash with better tab-completion, complex globbing and pluginsripgrep- a fastergrepwith friendlier defaultsfd- a fasterfindwith friendlier defaultsexa- a prettierlswith friendlier defaultsbat- a prettiercatwith syntax highlighting, line numbers, git highlights and paginghub- enables GitHub.com features like creating pull requests from the command linefzf- easily fuzzily filter any list (files, directories, git branches, etc.)
Install all of these tools in a single command (zsh & fzf benefit from additional configuration that we'll discuss):
brew install zsh ripgrep fd exa bat hub fzfSee the Cut for time section for a few more helpful utilities that I couldn't squeeze into this talk!
🐚 Shell - zsh
If you work at Opendoor view the up-to-date living guide here
A superset of Bash with modern bells and whistles. These include better tab-completion, more complex globbing support, a plugin system, and more!
zsh will be the default shell in macOS Catalina so might as well start getting used to it 😃
Set up:
brew install zsh
sudo sh -c "echo $(command -v zsh) >> /etc/shells"
chsh -s "$(command -v zsh)"Don't have time to discuss everything that's different but I do want to highlight tab completion. We need to add two lines to our .zshrc to turn this on (the onboarding tutorial has an option to do this). Add the following lines to ~/.zshrc:
autoload -Uz compinit
compinitNow source it to use our changes - source ~/.zshrc. Okay, let's walk through two (by no means comprehensive) examples of zsh tab completion vs bash tab completion:
ls -<TAB>
# bash does nothing
# zsh displays flags
git add <TAB>
# bash displays files in the directory
# zsh displays unstaged files
# additional note: repeatedly hitting Tab cycles through
# options in zsh, in bash it just redisplays all optionsPlugins add functionality to zsh. There are many different plugin managers, I use zplugin which is the fastest plugin manager I've found and supports loading plugins asynchronously.
Run the installation script:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/zdharma/zplugin/master/doc/install.sh)"The install script should add the below lines to your ~/.zshrc. If it doesn't, add them manually.
source "$HOME/.zplugin/bin/zplugin.zsh"
autoload -Uz _zplugin
(( ${+_comps} )) && _comps[zplugin]=_zpluginTo install the three plugins I'll discuss add the following snippet to ~/.zshrc:
# ref - search zsh-autosuggestions
# http://zdharma.org/zplugin/wiki/GALLERY/#plugins
zplugin ice wait lucid atload'_zsh_autosuggest_start'
zplugin light zsh-users/zsh-autosuggestions
# note: any plugins that define widgets the syntax highlighting might need to
# color (such as `zsh-autosuggestions`) must be loaded prior
# ref - search fast-syntax-highlighting
# http://zdharma.org/zplugin/wiki/GALLERY/#plugins
zplugin ice wait lucid atinit"ZPLGM[COMPINIT_OPTS]=-C; zpcompinit; zpcdreplay"
zplugin light zdharma/fast-syntax-highlighting
# prompt
# ref - https://github.com/romkatv/powerlevel10k#zplugin
zplugin ice depth=1
zplugin light romkatv/powerlevel10k- Context aware prompt - display context of current directory (e.g. git status, executable versions, virtual environments, etc.)
Install by adding the following line to
~/.zshrc-zplugin light romkatv/powerlevel10k - Syntax highlighting - highlight your commands as you type them
Install by adding the following lines to
~/.zshrc:zplugin ice wait lucid atinit"ZPLGM[COMPINIT_OPTS]=-C; zpcompinit; zpcdreplay" zplugin light zdharma/fast-syntax-highlighting
- History autocompletions - suggest previous commands from history as you type
Install by adding the following lines to
~/.zshrc:zplugin ice wait lucid atload'_zsh_autosuggest_start' zplugin light zsh-users/zsh-autosuggestions
This plugin benefits from configuring a few shortcuts:
# Ctrl-e accepts until end of line (same as right arrow) bindkey '^e' autosuggest-accept # Ctrl-Space accepts until end of line and immediately execute bindkey '^ ' autosuggest-execute # Ctrl-w accepts next word bindkey '^w' forward-word # count only alphanumeric characters as part of a word WORDCHARS=
🔎 ripgrep
A faster and generally more user friendly replacement for grep. It searches recursively by default, respects .gitignore (and .ignore) files, and skips hidden and binary files.
Here's a writeup of more details on the tool by it's creator including detailed benchmarks.
Here is a heads up comparison on an arbitrary query:
# takes ~30 seconds w/o `--exlude-dir` (this exclude also wouldn't cover all
# files ignored by ripgrep, e.g. go build files, python virtualenvironments, etc.)
grep -r TradeInStep . --exclude-dir=node_modules --color -n
rg TradeInStepHere are some usage examples:
# recursively search current directory for pattern
rg pattern
# include .gitignored and hidden files
rg -uu pattern
# search for whole word matches in files matching the given glob
rg -w @types/lodash -g 'package.json'🔎 fd
A simpler, faster find (fd is to find what ripgrep is to grep). Skips hidden directories, respects .gitignore files, colorized terminal output, smart case (case-insensitive by default, case sensitive if pattern includes a capital).
Here is a heads up comparison on an arbitrary query:
find . -iname '*TradeInStep*' -not -path '*/node_modules/*'
# or
fd TradeInStepA few other usage examples:
# search for files matching pattern (no more `find . -iname '*PATTERN*'`)
fd pattern
# include hidden and ignored files
fd --hidden --no-ignore pattern💎 exa
A prettier ls that comes with friendlier defaults and adds extra contextual information (like git info with --git).
Add the following line to ~/.zshrc to alias ls to exa: alias ls=exa
Note: if you do alias
lstoexayou can always use regularlswith/bin/ls
🦇 bat
A prettier cat with syntax highlighting, line numbers, git highlights and paging.
🐙🐈 hub
Augments git when using GitHub (the tool itself is developed by GitHub). hub supports PR creation, easier repo cloning, viewing CI status & more!
hub is a strict superset of git and GitHub suggests aliasing git to hub for easier usage (anecdotally I've had git aliased to hub for over a year now without any issues).
By far the most useful feature of hub for me is pull request creation:
# `-p` pushes branch if not pushed, `-o` opens PR in browser, `-c` copies PR link to clipboard
# first `-m` specifies PR title, second `-m` specific PR body, `-l` adds the given label (can
# specify multiple separated by commas - `-l label-one,label-two`), `-r` adds the given reviewer
# (again can specify multiple separated by commas - `-r username-one,username-two`)
hub pull-request -poc -m 'title here' -m 'body here' -l merge-when-green -r bmalehornHere a few other usage examples:
# clone a repository without the full url (omit the username for your own repos)
hub clone username/repo_name
# create a repository on GitHub (optional organization and repo name)
hub create organization/repo_name
# compare the current branch to master (or given base branch)
hub compare <optional-base-branch>
# view status of GitHub CI checks
hub ci-status -v
# open repo in browser
hub browse🌸🚀 fzf
A fantastic fuzzy finder for fun coding and my personal favorite of these utilities!
fzf enables interactive fuzzy filtering of a list of strings (file paths, lines of code, git commits, etc.) with previews!
To set up fzf let's run it's setup script:
$(brew --prefix)/opt/fzf/installWe now have completions and key bindings. First, let's talk completions:
# fuzzily cd to a directory
cd **<Tab>
# kill processes
kill -9 <Tab>
# fuzzily open file in your editor
vim **<Tab>Next, key bindings. The setup script adds three bindings. These can be triggered at any time, not just the start of a shell command!
Ctrl-r- shell historyCtrl-t- all files under the current directoryAlt-c- cd to selected directory under the current one
Finally, I have my own configuration that adds a few other handy shortcuts along with configuring previews. This can be added by copying and pasting the config from the fzf.zsh file in this gist to the end of your ~/.zshrc or by running the command below which curls the file down and appends it.
# install preview dependencies (can use the older versions
# (e.g. `grep` instead of `rg`, `find` instead of `fd`) of
# each of these if you prefer by editing `~/.zshrc`)
brew install bat exa fd
# append fzf.zsh from this gist to ~/.zshrc
curl https://gist.githubusercontent.com/nathanshelly/4b7020d09d413cab823914b06162145a/raw/de3a42bb78be18336ffc0c81878028c94894f72d/fzf.zsh >> ~/.zshrcHere are the new shortcuts this config adds:
Ctrl-p- open selected file(s) in$EDITORAlt-h- list commitsAlt-f- list unstaged filesAlt-r- list branches (local & remote)
- Why you should be using fzf
- Key bindings for
gitwithfzf - fzf for the win
- Turn your fzf into a live REPL
fasd- quickly access files and folders based on frequency and recency of accesstldr- a cliff-notes man pagetmux- a terminal multiplexer to replace endless terminal tabstrash- replacement forrmthat moves files to the trash so you can recover them
Install all of these tools in a single command - brew install fasd tldr tmux trash
💨 fasd
Quickly access files and folders from anywhere on your machine based on frequency and recency of access ("frecency").
v def conf => vim /some/awkward/path/to/type/default.conf
j abc => cd /hell/of/a/awkward/path/to/get/to/abcdef
m movie => mplayer /whatever/whatever/whatever/awesome_movie.mp4
o eng paper => xdg-open /you/dont/remember/where/english_paper.pdf
vim `f rc lo` => vim /etc/rc.local
vim `f rc conf` => vim /etc/rc.confSee the repo for more details including setup instructions! Note: the README doesn't mention using Homebrew but it's there - brew install fasd
📖 tldr
A cliff notes man page. Provides quick high-level documentation of a tool with some examples.
Run on tar:
🗑 trash
A replacement for rm. Files deleted with trash are moved to the system Trash folder so you can easily recover them if you accidentally delete something. Bonus, it works on files and directories (no need to ever type -r again).
🤹 tmux
Ripped shamelessly from the tmux README:
tmux is a terminal multiplexer.
It enables a number of terminals to be created, accessed, and controlled from a single screen. tmux may be detached from a screen and continue running in the background, then later reattached.
See any of these guides for a great primer on why you might want to use it and how to get started!

