Quick, repeatable dev environments

Going from 0-to-60 with a single command

up

2019-04-09

The Problem

I work on a bunch of different projects and it’s really frustrating when I have to hop between them frequently, re-configuring my environment each time or letting my environment bloat and get messy. Seems like a problem that can be solved with automation and scripting.

I use terminal emulators a lot, so an option has to involve that. I use Vim primarily, so an option has to involve that. No solution is likely to be perfect (hence not already having this problem solved), but I need to start with something.

That said, I think a solution is approximated by using tmux and tmuxp, with some more advanced Vim usage. The key for me, right now, is getting up to speed with tmuxp. I’ve used tmux and Vim for a long time, but kind of drift off and on with tmux because of the required reconfiguration.

tmuxp attempts to make the configuration part repeatable, which may be enough!

Vim

I try to keep my customizations down quite a bit. There are only a few that I use to enhance my ability to navigate around a project, and pickup where I left off.

First, I use netrw to get me a simple file drawer interface to browse my code as a tree, when I need to:

let g:netrw_liststyle = 3       " tree-style
let g:netrw_banner = 0          " banner off by default, toggle with I
let g:netrw_browse_split = 0    " open files in previous window
let g:netrw_winsize = 25        " 25 % of width

" use '-' to toggle netrw split
nnoremap - :Lexplore<Return>

Second, I keep undo records around longer than just a session:

" turn on and set the directory for persistent undo's (if the option exists)
if isdirectory($HOME . '/.vim/undo') == 0
  :silent !mkdir -p $HOME/.vim/undo > /dev/null 2>&1
endif
set undodir=$HOME/.vim/undo/,./.vim-undo/,.
set undofile

Third, I use :mksession and :source when I want to save my session state (minus netrw state…), which isn’t as often as I had thought I would. Honestly, I like closing vim to be a sort of reset on how my editor is viewing files. If I’m not done with a thing, though, and I have to bounce to something else for a bit, it can be handy to know how to use them.

tmux

I use tmux to manage sessions and workspaces, and a tool called tmuxp to script the creation of them.

There’s a little bit of up-front cost in time (5 minutes), but the gains are pretty useful.

I basically just issue a command like tmuxp load project1 and it’ll setup all the windows and pane’s I find useful, start all the applications that are useful to have running, and ssh into any servers I might need to connect to.

When I’m done, a simple <ctrl><b>:kill-session command closes everything.

Not really much to say about customizing tmux in this regard – I keep it pretty vanilla. The ONE thing I do make sure is in my .tmux.conf is a directive to force it to behave as if it can display 256 colors:

set -g default-terminal "screen-256color"

And, as for tmuxp, there’s not much more than creating a folder for the config files (I use ~/.tmuxp/), and then having basic configs like:

session_name: example
windows:
  - window_name: win1
    layout: 38a5,231x60,0,0[231x44,0,0,0,231x15,0,45,2]
    shell_command_before:
      - cd ~/some/place/on/disk
    panes:
      - shell_command:
        - cd ngapp
        - vim -c ":source ~/.vim/sessions/example.vim" -c ":mks! ~/.vim/sessions/example.vim"
      - shell_command:
        - cd ngapp
        - ng serve

The layout property there comes from the ‘layout’ tmux property. The string of numbers and symbols there, in this case, is just a custom layout. To get one of those, just fire up tmux and adjust everything the way you want, then execute a command to list it, IE tmux lsw -F "#{window_active} #{window_layout}" or something to that effect. See the ‘layout’ section in The Tao of tmux for a lot more detail there.