Terrible Blog

Because Terrible Labs loves you.

Stupid Vim Tricks: How to Change Insert Mode Cursor Shape With Tmux

| Comments

Rails developers spend a lot of time in the terminal, to say the least. tmux can be a powerful terminal productivity tool, with its ability to split terminal windows into panes, jump between sessions, and script all sorts of goodness. You’ll get the most out of tmux when it’s paired with an editor like emacs or vim, running natively inside the terminal itself.

When I made the jump from using MacVim exclusively to running vim inside a terminal session, I found that I really missed how MacVim changed the cursor shape from a block to a vertical bar in insert mode; it’s a great visual reminder of your current mode that doesn’t make you look away from where you’re currently working. Luckily, terminal vim inside tmux can emulate this behavior, but it’s a bit tricky to set up.

First, you’ll need a recent build of iTerm that supports the escape sequences we’ll use to change the cursor shape: this one or later should work fine.

You’ll need an updated copy of vim, if you’re still using the one that ships with OS X:

brew install macvim --override-system-vim

Now, in your .vimrc, we’ll add:

" set the cursor to a vertical line in insert mode and a solid block
" in command mode
let &t_SI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=1\x7\<Esc>\\"
let &t_EI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=0\x7\<Esc>\\"

At this point, vim running under tmux should switch cursor shapes when going back and forth from command mode to insert mode. Hooray! However, there’ll be an annoying one-second delay after changing back to command mode before the cursor changes shape. I’ve found the following admittedly hacky combination of settings eliminates this delay. Again, in your .vimrc:

" upon hitting escape to change modes,
" send successive move-left and move-right
" commands to immediately redraw the cursor
inoremap <special> <Esc> <Esc>hl

" don't blink the cursor
set guicursor+=i:blinkwait0

And finally, in your .tmux.conf:

# don't wait for an escape sequence after hitting
# Esc. fixes insert mode exit lag in vim
set -sg escape-time 0

Figuring this out helped me make the jump to using tmux full-time and it’s been a great thing for my command-line efficiency. If you’re looking for a good introduction to using tmux, check out The Pragmatic Programmmer’s tmux: Productive Mouse-Free Development.