Setting up my macOS Dev environment the right way: How to use DOTfiles to make life easier
Since I first started writing software in high school, I have had many software development computers and many software development environments. They were almost always someone else’s idea. I have used a variety of editors (NetBeans, Visual Studio, Notepad++, Xcode, VSCode, etc), terminals (PowerShell, Bash, zsh), and operating systems (Windows, Windows Bootcamp, Arch Linux, macOS). When I purchased my M1 MacBook Pro in late 2021, I decided to start fresh and quit using someone else’s developer environment idea. The following are the steps I took in my setup.
Terminal Setup
macOS comes with a built-in Bash terminal, but I prefer to download and use iTerm2. This is a pretty common choice among macOS users due to its expanded feature set like profiles, stats, plugins, and customizable color schemes (I like the slightly transparent style).
To accompany iTerm2, I installed Oh-my-zsh. All Unix terminals use Bash commands by default. Zsh is just an overlay onto Bash, just like iTerm2 for the terminal. It has themes you can customize, plugins that add functionality, and life-saving features like TAB complete (pressing the tab button to complete a command-line interface (CLI) command.)– a great feature if you struggle with spelling like me.
No terminal setup is complete without a set of quality configuration files. These files (called DOTfiles) provide the exact setup of your custom environment every time you sit down to code. Common DOTfiles (notice the proceeding “DOT”) are .bashrc and .zshrc. I typically do not change the .bashrc, and I usually only make a few changes to the .zshrc. Here you can see that these changes added only two plugins for Git and VSCode. I additionally added the command to `source ~/.zsh_profile`.
The .zsh_profile file is not necessary. If you choose, all the contents that I put in my .zsh_profile can just be added to the .bashrc or the .zshrc, but I like having it in a file to keep it a little more organized. The source command has this file initialized at setup.
In my .zsh_profle I have common variables that I want to be set in every open terminal like the $GOPATH and command aliases because I want to be able to quickly call these commands as shorthand for various other commands.
Now that I have configured my terminal to my liking I need to make them transferable to other developer machines. I have been trying to figure out for a while the best way to do this, but I usually end up copy-pasting them into a personal message channel or using an old setup that I sent myself in the past. I have set up more than five developer computers in the last five years, and each one was completely different. I was tired of trial and error trying to get things right. I wanted to make the perfect setup and then easily duplicate it. The answer to my problem was it and symlinks.
All of my DOTfiles are stored on GitHub here. I have a replication of this repository in my home directory ~/dotfiles. When my terminal starts up I need it to look at the files in this directory. I did this with a simple Unix symlink.
ln -s dotfiles/bash/bashrc .bashrc.
This means that every time the terminal tries to look up ~/.bashrc it looks at ~/dotfiles/bash/bashrc instead.
The text editor
When I am streaming on twitch I get asked all the time in chat what is the best way to get started with Vim. Yes, using Vim is a symbol of awesome, ninja-like developer mastery, but so is using a keyboard without letters on it or writing Bash scripts without Google. The only reason someone should use Vim is that they want to increase speed and productivity while decreasing the need for a mouse. I started by using the vim bindings in VSCode, but when there were issues with some of my favorite plugins I made the full switch to vim. (I have tried going back to VSCode due to its popularity among co-workers, but there is an exponential decrease in my productivity).
Vim, like VSCode, is a very simple text editor at its core, but the power comes from community-supported plug-ins. It is really simple to install on macOS using Homebrew. There are also a variety of projects built off of the Unix default VI editors including Vim, MacVim, and NeoVim. I have used all of them at one point or another; I liked the MacVim UI at the mouse support for when you need to copy something into the browser, but with the launch of Github’s copilot program, and it being compatible with only VSCode, Jetbrains products, and Neovim, I have switched to Neovim.
Like your terminal, vim uses DOTfiles to define and load your editor’s configuration. The .vimrc file is the default configuration file when you configure your vim setup. My .vimrc has 3 sections: the vi configurations, the plugin definitions, and the plugin configurations. Here is the Git copy of my .vimrc.
The Go Developer Environment
I am primarily a Go engineer. For work, I build out data pipelines using Go, and for personal projects, I still use Go because that is the main material for my talks and presentations. This means I need to have a good Go developer environment. There are 2 Vim plug-ins that I need to be successful: vim-go and gotests-vim. Vim-go integrates commands from the Go binary tool like Go build and Go test with linters, formatting, importing, code generations, and testing. Go tests generate Go table tests for functions.
All of my configurations are available for reference on GitHub. It was really fun to set up my M1 MacBook Pro. To check out the setup in action, come hang out with me on twitch every Friday from 2 pm MST to 5 pm MST.