Dotfiles

Photo by chuttersnap on Unsplash

Getting Started

Having a dotfiles repo can be a great way to have a central place to store configuration files that you may want to use across different computers. Also, when you get a new computer or change jobs, you can quickly get your system up to how your old one worked. I didn't use the idea until relatively recently, but I'm glad I started it.

Before I get into more details, I want to acknowledge that the following videos and dotfile repos helped me tremendously in getting started:
Thoughtbot Video on Dotfiles
Thoughtbot Dotfiles Repo
Chris Toomey Dotfiles Repo

Here is my dotfiles repo for reference.

In my view, this repo can be as simple or as detailed as you want it to be. To start, you probably want to have the configuration file for your shell of choice: zsh, bash, etc. If you use the thoughtbot rcm repo to manage the files (more on this later), you'll just want to name your configuration file without the preceding '.'. If you're using zsh, you'll create a 'zshrc' file in the root of the repo. You could use a different method, but essentially, you are just going to need to get the file in the dotfiles repo symlinked or copied to your $HOME directory in some way. I recommend rcm, as it makes it very simple.

Dotfile Management (rcm)

If you choose to go with rcm, then just get it installed on your system. You'll also need to add an rcrc file in your dotfiles repo. Once it's installed, then you can run (modify so that it points to where your rcrc file is located):

env RCRC=$HOME/git/dotfiles/rcrc rcup

This will symlink files in your dotfiles repo into your $HOME. For example, 'zshrc' will be symlinked to '$HOME/.zshrc'. When you add new files to the dotfiles repo, you'll need to re-run rcup, but you don't have to include the env RCRC part before it. Just run rcup.

Vim

I use vim as my editor, and this dotfiles setup is very useful for vim, as it can get very complex with lots of configuration files. If you use an IDE like VSCode, there may be configuration that you want in your dotfiles also.

For fellow vim users, I have a vimrc file, vimrc.functions file, and also a vim directory that contains several directories/files that contain most of the configuration. The vimrc file mostly just contains code to loop over the vim directory and load in all of the plugins and other configuration. The vimrc.functions file contains general functions that are used within vim. The bulk of the configuration is in the vim directory.

The first folder is the rcplugins folder. This contains any extra plugins that you use with vim. I create one file per plugin. Sometimes the file simply loads the plugin (I use this minimalist vim plugin manager), but you can also set custom mappings or variable settings that are relevant to that plugin. A simple example is the ack plugin:

" Ack - Integrata ack (grep replacement) into vim

Plug 'mileszs/ack.vim'

let g:ackprg = 'ag --nogroup --nocolor --column'

" vim:ft=vim

Next up is the rcfiles folder which contains more mappings and customizations that are not specific to plugins. I break these up into logical categories such as: theme, usability, windows, mappings, etc.

Finally, the ftplugin directory contains customizations that are specific to filetypes. If you want a setting specific for php files, then you'd create a php.vim file here and add the settings in that file. An example from my repo is the gitcommit.vim file, which has custom settings for git commit messages. I use this because for git commit messages, I want the text width to be 72 chars instead of the usual 80.

" Automatically wrap at 72 characters and spell check commit messages.
autocmd BufNewFile,BufRead PULLREQ_EDITMSG
set syntax=gitcommit
setlocal textwidth=72
setlocal colorcolumn=73
setlocal spell

Git

I have custom git hook functionality that I like to use for any git project that I work on, so adding those into .git-templates/hooks folder ensures that every git initiation uses those hooks. Specifically, I have pre-commit and commit-msg hooks that I run. They do some checks to determine what kind of project I'm working on, so phpcs pre-commit checks won't run if I'm in a Ruby based project. I'll expand on git hooks in a future blog post.

Other git configuration that is useful are gitconfig, gitignore, and gitmessage. I also use the gitconfig file in my local dotfiles repo, so I can use a different email associated with my git commits on my work computer vs home computer.

Executables

If you have custom executable files, then you can include those in your dotfiles as well. I just create a bin directory that contains all of the files. Then in your shell configuration you will want to make sure and include this bin directory in the path $HOME/.bin.

Package Manager

If you use a package manager like Homebrew, your dotfiles repo can also be a good place to store package install info. Homebrew lets you define a "Brewfile" file which can list out all of the packages that you want to install, then you can install it with brew bundle. If you are on a Mac and want to install Mac applications with cask, you can include those as well. If you're including this file, you will want to include "Brewfile" in the exclude list in your rcrc file. This will prevent Brewfile from being symlinked to ~/.Brewfile.

Now you can ensure that you'll have your most necessary applications installed when you get a new computer. To make it even easier, you can include this Brewfile in an install script, which I'll talk about next.

Install Scripts

To make sure all of the above is installed when getting set up on a new computer, I also created an install.sh script (and install-debian.sh for linux installs). This script will run brew bundle, install global composer packages, install npm packages, etc. I used it for setting up my computer for my current job, and I was up and running with all of the essentials very quickly.

Local Dotfiles

One final thing to consider is whether or not you want a separate repo for local dotfiles. You may want this to store some configuration that has private info in it (and keep the repo private), or it may be that you want different configuration for different environments (work vs home). In my case, I use a local dotfiles for both reasons. I have a private repo with separate branches for work and home. My reason for splitting work and home, is that I have some zsh/vim functions and mappings that are only needed in my work environment, plus I use a different email in my gitconfig.

To set up local dotfiles, you will need to update the rcrc file in your dotfiles repo to make sure that DOTFILES_DIRS includes the directory where you put your local dotfiles. Example:

DOTFILES_DIRS="$HOME/git/dotfiles-local $HOME/git/dotfiles"

You'll want to name your config files in your local repo with ".local" at the end of the name. For example: zshrc.local. This way it doesn't conflict with the base zshrc file when symlinking. Then in your main dotfiles repo, for every configuration that has local overrides, you'll want to include something like the following at the end of the file:

# Local config.
[[ -f ~/.zshrc.local ]] && source ~/.zshrc.local

Of course, after adding the local files, you'll need to run rcup again. Happy dotfiling!