28

If you're familiar with the iTerm2 application, you'll know that you can split views similar to vim, and the inactive views are "dimmed."

I usually work in vim with three vertical split views and it would be nice to dim the inactive ones by setting the background color to a darker tone, for example.

Is there a way to do this?

6 Answers 6

22

I have come up with the following solution (using 'colorcolumn' and unsetting 'cursorline'):

" Dim inactive windows using 'colorcolumn' setting " This tends to slow down redrawing, but is very useful. " Based on https://groups.google.com/d/msg/vim_use/IJU-Vk-QLJE/xz4hjPjCRBUJ " XXX: this will only work with lines containing text (i.e. not '~') function! s:DimInactiveWindows() for i in range(1, tabpagewinnr(tabpagenr(), '$')) let l:range = "" if i != winnr() if &wrap " HACK: when wrapping lines is enabled, we use the maximum number " of columns getting highlighted. This might get calculated by " looking for the longest visible line and using a multiple of " winwidth(). let l:width=256 " max else let l:width=winwidth(i) endif let l:range = join(range(1, l:width), ',') endif call setwinvar(i, '&colorcolumn', l:range) endfor endfunction augroup DimInactiveWindows au! au WinEnter * call s:DimInactiveWindows() au WinEnter * set cursorline au WinLeave * set nocursorline augroup END 

View it at my (current) dotfiles: https://github.com/blueyed/dotfiles/blob/master/vimrc#L351

Update I have created a plugin out of it: https://github.com/blueyed/vim-diminactive

Sign up to request clarification or add additional context in comments.

6 Comments

This might be made more efficient for any machines which are struggling. We don't really need to run for all windows every time we switch window. We just need to perform the setwinvar on any window we WinLeave, and setlocal nocolorcolumn on WinEnter. (That is assuming our session starts with just one window, and we never create multiple windows without entering each of them.)
@AndyRay I have created a plugin out of it: github.com/blueyed/vim-diminactive
I also knocked up a quick-and-dirty plugin, based on your answer: github.com/joeytwiddle/rc_files/blob/master/.vim/plugin/…
@joeytwiddle cool! Would have been good to now, before I've created mine. I would appreciate a pull request, if you want to merge your changes (e.g. ignoring some buftypes, via config).
@blueyed There is almost nothing novel in mine, but of course I will contribute in future if I find any improvements; it's neat that you made a repo. There are three limitations which I image you also suffer: 1. Really long wrapped lines don't get dimmed past column 256. 2. Out-of-bound lines aka "~" lines don't get dimmed. 3. The cursorline highlight masks any useful background highlighting you might have on dimmed windows (e.g. the last cope line in QuickFix, or the current tag line in TagList). I could disable dimming on those windows too, but then only edit windows will be dimmed!
|
13

Throwing this out there as a new answer. https://github.com/TaDaa/vimade fades inactive buffers, preserves syntax highlighting, and can also fade signs. I am the author, but I figure this might be useful to some as a newer alternative. Supports nvim and vim8, 256 color terminals, termguicolors, and gui.

1 Comment

Tried it, loved it, using it. Cheers.
8

In neovim(v0.2.1), the following configuration will dim inactive panes:

hi ActiveWindow ctermbg=16 | hi InactiveWindow ctermbg=233 set winhighlight=Normal:ActiveWindow,NormalNC:InactiveWindow 

3 Comments

Just wanted to add: If you use nvim in a GUI (e.g nvim-qt), replace ctermbg with guibg and use a hex color as a value, e.g. guibg=#E7E7E7.
I think there's a misconception here, you need not use winhighlight at all with neovim, the Normal and NormalNC highlight groups are all you need to specify separate nonactive window background color. You use winhighlight when you want to set different highlight state on specific windows.
I have built this into walh thanks!
1

Changing the background colour as you describe would require different colourschemes for different Vim windows. As far as I know this is not possible, as it is a global setting (see this answer from a few days ago).

As a visual aid to which window is active, I find the statusline is usally sufficient. The highlight groups are different for the active window (hi StatusLine) and any innactive windows (hi StatusLineNC). You could either choose a colourscheme with a very stark constrast between them, or edit your favourite colourscheme.

2 Comments

In addition to a contrasting StatusLine, I find it helpful to set a CursorLine that stands out.
Although this is the answer accepted by the OP, it's actually incorrect. The answer by @blueyed provides a script which, placed in my .vimrc, does effectively change the background colour of inactive buffers (windows). It's a bit of a hack, but it works.
1

As of 2023, the wincolor might be what you're asking for. It sets the background color (the real background color, not hl-Normal) for a window.

Just add these lines to your vimrc

" dim inactive window hi WindowInactive ctermbg=243 # or ctermbg=grey, in case you're not using an 256 color terminal au VimEnter,WinNew,WinEnter * set wincolor= au WinLeave * set wincolor=WindowInactive 

The result looks like alt

Comments

0

I created a colorscheme walh that handles this.

It doesn't do many fancy things, it just uses the terminal colors to do the highlights and dimming. This is nice because if you use tmux that dimming will match.

Looks something like this nvim|nvim(focus)|tmux : enter image description here

Comments