Screen_Shot_2014-05-30_at_1.37.33_PM

Salsify Engineering Blog

Using vim/tmux for Ruby on Rails

Posted by Daniel Piet

Nov 25, 2015 8:43:53 AM



Introduction


Using vim has been one of the greatest productivity boosters for my development life. I got into vim as a lowly system administrator because it seemed to be the tool of the trade. From there, my knowledge grew and now it is my editor of choice for almost all projects. This post will go through my current setup for Ruby on Rails development. I'd like to give a huge shout out to @tpope who has created a plethora of amazing plugins all worth making a part of your daily workflow.


Why Vim

vim keybindings

Given its steep learning curve, it is understandable that many people do not make the switch to vim. I'll admit that vim is not for everyone. Some people prefer a different experience when editing text. Since this blog post is not about persuading you to use vim I will simply direct you to the following blog posts for different points of view.

Vim for ruby

Most of my coworkers use IntelliJ's IDEA or RubyMine IDEs. While this is a great IDE I find it to be quite slow when it comes to indexing. I find the GUI interface difficult to navigate. Customization of the IDE is possible with plugins, but the plugin ecosystem is primarily for integrations and not workflow optimizations. Finally, at a whopping $499 for companies and $199 for individuals it may be out of the price range of the frugal developer. IntelliJ also does not support pry which is my preferred REPL over irb

Custom Keybindings

remap caps lock to escape

I like to have the escape key within easy reach. The escape key is crucial for quickly switching modes. Beyond this, I find it useful outside of vim, for closing modals and windows in various applications. I rarely use caps lock and when I do need to upcase a chunk of text I use vim's gU command.

On Linux this is fairly simple, mac requires a bit of work. For PC users I suggest using a VM.

GNU/Linux

Just create a quick script with the following invocations:

keycode 1 = Caps_Lock
keycode 58 = Escape

That's it! Super easy. For more XWindows options please refer to this post.

Mac

Mac is a little bit difficult in comparison. The best solution I found is outlined in this post.

It involves downloading the application SEIL, as well as turning the caps lock action OFF in the Modifier Keys section of the System Preferences, Keyboard tab.

Macs are funVery Fun

After this is done, go ahead and install SEIL and in the setting tab setup the caps lock switch.

seil is a weird name


This sums up my custom keybindings. Feel free to comment below with any keybindings you enjoy.

Vim's .vimrc

Much of my .vimrc consists of plugin specific content which will be discussed below in the plugin section but here are some must have defaults.

Basic set settings

" vi no compatible
set nocompatible
" mostly does the right thing
set smartindent
" turns off tab character
set expandtab
" left size numbering, some people prefer relativenumber, but with easy motion this is irrelevent
set number
" 2 spaces for tabs and shifts
set tabstop=2 shiftwidth=2
" makes backspace work like most other apps
set backspace=2
" scroll offset, keeps 2 lines above the cursor
set scrolloff=2

Custom ~/.vimrc Keybindings

Use ; as : in your vimrc

I like using the command interface to search for text and run various plugins. Remapping : to ; to avoid the extra Shift keystroke has proven to be a huge efficiency improvement. Here's how you do it.

nmap ; :

Use <Space> as your leader key

This has been an amazing productivity booster for me and I highly recommend it. While the leader defaults to \, the spacebar is much more convenient, and basically useless in Normal mode. Here's how to remap the leader key in your .vimrc.

let mapleader = "\<Space>"

Set // to search the current visual selection

This will allow you to select a word within visual mode, then with the quick double tap of / immediately search for the given word.

vnoremap // y/<C-R>"<CR>"

Set up easy quickfix navigation with <c-b> and <c-n>

If you don't use the quickfix window often this will not come in handy, but I have my searcher setup to pop into quickfix which makes this one of the most common shortcuts I use.

" next/prev quicklist item
nmap <c-b> :cprevious<CR>
nmap <c-n> :cnext<CR>

Keybind crosshairs on and off

Sometimes I lose my cursor which can be a pain, with vim crosshairs I always know where it is. After adding the following lines to your .vimrc <Leader>X will show you the cursor location.

hi CursorLine   cterm=NONE ctermbg=235
hi CursorColumn cterm=NONE ctermbg=235
nnoremap x :set cursorline! cursorcolumn!

