Dotfiles
Last updated: Fri Mar 24 2023
Table of Contents
Open Table of Contents
Essentials
There are a few command-line tools I use so heavily that I’m genuinely not sure how I would be productive without them.
git
Well, duh. Where would we even be as software engineers without git
?
That said, I like to set a lot of aliases in my .gitconfig
, like:
git bd
: branch delete, searching for branches withfzf
git c
: checkout branch, searching for branches withfzf
git cam
: commit all with messagegit camp
: commit all with message and pushgit ci
: checkout interactively; pick-and-choose files togit checkout
withfzf -m
git d
: diff with better behavior (showing staged and unstaged changes)git df
: diff with another branch by finding withfzf
git dfn
: diff with another branch by finding withfzf
, showing name-onlygit l
: show the log with one-line formatgit lf
: show the log and find a commit withfzf
git lfc
: show the log, find a commit withfzf
, and copy to pasteboardgit m
: merge branch, finding branches withfzf
git p
: pushgit s
: show statusgit unstage
: unstage the listed filesgit oops
: squash changes with the last commit, because I committed too early
fzf
fzf
is up there with git
as one of the miracles of command-line productivity. You throw it lines of text - usually piped in from somewhere else - and it presents a fancy, and highly customizable, fuzzy-find interface. As you can see above, that’s extremely useful when writing little shell scripts.
However, what I use it for most often is actually its Ctrl-R / Ctrl-T functionality. By default, Ctrl-R replaces the shell’s built-in search, using fzf
to fuzzy-find previous commands, even from days or weeks ago. Ctrl-T, meanwhile, performs a recursive fuzzy-find of filenames in the current directory and subdirectories, which is perfect to quickly pull up files by name regardless of the exact path.
rg
rg
is my all-purpose, cross-repo search tool. Throw a regex at rg
and it’ll chew through files looking for it, even respecting .gitignore
files!
I end up using it instead of my IDE’s search tool almost always - it’s just much more effective at actually finding what I’m looking for, and even works in plaintext situations, like if I need to search an Obsidian vault.
tmux
One of these days I’ll get around to writing up why I adopted tmux, but suffice to say I found my ~week of investment in learning tmux worthwhile, not least because I can operate a terminal without lifting my hands from the keyboard at all. When I’m running a terminal these days, I’m almost always running tmux. Among the benefits it offers:
- tmux can split the window with a simple hotkey, regardless of where it’s being run.
- Since tmux works on a client-server model, the shell keeps running even if you close the window.
- There’s a lot of utility just in having a pretty large scrollback buffer that you can save and search.
I also use a few plugins:
tmux-resurrect
/tmux-continuum
: Together, these plugins will automatically save the state of the tmux session and automatically restore it when you restart.tmux-open
: Just press “o” while a file or URL is highlighted in tmux to open it. That combines particulary well with the built-in regex searches; I have a few particular searches (e.g. for URLs) bound to various keys.tmux-yank
: This makes the copying behavior work a little better, notably while opening tmux via a VS Code terminal.vim-tmux-navigator
: This lets me use Ctrl-h/Ctrl-j/Ctrl-k/Ctrl-l to navigate around tmux splits and Neovim sessions.
Preferred
These are command-line tools I’ve been using a lot later that I would find inconvenient to switch away from.
fish
: I’m not convinced that fish, the “friendly interactive shell”, is radically better than, say, zsh with oh-my-zsh, but it does start up much faster, has nicer autocompletions by default, and has a much less confusing shell scripting language.neovim
: These days I use VS Code for most code editing - making Neovim work like an IDE is just too painful - but when I just need to quickly open and edit a file, I still fall back on it. I use a handful of plugins - notablyvim-tmux-navigator
to make it play nicer with tmux - but otherwise I try to keep its configuration pretty minimal.delta
: This little utility makes git diff output much prettier, with word-level highlighting, line numbers, and an optional side-by-side mode. It can even be used outside a git context as a replacement fordiff
in general!zoxide
: This is one of a couple different tools that remembers which directories you’ve previously visited, so you cancd
to them without typing out the full path. For instance, I can just goz dot
and I’ll jump to~/Developer/dotfiles
. I actually have this aliased directly tocd
- going back tocd
would be really annoying.just
: I used to write little Makefiles encapsulating various useful commands for a project. Unfortunately, thanks to its history as a build tool,make
has many well-known rough edges, like the requirement for.PHONY
rules.just
is a tool that basically provides Makefiles without the build system. That may not sound useful, and Hacker News types mock it every time it’s posted, but I still like to make one for almost every repo. A great example where it’s useful is withhledger
, a plain-text accounting system with a, uh, convoluted CLI - I can turn a command likehledger is -D -p "from 7 days ago" -f 2023.journal
intojust daily
, and it’s helpfully documented directly in thejustfile
.cheat
/tldr
: These are similar tools for sharing command-line cheatsheets.cheat
allows you to manage your own cheatsheets, while I’ve foundtldr
’s community-contributed cheatsheets to be high quality. I use both.
Modernized Unix Tools
I use a few standard Unix utilies that I’ve aliased to more modern versions.
bat
(forcat
): A few of the other tools like to send output throughcat
, and every so often it’s useful to splat a file to the command line. In those instances I usebat
instead ofcat
, because its output is a bit nicer and it automatically pipes to a pager likeless
if the output is too long.exa
(forls
): It’sls
with pretty colors and icons! Frankly I don’t have a strong reason to prefer this over bog-standardls
, but the colors are nice.sd
(forsed
): I often do search-and-replace through an IDE, but sometimes it’s nice to do it from the command line and just checkgit diff
for changes. Unfortunatelysed
makes absolutely no sense to me.sd
is a simple alternative with a better interface for the common case.fd
(forfind
):fd
works almost identically tofind
, but it’s a bit faster and, likerg
, respects.gitignore
files by default. In particular, I havefzf
’s Ctrl-T hotkey set up to usefd
by default.- HTTPie: This is a straightforward replacement for good ol’ curl or wget for making basic HTTP requests, but I prefer it to curl because the command-line interface makes a lot more sense.
dust
(fordu
): Every so often I need to check why a directory is so big, and in those instances I turn todust
, a modern replacement fordu
with prettier output.
Situationally Useful
I don’t use this often, but they’re helpful when I do need them.
gh
: Did you know GitHub has a fully-featured CLI that can access basically any GitHub API? That said, in practice, I rarely need many of the featuresgh
provides, but it does do a couple cool things:gh repo create --source .
will create a new repo on GitHub from the current directory, assuming it’s a git repository. That’s especially useful if I create a new project locally and then decide I want to push it to GitHub.gh pr view -w
opens the PR for the current branch, if any, in the web browser.
tig:
This is a pretty git viewer, but I mainly use it fortig stash
, which lets me interactively explore my git stash.jq
: I know a lot of folks lovejq
for working with JSON, but frankly I find it a pain to work with - its filter syntax is so idiosyncratic that I feel lost every time I pull it up. That said, when I do need to work with JSON,jq
is the obvious place to go; even just piping JSON output throughjq
for pretty printing is useful.terminal-notifier
: I don’t often need to trigger desktop push notifications from a shell script, but when I do,terminal-notifier
is the place to go.watchexec
: This is a cute little Rust tool that watches a file and reruns a command any time the watched file changes. I don’t realistically have a use for that, but if I ever do,watchexec
is where I’ll turn first.