paint-brush
Automatic Window Resizing in Vimby@sambernheim
3,363 reads
3,363 reads

Automatic Window Resizing in Vim

by Sam BernheimJune 30th, 2020
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

A common workflow in Vim is to use multiple windows to view and edit various files at the same time. Once opened though, the size of each window often remains unchanged unless explicitly resized. A nicer workflow would be for the focused window's width to automatically expand. It's accomplished with the following snippet that uses an autogroup to call a function on the " ReduceNoise" autocmd! " Automatically resize active split to 85 width" The second line equalizes the width and height for all the other unfocused windows.
featured image - Automatic Window Resizing in Vim
Sam Bernheim HackerNoon profile picture

A common workflow in vim is to use multiple windows to view and edit various files at the same time. Once opened though, the size of each window often remains unchanged unless explicitly resized.

A nicer workflow would be for the focused window's width to automatically expand.

The Code

This behavoir requires surprisingly little vim script and has become one of my favorite additions. It's accomplished with the following snippet that uses an autogroup to call a function on the

WinEnter
vim event.

augroup ReduceNoise
    autocmd!
    " Automatically resize active split to 85 width
    autocmd WinEnter * :call ResizeSplits()
augroup END

function! ResizeSplits()
    set winwidth=85
    wincmd =
endfunction

The first line of the function sets

winwidth
to 85. This settings controls the width for the active window; the number represents the number of columns for the active window including the sign and line number columns. If those require 5 columns and
winwidth
is set to 85, 80 columns are used for the text.

The second line,

wincmd =
, equalizes the width and height for all the other unfocused windows; see
: h wincmd
for more information and some other great window commands.

Beyond Resizing

The above is a slimmed down version of a more practical implementation. Controlling other window settings can reduce additional noise on unfocused windows increasing your signal to noise ratio fo r your active work. Some additional ideas include:

  • Display absolute line numbers in unfocused windows and relative line numbers only in the focused window
  • Only display the sign column in the focused window
  • Only show the cursor line in the focused window
  • Disabling syntax settings of the unfocused windows

Enabling these settings is easily done by extending the above autogroup to include some additional auto commands like the ones shown below.

autocmd WinEnter * setlocal cursorline
autocmd WinEnter * setlocal signcolumn=auto

autocmd WinLeave * setlocal nocursorline
autocmd WinLeave * setlocal signcolumn=no

When a window is entered, the

cursorline
and
signcolumn
are enabled. Unfocused windows disable these settings.

Whatever you do and don't like to see in focused and unfocused windows is now in your control. This can include status lines for active and inactive windows through (each window can have its own status line setup: see an example here in my vimrc).

The Gotchas

The autocommands and resizing function work well in most cases, but may have some unintended effects. Windows created by plugins like NERDTree or to display the quick fix and location list may expand unexpectedly when focused.

One resolution to this unintended behvaoir is to add some if statements to the resize function to only execute if the active window's file type is not NERDTree, quick fix, or location list. You may not want

wincmd =
to run when on these windows as it equalizes not just the width but also the height of all open windows.

Despite these (minor) shortcomings (most of which can be accounted for and fixed), this has become one of my favorite and most useful settings. Its a pattern you won't know you missed until you had it.

As always, here's my vimrc for these settings along with the rest of my dotfiles.

At least one plugin has been created for this behavior: Lens.vim. If plugins are more appealing to your set up it can support some additional cool features.