Toggle paste mode

I do a lot of pasting of code, and to type :set paste and :set nopaste is rather annoying. Now I toggle paste mode with <Leader>p

" toggle paste in cmd only
nnoremap <Leader>p :set invpaste<CR>

Fast JSON beautifier

Since my work consists largely of web development, I often will have large blobs of JSON I need to verify or work with. Being able to beautify at a key stroke has been a great tool in my arsenal. I use the tool jq to clean up my JSON. You can find install directions for the project on its github page. After installing, just add the following to your .vimrc.

" json beautifier
nnoremap <Leader>z :%!jq '.'<CR>

Easy pry integration

If you are not currently using pry, I highly recommend it. It is by far the best replacement for irb and has allowed me to quickly debug code. In my vim integration I have two custom settings which speed this process up. The first inserts a pry breakpoint at a keystoke, and the second quickly searches for all existing breakpoints. The pry insert commands came from this plugin.

" quickfix list for breakpoints
nmap <Leader>i :Ag binding.pry<CR>

" …also, Insert Mode as bpry<space>
iabbr bpry require'pry';binding.pry
" And admit that the typos happen:
iabbr bpry require'pry';binding.pry

" Add the pry debug line with \bp (or <Space>bp, if you did: map <Space> <Leader> )
map <Leader>bp orequire'pry';binding.pry<esc>:w<cr>
" Alias for one-handed operation:
map <Leader><Leader>p <Leader>bp

Plugins

I use an large number of plugins and am constantly adding or deleting from plugin folder. My plugin manager of choice is pathogen. My workflow with it is great, I just add plugins as submodules to my /bundle directory. Then when I want to update my plugins I can just update the submodules. On a new box I just clone the repo and bring down any associated submodules. Again, @tpope is the greatest.

This list is by no means complete but should be enough to get you going. The plugins are ordered by use, so if you prefer a lightweight installation just grab the top few.

Ag

If you have not yet experienced the greatness that is the_silver_searcher, I highly recommend it. I have followed Thoughtbot's wonderful guide to set it up. Now, when I need to search for a word in normal mode I just tap K. For code base searches the command :Ag "search term" will pop the results in quickfix list which I can navigate with <c-b> and <c-b>

ctrlp

ctrlp is fuzzy file finder for vim, it is super useful for navigating large codebases but required a bit of custom configuration which I have shared here.

" ctrlp custom configurations
let g:ctrlp_max_files=0
let g:ctrlp_max_files=0
let g:ctrlp_match_window = 'bottom,order:btt,min:1,max:15,results:50'
" project specific
let g:ctrlp_custom_ignore = 'node_modules/\|DS_Store/\|git/\|bower_components/\|vendor\|tmp\|db'

This configures ctrlp to use ag.

" Use ag in CtrlP for listing files. Lightning fast and respects .gitignore
let g:ctrlp_user_command = 'ag %s -l --nocolor -g " --ignore node_modules --ignore DS_Store --ignore git --ignore bower_components --ignore vendor --ignore tmp --ignore db --    ignore app/resources'
" ag is fast enough that CtrlP doesn't need to cache
let g:ctrlp_use_caching = 0"

Airline

Airline gives you a powerline like interface without all the bloat.

airline

youcompleteme

YouCompleteMe gives you great code completion for vim. I also use UltiSnips for snippets which is hooked into YouCompleteMe. This requires a bit of setup to ensure the keystrokes work correctly. This can be done by installing SuperTab and adding the following to your .vimrc

" make YCM compatible with UltiSnips (using supertab)
let g:ycm_key_list_select_completion = ['<C-j>']
let g:ycm_key_list_previous_completion = ['<C-k>']
let g:SuperTabDefaultCompletionType = '<C-j>'

" ultisnips directory
"let g:UltiSnipsSnippetDirectories=["UltiSnips"]
let g:UltiSnipsExpandTrigger="<tab>"
let g:UltiSnipsJumpForwardTrigger="<tab>"
let g:UltiSnipsJumpBackwardTrigger="<s-tab>"

youcompleteme

nerdtree

