Vim Tips Wiki
Tip 231 Printable Monobook Previous Next

created 2002 · complexity basic · author Salman Halim · version 6.0

In a complex project you may be working with many files (buffers) in Vim, or you may be working with many instances of Vim. In addition, you may be working on files in different directories.

It may help to automatically change the color scheme to clearly identify where you are (which file, or which Vim, or which directory) to avoid accidentally changing the wrong file.

Which file[]

When using one instance of Vim to edit multiple files it can be easy to switch to Vim from another application then start typing in the current buffer which may not be for the intended file (requires Esc, undo, go to the other buffer and . to redo).

One way to avoid this is to use a different color scheme depending on the file you are working on:

au BufEnter * if (exists("b:colors_name")) | let b:current_colors=colors_name
 \| execute "colorscheme " . b:colors_name | endif
au BufLeave * if (exists("b:current_colors")) | execute "colorscheme " . b:current_colors | endif

If you define b:colors_name with a particular color scheme name, then the above autocommands will switch to that colorscheme when you enter that window, and will return to the original color upon departure.

Inside ftplugin/java.vim, for example, you might have let b:colors_name=morning, causing all java files to have a distinguishing color scheme.

Which directory[]

When editing files in two different directories, for example when copying code from one file to another, changing the color scheme helps to quickly identify the directory of the current file:

:autocmd BufEnter * if match(@%,'/otherdir/')>=0 | colorscheme oceanblack | else | colorscheme inkpot | end

Register @% contains the name of the current file.

The procedure does not work well for split windows (it might be better to use BufWinEnter instead of BufEnter?).

Which instance[]

On some systems using focus-follows-mouse, it can be convenient to have many instances of Vim running, then select the required instance by pointing with the mouse (no click required).

The following shows the focused Vim with a white background, while the others are dark. That makes it easy to be sure you are typing in the right window.

:autocmd FocusLost * :colorscheme desert
:autocmd FocusGained * :colorscheme default


Proposed variant for Which file, to be pasted in the vimrc or as a global plugin:

if has('autocmd')
	" change colorscheme depending on current buffer
	" if desired, you may set a user-default colorscheme before this point,
	" otherwise we'll use the Vim default.
	" Variables used:
		" g:colors_name : current colorscheme at any moment
		" b:colors_name (if any): colorscheme to be used for the current buffer
		" s:colors_name : default colorscheme, to be used where b:colors_name hasn't been set
	if has('user_commands')
		" User commands defined:
			" ColorScheme <name>
				" set the colorscheme for the current buffer
			" ColorDefault <name>
				" change the default colorscheme
		command -nargs=1 -bar ColorScheme
			\ colorscheme <args>
			\ | let b:colors_name = g:colors_name
		command -nargs=1 -bar ColorDefault
			\ let s:colors_name = <q-args>
			\ | if !exists('b:colors_name')
				\ | colors <args>
			\ | endif
	if !exists('g:colors_name')
		let g:colors_name = 'default'
	let s:colors_name = g:colors_name
	au BufEnter *
		\ let s:new_colors = (exists('b:colors_name')?(b:colors_name):(s:colors_name))
		\ | if s:new_colors != g:colors_name
			\ | exe 'colors' s:new_colors
		\ | endif
  • Advantages:
    • Don't invoke the :colorscheme command if the desired colorscheme is already set
    • When switching between buffers, both of which have b:colors_name set, don't load (even temporarily) the colorscheme which was set before we entered the one we're now leaving
    • Handles the case when no "default colorscheme" is set by the vimrc
    • "Degrades gracefully" when run on feature-poor versions of Vim
  • Caveats and known bugs:

--Tonymec 03:22, September 23, 2009 (UTC)