Dotfiles
Last updated: 3/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 withfzfgit c: checkout branch, searching for branches withfzfgit cam: commit all with messagegit camp: commit all with message and pushgit ci: checkout interactively; pick-and-choose files togit checkoutwithfzf -mgit d: diff with better behavior (showing staged and unstaged changes)git df: diff with another branch by finding withfzfgit 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 withfzfgit lfc: show the log, find a commit withfzf, and copy to pasteboardgit m: merge branch, finding branches withfzfgit 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-navigatorto 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 fordiffin general!zoxide: This is one of a couple different tools that remembers which directories you’ve previously visited, so you cancdto them without typing out the full path. For instance, I can just goz dotand I’ll jump to~/Developer/dotfiles. I actually have this aliased directly tocd- going back tocdwould 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,makehas many well-known rough edges, like the requirement for.PHONYrules.justis 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.journalintojust daily, and it’s helpfully documented directly in thejustfile.cheat/tldr: These are similar tools for sharing command-line cheatsheets.cheatallows 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 usebatinstead ofcat, because its output is a bit nicer and it automatically pipes to a pager likelessif the output is too long.exa(forls): It’slswith 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 difffor changes. Unfortunatelysedmakes absolutely no sense to me.sdis a simple alternative with a better interface for the common case.fd(forfind):fdworks almost identically tofind, but it’s a bit faster and, likerg, respects.gitignorefiles by default. In particular, I havefzf’s Ctrl-T hotkey set up to usefdby 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 forduwith 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 featuresghprovides, 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 -wopens 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 lovejqfor 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,jqis the obvious place to go; even just piping JSON output throughjqfor 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-notifieris 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,watchexecis where I’ll turn first.