Skip to main content

Posts about vim

Managing dotfiles with dotbot

We have an amazing development tool at Shopify called spin. Spin lets you create brand new cloud-based development environments in just a few seconds, right from your CLI. These environments are meant to be somewhat short-lived; I often spin one up just for the day to work on a PR, and then destroy it after my PR is merged.

As a longtime vim and linux user, I want to make sure that all my configuration files (aka "dotfiles") are made available automatically on any new environments that I'm setting up.

There are many different ways of managing your dotfiles. I started my journey with a "simple" shell script that tried to set up .vimrc, .zshrc, etc. Inevitably this script became overly complex, and was too cumbersome to maintain.

I briefly toyed around with ansible for managing my local system, but I found it to be overkill just managing dotfiles on remote systems.

Finally I discovered dotbot, which has a few features that I like:

  • No dependencies
  • Add into your dotfiles repo via a git submodule
  • Supports most of the stuff I need, without being too complicated
  • Configuration is easy to read & write
  • Safe to re-run

In particular, to set up neovim, I have something like this in my dotbot configuration:

# install.conf.yaml
---
- defaults:
    link:
      relink: true
      force: true

- link:
    # This line symlinks the astronvim repo from the dotfiles checkout 
    # into ~/.config/nvim
    ~/.config/nvim: vim/astronvim
    # Link in our user configuration for astronvim
    ~/.config/nvim/lua/user/init.lua:
      path: vim/user_init.lua

- shell:
    # Install all neovim plugins with packer
    - nvim --headless -c 'autocmd User PackerComplete quitall' -c PackerSync

Since setting up my dotfiles with dotbot, I've discovered that I'm much more willing to experiment with different configurations and tools. It's easy to blow away local directories, or git restore in my dotfiles repo, and then re-run the install script.

One small tweak I made to the generic install script is to split up configurations by operating system and environment. I have different configurations for Linux, macOS, and spin. I also have the install script send logs to the home directory, which makes it easier to debug when something has gone wrong. Adding exec &> >(tee -a $HOME/.dotfile-install.log) at the top of the install script copies the script output to a log file in my home directory, as well as outputting to stdout/stderr.

My dotfiles can be found on github.

svn-commit

Hate it when you write a big long commit message in subversion, and then the commit fails for some reason and you have to commit again? Tired of reading in the aborted commit log message into new commit log? Can't remember what subversion calls the aborted log messages? Me too. So I wrote this little plugin for vim that will look in the current directory for any aborted subversion commit logs. It will pick the newest one, and read that in. Just put this script into ~/.vim/ftplugin and name it something starting with "svn" and you should be good to go!


" SVN aborted commit log reader

" Reads in the newest svn-commit.tmp log in the current directory

" (these get left behind by aborted commits)

"

" Written by Chris AtLee 

" Released under the GPLv2

" Version 0.2



function s:ReadPrevCommitLog()
    " Get the newest file (ignoring this one)
    let commitfile = system("ls -t svn-commit*.tmp | grep -v " . bufname("%") . " | head -1")
    " Strip off trailing newline
    let commitfile = substitute(commitfile, "\\s*\\n$", "", "")
    " If we're left with a file that actually exists, then we can read it in
    if filereadable(commitfile)
        " Read in the old commit message
        "echo "Reading " . commitfile
        silent exe "0read " . commitfile

        " Delete everything from the first "^--This line" to the last one
        normal 1G
        let first = search("^--This line", "")
        normal G$
        let last = search("^--This line", "b") - 1

        if last > first
            silent exe first . "," . last . "d"
        endif
        normal 1G
        set modified
    endif
endf

call s:ReadPrevCommitLog()