Improving My Ruby Workflow, part 1

using vim, tmux, and some gems to become a more efficient coder.

When considering possible new year resolutions, I decided that I would pick a goal which was realistic, useful, measurable, and attainable — requirements that previous resolutions have failed to meet. So, I switched to vim from Sublime Text 3. I have been resisting this change for awhile now, mostly due to the relative difficulty of learning vim, but as I am acclimating to this change, I have found that it is not nearly as daunting as others have claimed. In fact, I am already seeing how this could benefit my workflow greatly.

Along the way, I have run into several other nifty tools that work nicely with vim. There are multiple plugins for vim which allow you to replicate the features you are probably used to in other text editors. Additionally, tmux is an outstanding tool for managing your terminals and has other features as well.

Although I am new to this area (I have been using this setup for under a week at the time of this writing), I felt like it would be a good idea to document my progression. This post series will guide you through a basic setup of vim, tmux, and a few gems that will make you more efficient.

INSTALL VIM AND TMUX

To get started, you will need to install vim and tmux. The installation of these tools can vary according to which operating system/distribution you use. As I doubt that everyone reading this will be using Arch Linux, my recommendation is to search for installation instructions that are specific for your environment.

BASIC CONFIGURATION

As with many Linux utilities, you are able to configure the absolute crap out of vim. However, doing so is outside of the scope of this post. For now, download all of the files in this repo to your home directory. You are free to find alternate configurations or make your own; just be aware that keybindings may differ from examples provided in this guide.

LEARNING VIM

To get started with vim, I recommend the free levels offered at Vim Adventures. It was recommended to me, so I gave it a try and found that it was exactly what I needed to get me started. Vim Adventures is a game which teaches basic vim usage, and they offer three free levels after which you can purchase a license for additional levels.

Whether or not you choose to play through some Vim Adventures, ensure that you take the time to go through the Vim Book. It’s available free and in either LibreOffice or PDF format. I thoroughly recommend it.

Ultimately, you get better with vim as you use it. Use these resources to get started, and force yourself to use vim for everything.

USEFUL VIM PLUGINS

There are a host of excellent vim plugins available, and I have listed several that I have found especially relevant to Ruby development below. In the future, I plan on writing more about their usage, but for now, I am still getting used to them.

I recommend that you utilize vim-pathogen to manage your plugins. Of these plugins, only vim-slime is necessary to follow along with this part of the guide. Basic instructions for each plugin can be found in the README of their respective repositories.

vim-pathogen: manages your plugins for you. *HIGHLY RECOMMENDED*

vim-slime: lets you send code from vim to a REPL. *REQUIRED*

vim-rubocop: enforces best practices. For more information about the style guide, check out this.

vim-fugitive: integrates git commands.

vim-rails: integrates rails commands.

vim-rake: integrates rake commands.

vim-bundler: integrates bundler commands.

SO WHAT IS TMUX?

Tmux is a terminal multiplexer which allows you to manage multiple terminal instances at once. You can organize your terminals into windows and panes which allows you to easily multitask. It is a boon for productivity.

Tmux especially shines when used in combination with vim and vim-slime; with just a couple keystrokes you can easily send code from vim directly to a REPL running in tmux. Using this technique allows you to easily test and debug your code as you write it. This will be explored later in the section of this guide concerning pry.

INSTALL AND CONFIGURE TMUXINATOR

Tmuxinator is a gem which allows you to save the layout of your tmux session’s windows and panes. Install it and follow the basic guide contained in the repo to set your own layout up. For demonstration purposes, an example layout is provided (.tmuxinator/ruby-dev.yml), which you should have installed earlier along with the dotfile configurations for vim and tmux.

Although you do not *need* tmuxinator, it will greatly improve your efficiency by allowing you to open a previously saved layout of terminals with the programs you want running in each of them.

In the example layout that I have provided, I have a “project” window that is split into two panes. When the tmux session is launched using this layout, it will execute the clear command in both panes (all the panes, actually), then ls for the top pane to list the files in the working directory, and bundle exec rails s to launch the rails server in the bottom pane. Seeing the project structure lets me get oriented, while launching the rails server reminds me to take a look at the working web app before I get started mucking around.

The next window is the “testing” window which contains a top pane running pry and a bottom pane running bundle exec guard. Pry is the REPL we will be using in this guide to debug code, and guard automatically runs tests that you have written whenever you have written changes to the relevant files. Guard will not be covered in this guide, but I may write more about it down the road.

And the last window — “scratch” — is just a single pane with a command prompt in case I need an extra terminal quick.

USING A REPL

REPL (short for Read-eval-print loop) is nothing more than a console that lets you interactively write code. IRB (interactive ruby) is the default which comes with Ruby, but pry has debugging features which make it more appealing to many. But programming using solely a REPL is simply not feasible. By using a pipe consisting of vim -> vim-slime -> tmux -> pry, you can write code in your text editor and immediately send it to the REPL for a quick evaluation. By using the additional debugging features of pry, you can turn the REPL into a powerful tool to make you a more efficient coder.

RECAP

