← Back to index

Vim: Semantic execution

A REPL is an excellent tool for exploring data or spiking out ideas. We can quickly answer our questions, then get back to our editor to resume feature work. But when we are unable to get answers quickly and complexity mounts, the REPL becomes a hindrance1. Much of our time is spent moving back through the command history, hunting for that one thing we need.

If we instead do this exploration within our editor, we can retain every piece of code we write, while maintaining the quick feedback loop. It becomes easier to make adjustments or find that one thing.

We'll need to execute these scripts differently, depending on the type, which we can configure Vim to do. We can take advantage of the filetype plugin system to use the same mapping for all our scripts. Let's use <leader>x as the mapping, as a mnemonic for "execute." We'll make use of the clear command to keep our output isolated, so we can focus on it.

Create a .vim/ftplugin/ruby.vim file with the following:

nnoremap <buffer> <leader>x :!clear; ruby '%'<cr>

With this, we can execute simple Ruby files with our <leader>x mapping. Then, we can make whatever tweaks we want, and keep iterating until we get what we need.

simple ruby file

Since this is configured with Vimscript, we can tailor it for it our needs. Let's look at a bit more complex example.

.vim/ftplugin/ruby.vim:

if getline(1) == "# rails"
  nnoremap <buffer> <leader>x :!clear; rails runner '%'<cr>
else
  nnoremap <buffer> <leader>x :!clear; ruby '%'<cr>
endif

With # rails as the first line of a Ruby script, we use rails runner to execute within the context of our Rails app, with access to our models and all other supporting code. We can even store these files in the tmp/ directory and refer to them later.

If we set this up for all the languages we use2, then Vim acts as our anchor, no matter what tools our explorations require. It feels good to be home.

  1. Some REPLs do provide basic functionality for dealing with complexity. In psql, the \e command will open your editor with the most recent statement. In node, the .editor command allows for multiple lines, but doesn't open the editor. We can use the interactive_editor gem with irb, but it doesn't pull the command history, so we need to remember to start the session with it. 

  2. Some reference code that may be useful: go, html, javascript, markdown, ruby, sql