While I mainly use ctrlp for switching files, its nice to have a directory explorer handy for the times when you want to see a directory structure. Nerdtree does the job.

nerdtree

easymotion

Easymotion is a feature-rich plugin that makes it simple to navigate to any position in the current buffer.

easymotion

fugitive

Fugitive is yet another great plugin by @tpope. Gives your vim full git integration capabilities. I love it for:Gblame

fugitive

vim-surround

@tpope owns the plugin space, vim-surround gives you quick keybindings for adding and removing delimiters.

ruby-refactoring

ruby-refactoring is a sweet little plugin give you the ability to quickly refactor ruby code like an IDE. It's a little rough around the edges but I find it quite effective in the instances which I use it.

delimitMate

Auto complete delimiters with delimitMate.

vim-rails

@tpope has built a great plugin for navigating rails projects. If I'm not using Leader] to drill into things I will always go to @tpope's vim-rails plugin

vim-rspec

Thoughtbot is a consultancy known for their love of vim. If you have a chance I'd highly recommend checking out their videos and blog posts. They have produced a ton of helpful tools and content including vim-rspec.

trailing whitespace

I don't like extra whitespace, vim-trailing-whitespace gets rid of it. In my ~/.vimrc I've defined a Leader shortcut to make this super easy.

nnoremap w :FixWhitespace

Big Wins with Exubrant Tags

Getting eTags to work may be a bit difficult compared to other plugins but being able to 'drill' into method definitions is incredibly useful and quickens up the 'grokability' of a codebase. The following two posts can help you set things up.

ctags
using-vim-exuberant-ctags-easy-source-navigation

Be able to drill into Gems with Gem-ctags

Often times, when drilling into the codebase is not enough, one needs to go code spelunking into the gems themselves. This is where gem-ctags comes into play. The gem creates a tag folder for your gems which allows drills to directly open the definition.

Tmux for fun and profit

My tmux configuration is pretty self explanatory from the tmux.conf so I'll just pop that in here.

Some of the big wins were from switching over the normal b key binding to use q instead. I primarily use tmux for terminal history hence the increased size. Alongside this, utilizing vim style selection and movement have definitely sped up my productivity.

Auto name tmux panes from vim

This addition to the .vimrc will rename yourtmux pane to the file you are editing in.

" Rename for tmux

autocmd BufReadPost,FileReadPost,BufNewFile * call system("tmux rename-window " . expand("%"))

Below is my tmux.conf

#### COLOUR (Solarized 256)
set -g default-terminal "screen-256color"

# vim mode, plus vim style keys
set-window-option -g mode-keys vi
bind-key -t vi-copy 'v' begin-selection
bind-key -t vi-copy 'y' copy-selection

# default statusbar colors
set-option -g status-bg colour16 #black
set-option -g status-fg white
set-option -g status-attr white

# center windows
set -g status-justify centre

# default window title colors
set-window-option -g window-status-fg white
set-window-option -g window-status-bg default
#set-window-option -g window-status-attr dim

# active window title colors
set-window-option -g window-status-current-fg white
set-window-option -g window-status-current-bg default
#set-window-option -g window-status-current-attr bright

# pane border
set-option -g pane-border-fg colour16 #base02
set-option -g pane-active-border-fg colour16 #base01

# message text
set-option -g message-bg default
set-option -g message-fg white

# pane number display
set-option -g display-panes-active-colour blue
set-option -g display-panes-colour red

# clock
set-window-option -g clock-mode-colour white

new true
set set-remain-on-exit on
new -n one ls
neww -n two ls

# remap prefix to ctrl + a
set -g prefix C-q
unbind C-b
bind C-q send-prefix

# quick pane cycling
unbind ^Q
bind ^Q select-pane -t :.+

# better movement
bind k select-pane -U
bind j select-pane -D
bind l select-pane -R
bind h select-pane -L

bind Up resize-pane -U 20
bind Down resize-pane -D 20
bind Left resize-pane -L 20
bind Right resize-pane -R 20

# more hist
set -g history-limit 20000

Conclusion

I have enjoyed sharing my Ruby on Rails vim setup and workflow with you. Please feel free to comment on this blog post with your own tips and personal preferences for development tools.

comments powered by Disqus

Recent Posts