Vim Tips Wiki
Tip 1598 Printable Monobook Previous Next

created 2008 · complexity basic · author Fritzophrenic · version 7.0

Sometimes a user wants to initialize certain settings whenever a window is created, instead of whenever a buffer is created or loaded into a window. Common uses might include setting window-local options like 'number' and 'wrap', or setting up highlighting using :match or matchadd().

To accomplish this, one might think to use the BufWinEnter autocmd event, which will almost work, because it will fire whenever a buffer is loaded into a window, even when the buffer is already open in another window. Unfortunately, it fails to fire when using the :split command with no arguments (quite a common occurrence for many users) and therefore a different method is needed.

The WinEnter event, which fires whenever you enter a window, is a likely candidate. With experimentation, you can see that it even fires for commands like :pedit which do not end with the cursor in the newly created window. Unfortunately, it is unlikely that anyone wants to set up options whenever a window is entered, so it is necessary to test to make sure this is the first time the window has been entered. This is made simple by Vim's support of window local variables. The following autocmd will set up a window-local variable, w:created, that will be set to 1 after any other WinEnter events fire. This allows a user to test for its existence in an autocmd defined pretty much anywhere without worrying about the order.

" autocmd that will set up the w:created variable
autocmd VimEnter * autocmd WinEnter * let w:created=1

" Consider this one, since WinEnter doesn't fire on the first window created when Vim launches.
" You'll need to set any options for the first window in your vimrc,
" or in an earlier VimEnter autocmd if you include this
autocmd VimEnter * let w:created=1

" Example of how to use w:created in an autocmd to initialize a window-local option
autocmd WinEnter * if !exists('w:created') | setlocal nu | endif

If you want the autocmd for setting the w:created variable to be contained in a given augroup, use the optional group argument to the autocmd, for example:

augroup mygroup
  autocmd VimEnter * autocmd mygroup WinEnter * let w:created=1
augroup END


The same should work using TabEnter and t:created instead of WinEnter and w:created if you want to set up things for each new tab.