Using a dictionary instead of a list clarifies the code.
vim-gitgutter
A Vim plugin which shows a git diff in the 'gutter' (sign column). It shows whether each line has been added, modified, and where lines have been removed. You can also stage and revert individual hunks.
Features:
- Shows signs for added, modified, and removed lines.
- Ensures signs are always as up to date as possible (but without running more than necessary).
- Quick jumping between blocks of changed lines ("hunks").
- Stage/revert individual hunks.
- Optional line highlighting.
- Fully customisable (signs, sign column, line highlights, mappings, extra git-diff arguments, etc).
- Can be toggled on/off.
- Preserves signs from other plugins.
- Easy to integrate diff stats into status line; built-in integration with vim-airline.
Constraints:
- Supports git only.
Screenshot
In the screenshot above you can see:
- Line 15 has been modified.
- Lines 21-24 are new.
- A line or lines were removed between lines 25 and 26.
Installation
Before installation, please check your Vim supports signs by running :echo has('signs'). 1 means you're all set; 0 means you need to install a Vim with signs support. If you're compiling Vim yourself you need the 'big' or 'huge' feature set. MacVim supports signs.
If you don't have a preferred installation method, I recommend installing pathogen.vim, and then simply copy and paste:
cd ~/.vim/bundle
git clone git://github.com/airblade/vim-gitgutter.git
Or for Vundle users:
Add Bundle 'airblade/vim-gitgutter' to your ~/.vimrc and then:
- either within Vim:
:BundleInstall - or in your shell:
vim +BundleInstall +qall
Usage
You don't have to do anything: it just works.
With one exception the plugin diffs your saved buffers, i.e. the files on disk. It produces the same result as running git diff on the command line. The exception is realtime updating: in this case the plugin diffs the (unsaved) buffer contents against the version in git.
You can explicitly turn vim-gitgutter off and on (defaults to on):
- turn off with
:GitGutterDisable - turn on with
:GitGutterEnable - toggle with
:GitGutterToggle.
And you can turn line highlighting on and off (defaults to off):
- turn on with
:GitGutterLineHighlightsEnable - turn off with
:GitGutterLineHighlightsDisable - toggle with
:GitGutterLineHighlightsToggle.
Furthermore you can jump between hunks:
- jump to next hunk:
]h - jump to previous hunk:
[h.
Both of those take a preceding count.
To set your own mappings for these, for example gh and gH:
nmap gh <Plug>GitGutterNextHunk
nmap gH <Plug>GitGutterPrevHunk
When your cursor is in a hunk, you can:
- stage the hunk with
<Leader>hsor - revert it with
<Leader>hr.
To set your own mappings for these, for example if you prefer the mnemonics hunk-add and hunk-undo:
nmap <Leader>ha <Plug>GitGutterStageHunk
nmap <Leader>hu <Plug>GitGutterRevertHunk
Finally, you can force vim-gitgutter to update its signs across all visible buffers with :GitGutterAll.
See the customisation section below for how to change the defaults.
When are the signs updated?
By default the signs are updated when you:
- Stop typing (realtime)
- Change buffer (eager)
- Change tab (eager)
- Save a buffer (always)
- Change a file outside Vim (always)
- Focus the GUI (eager but not gVim on Windows).
This can cause a noticeable lag on some systems so you can configure the plugin to update less often. See the customisation section below.
Customisation
You can customise:
- The sign column's colours
- Whether or not the sign column is shown when there aren't any signs (defaults to no)
- The signs' colours and symbols
- Line highlights
- Extra arguments for
git diff - Whether or not to escape
grep(default to no) - Whether or not vim-gitgutter is on initially (defaults to on)
- Whether or not signs are shown (defaults to yes)
- Whether or not line highlighting is on initially (defaults to off)
- Whether or not vim-gitgutter runs in "realtime" (defaults to yes)
- Whether or not vim-gitgutter runs eagerly (defaults to yes)
Please note that vim-gitgutter won't override any colours or highlights you've set in your colorscheme.
Sign column
The background colour of the sign column is controlled by the SignColumn highlight group. This will be either set in your colorscheme or Vim's default.
To find out where it's set, and to what it's set, use :verbose highlight SignColumn.
If your SignColumn is not set (:highlight SignColumn gives you SignColumn xxx cleared), vim-gitgutter will set it to the same as your line number column (i.e. the LineNr highlight group).
To change your sign column's appearance, update your colorscheme or ~/.vimrc like this:
- For the same appearance as your line number column:
highlight clear SignColumn - For a specific appearance on terminal Vim:
highlight SignColumn ctermbg=whatever - For a specific appearance on gVim/MacVim:
highlight SignColumn guibg=whatever
By default the sign column will appear when there are signs to show and disappear when there aren't. If you would always like the sign column to be there, add let g:gitgutter_sign_column_always = 1 to your ~/.vimrc.
Signs' colours and symbols
To customise the colours, set up the following highlight groups in your colorscheme or ~/.vimrc:
GitGutterAdd " an added line
GitGutterChange " a changed line
GitGutterDelete " at least one removed line
GitGutterChangeDelete " a changed line followed by at least one removed line
You can either set these with highlight GitGutterAdd {key}={arg}... or link them to existing highlight groups with, say, highlight link GitGutterAdd DiffAdd.
To customise the symbols, add the following to your ~/.vimrc:
let g:gitgutter_sign_added = 'xx'
let g:gitgutter_sign_modified = 'yy'
let g:gitgutter_sign_removed = 'zz'
let g:gitgutter_sign_modified_removed = 'ww'
Whether or not signs are shown
If you never want signs to be shown (presumably you only want the line highlights), add this to your ~/.vimrc:
let g:gitgutter_signs = 0
Line highlights
Similarly to the signs' colours, set up the following highlight groups in your colorscheme or ~/.vimrc:
GitGutterAddLine " default: links to DiffAdd
GitGutterChangeLine " default: links to DiffChange
GitGutterDeleteLine " default: links to DiffDelete
GitGutterChangeDeleteLine " default: links to GitGutterChangeLineDefault, i.e. DiffChange
Extra arguments for git diff
If you want to pass extra arguments to git diff, for example to ignore whitespace, do so like this:
let g:gitgutter_diff_args = '-w'
Whether or not to escape grep
If you have grep aliased to something which changes its output, for example grep --color=auto -H, you will need to tell vim-gitgutter to use raw grep:
let g:gitgutter_escape_grep = 1
To turn off vim-gitgutter by default
Add let g:gitgutter_enabled = 0 to your ~/.vimrc.
To turn on line highlighting by default
Add let g:gitgutter_highlight_lines = 1 to your ~/.vimrc.
To stop vim-gitgutter running in realtime
By default the plugin runs when you stop typing. The delay is governed by updatetime (Vim's default is 4000ms, i.e. 4 seconds; I prefer 750.)
To turn this off, add the following to your ~/.vimrc:
let g:gitgutter_realtime = 0
To stop vim-gitgutter running eagerly
By default the plugin also runs on BufEnter (to notice git add outside vim), TabEnter and FocusGained.
This can cause a noticeable lag for some people so you can set the plugin to run instead only when you read or write a file.
To turn off eager execution, add this to your ~/.vimrc:
let g:gitgutter_eager = 0
Note that FocusGained is not activated in gVim on Windows due to a Vim/shell bug causing an infinite loop.
The plugin always runs on FileChangedShellPost to notice git stash outside vim.
FAQ
Why are the colours in the sign column weird?
Your colorscheme is configuring the SignColumn highlight group weirdly. Please see the section above on customising the sign column.
There's a noticeable lag when vim-gitter runs; how can I avoid it?
By default vim-gitgutter runs often so the signs are as accurate as possible. However on some systems this causes a noticeable lag. If you would like to trade a little accuracy for speed, add this to your ~/.vimrc:
let g:gitgutter_realtime = 0
let g:gitgutter_eager = 0
Why is no sign shown if I delete the first line(s) in a file?
vim-gitgutter shows removed lines with a sign on the line above. In this case there isn't a line above so vim-gitgutter can't show the sign. In due course I'll fix this with an overline character on the first line.
What happens if I also use another plugin which uses signs (e.g. Syntastic)?
Vim only allows one sign per line. Before adding a sign to a line, vim-gitgutter checks whether a sign has already been added by somebody else. If so it doesn't do anything. In other words vim-gitgutter won't overwrite another plugin's signs. It also won't remove another plugin's signs.
Why aren't any signs showing at all?
Here are some things you can check:
- Your git config is compatible with the version of git which your Vim is calling (
:echo system('git --version')). - Your Vim supports signs (
:echo has('signs')should give1). - Your file is being tracked by git and has unstaged, saved changes.
- If you use the Fish shell, add
set shell=/bin/bashto your~/.vimrc.
Shameless Plug
If this plugin has helped you, or you'd like to learn more about Vim, why not check out these two screencasts I wrote for PeepCode:
You can read reviews at PeepCode and also on my portfolio.
Intellectual Property
Copyright Andrew Stewart, AirBlade Software Ltd. Released under the MIT licence.