Assuming that you made it this far in the guide, you have installed vim and tmux, familiarized yourself with vim’s basic usage, downloaded and placed the contents of the dotfiles repo into your home directory, installed at least the vim-slime plugin, and installed both tmuxinator and pry. Cool.

So, I have something to tell you: I have not included the step-by-step commands for the installation process on purpose. If you struggled to get to this point, feel good about yourself; you were able to find the appropriate resources (e.g. the documentation) and troubleshoot as necessary. Get in the habit. When possible, consult the documentation, be it a wiki, a manpage, or a README. Most projects have updated instructions to get you running, especially in the Ruby world. A guide (such as this one) can quickly lose its utility if it contains outdated commands, so I have decided to forego verbose installation instructions to avoid just that.

Admittedly, it is a lot to setup and configure, but if you performed the installation of these tools correctly, you are about to see the payoff.

PUTTING IT ALL TOGETHER

For the sake of brevity, I will run through a single example which will illustrate the utility of programming with a REPL. Although this was not the original purpose of the guide, it mirrors the path my past few days have taken. As a result of choosing to learn how to use vim, I heeded the advice of a much better programmer than I and looked into using a REPL. My friend, however, is a C/Python guy, so I needed to look into a REPL for Ruby. I found pry and felt like I needed to tell the world.

Open a terminal and execute the following commands:

touch example.rb
vim example.rb

Open another terminal and execute the following command:

mux ruby-dev

Performing the first step creates a file named example.rb and opens it in vim. The second step uses the mux (shortform for tmuxinator) command to open a new tmux session using the previously saved tmux layout generated by tmuxinator. The session name in the example can be changed to whatever the name for your desired layout is.

You may have noticed when you opened the tmux session that the bottom pane produced an error (if you are using my layout). The reason for this is that the session did not open in a directory with a rails project in it; it opened in your home directory. You can modify this behavior by altering the value of the “root” property in the layout file to whatever directory you choose.

Switch to window 1 (numbering for windows begins at 0) “testing” by entering the following keystrokes in tmux:

Ctrl-a, 1

Ctrl-a (the control and ‘a’ keys simultaneously depressed) is the prefix for all other keystroke commands. It essentially tells tmux to listen for a command that is about to be given. After the prefix, the number for the desired window is used, in this case ‘1’ for the “testing” window. Note: this guide uses an altered prefix instead of the standard Ctrl-b prefix which is the tmux default.

You will notice that guard (if you even have it installed) also produces an error because it is not in a directory containing a Guardfile. That is fine, for now. The important thing here is that pry should be running in the top pane.

Switch back over to the example.rb script and enter insert mode by pressing ‘i’. Now type (refrain from copy/pasting for awhile until you get comfortable with vim):

x = 'hello'
y = 'world'
xy = "#{x.capitalize}, #{y.upcase}!"

Exit insert mode by pressing the Esc key.

Navigate to the line 3 quickly by entering ‘G’ , then enter ‘$’ to bring the cursor to the end of the line.

Enter visual mode by pressing the ‘v’ key, and either use the cursor movement keys (hjkl) to select the three lines or just enter ‘gg’ to bring expand the selection to the top of the file.

Here is where vim-slime comes to the rescue. By entering ‘Ctrl-c, Ctrl-c’ (just hold down Ctrl and hit ‘c’ twice), you are telling vim to use vim-slime to send the selection to the REPL. Before pressing it, make sure that the pry instance is the currently active pane. When you press it, vim prompts you for a tmux socket and target pane. For now, just press Enter twice to accept the defaults and watch the magic happen.

Pry reads the input piped to it from vim, evaluates the statement, prints the result, and loops again (REPL). You can see this in action below:

[1] pry(main)> x = ‘hello’
=> “hello”
[2] pry(main)> y = ‘world’
=> “world”
[3] pry(main)> xy = “#{x.capitalize}, #{y.upcase}!”
=> “Hello, WORLD!”

Vim-slime sends pry the first line (x = ’hello’), evaluates it (stores the string ‘hello’ in a variable called x), prints the value, and loops again to process the next line. It does the same for line 2 and line 3, ending after the value contained in xy (“Hello, WORLD!”) is printed.

FURTHER EXPLORATION

This guide is the absolute smallest scratch on the surface of this topic. There are so many more commands and configurations for vim, tmux, tmuxinator, and pry; it would be impossible to fit it all in one guide. As I progressively get more familiar and proficient with these tools, I will explore this development environment further in future guides.

As this post primarily concerned configuring the environment, future posts in this series will address debugging a Ruby script with pry and using guard to run your tests automatically.

RECOMMENDATIONS

  1. Get comfortable using vim. Force yourself to use it for everything.
  2. Look at the man page for tmux or browse the official documentation. Learn the commands.
  3. Make your own layout using tmuxinator.
  4. Make your vim look pretty; find a theme you like and figure out how to install it (easy).
  5. Write your own script and practice sending bits to the REPL. Look up how to send it in a different way using vim-slime.
  6. Read up on the different pry commands and research how other people use pry when they code.

Thanks for reading this post, and I wish you the best in your NYR endeavors!
Recommend or share if you appreciate!

Like what you read? Give Richard Davis a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.