Tuesday, October 7, 2014

Automatically Resize Vim Splits

If you think "Vim splits" may have something to do with a cleaning product then this post might not be for you. Geekery ahead.

I am a long-time user of the Vim text editor. It's made for use from the keyboard (though you can use a mouse if you want), and works great running on a remote computer. When I program I often use split windows, where I have multiple files open and visible at the same time in different window panes:

A Vim editor with three splits, each editing a different file.

Split windows are very useful. But when you have many splits or when you're on a small laptop screen, each split becomes too small to edit things properly. You can of course resize them in various ways: ctrl-w _ and ctrl-w | will maximize vertically and horizontally; ctrl-w + and -, and < and > will increase and decrease the split size; and ctrl-w = will equalize them all. But that's a hassle; also, when you maximize a split you no longer see the contents of the other ones. Ideally you'd increase the size just enough to edit properly, and do it automatically.

So I have a small function written in Vimscript that I stick in my vimrc file:

" Resize the current split to at least (90,25) but no more than (140,60)
" or 2/3 of the available space otherwise.

function Splitresize()
    let hmax = max([winwidth(0), float2nr(&columns*0.66), 90])
    let vmax = max([winheight(0), float2nr(&lines*0.66), 25])
    exe "vertical resize" . (min([hmax, 140]))
    exe "resize" . (min([vmax, 60]))

When you call this (on the command line as :call Splitresize()), it will resize the current split to 2/3 of the entire editor width and height; but always at least 90 columns by 25 rows, and no more than 140 colmuns by 60 rows. That guarantees that the split is always large enough even on small screens, and never becomes ridiculously huge on large screens.

I moved from split 2 on the left to split 3 on the lower
right, and it has resized itself to a comfortable size.

My preferred way to make this automatic is to add these mappings:

" move between splits without the ctrl-w prefix

nnoremap <silent><C-J> <C-W><C-J>:call Splitresize()<CR>
nnoremap <silent><C-K> <C-W><C-K>:call Splitresize()<CR>
nnoremap <silent><C-L> <C-W><C-L>:call Splitresize()<CR>
nnoremap <silent><C-H> <C-W><C-H>:call Splitresize()<CR>

You can move between splits with ctrl-w h, j, k and l. It's a bother to press ctrl-w all the time, though, so many people add mappings so ctrl-h, j, k and l move between splits directly. These mappings add :call Splitresize() to the end, so your splits will resize automatically when you move to them. And you can still use the ctrl-w hjkl mappings or select a split with the mouse when you don't want the split to resize.

If you use Vim then give this a try. And if you have any feedback or ideas to improve this then please get in touch.

No comments: