How I Program — 10 Years In
To be an excellent programmer, you must have a set of tools and know them extremely well. I believe that if everyone was more open about their tooling and workflow, we could all learn a lot from each other. This post is an overview of the tools I use and why I use them.
The best investment is in the tools of one's own trade.
— Benjamin Franklin
I spend most of my day in a terminal, so I'm going to talk about it first. I'll go over the features I use that are specific to iTerm2 and then some important configuration.
The most important feature of iTerm2 that I don't get from the terminal app that comes with macOS is an easy way to backup and sync settings. I have multiple computers that I use daily and often change config that I want changed on all of my machines, so simple sync is really helpful.
The other really important feature of iTerm2 is the non-standard fullscreen mode. It uses the old style of fullscreen where the app isn't put into a separate space and doesn't have the dreaded and impossible to turn off animation between spaces that will cost you hours of your life every year.
Probably the most important stylistic configuration of your terminal is the color scheme you use. I like solarized because of the low contrast and soft colors. I've used various versions of it for so long now that I find anything else to be hard on the eyes. I'm currently using the 256 color version of base16 solarized because it works well with iTerm, tmux and vim.
I currently use Input mono by David Jonathan Ross as my font. I find it very easy to read and it works really well with my preferred and very luxurious setup of 24pt on a 5k iMac. I used Inconsolata for a long time before switching to Input and still think it is a solid choice.
I switched to zsh so long ago and always change my shell immediately on new computers. Because of this, I can't even remember what it does on it's own that bash doesn't. That's not the important part though. What matters is the really good community around zsh plugins and themes.
I use pure prompt by the amazing Sindre Sorhus as my zsh prompt. I really like it because it's fast, clean and shows me exactly the information that I care about, and nothing else. Seeing the current git branch and it's status (dirty, unpushed and unpulled) is really helpful because I spend a lot of time switching between branches.
I currently use anitbody to manage my zsh plugins, mainly because it is the fastest. I have used oh-my-zsh and antigen previously, but antibody is much faster than both.
zsh-syntax-highlighting is really helpful for catching typos bad commands before you run them. If they aren't installed on your path, they will be colored red.s
zsh-autosuggestions will suggest commands as you type, based on your command history. This will both increase how fast you type commands and serve as a memory of sorts for infrequently used commands.
zsh-completions tries to add tab completions for as many things as possible. Some of the more important ones to me are yarn and nvm.
vi-mode adds vim like support to zsh. Being able to hit esc and then j/k to navigate through history is so much nicer than having to move your hand down to the arrow keys. It also allows you to do things like move and edit words/lines at a time, which can be really nice if you are dealing with long commands.
Tmux is something that I have only been using heavily in the last year or so. I don't spend that much time working one things via ssh, but as I have learned, tmux is useful for so much more than that. What I love tmux for is the ability to have several sessions (think of them like tabs) going at the same time that I can quickly jump between with a fuzzy search, and are saved across system restarts. After restarting I can just restore my tmux state and switch to the session I need to work on. No making new panes, opening vim, setting up tig, starting tests, etc.
It is also worth mentioning that having a split tmux pane with vim on one side and your tests running on the other is really nice for being able to see your test results and write code without any context switching.
There are a few important plugins and some configuration that I use to make this all possible.
tmux-sessionist adds several keyboard shortcuts for more convenient session management as well as a quick switcher for sessions.
tmux-resurrect adds the ability to save and restore your tmux environment across restarts. Once you start using a lot of tmux sessions, this saves a lot of time every system software update.
tmux-continuum uses tmux-resurrect to constantly save your tmux environment and automatically restores it when starting tmux. This way you don't have to remember to save it before restarting and it is saved when your computer crashes.
Git is very interesting because everyone uses it all the time, but so many people are afraid of it and don't really know how to use it. It's also something that seems to have a near unlimited growth curve. It amazes me that I've been using it every day for ten years and still learn new things monthly.
I'm not a fan of GUI git clients for a few reasons. The first is that most of my workflow is already in the terminal, so I'd rather not switch out unless I have to. The second, and more generally applicable is that I find tig combined with the git cli to be faster, simpler and far more flexible than any GUI client I have seen. Someday I will write a whole post on using tig, but the main things I like it for is good keyboard shortcuts, chunk based staging and easy history navigation.
I'm currently lucky enough to be using GitHub for work, so I use hub, which is a nice little command line wrapper for git. It adds several GitHub focused convenience methods like being able to open a pull request and quickly open important pages like issues.
This is by far the most complicated and personal part of my setup. I wouldn't suggest starting from someone else's setup, so I'm not going to cover everything. This is a selection of plugins and settings that have had the biggest impact on my productivity while using vim.
I plan to write a series of smaller posts, outlining specific parts of my vim setup that can easily be setup and tested in isolation.
I'm not very good at typing and I don't like doing it more than I have to, so a large part of my vim configuration is target at reducing it. I start by mapping leader to
; so that I can start a leader command without leaving home row. I then map all of my important actions to be a combination of leader and another home row key. For example,
<leader>f opens fzf in file mode. I also use
l for very easy split navigation.
When I started using vim one of my biggest issues was the lack of native clipboard integration. By setting
set clipboard=unnamed, your vim history is added to your system clipboard and your system clipboard is accessible from vim. I set this a long time ago and have never looked back.
I use quite a few plugins, so I'm not going to cover them all here. This is a selection of the most useful and potentially non-obvious ones.
- Ale stands for Asynchronous Lint Engine and is essential for a modern editing experience. It uses new async functionality in vim 8 to provide performant linting of files as you type. I use it for Flow, Prettier and ESLint.
- fzf.vim is the vim plugin for the amazing command line fuzzy finder fzf. It's crazy fast, even on huge projects and has an excellent fuzzy matching algorithm.
- vim-gitgutter adds git diff data to the gutter of each file. This makes it really easy to keep track of exactly what you have changed without leaving vim.
- vim-fugitive can do all kinds of cool stuff, but the real magic for me is being able to type
:Gbrowseand have the current file open in a new Chrome tab. This is great for getting a link to share with others when discussing a specific file or even line. It also has pretty good git blame support.
- vim-xcode helps with running, building, testing and more, from the command line. I absolutely despise Xcode so much that even opening it makes me angry, so I'm very thankful for vim-xcode.
- lightline is the lightest and fastest statusbar that I have found yet. I have gone through most of the others, but found them all to be slow or hard to configure.
I have been tracking my various dotfiles in a repository on GitHub for quite some time now. It doesn't feel like a perfect solution, but it does allow for a relatively easy way to keep track of changes, sync changes between computers and setup new computers. github.com/rileytomasek/dotfiles.
If you made it this far, hopefully you learned a thing or two that will make your life easier. If you saw anything I'm doing sub-optimally or not doing at all, please let me know and I'll give it a shot!
Thanks for reading.