aboutsummaryrefslogtreecommitdiff
path: root/vim/bundle/vim-gitgutter
diff options
context:
space:
mode:
Diffstat (limited to 'vim/bundle/vim-gitgutter')
-rw-r--r--vim/bundle/vim-gitgutter/.gitignore5
-rw-r--r--vim/bundle/vim-gitgutter/README.mkd499
-rw-r--r--vim/bundle/vim-gitgutter/autoload/gitgutter.vim253
-rw-r--r--vim/bundle/vim-gitgutter/autoload/gitgutter/async.vim196
-rw-r--r--vim/bundle/vim-gitgutter/autoload/gitgutter/debug.vim119
-rw-r--r--vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim342
-rw-r--r--vim/bundle/vim-gitgutter/autoload/gitgutter/highlight.vim115
-rw-r--r--vim/bundle/vim-gitgutter/autoload/gitgutter/hunk.vim137
-rw-r--r--vim/bundle/vim-gitgutter/autoload/gitgutter/sign.vim173
-rw-r--r--vim/bundle/vim-gitgutter/autoload/gitgutter/utility.vim199
-rw-r--r--vim/bundle/vim-gitgutter/doc/gitgutter.txt340
-rw-r--r--vim/bundle/vim-gitgutter/plugin/gitgutter.vim224
-rw-r--r--vim/bundle/vim-gitgutter/screenshot.pngbin0 -> 16191 bytes
-rw-r--r--vim/bundle/vim-gitgutter/test/=fixture=.txt0
-rw-r--r--vim/bundle/vim-gitgutter/test/README.markdown30
-rw-r--r--vim/bundle/vim-gitgutter/test/addLines.expected4
-rw-r--r--vim/bundle/vim-gitgutter/test/addLinesFish.expected4
-rw-r--r--vim/bundle/vim-gitgutter/test/ambiguousFile.expected4
-rw-r--r--vim/bundle/vim-gitgutter/test/fileAddedToGit.expected4
-rw-r--r--vim/bundle/vim-gitgutter/test/filenameWithEquals.expected5
-rw-r--r--vim/bundle/vim-gitgutter/test/filenameWithSquareBrackets.expected5
-rw-r--r--vim/bundle/vim-gitgutter/test/fix[tu]re.txt0
-rw-r--r--vim/bundle/vim-gitgutter/test/fixture.txt11
-rw-r--r--vim/bundle/vim-gitgutter/test/followSymlink.expected4
-rw-r--r--vim/bundle/vim-gitgutter/test/helper.vim27
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkHunkOutsideNoopStageGitDiffStaged.expected0
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkHunkOutsideNoopUndoGitDiffStaged.expected0
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkOutsideNoopStageSigns.expected2
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkOutsideNoopUndoSigns.expected2
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkStageGitDiff.expected13
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkStageNearbyGitDiff.expected13
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkStageNearbyGitDiffStaged.expected12
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkStageNearbySigns.expected6
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkStageSigns.expected2
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkUndoGitDiff.expected0
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkUndoNearbyGitDiff.expected13
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkUndoNearbySigns.expected6
-rw-r--r--vim/bundle/vim-gitgutter/test/hunkUndoSigns.expected2
-rw-r--r--vim/bundle/vim-gitgutter/test/keepAlt.expected3
-rw-r--r--vim/bundle/vim-gitgutter/test/keepModified.expected2
-rw-r--r--vim/bundle/vim-gitgutter/test/keepOpMarks.expected4
-rw-r--r--vim/bundle/vim-gitgutter/test/modifyLines.expected4
-rw-r--r--vim/bundle/vim-gitgutter/test/noModifications.expected2
-rw-r--r--vim/bundle/vim-gitgutter/test/orphanedSigns.expected4
-rw-r--r--vim/bundle/vim-gitgutter/test/removeFirstLines.expected4
-rw-r--r--vim/bundle/vim-gitgutter/test/removeLines.expected4
-rw-r--r--vim/bundle/vim-gitgutter/test/signColumnAlways.expected4
-rwxr-xr-xvim/bundle/vim-gitgutter/test/test50
-rw-r--r--vim/bundle/vim-gitgutter/test/testAddLines.vim6
-rw-r--r--vim/bundle/vim-gitgutter/test/testAddLinesFish.vim7
-rw-r--r--vim/bundle/vim-gitgutter/test/testEditAmbiguousFile.vim9
-rw-r--r--vim/bundle/vim-gitgutter/test/testFileAddedToGit.vim12
-rw-r--r--vim/bundle/vim-gitgutter/test/testFilenameWithEquals.vim12
-rw-r--r--vim/bundle/vim-gitgutter/test/testFilenameWithSquareBrackets.vim9
-rw-r--r--vim/bundle/vim-gitgutter/test/testFollowSymlink.vim10
-rw-r--r--vim/bundle/vim-gitgutter/test/testHunkOutsideNoop.vim13
-rw-r--r--vim/bundle/vim-gitgutter/test/testHunkStage.vim7
-rw-r--r--vim/bundle/vim-gitgutter/test/testHunkStageNearbyHunk.vim10
-rw-r--r--vim/bundle/vim-gitgutter/test/testHunkUndo.vim7
-rw-r--r--vim/bundle/vim-gitgutter/test/testHunkUndoNearbyHunk.vim9
-rw-r--r--vim/bundle/vim-gitgutter/test/testKeepAlt.vim12
-rw-r--r--vim/bundle/vim-gitgutter/test/testKeepModified.vim8
-rw-r--r--vim/bundle/vim-gitgutter/test/testKeepOpMarks.vim10
-rw-r--r--vim/bundle/vim-gitgutter/test/testModifyLines.vim6
-rw-r--r--vim/bundle/vim-gitgutter/test/testNoModifications.vim4
-rw-r--r--vim/bundle/vim-gitgutter/test/testOrphanedSigns.vim8
-rw-r--r--vim/bundle/vim-gitgutter/test/testRemoveFirstLines.vim6
-rw-r--r--vim/bundle/vim-gitgutter/test/testRemoveLines.vim6
-rw-r--r--vim/bundle/vim-gitgutter/test/testSignColumnAlways.vim7
-rw-r--r--vim/bundle/vim-gitgutter/test/testUntrackedFileOutsideRepo.vim6
-rw-r--r--vim/bundle/vim-gitgutter/test/testUntrackedFileSquareBracketsWithinRepo.vim10
-rw-r--r--vim/bundle/vim-gitgutter/test/testUntrackedFileWithinRepo.vim10
-rw-r--r--vim/bundle/vim-gitgutter/test/untrackedFileOutsideRepo.expected2
-rw-r--r--vim/bundle/vim-gitgutter/test/untrackedFileSquareBracketsWithinRepo.expected2
-rw-r--r--vim/bundle/vim-gitgutter/test/untrackedFileWithinRepo.expected2
75 files changed, 3062 insertions, 0 deletions
diff --git a/vim/bundle/vim-gitgutter/.gitignore b/vim/bundle/vim-gitgutter/.gitignore
new file mode 100644
index 0000000..82fb253
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/.gitignore
@@ -0,0 +1,5 @@
+/doc/tags
+/misc
+/test/*.actual
+*.log
+
diff --git a/vim/bundle/vim-gitgutter/README.mkd b/vim/bundle/vim-gitgutter/README.mkd
new file mode 100644
index 0000000..6fc92ae
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/README.mkd
@@ -0,0 +1,499 @@
+## 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 undo individual hunks.
+
+Features:
+
+* Shows signs for added, modified, and removed lines.
+* Runs the diffs asynchronously in terminal Vim/MacVim (7.4.1826+), gVim (7.4.1850+), MacVim GUI (7.4.1832+), and NeoVim.
+* 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/undo/preview individual hunks.
+* Provides a hunk text object.
+* Diffs against index (default) or any commit.
+* Handles line endings correctly, even with repos that do CRLF conversion.
+* 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](https://github.com/bling/vim-airline/).
+* Works with fish shell (in addition to the usual shells).
+
+Constraints:
+
+* Supports git only.
+
+If you work with other version control systems, I recommend [vim-signify](https://github.com/mhinz/vim-signify).
+
+
+### Screenshot
+
+![screenshot](https://raw.github.com/airblade/vim-gitgutter/master/screenshot.png)
+
+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.
+
+You install vim-gitgutter like any other vim plugin.
+
+##### Pathogen
+
+```
+cd ~/.vim/bundle
+git clone git://github.com/airblade/vim-gitgutter.git
+```
+
+##### Voom
+
+Edit your plugin manifest (`voom edit`) and add:
+
+```
+airblade/vim-gitgutter
+```
+
+##### VimPlug
+
+Place this in your .vimrc:
+
+```viml
+Plug 'airblade/vim-gitgutter'
+```
+
+Then run the following in Vim:
+
+```
+:source %
+:PlugInstall
+```
+
+##### NeoBundle
+
+Place this in your .vimrc:
+
+```viml
+NeoBundle 'airblade/vim-gitgutter'
+```
+
+Then run the following in Vim:
+
+```
+:source %
+:NeoBundleInstall
+```
+
+##### No plugin manager
+
+Copy vim-gitgutter's subdirectories into your vim configuration directory:
+
+```
+cd /tmp && git clone git://github.com/airblade/vim-gitgutter.git
+cp -r vim-gitgutter/* ~/.vim/
+```
+
+See `:help add-global-plugin`.
+
+
+If you are on Windows you may find the command prompt pops up briefly every time vim-gitgutter runs. You can avoid this by installing both [vim-misc](https://github.com/xolox/vim-misc) and [vim-shell](https://github.com/xolox/vim-shell). If you have those two plugins but don't want vim-gitgutter to use them, you can opt out with `let g:gitgutter_avoid_cmd_prompt_on_windows = 0` in your `~/.vimrc`.
+
+
+### Getting started
+
+When you make a change to a file tracked by git, the diff markers should appear automatically. The delay is governed by vim's `updatetime` option; the default value is 4 seconds but I suggest reducing it to around 250ms (add `set updatetime=250` to your vimrc).
+
+You can jump between hunks with `[c` and `]c`. You can preview, stage, and undo hunks with `<leader>hp`, `<leader>hs`, and `<leader>hu` respectively.
+
+You cannot currently unstage a staged hunk.
+
+
+#### Activation
+
+You can explicitly turn vim-gitgutter off and on (defaults to on):
+
+* turn off with `:GitGutterDisable`
+* turn on with `:GitGutterEnable`
+* toggle with `:GitGutterToggle`.
+
+You can turn the signs on and off (defaults to on):
+
+* turn on with `:GitGutterSignsEnable`
+* turn off with `:GitGutterSignsDisable`
+* toggle with `:GitGutterSignsToggle`.
+
+And you can turn line highlighting on and off (defaults to off):
+
+* turn on with `:GitGutterLineHighlightsEnable`
+* turn off with `:GitGutterLineHighlightsDisable`
+* toggle with `:GitGutterLineHighlightsToggle`.
+
+Note that if you have line highlighting on and signs off, you will have an empty sign column – more accurately, a sign column with invisible signs. This is because line highlighting requires signs and Vim always shows the sign column even if the signs are invisible.
+
+If you switch off both line highlighting and signs, you won't see the sign column. That is unless you have set `let g:gitgutter_sign_column_always = 1` so it's always there.
+
+To keep your Vim snappy, vim-gitgutter will suppress itself when a file has more than 500 changes. As soon as the number of changes falls below the limit vim-gitgutter will show the signs again. You can configure the threshold with:
+
+```viml
+let g:gitgutter_max_signs = 500 " default value
+```
+
+#### Hunks
+
+You can jump between hunks:
+
+* jump to next hunk (change): `]c`
+* jump to previous hunk (change): `[c`.
+
+Both of those take a preceding count.
+
+To set your own mappings for these, for example `]h` and `[h`:
+
+```viml
+nmap ]h <Plug>GitGutterNextHunk
+nmap [h <Plug>GitGutterPrevHunk
+```
+
+You can stage or undo an individual hunk when your cursor is in it:
+
+* stage the hunk with `<Leader>hs` or
+* undo it with `<Leader>hu`.
+
+See the FAQ if you want to unstage staged changes.
+
+The `.` command will work with both these if you install [repeat.vim](https://github.com/tpope/vim-repeat).
+
+To set your own mappings for these, for example if you prefer the mnemonics hunk-add and hunk-revert:
+
+```viml
+nmap <Leader>ha <Plug>GitGutterStageHunk
+nmap <Leader>hr <Plug>GitGutterUndoHunk
+```
+
+And you can preview a hunk's changes with `<Leader>hp`. You can of course change this mapping, e.g:
+
+```viml
+nmap <Leader>hv <Plug>GitGutterPreviewHunk
+```
+
+A hunk text object is provided which works in visual and operator-pending modes.
+
+- `ic` operates on all lines in the current hunk.
+- `ac` operates on all lines in the current hunk and any trailing empty lines.
+
+To re-map these, for example to `ih` and `ah`:
+
+```viml
+omap ih <Plug>GitGutterTextObjectInnerPending
+omap ah <Plug>GitGutterTextObjectOuterPending
+xmap ih <Plug>GitGutterTextObjectInnerVisual
+xmap ah <Plug>GitGutterTextObjectOuterVisual
+```
+
+If you don't want vim-gitgutter to set up any mappings at all, use this:
+
+```viml
+let g:gitgutter_map_keys = 0
+```
+
+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 as follows:
+
+| Event | Reason for update | Configuration |
+|---------------------------|--------------------------------------|------------------------|
+| Stop typing | So the signs are real time | `g:gitgutter_realtime` |
+| Switch buffer | To notice change to git index | `g:gitgutter_eager` |
+| Switch tab | To notice change to git index | `g:gitgutter_eager` |
+| Focus the GUI | To notice change to git index | `g:gitgutter_eager` (not gVim on Windows) |
+| Read a file into a buffer | To display initial signs | [always] |
+| Save a buffer | So non-realtime signs are up to date | [always] |
+| Change a file outside Vim | To notice `git stash` | [always] |
+
+The length of time Vim waits after you stop typing before it triggers the plugin is governed by the setting `updatetime`. This defaults to `4000` milliseconds which is rather too long. I recommend around `250` milliseconds but it depends on your system and your preferences. Note that in terminal Vim pre-7.4.427 an `updatetime` of less than approximately `1000` milliseconds can lead to random highlighting glitches; the lower the `updatetime`, the more glitches.
+
+If you experience a lag, you can trade speed for accuracy:
+
+```viml
+let g:gitgutter_realtime = 0
+let g:gitgutter_eager = 0
+```
+
+Note the realtime updating requires Vim 7.3.105 or higher.
+
+
+### 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
+* The base of the diff
+* Extra arguments for `git diff`
+* Key mappings
+* 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)
+* Whether or not vim-gitgutter runs asynchronously (defaults to yes)
+
+Please note that vim-gitgutter won't override any colours or highlights you've set in your colorscheme.
+
+
+#### Sign column
+
+By default vim-gitgutter will make the sign column look like the line number column.
+
+To customise your sign column's background color, first tell vim-gitgutter to leave it alone:
+
+```viml
+let g:gitgutter_override_sign_column_highlight = 0
+```
+
+And then either update your colorscheme's `SignColumn` highlight group or set it in your vimrc:
+
+```viml
+highlight SignColumn ctermbg=whatever " terminal Vim
+highlight SignColumn guibg=whatever " gVim/MacVim
+```
+
+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`:
+
+```viml
+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`:
+
+```viml
+let g:gitgutter_sign_added = 'xx'
+let g:gitgutter_sign_modified = 'yy'
+let g:gitgutter_sign_removed = 'zz'
+let g:gitgutter_sign_removed_first_line = '^^'
+let g:gitgutter_sign_modified_removed = 'ww'
+```
+
+
+#### Line highlights
+
+Similarly to the signs' colours, set up the following highlight groups in your colorscheme or `~/.vimrc`:
+
+```viml
+GitGutterAddLine " default: links to DiffAdd
+GitGutterChangeLine " default: links to DiffChange
+GitGutterDeleteLine " default: links to DiffDelete
+GitGutterChangeDeleteLine " default: links to GitGutterChangeLineDefault, i.e. DiffChange
+```
+
+
+#### The base of the diff
+
+By default buffers are diffed against the index. However you can diff against any commit by setting:
+
+```viml
+let g:gitgutter_diff_base = '<commit SHA>'
+```
+
+
+#### Extra arguments for `git diff`
+
+If you want to pass extra arguments to `git diff`, for example to ignore whitespace, do so like this:
+
+```viml
+let g:gitgutter_diff_args = '-w'
+```
+
+#### Key mappings
+
+To disable all key mappings:
+
+```viml
+let g:gitgutter_map_keys = 0
+```
+
+See above for configuring maps for hunk-jumping and staging/undoing.
+
+
+#### Use a custom `grep` command
+
+If you use an alternative to grep, or your grep does not support the `color` flag, you can tell vim-gitgutter to use it here. It only needs to support extended POSIX regex.
+
+```viml
+" Default:
+let g:gitgutter_grep_command = 'grep --color=never -e'
+```
+
+#### To turn off vim-gitgutter by default
+
+Add `let g:gitgutter_enabled = 0` to your `~/.vimrc`.
+
+
+#### To turn off signs by default
+
+Add `let g:gitgutter_signs = 0` to your `~/.vimrc`.
+
+
+#### To turn on line highlighting by default
+
+Add `let g:gitgutter_highlight_lines = 1` to your `~/.vimrc`.
+
+
+#### To turn off asynchronous updates
+
+By default diffs are run asynchronously. To run diffs synchronously instead:
+
+```viml
+let g:gitgutter_async = 0
+```
+
+
+### Extensions
+
+#### Operate on every line in a hunk
+
+You can map an operator to do whatever you want to every line in a hunk.
+
+Let's say, for example, you want to remove trailing whitespace.
+
+```viml
+function! CleanUp(...)
+ if a:0 " opfunc
+ let [first, last] = [line("'["), line("']")]
+ else
+ let [first, last] = [line("'<"), line("'>")]
+ endif
+ for lnum in range(first, last)
+ let line = getline(lnum)
+
+ " clean up the text, e.g.:
+ let line = substitute(line, '\s\+$', '', '')
+
+ call setline(lnum, line)
+ endfor
+endfunction
+
+nmap <silent> <Leader>x :set opfunc=CleanUp<CR>g@
+```
+
+Then place your cursor in a hunk and type `\xic` (assuming a leader of `\`).
+
+Alternatively you could place your cursor in a hunk, type `vic` to select it, then `:call CleanUp()`.
+
+
+#### Operate on every changed line in a file
+
+You can write a command to do whatever you want to every changed line in a file.
+
+```viml
+function! GlobalChangedLines(ex_cmd)
+ for hunk in GitGutterGetHunks()
+ for lnum in range(hunk[2], hunk[2]+hunk[3]-1)
+ let cursor = getcurpos()
+ silent! execute lnum.a:ex_cmd
+ call setpos('.', cursor)
+ endfor
+ endfor
+endfunction
+
+command -nargs=1 Glines call GlobalChangedLines(<q-args>)
+```
+
+Let's say, for example, you want to remove trailing whitespace from all changed lines:
+
+```viml
+:Glines s/\s\+$//
+```
+
+
+### FAQ
+
+> Why can't I unstage staged changes?
+
+Unstaging staged hunks is feasible but not quite as easy as it sounds. There are three relevant versions of a file at any one time:
+
+1. The version at HEAD in the repo.
+2. The version staged in the index.
+3. The version in the working tree, in your vim buffer.
+
+`git-diff` without arguments shows you how 3 and 2 differ; this is what vim-gitgutter shows too.
+
+`git-diff --staged` shows you how 2 and 1 differ.
+
+Let's say your are looking at a file in vim which has some unstaged changes. Now you stage a hunk, either via vim-gitgutter or another means. The hunk is no longer marked in vim-gitgutter because it is the same in 3 and 2.
+
+Now you want to unstage that hunk. To see it, you need the difference between 2 and 1. For vim-gitgutter to shows those differences, it would need to show you 2 instead of 3 in your vim buffer. But 2 is virtual so vim-gitgutter would need to handle it without touching 3.
+
+I intend to implement this but I can't commit to any deadline.
+
+> 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. The delay is governed by `updatetime`; see [above](#when-are-the-signs-updated) for more information.
+
+If you don't want realtime updates and would like to trade a little accuracy for speed, add this to your `~/.vimrc`:
+
+```viml
+let g:gitgutter_realtime = 0
+let g:gitgutter_eager = 0
+```
+
+> 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:
+
+* `:echo system("git --version")` succeeds.
+* Your git config is compatible with the version of git returned by the command above.
+* Your Vim supports signs (`:echo has('signs')` should give `1`).
+* Your file is being tracked by git and has unstaged changes.
+* If your grep does not support the `color` flag, add `let g:gitgutter_grep_command = 'grep -e'` to your `~/.vimrc`.
+
+
+### Shameless Plug
+
+If this plugin has helped you, or you'd like to learn more about Vim, why not check out this screencast I wrote for PeepCode:
+
+* [Smash Into Vim][siv]
+
+This was one of PeepCode's all-time top three bestsellers and is now available at Pluralsight.
+
+You can read reviews on my [website][airblade].
+
+
+### Intellectual Property
+
+Copyright Andrew Stewart, AirBlade Software Ltd. Released under the MIT licence.
+
+
+ [pathogen]: https://github.com/tpope/vim-pathogen
+ [siv]: http://pluralsight.com/training/Courses/TableOfContents/smash-into-vim
+ [airblade]: http://airbladesoftware.com/peepcode-vim
+ [macvim]: http://code.google.com/p/macvim/
diff --git a/vim/bundle/vim-gitgutter/autoload/gitgutter.vim b/vim/bundle/vim-gitgutter/autoload/gitgutter.vim
new file mode 100644
index 0000000..3b1770a
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/autoload/gitgutter.vim
@@ -0,0 +1,253 @@
+let s:nomodeline = (v:version > 703 || (v:version == 703 && has('patch442'))) ? '<nomodeline>' : ''
+
+" Primary functions {{{
+
+function! gitgutter#all() abort
+ for buffer_id in tabpagebuflist()
+ let file = expand('#' . buffer_id . ':p')
+ if !empty(file)
+ call gitgutter#process_buffer(buffer_id, 0)
+ endif
+ endfor
+endfunction
+
+" bufnr: (integer) the buffer to process.
+" realtime: (boolean) when truthy, do a realtime diff; otherwise do a disk-based diff.
+function! gitgutter#process_buffer(bufnr, realtime) abort
+ call gitgutter#utility#use_known_shell()
+
+ call gitgutter#utility#set_buffer(a:bufnr)
+ if gitgutter#utility#is_active()
+ if g:gitgutter_sign_column_always
+ call gitgutter#sign#add_dummy_sign()
+ endif
+ try
+ if !a:realtime || gitgutter#utility#has_fresh_changes()
+ let diff = gitgutter#diff#run_diff(a:realtime || gitgutter#utility#has_unsaved_changes(), 0)
+ if diff != 'async'
+ call gitgutter#handle_diff(diff)
+ endif
+ endif
+ catch /diff failed/
+ call gitgutter#debug#log('diff failed')
+ call gitgutter#hunk#reset()
+ endtry
+ execute "silent doautocmd" s:nomodeline "User GitGutter"
+ else
+ call gitgutter#hunk#reset()
+ endif
+
+ call gitgutter#utility#restore_shell()
+endfunction
+
+
+function! gitgutter#handle_diff(diff) abort
+ call gitgutter#debug#log(a:diff)
+
+ call setbufvar(gitgutter#utility#bufnr(), 'gitgutter_tracked', 1)
+
+ call gitgutter#hunk#set_hunks(gitgutter#diff#parse_diff(a:diff))
+ let modified_lines = gitgutter#diff#process_hunks(gitgutter#hunk#hunks())
+
+ if len(modified_lines) > g:gitgutter_max_signs
+ call gitgutter#utility#warn_once('exceeded maximum number of signs (configured by g:gitgutter_max_signs).', 'max_signs')
+ call gitgutter#sign#clear_signs()
+ return
+ endif
+
+ if g:gitgutter_signs || g:gitgutter_highlight_lines
+ call gitgutter#sign#update_signs(modified_lines)
+ endif
+
+ call gitgutter#utility#save_last_seen_change()
+endfunction
+
+function! gitgutter#disable() abort
+ " get list of all buffers (across all tabs)
+ let buflist = []
+ for i in range(tabpagenr('$'))
+ call extend(buflist, tabpagebuflist(i + 1))
+ endfor
+
+ for buffer_id in buflist
+ let file = expand('#' . buffer_id . ':p')
+ if !empty(file)
+ call gitgutter#utility#set_buffer(buffer_id)
+ call gitgutter#sign#clear_signs()
+ call gitgutter#sign#remove_dummy_sign(1)
+ call gitgutter#hunk#reset()
+ endif
+ endfor
+
+ let g:gitgutter_enabled = 0
+endfunction
+
+function! gitgutter#enable() abort
+ let g:gitgutter_enabled = 1
+ call gitgutter#all()
+endfunction
+
+function! gitgutter#toggle() abort
+ if g:gitgutter_enabled
+ call gitgutter#disable()
+ else
+ call gitgutter#enable()
+ endif
+endfunction
+
+" }}}
+
+" Line highlights {{{
+
+function! gitgutter#line_highlights_disable() abort
+ let g:gitgutter_highlight_lines = 0
+ call gitgutter#highlight#define_sign_line_highlights()
+
+ if !g:gitgutter_signs
+ call gitgutter#sign#clear_signs()
+ call gitgutter#sign#remove_dummy_sign(0)
+ endif
+
+ redraw!
+endfunction
+
+function! gitgutter#line_highlights_enable() abort
+ let old_highlight_lines = g:gitgutter_highlight_lines
+
+ let g:gitgutter_highlight_lines = 1
+ call gitgutter#highlight#define_sign_line_highlights()
+
+ if !old_highlight_lines && !g:gitgutter_signs
+ call gitgutter#all()
+ endif
+
+ redraw!
+endfunction
+
+function! gitgutter#line_highlights_toggle() abort
+ if g:gitgutter_highlight_lines
+ call gitgutter#line_highlights_disable()
+ else
+ call gitgutter#line_highlights_enable()
+ endif
+endfunction
+
+" }}}
+
+" Signs {{{
+
+function! gitgutter#signs_enable() abort
+ let old_signs = g:gitgutter_signs
+
+ let g:gitgutter_signs = 1
+ call gitgutter#highlight#define_sign_text_highlights()
+
+ if !old_signs && !g:gitgutter_highlight_lines
+ call gitgutter#all()
+ endif
+endfunction
+
+function! gitgutter#signs_disable() abort
+ let g:gitgutter_signs = 0
+ call gitgutter#highlight#define_sign_text_highlights()
+
+ if !g:gitgutter_highlight_lines
+ call gitgutter#sign#clear_signs()
+ call gitgutter#sign#remove_dummy_sign(0)
+ endif
+endfunction
+
+function! gitgutter#signs_toggle() abort
+ if g:gitgutter_signs
+ call gitgutter#signs_disable()
+ else
+ call gitgutter#signs_enable()
+ endif
+endfunction
+
+" }}}
+
+" Hunks {{{
+
+function! gitgutter#stage_hunk() abort
+ call gitgutter#utility#use_known_shell()
+ if gitgutter#utility#is_active()
+ " Ensure the working copy of the file is up to date.
+ " It doesn't make sense to stage a hunk otherwise.
+ noautocmd silent write
+ let diff = gitgutter#diff#run_diff(0, 1)
+ call gitgutter#handle_diff(diff)
+
+ if empty(gitgutter#hunk#current_hunk())
+ call gitgutter#utility#warn('cursor is not in a hunk')
+ else
+ let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk(diff, 'stage')
+ call gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file(g:gitgutter_git_executable.' apply --cached --unidiff-zero - '), diff_for_hunk)
+
+ " refresh gitgutter's view of buffer
+ silent execute "GitGutter"
+ endif
+
+ silent! call repeat#set("\<Plug>GitGutterStageHunk", -1)<CR>
+ endif
+ call gitgutter#utility#restore_shell()
+endfunction
+
+function! gitgutter#undo_hunk() abort
+ call gitgutter#utility#use_known_shell()
+ if gitgutter#utility#is_active()
+ " Ensure the working copy of the file is up to date.
+ " It doesn't make sense to stage a hunk otherwise.
+ noautocmd silent write
+ let diff = gitgutter#diff#run_diff(0, 1)
+ call gitgutter#handle_diff(diff)
+
+ if empty(gitgutter#hunk#current_hunk())
+ call gitgutter#utility#warn('cursor is not in a hunk')
+ else
+ let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk(diff, 'undo')
+ call gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file(g:gitgutter_git_executable.' apply --reverse --unidiff-zero - '), diff_for_hunk)
+
+ " reload file preserving screen line position
+ let wl = winline()
+ silent edit
+ let offset = wl - winline()
+ execute "normal ".offset."\<C-Y>"
+ endif
+
+ silent! call repeat#set("\<Plug>GitGutterUndoHunk", -1)<CR>
+ endif
+ call gitgutter#utility#restore_shell()
+endfunction
+
+function! gitgutter#preview_hunk() abort
+ call gitgutter#utility#use_known_shell()
+ if gitgutter#utility#is_active()
+ " Ensure the working copy of the file is up to date.
+ " It doesn't make sense to stage a hunk otherwise.
+ noautocmd silent write
+ let diff = gitgutter#diff#run_diff(0, 1)
+ call gitgutter#handle_diff(diff)
+
+ if empty(gitgutter#hunk#current_hunk())
+ call gitgutter#utility#warn('cursor is not in a hunk')
+ else
+ let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk(diff, 'preview')
+
+ silent! wincmd P
+ if !&previewwindow
+ execute 'bo ' . &previewheight . ' new'
+ set previewwindow
+ endif
+
+ setlocal noro modifiable filetype=diff buftype=nofile bufhidden=delete noswapfile
+ execute "%delete_"
+ call append(0, split(diff_for_hunk, "\n"))
+
+ wincmd p
+ endif
+ endif
+ call gitgutter#utility#restore_shell()
+endfunction
+
+" }}}
diff --git a/vim/bundle/vim-gitgutter/autoload/gitgutter/async.vim b/vim/bundle/vim-gitgutter/autoload/gitgutter/async.vim
new file mode 100644
index 0000000..78e725f
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/autoload/gitgutter/async.vim
@@ -0,0 +1,196 @@
+let s:jobs = {}
+
+" Nvim has always supported async commands.
+"
+" Vim introduced async in 7.4.1826.
+"
+" gVim didn't support aync until 7.4.1850 (though I haven't been able to
+" verify this myself).
+"
+" MacVim-GUI didn't support async until 7.4.1832 (actually commit
+" 88f4fe0 but 7.4.1832 was the first subsequent patch release).
+let s:available = has('nvim') || (
+ \ (has('patch-7-4-1826') && !has('gui_running')) ||
+ \ (has('patch-7-4-1850') && has('gui_running')) ||
+ \ (has('patch-7-4-1832') && has('gui_macvim'))
+ \ )
+
+function! gitgutter#async#available()
+ return s:available
+endfunction
+
+function! gitgutter#async#execute(cmd) abort
+ let bufnr = gitgutter#utility#bufnr()
+
+ if has('nvim')
+ if has('unix')
+ let command = ["/bin/sh", "-c", a:cmd]
+ elseif has('win32')
+ let command = ["cmd.exe", "/c", a:cmd]
+ else
+ throw 'unknown os'
+ endif
+ " Make the job use a shell while avoiding (un)quoting problems.
+ let job_id = jobstart(command, {
+ \ 'buffer': bufnr,
+ \ 'on_stdout': function('gitgutter#async#handle_diff_job_nvim'),
+ \ 'on_stderr': function('gitgutter#async#handle_diff_job_nvim'),
+ \ 'on_exit': function('gitgutter#async#handle_diff_job_nvim')
+ \ })
+ call gitgutter#debug#log('[nvim job: '.job_id.', buffer: '.bufnr.'] '.a:cmd)
+ if job_id < 1
+ throw 'diff failed'
+ endif
+
+ " Note that when `cmd` doesn't produce any output, i.e. the diff is empty,
+ " the `stdout` event is not fired on the job handler. Therefore we keep
+ " track of the jobs ourselves so we can spot empty diffs.
+ call s:job_started(job_id)
+
+ else
+ " Make the job use a shell.
+ "
+ " Pass a handler for stdout but not for stderr so that errors are
+ " ignored (and thus signs are not updated; this assumes that an error
+ " only occurs when a file is not tracked by git).
+
+ if has('unix')
+ let command = ["/bin/sh", "-c", a:cmd]
+ elseif has('win32')
+ " Help docs recommend {command} be a string on Windows. But I think
+ " they also say that will run the command directly, which I believe would
+ " mean the redirection and pipe stuff wouldn't work.
+ " let command = "cmd.exe /c ".a:cmd
+ let command = ["cmd.exe", "/c", a:cmd]
+ else
+ throw 'unknown os'
+ endif
+
+ let job = job_start(command, {
+ \ 'out_cb': 'gitgutter#async#handle_diff_job_vim',
+ \ 'close_cb': 'gitgutter#async#handle_diff_job_vim_close'
+ \ })
+ call gitgutter#debug#log('[vim job: '.string(job_info(job)).', buffer: '.bufnr.'] '.a:cmd)
+
+ call s:job_started(s:channel_id(job_getchannel(job)), bufnr)
+ endif
+endfunction
+
+
+function! gitgutter#async#handle_diff_job_nvim(job_id, data, event) abort
+ call gitgutter#debug#log('job_id: '.a:job_id.', event: '.a:event.', buffer: '.self.buffer)
+
+ let current_buffer = gitgutter#utility#bufnr()
+ call gitgutter#utility#set_buffer(self.buffer)
+
+ if a:event == 'stdout'
+ " a:data is a list
+ call s:job_finished(a:job_id)
+ call gitgutter#handle_diff(gitgutter#utility#stringify(a:data))
+
+ elseif a:event == 'exit'
+ " If the exit event is triggered without a preceding stdout event,
+ " the diff was empty.
+ if s:is_job_started(a:job_id)
+ call gitgutter#handle_diff("")
+ call s:job_finished(a:job_id)
+ endif
+
+ else " a:event is stderr
+ call gitgutter#hunk#reset()
+ call s:job_finished(a:job_id)
+
+ endif
+
+ call gitgutter#utility#set_buffer(current_buffer)
+endfunction
+
+
+" Channel is in NL mode.
+function! gitgutter#async#handle_diff_job_vim(channel, line) abort
+ call gitgutter#debug#log('channel: '.a:channel.', line: '.a:line)
+
+ call s:accumulate_job_output(s:channel_id(a:channel), a:line)
+endfunction
+
+function! gitgutter#async#handle_diff_job_vim_close(channel) abort
+ call gitgutter#debug#log('channel: '.a:channel)
+
+ let channel_id = s:channel_id(a:channel)
+
+ let current_buffer = gitgutter#utility#bufnr()
+ call gitgutter#utility#set_buffer(s:job_buffer(channel_id))
+
+ call gitgutter#handle_diff(s:job_output(channel_id))
+ call s:job_finished(channel_id)
+
+ call gitgutter#utility#set_buffer(current_buffer)
+endfunction
+
+
+function! s:channel_id(channel) abort
+ " This seems to be the only way to get info about the channel once closed.
+ return matchstr(a:channel, '\d\+')
+endfunction
+
+
+"
+" Keep track of jobs.
+"
+" nvim: receives all the job's output at once so we don't need to accumulate
+" it ourselves. We can pass the buffer number into the job so we don't need
+" to track that either.
+"
+" s:jobs {} -> key: job's id, value: anything truthy
+"
+" vim: receives the job's output line by line so we need to accumulate it.
+" We also need to keep track of the buffer the job is running for.
+" Vim job's don't have an id. Instead we could use the external process's id
+" or the channel's id (there seems to be 1 channel per job). Arbitrarily
+" choose the channel's id.
+"
+" s:jobs {} -> key: channel's id, value: {} key: output, value: [] job's output
+" key: buffer: value: buffer number
+
+
+" nvim:
+" id: job's id
+"
+" vim:
+" id: channel's id
+" arg: buffer number
+function! s:job_started(id, ...) abort
+ if a:0 " vim
+ let s:jobs[a:id] = {'output': [], 'buffer': a:1}
+ else " nvim
+ let s:jobs[a:id] = 1
+ endif
+endfunction
+
+function! s:is_job_started(id) abort
+ return has_key(s:jobs, a:id)
+endfunction
+
+function! s:accumulate_job_output(id, line) abort
+ call add(s:jobs[a:id].output, a:line)
+endfunction
+
+" Returns a string
+function! s:job_output(id) abort
+ if has_key(s:jobs, a:id)
+ return gitgutter#utility#stringify(s:jobs[a:id].output)
+ else
+ return ""
+ endif
+endfunction
+
+function! s:job_buffer(id) abort
+ return s:jobs[a:id].buffer
+endfunction
+
+function! s:job_finished(id) abort
+ if has_key(s:jobs, a:id)
+ unlet s:jobs[a:id]
+ endif
+endfunction
+
diff --git a/vim/bundle/vim-gitgutter/autoload/gitgutter/debug.vim b/vim/bundle/vim-gitgutter/autoload/gitgutter/debug.vim
new file mode 100644
index 0000000..594f044
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/autoload/gitgutter/debug.vim
@@ -0,0 +1,119 @@
+let s:plugin_dir = expand('<sfile>:p:h:h:h').'/'
+let s:log_file = s:plugin_dir.'gitgutter.log'
+let s:channel_log = s:plugin_dir.'channel.log'
+let s:new_log_session = 1
+
+
+function! gitgutter#debug#debug()
+ " Open a scratch buffer
+ vsplit __GitGutter_Debug__
+ normal! ggdG
+ setlocal buftype=nofile
+ setlocal bufhidden=delete
+ setlocal noswapfile
+
+ call gitgutter#debug#vim_version()
+ call gitgutter#debug#separator()
+
+ call gitgutter#debug#git_version()
+ call gitgutter#debug#separator()
+
+ call gitgutter#debug#grep_version()
+ call gitgutter#debug#separator()
+
+ call gitgutter#debug#option('updatetime')
+ call gitgutter#debug#option('shell')
+ call gitgutter#debug#option('shellcmdflag')
+ call gitgutter#debug#option('shellpipe')
+ call gitgutter#debug#option('shellquote')
+ call gitgutter#debug#option('shellredir')
+ call gitgutter#debug#option('shellslash')
+ call gitgutter#debug#option('shelltemp')
+ call gitgutter#debug#option('shelltype')
+ call gitgutter#debug#option('shellxescape')
+ call gitgutter#debug#option('shellxquote')
+endfunction
+
+
+function! gitgutter#debug#separator()
+ call gitgutter#debug#output('')
+endfunction
+
+function! gitgutter#debug#vim_version()
+ redir => version_info
+ silent execute 'version'
+ redir END
+ call gitgutter#debug#output(split(version_info, '\n')[0:2])
+endfunction
+
+function! gitgutter#debug#git_version()
+ let v = system(g:gitgutter_git_executable.' --version')
+ call gitgutter#debug#output( substitute(v, '\n$', '', '') )
+endfunction
+
+function! gitgutter#debug#grep_version()
+ let v = system('grep --version')
+ call gitgutter#debug#output( substitute(v, '\n$', '', '') )
+
+ let v = system('grep --help')
+ call gitgutter#debug#output( substitute(v, '\%x00', '', 'g') )
+endfunction
+
+function! gitgutter#debug#option(name)
+ if exists('+' . a:name)
+ let v = eval('&' . a:name)
+ call gitgutter#debug#output(a:name . '=' . v)
+ " redir => output
+ " silent execute "verbose set " . a:name . "?"
+ " redir END
+ " call gitgutter#debug#output(a:name . '=' . output)
+ else
+ call gitgutter#debug#output(a:name . ' [n/a]')
+ end
+endfunction
+
+function! gitgutter#debug#output(text)
+ call append(line('$'), a:text)
+endfunction
+
+" assumes optional args are calling function's optional args
+function! gitgutter#debug#log(message, ...) abort
+ if g:gitgutter_log
+ if s:new_log_session && gitgutter#async#available()
+ if exists('*ch_logfile')
+ call ch_logfile(s:channel_log, 'w')
+ endif
+ endif
+
+ execute 'redir >> '.s:log_file
+ if s:new_log_session
+ let s:start = reltime()
+ silent echo "\n==== start log session ===="
+ endif
+
+ let elapsed = reltimestr(reltime(s:start)).' '
+ silent echo ''
+ " callers excluding this function
+ silent echo elapsed.expand('<sfile>')[:-22].':'
+ silent echo elapsed.s:format_for_log(a:message)
+ if a:0 && !empty(a:1)
+ for msg in a:000
+ silent echo elapsed.s:format_for_log(msg)
+ endfor
+ endif
+ redir END
+
+ let s:new_log_session = 0
+ endif
+endfunction
+
+function! s:format_for_log(data) abort
+ if type(a:data) == 1
+ return join(split(a:data,'\n'),"\n")
+ elseif type(a:data) == 3
+ return '['.join(a:data,"\n").']'
+ else
+ return a:data
+ endif
+endfunction
+
diff --git a/vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim b/vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim
new file mode 100644
index 0000000..170193b
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim
@@ -0,0 +1,342 @@
+if exists('g:gitgutter_grep_command')
+ let s:grep_available = 1
+ let s:grep_command = g:gitgutter_grep_command
+else
+ let s:grep_available = executable('grep')
+ if s:grep_available
+ let s:grep_command = 'grep --color=never -e'
+ endif
+endif
+let s:hunk_re = '^@@ -\(\d\+\),\?\(\d*\) +\(\d\+\),\?\(\d*\) @@'
+
+let s:c_flag = gitgutter#utility#git_supports_command_line_config_override()
+
+let s:temp_index = tempname()
+let s:temp_buffer = tempname()
+
+" Returns a diff of the buffer.
+"
+" The way to get the diff depends on whether the buffer is saved or unsaved.
+"
+" * Saved: the buffer contents is the same as the file on disk in the working
+" tree so we simply do:
+"
+" git diff myfile
+"
+" * Unsaved: the buffer contents is not the same as the file on disk so we
+" need to pass two instances of the file to git-diff:
+"
+" git diff myfileA myfileB
+"
+" The first instance is the file in the index which we obtain with:
+"
+" git show :myfile > myfileA
+"
+" The second instance is the buffer contents. Ideally we would pass this to
+" git-diff on stdin via the second argument to vim's system() function.
+" Unfortunately git-diff does not do CRLF conversion for input received on
+" stdin, and git-show never performs CRLF conversion, so repos with CRLF
+" conversion report that every line is modified due to mismatching EOLs.
+"
+" Instead, we write the buffer contents to a temporary file - myfileB in this
+" example. Note the file extension must be preserved for the CRLF
+" conversion to work.
+"
+" Before diffing a buffer for the first time, we check whether git knows about
+" the file:
+"
+" git ls-files --error-unmatch myfile
+"
+" After running the diff we pass it through grep where available to reduce
+" subsequent processing by the plugin. If grep is not available the plugin
+" does the filtering instead.
+function! gitgutter#diff#run_diff(realtime, preserve_full_diff) abort
+ " Wrap compound commands in parentheses to make Windows happy.
+ " bash doesn't mind the parentheses.
+ let cmd = '('
+
+ let bufnr = gitgutter#utility#bufnr()
+ let tracked = getbufvar(bufnr, 'gitgutter_tracked') " i.e. tracked by git
+ if !tracked
+ " Don't bother trying to realtime-diff an untracked file.
+ " NOTE: perhaps we should pull this guard up to the caller?
+ if a:realtime
+ throw 'diff failed'
+ else
+ let cmd .= g:gitgutter_git_executable.' ls-files --error-unmatch '.gitgutter#utility#shellescape(gitgutter#utility#filename()).' && ('
+ endif
+ endif
+
+ if a:realtime
+ let blob_name = g:gitgutter_diff_base.':'.gitgutter#utility#shellescape(gitgutter#utility#file_relative_to_repo_root())
+ let blob_file = s:temp_index
+ let buff_file = s:temp_buffer
+ let extension = gitgutter#utility#extension()
+ if !empty(extension)
+ let blob_file .= '.'.extension
+ let buff_file .= '.'.extension
+ endif
+ let cmd .= g:gitgutter_git_executable.' show '.blob_name.' > '.blob_file.' && '
+
+ " Writing the whole buffer resets the '[ and '] marks and also the
+ " 'modified' flag (if &cpoptions includes '+'). These are unwanted
+ " side-effects so we save and restore the values ourselves.
+ let modified = getbufvar(bufnr, "&mod")
+ let op_mark_start = getpos("'[")
+ let op_mark_end = getpos("']")
+
+ execute 'keepalt noautocmd silent write!' buff_file
+
+ call setbufvar(bufnr, "&mod", modified)
+ call setpos("'[", op_mark_start)
+ call setpos("']", op_mark_end)
+ endif
+
+ let cmd .= g:gitgutter_git_executable
+ if s:c_flag
+ let cmd .= ' -c "diff.autorefreshindex=0"'
+ endif
+ let cmd .= ' diff --no-ext-diff --no-color -U0 '.g:gitgutter_diff_args.' '
+
+ if a:realtime
+ let cmd .= ' -- '.blob_file.' '.buff_file
+ else
+ let cmd .= g:gitgutter_diff_base.' -- '.gitgutter#utility#shellescape(gitgutter#utility#filename())
+ endif
+
+ if !a:preserve_full_diff && s:grep_available
+ let cmd .= ' | '.s:grep_command.' '.gitgutter#utility#shellescape('^@@ ')
+ endif
+
+ if (!a:preserve_full_diff && s:grep_available) || a:realtime
+ " grep exits with 1 when no matches are found; diff exits with 1 when
+ " differences are found. However we want to treat non-matches and
+ " differences as non-erroneous behaviour; so we OR the command with one
+ " which always exits with success (0).
+ let cmd .= ' || exit 0'
+ endif
+
+ let cmd .= ')'
+
+ if !tracked
+ let cmd .= ')'
+ endif
+
+ let cmd = gitgutter#utility#command_in_directory_of_file(cmd)
+
+ if g:gitgutter_async && gitgutter#async#available() && !a:preserve_full_diff
+ call gitgutter#async#execute(cmd)
+ return 'async'
+
+ else
+ let diff = gitgutter#utility#system(cmd)
+
+ if gitgutter#utility#shell_error()
+ " A shell error indicates the file is not tracked by git (unless something bizarre is going on).
+ throw 'diff failed'
+ endif
+
+ return diff
+ endif
+endfunction
+
+function! gitgutter#diff#parse_diff(diff) abort
+ let hunks = []
+ for line in split(a:diff, '\n')
+ let hunk_info = gitgutter#diff#parse_hunk(line)
+ if len(hunk_info) == 4
+ call add(hunks, hunk_info)
+ endif
+ endfor
+ return hunks
+endfunction
+
+function! gitgutter#diff#parse_hunk(line) abort
+ let matches = matchlist(a:line, s:hunk_re)
+ if len(matches) > 0
+ let from_line = str2nr(matches[1])
+ let from_count = (matches[2] == '') ? 1 : str2nr(matches[2])
+ let to_line = str2nr(matches[3])
+ let to_count = (matches[4] == '') ? 1 : str2nr(matches[4])
+ return [from_line, from_count, to_line, to_count]
+ else
+ return []
+ end
+endfunction
+
+function! gitgutter#diff#process_hunks(hunks) abort
+ call gitgutter#hunk#reset()
+ let modified_lines = []
+ for hunk in a:hunks
+ call extend(modified_lines, gitgutter#diff#process_hunk(hunk))
+ endfor
+ return modified_lines
+endfunction
+
+" Returns [ [<line_number (number)>, <name (string)>], ...]
+function! gitgutter#diff#process_hunk(hunk) abort
+ let modifications = []
+ let from_line = a:hunk[0]
+ let from_count = a:hunk[1]
+ let to_line = a:hunk[2]
+ let to_count = a:hunk[3]
+
+ if gitgutter#diff#is_added(from_count, to_count)
+ call gitgutter#diff#process_added(modifications, from_count, to_count, to_line)
+ call gitgutter#hunk#increment_lines_added(to_count)
+
+ elseif gitgutter#diff#is_removed(from_count, to_count)
+ call gitgutter#diff#process_removed(modifications, from_count, to_count, to_line)
+ call gitgutter#hunk#increment_lines_removed(from_count)
+
+ elseif gitgutter#diff#is_modified(from_count, to_count)
+ call gitgutter#diff#process_modified(modifications, from_count, to_count, to_line)
+ call gitgutter#hunk#increment_lines_modified(to_count)
+
+ elseif gitgutter#diff#is_modified_and_added(from_count, to_count)
+ call gitgutter#diff#process_modified_and_added(modifications, from_count, to_count, to_line)
+ call gitgutter#hunk#increment_lines_added(to_count - from_count)
+ call gitgutter#hunk#increment_lines_modified(from_count)
+
+ elseif gitgutter#diff#is_modified_and_removed(from_count, to_count)
+ call gitgutter#diff#process_modified_and_removed(modifications, from_count, to_count, to_line)
+ call gitgutter#hunk#increment_lines_modified(to_count)
+ call gitgutter#hunk#increment_lines_removed(from_count - to_count)
+
+ endif
+ return modifications
+endfunction
+
+function! gitgutter#diff#is_added(from_count, to_count) abort
+ return a:from_count == 0 && a:to_count > 0
+endfunction
+
+function! gitgutter#diff#is_removed(from_count, to_count) abort
+ return a:from_count > 0 && a:to_count == 0
+endfunction
+
+function! gitgutter#diff#is_modified(from_count, to_count) abort
+ return a:from_count > 0 && a:to_count > 0 && a:from_count == a:to_count
+endfunction
+
+function! gitgutter#diff#is_modified_and_added(from_count, to_count) abort
+ return a:from_count > 0 && a:to_count > 0 && a:from_count < a:to_count
+endfunction
+
+function! gitgutter#diff#is_modified_and_removed(from_count, to_count) abort
+ return a:from_count > 0 && a:to_count > 0 && a:from_count > a:to_count
+endfunction
+
+function! gitgutter#diff#process_added(modifications, from_count, to_count, to_line) abort
+ let offset = 0
+ while offset < a:to_count
+ let line_number = a:to_line + offset
+ call add(a:modifications, [line_number, 'added'])
+ let offset += 1
+ endwhile
+endfunction
+
+function! gitgutter#diff#process_removed(modifications, from_count, to_count, to_line) abort
+ if a:to_line == 0
+ call add(a:modifications, [1, 'removed_first_line'])
+ else
+ call add(a:modifications, [a:to_line, 'removed'])
+ endif
+endfunction
+
+function! gitgutter#diff#process_modified(modifications, from_count, to_count, to_line) abort
+ let offset = 0
+ while offset < a:to_count
+ let line_number = a:to_line + offset
+ call add(a:modifications, [line_number, 'modified'])
+ let offset += 1
+ endwhile
+endfunction
+
+function! gitgutter#diff#process_modified_and_added(modifications, from_count, to_count, to_line) abort
+ let offset = 0
+ while offset < a:from_count
+ let line_number = a:to_line + offset
+ call add(a:modifications, [line_number, 'modified'])
+ let offset += 1
+ endwhile
+ while offset < a:to_count
+ let line_number = a:to_line + offset
+ call add(a:modifications, [line_number, 'added'])
+ let offset += 1
+ endwhile
+endfunction
+
+function! gitgutter#diff#process_modified_and_removed(modifications, from_count, to_count, to_line) abort
+ let offset = 0
+ while offset < a:to_count
+ let line_number = a:to_line + offset
+ call add(a:modifications, [line_number, 'modified'])
+ let offset += 1
+ endwhile
+ let a:modifications[-1] = [a:to_line + offset - 1, 'modified_removed']
+endfunction
+
+" Generates a zero-context diff for the current hunk.
+"
+" diff - the full diff for the buffer
+" type - stage | undo | preview
+function! gitgutter#diff#generate_diff_for_hunk(diff, type) abort
+ let diff_for_hunk = gitgutter#diff#discard_hunks(a:diff, a:type == 'stage' || a:type == 'undo')
+
+ if a:type == 'stage' || a:type == 'undo'
+ let diff_for_hunk = gitgutter#diff#adjust_hunk_summary(diff_for_hunk, a:type == 'stage')
+ endif
+
+ return diff_for_hunk
+endfunction
+
+" Returns the diff with all hunks discarded except the current.
+"
+" diff - the diff to process
+" keep_header - truthy to keep the diff header and hunk summary, falsy to discard it
+function! gitgutter#diff#discard_hunks(diff, keep_header) abort
+ let modified_diff = []
+ let keep_line = a:keep_header
+ for line in split(a:diff, '\n')
+ let hunk_info = gitgutter#diff#parse_hunk(line)
+ if len(hunk_info) == 4 " start of new hunk
+ let keep_line = gitgutter#hunk#cursor_in_hunk(hunk_info)
+ endif
+ if keep_line
+ call add(modified_diff, line)
+ endif
+ endfor
+
+ if a:keep_header
+ return gitgutter#utility#stringify(modified_diff)
+ else
+ " Discard hunk summary too.
+ return gitgutter#utility#stringify(modified_diff[1:])
+ endif
+endfunction
+
+" Adjust hunk summary (from's / to's line number) to ignore changes above/before this one.
+"
+" diff_for_hunk - a diff containing only the hunk of interest
+" staging - truthy if the hunk is to be staged, falsy if it is to be undone
+"
+" TODO: push this down to #discard_hunks?
+function! gitgutter#diff#adjust_hunk_summary(diff_for_hunk, staging) abort
+ let line_adjustment = gitgutter#hunk#line_adjustment_for_current_hunk()
+ let adj_diff = []
+ for line in split(a:diff_for_hunk, '\n')
+ if match(line, s:hunk_re) != -1
+ if a:staging
+ " increment 'to' line number
+ let line = substitute(line, '+\@<=\(\d\+\)', '\=submatch(1)+line_adjustment', '')
+ else
+ " decrement 'from' line number
+ let line = substitute(line, '-\@<=\(\d\+\)', '\=submatch(1)-line_adjustment', '')
+ endif
+ endif
+ call add(adj_diff, line)
+ endfor
+ return gitgutter#utility#stringify(adj_diff)
+endfunction
+
diff --git a/vim/bundle/vim-gitgutter/autoload/gitgutter/highlight.vim b/vim/bundle/vim-gitgutter/autoload/gitgutter/highlight.vim
new file mode 100644
index 0000000..e3b774b
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/autoload/gitgutter/highlight.vim
@@ -0,0 +1,115 @@
+function! gitgutter#highlight#define_sign_column_highlight() abort
+ if g:gitgutter_override_sign_column_highlight
+ highlight! link SignColumn LineNr
+ else
+ highlight default link SignColumn LineNr
+ endif
+endfunction
+
+function! gitgutter#highlight#define_highlights() abort
+ let [guibg, ctermbg] = gitgutter#highlight#get_background_colors('SignColumn')
+
+ " Highlights used by the signs.
+
+ execute "highlight GitGutterAddDefault guifg=#009900 guibg=" . guibg . " ctermfg=2 ctermbg=" . ctermbg
+ execute "highlight GitGutterChangeDefault guifg=#bbbb00 guibg=" . guibg . " ctermfg=3 ctermbg=" . ctermbg
+ execute "highlight GitGutterDeleteDefault guifg=#ff2222 guibg=" . guibg . " ctermfg=1 ctermbg=" . ctermbg
+ highlight default link GitGutterChangeDeleteDefault GitGutterChangeDefault
+
+ execute "highlight GitGutterAddInvisible guifg=bg guibg=" . guibg . " ctermfg=" . ctermbg . " ctermbg=" . ctermbg
+ execute "highlight GitGutterChangeInvisible guifg=bg guibg=" . guibg . " ctermfg=" . ctermbg . " ctermbg=" . ctermbg
+ execute "highlight GitGutterDeleteInvisible guifg=bg guibg=" . guibg . " ctermfg=" . ctermbg . " ctermbg=" . ctermbg
+ highlight default link GitGutterChangeDeleteInvisible GitGutterChangeInvisble
+
+ highlight default link GitGutterAdd GitGutterAddDefault
+ highlight default link GitGutterChange GitGutterChangeDefault
+ highlight default link GitGutterDelete GitGutterDeleteDefault
+ highlight default link GitGutterChangeDelete GitGutterChangeDeleteDefault
+
+ " Highlights used for the whole line.
+
+ highlight default link GitGutterAddLine DiffAdd
+ highlight default link GitGutterChangeLine DiffChange
+ highlight default link GitGutterDeleteLine DiffDelete
+ highlight default link GitGutterChangeDeleteLine GitGutterChangeLine
+endfunction
+
+function! gitgutter#highlight#define_signs() abort
+ sign define GitGutterLineAdded
+ sign define GitGutterLineModified
+ sign define GitGutterLineRemoved
+ sign define GitGutterLineRemovedFirstLine
+ sign define GitGutterLineModifiedRemoved
+ sign define GitGutterDummy
+
+ call gitgutter#highlight#define_sign_text()
+ call gitgutter#highlight#define_sign_text_highlights()
+ call gitgutter#highlight#define_sign_line_highlights()
+endfunction
+
+function! gitgutter#highlight#define_sign_text() abort
+ execute "sign define GitGutterLineAdded text=" . g:gitgutter_sign_added
+ execute "sign define GitGutterLineModified text=" . g:gitgutter_sign_modified
+ execute "sign define GitGutterLineRemoved text=" . g:gitgutter_sign_removed
+ execute "sign define GitGutterLineRemovedFirstLine text=" . g:gitgutter_sign_removed_first_line
+ execute "sign define GitGutterLineModifiedRemoved text=" . g:gitgutter_sign_modified_removed
+endfunction
+
+function! gitgutter#highlight#define_sign_text_highlights() abort
+ " Once a sign's text attribute has been defined, it cannot be undefined or
+ " set to an empty value. So to make signs' text disappear (when toggling
+ " off or disabling) we make them invisible by setting their foreground colours
+ " to the background's.
+ if g:gitgutter_signs
+ sign define GitGutterLineAdded texthl=GitGutterAdd
+ sign define GitGutterLineModified texthl=GitGutterChange
+ sign define GitGutterLineRemoved texthl=GitGutterDelete
+ sign define GitGutterLineRemovedFirstLine texthl=GitGutterDelete
+ sign define GitGutterLineModifiedRemoved texthl=GitGutterChangeDelete
+ else
+ sign define GitGutterLineAdded texthl=GitGutterAddInvisible
+ sign define GitGutterLineModified texthl=GitGutterChangeInvisible
+ sign define GitGutterLineRemoved texthl=GitGutterDeleteInvisible
+ sign define GitGutterLineRemovedFirstLine texthl=GitGutterDeleteInvisible
+ sign define GitGutterLineModifiedRemoved texthl=GitGutterChangeDeleteInvisible
+ endif
+endfunction
+
+function! gitgutter#highlight#define_sign_line_highlights() abort
+ if g:gitgutter_highlight_lines
+ sign define GitGutterLineAdded linehl=GitGutterAddLine
+ sign define GitGutterLineModified linehl=GitGutterChangeLine
+ sign define GitGutterLineRemoved linehl=GitGutterDeleteLine
+ sign define GitGutterLineRemovedFirstLine linehl=GitGutterDeleteLine
+ sign define GitGutterLineModifiedRemoved linehl=GitGutterChangeDeleteLine
+ else
+ sign define GitGutterLineAdded linehl=
+ sign define GitGutterLineModified linehl=
+ sign define GitGutterLineRemoved linehl=
+ sign define GitGutterLineRemovedFirstLine linehl=
+ sign define GitGutterLineModifiedRemoved linehl=
+ endif
+endfunction
+
+function! gitgutter#highlight#get_background_colors(group) abort
+ redir => highlight
+ silent execute 'silent highlight ' . a:group
+ redir END
+
+ let link_matches = matchlist(highlight, 'links to \(\S\+\)')
+ if len(link_matches) > 0 " follow the link
+ return gitgutter#highlight#get_background_colors(link_matches[1])
+ endif
+
+ let ctermbg = gitgutter#highlight#match_highlight(highlight, 'ctermbg=\([0-9A-Za-z]\+\)')
+ let guibg = gitgutter#highlight#match_highlight(highlight, 'guibg=\([#0-9A-Za-z]\+\)')
+ return [guibg, ctermbg]
+endfunction
+
+function! gitgutter#highlight#match_highlight(highlight, pattern) abort
+ let matches = matchlist(a:highlight, a:pattern)
+ if len(matches) == 0
+ return 'NONE'
+ endif
+ return matches[1]
+endfunction
diff --git a/vim/bundle/vim-gitgutter/autoload/gitgutter/hunk.vim b/vim/bundle/vim-gitgutter/autoload/gitgutter/hunk.vim
new file mode 100644
index 0000000..0fd0246
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/autoload/gitgutter/hunk.vim
@@ -0,0 +1,137 @@
+let s:hunks = []
+
+function! gitgutter#hunk#set_hunks(hunks) abort
+ let s:hunks = a:hunks
+endfunction
+
+function! gitgutter#hunk#hunks() abort
+ return s:hunks
+endfunction
+
+function! gitgutter#hunk#summary(bufnr) abort
+ return get(getbufvar(a:bufnr,''), 'gitgutter_summary', [0,0,0])
+endfunction
+
+function! gitgutter#hunk#reset() abort
+ call setbufvar(gitgutter#utility#bufnr(), 'gitgutter_summary', [0,0,0])
+endfunction
+
+function! gitgutter#hunk#increment_lines_added(count) abort
+ let bufnr = gitgutter#utility#bufnr()
+ let summary = gitgutter#hunk#summary(bufnr)
+ let summary[0] += a:count
+ call setbufvar(bufnr, 'gitgutter_summary', summary)
+endfunction
+
+function! gitgutter#hunk#increment_lines_modified(count) abort
+ let bufnr = gitgutter#utility#bufnr()
+ let summary = gitgutter#hunk#summary(bufnr)
+ let summary[1] += a:count
+ call setbufvar(bufnr, 'gitgutter_summary', summary)
+endfunction
+
+function! gitgutter#hunk#increment_lines_removed(count) abort
+ let bufnr = gitgutter#utility#bufnr()
+ let summary = gitgutter#hunk#summary(bufnr)
+ let summary[2] += a:count
+ call setbufvar(bufnr, 'gitgutter_summary', summary)
+endfunction
+
+function! gitgutter#hunk#next_hunk(count) abort
+ if gitgutter#utility#is_active()
+ let current_line = line('.')
+ let hunk_count = 0
+ for hunk in s:hunks
+ if hunk[2] > current_line
+ let hunk_count += 1
+ if hunk_count == a:count
+ execute 'normal!' hunk[2] . 'G'
+ return
+ endif
+ endif
+ endfor
+ call gitgutter#utility#warn('No more hunks')
+ endif
+endfunction
+
+function! gitgutter#hunk#prev_hunk(count) abort
+ if gitgutter#utility#is_active()
+ let current_line = line('.')
+ let hunk_count = 0
+ for hunk in reverse(copy(s:hunks))
+ if hunk[2] < current_line
+ let hunk_count += 1
+ if hunk_count == a:count
+ let target = hunk[2] == 0 ? 1 : hunk[2]
+ execute 'normal!' target . 'G'
+ return
+ endif
+ endif
+ endfor
+ call gitgutter#utility#warn('No previous hunks')
+ endif
+endfunction
+
+" Returns the hunk the cursor is currently in or an empty list if the cursor
+" isn't in a hunk.
+function! gitgutter#hunk#current_hunk() abort
+ let current_hunk = []
+
+ for hunk in s:hunks
+ if gitgutter#hunk#cursor_in_hunk(hunk)
+ let current_hunk = hunk
+ break
+ endif
+ endfor
+
+ return current_hunk
+endfunction
+
+function! gitgutter#hunk#cursor_in_hunk(hunk) abort
+ let current_line = line('.')
+
+ if current_line == 1 && a:hunk[2] == 0
+ return 1
+ endif
+
+ if current_line >= a:hunk[2] && current_line < a:hunk[2] + (a:hunk[3] == 0 ? 1 : a:hunk[3])
+ return 1
+ endif
+
+ return 0
+endfunction
+
+" Returns the number of lines the current hunk is offset from where it would
+" be if any changes above it in the file didn't exist.
+function! gitgutter#hunk#line_adjustment_for_current_hunk() abort
+ let adj = 0
+ for hunk in s:hunks
+ if gitgutter#hunk#cursor_in_hunk(hunk)
+ break
+ else
+ let adj += hunk[1] - hunk[3]
+ endif
+ endfor
+ return adj
+endfunction
+
+function! gitgutter#hunk#text_object(inner) abort
+ let hunk = gitgutter#hunk#current_hunk()
+
+ if empty(hunk)
+ return
+ endif
+
+ let [first_line, last_line] = [hunk[2], hunk[2] + hunk[3] - 1]
+
+ if ! a:inner
+ let lnum = last_line
+ let eof = line('$')
+ while lnum < eof && empty(getline(lnum + 1))
+ let lnum +=1
+ endwhile
+ let last_line = lnum
+ endif
+
+ execute 'normal! 'first_line.'GV'.last_line.'G'
+endfunction
diff --git a/vim/bundle/vim-gitgutter/autoload/gitgutter/sign.vim b/vim/bundle/vim-gitgutter/autoload/gitgutter/sign.vim
new file mode 100644
index 0000000..6bd5efa
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/autoload/gitgutter/sign.vim
@@ -0,0 +1,173 @@
+" Vim doesn't namespace sign ids so every plugin shares the same
+" namespace. Sign ids are simply integers so to avoid clashes with other
+" signs we guess at a clear run.
+"
+" Note also we currently never reset s:next_sign_id.
+let s:first_sign_id = 3000
+let s:next_sign_id = s:first_sign_id
+let s:dummy_sign_id = s:first_sign_id - 1
+" Remove-all-signs optimisation requires Vim 7.3.596+.
+let s:supports_star = v:version > 703 || (v:version == 703 && has("patch596"))
+
+
+" Removes gitgutter's signs (excluding dummy sign) from the buffer being processed.
+function! gitgutter#sign#clear_signs() abort
+ let bufnr = gitgutter#utility#bufnr()
+ call gitgutter#sign#find_current_signs()
+
+ let sign_ids = map(values(getbufvar(bufnr, 'gitgutter_gitgutter_signs')), 'v:val.id')
+ call gitgutter#sign#remove_signs(sign_ids, 1)
+ call setbufvar(bufnr, 'gitgutter_gitgutter_signs', {})
+endfunction
+
+
+" Updates gitgutter's signs in the buffer being processed.
+"
+" modified_lines: list of [<line_number (number)>, <name (string)>]
+" where name = 'added|removed|modified|modified_removed'
+function! gitgutter#sign#update_signs(modified_lines) abort
+ call gitgutter#sign#find_current_signs()
+
+ let new_gitgutter_signs_line_numbers = map(copy(a:modified_lines), 'v:val[0]')
+ let obsolete_signs = gitgutter#sign#obsolete_gitgutter_signs_to_remove(new_gitgutter_signs_line_numbers)
+
+ let flicker_possible = s:remove_all_old_signs && !empty(a:modified_lines)
+ if flicker_possible
+ call gitgutter#sign#add_dummy_sign()
+ endif
+
+ call gitgutter#sign#remove_signs(obsolete_signs, s:remove_all_old_signs)
+ call gitgutter#sign#upsert_new_gitgutter_signs(a:modified_lines)
+
+ if flicker_possible
+ call gitgutter#sign#remove_dummy_sign(0)
+ endif
+endfunction
+
+
+function! gitgutter#sign#add_dummy_sign() abort
+ let bufnr = gitgutter#utility#bufnr()
+ if !getbufvar(bufnr, 'gitgutter_dummy_sign')
+ execute "sign place" s:dummy_sign_id "line=" . 9999 "name=GitGutterDummy buffer=" . bufnr
+ call setbufvar(bufnr, 'gitgutter_dummy_sign', 1)
+ endif
+endfunction
+
+function! gitgutter#sign#remove_dummy_sign(force) abort
+ let bufnr = gitgutter#utility#bufnr()
+ if getbufvar(bufnr, 'gitgutter_dummy_sign') && (a:force || !g:gitgutter_sign_column_always)
+ execute "sign unplace" s:dummy_sign_id "buffer=" . bufnr
+ call setbufvar(bufnr, 'gitgutter_dummy_sign', 0)
+ endif
+endfunction
+
+
+"
+" Internal functions
+"
+
+
+function! gitgutter#sign#find_current_signs() abort
+ let bufnr = gitgutter#utility#bufnr()
+ let gitgutter_signs = {} " <line_number (string)>: {'id': <id (number)>, 'name': <name (string)>}
+ let other_signs = [] " [<line_number (number),...]
+ let dummy_sign_placed = 0
+
+ redir => signs
+ silent execute "sign place buffer=" . bufnr
+ redir END
+
+ for sign_line in filter(split(signs, '\n')[2:], 'v:val =~# "="')
+ " Typical sign line: line=88 id=1234 name=GitGutterLineAdded
+ " We assume splitting is faster than a regexp.
+ let components = split(sign_line)
+ let name = split(components[2], '=')[1]
+ if name =~# 'GitGutterDummy'
+ let dummy_sign_placed = 1
+ else
+ let line_number = str2nr(split(components[0], '=')[1])
+ if name =~# 'GitGutter'
+ let id = str2nr(split(components[1], '=')[1])
+ " Remove orphaned signs (signs placed on lines which have been deleted).
+ " (When a line is deleted its sign lingers. Subsequent lines' signs'
+ " line numbers are decremented appropriately.)
+ if has_key(gitgutter_signs, line_number)
+ execute "sign unplace" gitgutter_signs[line_number].id
+ endif
+ let gitgutter_signs[line_number] = {'id': id, 'name': name}
+ else
+ call add(other_signs, line_number)
+ endif
+ end
+ endfor
+
+ call setbufvar(bufnr, 'gitgutter_dummy_sign', dummy_sign_placed)
+ call setbufvar(bufnr, 'gitgutter_gitgutter_signs', gitgutter_signs)
+ call setbufvar(bufnr, 'gitgutter_other_signs', other_signs)
+endfunction
+
+
+" Returns a list of [<id (number)>, ...]
+" Sets `s:remove_all_old_signs` as a side-effect.
+function! gitgutter#sign#obsolete_gitgutter_signs_to_remove(new_gitgutter_signs_line_numbers) abort
+ let bufnr = gitgutter#utility#bufnr()
+ let signs_to_remove = [] " list of [<id (number)>, ...]
+ let remove_all_signs = 1
+ let old_gitgutter_signs = getbufvar(bufnr, 'gitgutter_gitgutter_signs')
+ for line_number in keys(old_gitgutter_signs)
+ if index(a:new_gitgutter_signs_line_numbers, str2nr(line_number)) == -1
+ call add(signs_to_remove, old_gitgutter_signs[line_number].id)
+ else
+ let remove_all_signs = 0
+ endif
+ endfor
+ let s:remove_all_old_signs = remove_all_signs
+ return signs_to_remove
+endfunction
+
+
+function! gitgutter#sign#remove_signs(sign_ids, all_signs) abort
+ let bufnr = gitgutter#utility#bufnr()
+ if a:all_signs && s:supports_star && empty(getbufvar(bufnr, 'gitgutter_other_signs'))
+ let dummy_sign_present = getbufvar(bufnr, 'gitgutter_dummy_sign')
+ execute "sign unplace * buffer=" . bufnr
+ if dummy_sign_present
+ execute "sign place" s:dummy_sign_id "line=" . 9999 "name=GitGutterDummy buffer=" . bufnr
+ endif
+ else
+ for id in a:sign_ids
+ execute "sign unplace" id
+ endfor
+ endif
+endfunction
+
+
+function! gitgutter#sign#upsert_new_gitgutter_signs(modified_lines) abort
+ let bufnr = gitgutter#utility#bufnr()
+ let other_signs = getbufvar(bufnr, 'gitgutter_other_signs')
+ let old_gitgutter_signs = getbufvar(bufnr, 'gitgutter_gitgutter_signs')
+
+ for line in a:modified_lines
+ let line_number = line[0] " <number>
+ if index(other_signs, line_number) == -1 " don't clobber others' signs
+ let name = gitgutter#utility#highlight_name_for_change(line[1])
+ if !has_key(old_gitgutter_signs, line_number) " insert
+ let id = gitgutter#sign#next_sign_id()
+ execute "sign place" id "line=" . line_number "name=" . name "buffer=" . bufnr
+ else " update if sign has changed
+ let old_sign = old_gitgutter_signs[line_number]
+ if old_sign.name !=# name
+ execute "sign place" old_sign.id "name=" . name "buffer=" . bufnr
+ end
+ endif
+ endif
+ endfor
+ " At this point b:gitgutter_gitgutter_signs is out of date.
+endfunction
+
+
+function! gitgutter#sign#next_sign_id() abort
+ let next_id = s:next_sign_id
+ let s:next_sign_id += 1
+ return next_id
+endfunction
diff --git a/vim/bundle/vim-gitgutter/autoload/gitgutter/utility.vim b/vim/bundle/vim-gitgutter/autoload/gitgutter/utility.vim
new file mode 100644
index 0000000..3135453
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/autoload/gitgutter/utility.vim
@@ -0,0 +1,199 @@
+let s:file = ''
+let s:using_xolox_shell = -1
+let s:exit_code = 0
+
+function! gitgutter#utility#warn(message) abort
+ echohl WarningMsg
+ echo 'vim-gitgutter: ' . a:message
+ echohl None
+ let v:warningmsg = a:message
+endfunction
+
+function! gitgutter#utility#warn_once(message, key) abort
+ if empty(getbufvar(s:bufnr, a:key))
+ call setbufvar(s:bufnr, a:key, '1')
+ echohl WarningMsg
+ redraw | echo 'vim-gitgutter: ' . a:message
+ echohl None
+ let v:warningmsg = a:message
+ endif
+endfunction
+
+" Returns truthy when the buffer's file should be processed; and falsey when it shouldn't.
+" This function does not and should not make any system calls.
+function! gitgutter#utility#is_active() abort
+ return g:gitgutter_enabled &&
+ \ !pumvisible() &&
+ \ gitgutter#utility#is_file_buffer() &&
+ \ gitgutter#utility#exists_file() &&
+ \ gitgutter#utility#not_git_dir()
+endfunction
+
+function! gitgutter#utility#not_git_dir() abort
+ return gitgutter#utility#full_path_to_directory_of_file() !~ '[/\\]\.git\($\|[/\\]\)'
+endfunction
+
+function! gitgutter#utility#is_file_buffer() abort
+ return empty(getbufvar(s:bufnr, '&buftype'))
+endfunction
+
+" A replacement for the built-in `shellescape(arg)`.
+"
+" Recent versions of Vim handle shell escaping pretty well. However older
+" versions aren't as good. This attempts to do the right thing.
+"
+" See:
+" https://github.com/tpope/vim-fugitive/blob/8f0b8edfbd246c0026b7a2388e1d883d579ac7f6/plugin/fugitive.vim#L29-L37
+function! gitgutter#utility#shellescape(arg) abort
+ if a:arg =~ '^[A-Za-z0-9_/.-]\+$'
+ return a:arg
+ elseif &shell =~# 'cmd' || gitgutter#utility#using_xolox_shell()
+ return '"' . substitute(substitute(a:arg, '"', '""', 'g'), '%', '"%"', 'g') . '"'
+ else
+ return shellescape(a:arg)
+ endif
+endfunction
+
+function! gitgutter#utility#set_buffer(bufnr) abort
+ let s:bufnr = a:bufnr
+ let s:file = resolve(bufname(a:bufnr))
+endfunction
+
+function! gitgutter#utility#bufnr()
+ return s:bufnr
+endfunction
+
+function! gitgutter#utility#file()
+ return s:file
+endfunction
+
+function! gitgutter#utility#filename() abort
+ return fnamemodify(s:file, ':t')
+endfunction
+
+function! gitgutter#utility#extension() abort
+ return fnamemodify(s:file, ':e')
+endfunction
+
+function! gitgutter#utility#full_path_to_directory_of_file() abort
+ return fnamemodify(s:file, ':p:h')
+endfunction
+
+function! gitgutter#utility#directory_of_file() abort
+ return fnamemodify(s:file, ':h')
+endfunction
+
+function! gitgutter#utility#exists_file() abort
+ return filereadable(s:file)
+endfunction
+
+function! gitgutter#utility#has_unsaved_changes() abort
+ return getbufvar(s:bufnr, "&mod")
+endfunction
+
+function! gitgutter#utility#has_fresh_changes() abort
+ return getbufvar(s:bufnr, 'changedtick') != getbufvar(s:bufnr, 'gitgutter_last_tick')
+endfunction
+
+function! gitgutter#utility#save_last_seen_change() abort
+ call setbufvar(s:bufnr, 'gitgutter_last_tick', getbufvar(s:bufnr, 'changedtick'))
+endfunction
+
+function! gitgutter#utility#shell_error() abort
+ return gitgutter#utility#using_xolox_shell() ? s:exit_code : v:shell_error
+endfunction
+
+function! gitgutter#utility#using_xolox_shell() abort
+ if s:using_xolox_shell == -1
+ if !g:gitgutter_avoid_cmd_prompt_on_windows
+ let s:using_xolox_shell = 0
+ " Although xolox/vim-shell works on both windows and unix we only want to use
+ " it on windows.
+ elseif has('win32') || has('win64') || has('win32unix')
+ let s:using_xolox_shell = exists('g:xolox#misc#version') && exists('g:xolox#shell#version')
+ else
+ let s:using_xolox_shell = 0
+ endif
+ endif
+ return s:using_xolox_shell
+endfunction
+
+function! gitgutter#utility#system(cmd, ...) abort
+ call gitgutter#debug#log(a:cmd, a:000)
+
+ if gitgutter#utility#using_xolox_shell()
+ let options = {'command': a:cmd, 'check': 0}
+ if a:0 > 0
+ let options['stdin'] = a:1
+ endif
+ let ret = xolox#misc#os#exec(options)
+ let output = join(ret.stdout, "\n")
+ let s:exit_code = ret.exit_code
+ else
+ silent let output = (a:0 == 0) ? system(a:cmd) : system(a:cmd, a:1)
+ endif
+ return output
+endfunction
+
+function! gitgutter#utility#file_relative_to_repo_root() abort
+ let file_path_relative_to_repo_root = getbufvar(s:bufnr, 'gitgutter_repo_relative_path')
+ if empty(file_path_relative_to_repo_root)
+ let dir_path_relative_to_repo_root = gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file(g:gitgutter_git_executable.' rev-parse --show-prefix'))
+ let dir_path_relative_to_repo_root = gitgutter#utility#strip_trailing_new_line(dir_path_relative_to_repo_root)
+ let file_path_relative_to_repo_root = dir_path_relative_to_repo_root . gitgutter#utility#filename()
+ call setbufvar(s:bufnr, 'gitgutter_repo_relative_path', file_path_relative_to_repo_root)
+ endif
+ return file_path_relative_to_repo_root
+endfunction
+
+function! gitgutter#utility#command_in_directory_of_file(cmd) abort
+ return 'cd '.gitgutter#utility#shellescape(gitgutter#utility#directory_of_file()).' && '.a:cmd
+endfunction
+
+function! gitgutter#utility#highlight_name_for_change(text) abort
+ if a:text ==# 'added'
+ return 'GitGutterLineAdded'
+ elseif a:text ==# 'removed'
+ return 'GitGutterLineRemoved'
+ elseif a:text ==# 'removed_first_line'
+ return 'GitGutterLineRemovedFirstLine'
+ elseif a:text ==# 'modified'
+ return 'GitGutterLineModified'
+ elseif a:text ==# 'modified_removed'
+ return 'GitGutterLineModifiedRemoved'
+ endif
+endfunction
+
+function! gitgutter#utility#strip_trailing_new_line(line) abort
+ return substitute(a:line, '\n$', '', '')
+endfunction
+
+function! gitgutter#utility#git_version() abort
+ return matchstr(system(g:gitgutter_git_executable.' --version'), '[0-9.]\+')
+endfunction
+
+" True for git v1.7.2+.
+function! gitgutter#utility#git_supports_command_line_config_override() abort
+ let [major, minor, patch; _] = split(gitgutter#utility#git_version(), '\.')
+ return major > 1 || (major == 1 && minor > 7) || (minor == 7 && patch > 1)
+endfunction
+
+function! gitgutter#utility#stringify(list) abort
+ return join(a:list, "\n")."\n"
+endfunction
+
+function! gitgutter#utility#use_known_shell() abort
+ if has('unix')
+ let s:shell = &shell
+ let s:shellcmdflag = &shellcmdflag
+ set shell=/bin/sh
+ set shellcmdflag=-c
+ endif
+endfunction
+
+function! gitgutter#utility#restore_shell() abort
+ if has('unix')
+ let &shell = s:shell
+ let &shellcmdflag = s:shellcmdflag
+ endif
+endfunction
diff --git a/vim/bundle/vim-gitgutter/doc/gitgutter.txt b/vim/bundle/vim-gitgutter/doc/gitgutter.txt
new file mode 100644
index 0000000..d4bb774
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/doc/gitgutter.txt
@@ -0,0 +1,340 @@
+*gitgutter.txt* A Vim plugin which shows a git diff in the gutter.
+
+
+ Vim Git Gutter
+
+
+Author: Andy Stewart <http://airbladesoftware.com/>
+Plugin Homepage: <https://github.com/airblade/vim-gitgutter>
+
+===============================================================================
+CONTENTS *GitGutterContents*
+
+ 1. Introduction ................. |GitGutterIntroduction|
+ 2. Installation ................. |GitGutterInstallation|
+ 3. Usage ........................ |GitGutterUsage|
+ 4. Commands ..................... |GitGutterCommands|
+ 5. Autocommand .................. |GitGutterAutocmd|
+ 6. CUSTOMISATION................. |GitGutterCustomisation|
+ 7. FAQ .......................... |GitGutterFAQ|
+
+===============================================================================
+1. INTRODUCTION *GitGutterIntroduction*
+ *GitGutter*
+
+Vim Git Gutter is 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.
+
+This is a port of the Git Gutter plugin for Sublime Text 2.
+
+===============================================================================
+2. INSTALLATION *GitGutterInstallation*
+
+* Pathogen:
+>
+ cd ~/.vim/bundle
+ git clone git://github.com/airblade/vim-gitgutter.git
+<
+* Voom:
+
+Edit your plugin manifest (`voom edit`) and add:
+>
+ airblade/vim-gitgutter
+<
+* VimPlug:
+
+Place this in your .vimrc:
+>
+ Plug 'airblade/vim-gitgutter'
+<
+Then run the following in Vim:
+>
+ :source %
+ :PlugInstall
+<
+* NeoBundle:
+
+Place this in your .vimrc:
+>
+ NeoBundle 'airblade/vim-gitgutter'
+<
+Then run the following in Vim:
+>
+ :source %
+ :NeoBundleInstall
+<
+* No plugin manager:
+
+Copy vim-gitgutter's subdirectories into your vim configuration directory:
+>
+ cd tmp && git clone git://github.com/airblade/vim-gitgutter.git
+ cp vim-gitgutter/* ~/.vim/
+<
+See |add-global-plugin|.
+
+===============================================================================
+3. USAGE *GitGutterUsage*
+
+You don't have to do anything: it just works.
+
+===============================================================================
+4. COMMANDS *GitGutterCommands*
+
+Commands for turning Git Gutter on and off:
+
+ :GitGutterDisable *:GitGutterDisable*
+ Explicitly turn Git Gutter off.
+
+ :GitGutterEnable *:GitGutterEnable*
+ Explicitly turn Git Gutter on.
+
+ :GitGutterToggle *:GitGutterToggle*
+ Explicitly turn Git Gutter on if it was off and vice versa.
+
+ :GitGutter *:GitGutter*
+ Update signs for the current buffer.
+
+ :GitGutterAll *:GitGutterAll*
+ Update signs across all buffers.
+
+Commands for turning signs on and off (defaults to on):
+
+ :GitGutterSignsEnable *:GitGutterSignsEnable*
+ Explicitly turn line signs on.
+
+ :GitGutterSignsDisable *:GitGutterSignsDisable*
+ Explicitly turn line signs off.
+
+ :GitGutterSignsToggle *:GitGutterSignsToggle*
+ Explicitly turn line signs on if it was off and vice versa.
+
+Commands for turning line highlighting on and off (defaults to off):
+
+ :GitGutterLineHighlightsEnable *:GitGutterLineHighlightsEnable*
+ Explicitly turn line highlighting on.
+
+ :GitGutterLineHighlightsDisable *:GitGutterLineHighlightsDisable*
+ Explicitly turn line highlighting off.
+
+ :GitGutterLineHighlightsToggle *:GitGutterLineHighlightsToggle*
+ Explicitly turn line highlighting on if it was off and vice versa.
+
+Commands for jumping between marked hunks:
+
+ :GitGutterNextHunk *:GitGutterNextHunk*
+ Jump to the next marked hunk. Takes a count.
+
+ :GitGutterPrevHunk *:GitGutterPrevHunk*
+ Jump to the previous marked hunk. Takes a count.
+
+Commands for staging or undoing individual hunks:
+
+ :GitGutterStageHunk *:GitGutterStageHunk*
+ Stage the hunk the cursor is in.
+
+ :GitGutterUndoHunk *:GitGutterUndoHunk*
+ Undo the hunk the cursor is in.
+
+ :GitGutterPreviewHunk *:GitGutterPreviewHunk*
+ Preview the hunk the cursor is in.
+
+===============================================================================
+5. AUTOCOMMAND *GitGutterAutocmd*
+
+After updating a buffer's signs vim-gitgutter fires a |User| |autocmd| with the
+event GitGutter. You can listen for this event, for example:
+>
+ autocmd User GitGutter call updateMyStatusLine()
+<
+
+===============================================================================
+6. CUSTOMISATION *GitGutterCustomisation*
+
+You can customise:
+
+- The sign column's colours
+- The signs' colours and symbols
+- Line highlights
+- The base of the diff
+- Extra arguments for git-diff
+- Key mappings
+- The grep executable used
+- 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)
+- Whether or not vim-gitgutter runs asynchronously (defaults to yes)
+
+Please note that vim-gitgutter won't override any colours or highlights you've
+set in your colorscheme.
+
+SIGN COLUMN
+
+By default vim-gitgutter will make the sign column look like the line number
+column (i.e. the |hl-LineNr| highlight group).
+
+To customise your sign column's background color, first tell vim-gitgutter to
+leave it alone:
+>
+ let g:gitgutter_override_sign_column_highlight = 0
+<
+
+And then either update your colorscheme's |hlSignColumn| highlight group or set
+it in your |vimrc|:
+
+ Desired appearance Command ~
+ Same as line number column highlight clear SignColumn
+ User-defined (terminal Vim) highlight SignColumn ctermbg={whatever}
+ User-defined (graphical Vim) highlight SignColumn guibg={whatever}
+
+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'
+<
+
+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
+<
+
+THE BASE OF THE DIFF
+
+By default buffers are diffed against the index. To diff against a commit
+instead:
+>
+ let g:gitgutter_diff_base = '<commit SHA>'
+<
+
+EXTRA ARGUMENTS FOR GIT-DIFF
+
+To pass extra arguments to git-diff, add this to your |vimrc|:
+>
+ let g:gitgutter_diff_args = '-w'
+<
+
+KEY MAPPINGS
+
+To disable all key maps:
+>
+ let g:gitgutter_map_keys = 0
+<
+
+To change the hunk-jumping maps (defaults shown):
+>
+ nmap [c <Plug>GitGutterPrevHunk
+ nmap ]c <Plug>GitGutterNextHunk
+<
+
+To change the hunk-staging/undoing/previewing maps (defaults shown):
+>
+ nmap <Leader>hs <Plug>GitGutterStageHunk
+ nmap <Leader>hu <Plug>GitGutterUndoHunk
+ nmap <Leader>hp <Plug>GitGutterPreviewHunk
+<
+
+To change the hunk text object maps (defaults shown):
+>
+ omap ic <Plug>GitGutterTextObjectInnerPending
+ omap ac <Plug>GitGutterTextObjectOuterPending
+ xmap ic <Plug>GitGutterTextObjectInnerVisual
+ xmap ac <Plug>GitGutterTextObjectOuterVisual
+<
+
+TO USE A CUSTOM GREP COMMAND
+
+To use a custom invocation for grep, use this:
+>
+ let g:gitgutter_grep_command = 'grep --color=never -e'
+<
+
+TO TURN OFF VIM-GITGUTTER BY DEFAULT
+
+Add to your |vimrc|
+>
+ let g:gitgutter_enabled = 0
+<
+
+TO TURN OFF SIGNS BY DEFAULT
+
+Add to your |vimrc|
+>
+ let g:gitgutter_signs = 0
+<
+
+Note that the sign column will still be present if you have line highlighting
+switched on.
+
+TO TURN ON LINE HIGHLIGHTING BY DEFAULT
+
+Add to your |vimrc|
+>
+ let g:gitgutter_highlight_lines = 1
+<
+
+TO STOP VIM-GITGUTTER RUNNING IN REALTIME
+
+Add to your |vimrc|
+>
+ let g:gitgutter_realtime = 0
+<
+
+TO STOP VIM-GITGUTTER RUNNING EAGERLY
+
+Add to your |vimrc|
+>
+ let g:gitgutter_eager = 0
+<
+
+TO TURN OFF ASYNCHRONOUS UPDATES
+
+By default diffs are run asynchronously. To run diffs synchronously
+instead:
+
+Add to your |vimrc|
+>
+let g:gitgutter_async = 0
+<
+
+===============================================================================
+7. FAQ *GitGutterFAQ*
+
+a. Why are the colours in the sign column weird?
+
+ Your colorscheme is configuring the |hl-SignColumn| highlight group weirdly.
+ Please see |GitGutterCustomisation| on customising the sign column.
+
+b. 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.
diff --git a/vim/bundle/vim-gitgutter/plugin/gitgutter.vim b/vim/bundle/vim-gitgutter/plugin/gitgutter.vim
new file mode 100644
index 0000000..ff87a0a
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/plugin/gitgutter.vim
@@ -0,0 +1,224 @@
+scriptencoding utf-8
+
+if exists('g:loaded_gitgutter') || !has('signs') || &cp
+ finish
+endif
+let g:loaded_gitgutter = 1
+
+" Initialisation {{{
+
+" Realtime sign updates require Vim 7.3.105+.
+if v:version < 703 || (v:version == 703 && !has("patch105"))
+ let g:gitgutter_realtime = 0
+endif
+
+" Eager updates require gettabvar()/settabvar().
+if !exists("*gettabvar")
+ let g:gitgutter_eager = 0
+endif
+
+function! s:set(var, default) abort
+ if !exists(a:var)
+ if type(a:default)
+ execute 'let' a:var '=' string(a:default)
+ else
+ execute 'let' a:var '=' a:default
+ endif
+ endif
+endfunction
+
+call s:set('g:gitgutter_enabled', 1)
+call s:set('g:gitgutter_max_signs', 500)
+call s:set('g:gitgutter_signs', 1)
+call s:set('g:gitgutter_highlight_lines', 0)
+call s:set('g:gitgutter_sign_column_always', 0)
+call s:set('g:gitgutter_override_sign_column_highlight', 1)
+call s:set('g:gitgutter_realtime', 1)
+call s:set('g:gitgutter_eager', 1)
+call s:set('g:gitgutter_sign_added', '+')
+call s:set('g:gitgutter_sign_modified', '~')
+call s:set('g:gitgutter_sign_removed', '_')
+try
+ call s:set('g:gitgutter_sign_removed_first_line', '‾')
+catch /E239/
+ let g:gitgutter_sign_removed_first_line = '_^'
+endtry
+
+call s:set('g:gitgutter_sign_modified_removed', '~_')
+call s:set('g:gitgutter_diff_args', '')
+call s:set('g:gitgutter_diff_base', '')
+call s:set('g:gitgutter_map_keys', 1)
+call s:set('g:gitgutter_avoid_cmd_prompt_on_windows', 1)
+call s:set('g:gitgutter_async', 1)
+call s:set('g:gitgutter_log', 0)
+call s:set('g:gitgutter_git_executable', 'git')
+
+if !executable(g:gitgutter_git_executable)
+ call gitgutter#utility#warn('cannot find git. Please set g:gitgutter_git_executable.')
+endif
+
+call gitgutter#highlight#define_sign_column_highlight()
+call gitgutter#highlight#define_highlights()
+call gitgutter#highlight#define_signs()
+
+" }}}
+
+" Primary functions {{{
+
+command -bar GitGutterAll call gitgutter#all()
+command -bar GitGutter call gitgutter#process_buffer(bufnr(''), 0)
+
+command -bar GitGutterDisable call gitgutter#disable()
+command -bar GitGutterEnable call gitgutter#enable()
+command -bar GitGutterToggle call gitgutter#toggle()
+
+" }}}
+
+" Line highlights {{{
+
+command -bar GitGutterLineHighlightsDisable call gitgutter#line_highlights_disable()
+command -bar GitGutterLineHighlightsEnable call gitgutter#line_highlights_enable()
+command -bar GitGutterLineHighlightsToggle call gitgutter#line_highlights_toggle()
+
+" }}}
+
+" Signs {{{
+
+command -bar GitGutterSignsEnable call gitgutter#signs_enable()
+command -bar GitGutterSignsDisable call gitgutter#signs_disable()
+command -bar GitGutterSignsToggle call gitgutter#signs_toggle()
+
+" }}}
+
+" Hunks {{{
+
+command -bar -count=1 GitGutterNextHunk call gitgutter#hunk#next_hunk(<count>)
+command -bar -count=1 GitGutterPrevHunk call gitgutter#hunk#prev_hunk(<count>)
+
+command -bar GitGutterStageHunk call gitgutter#stage_hunk()
+command -bar GitGutterUndoHunk call gitgutter#undo_hunk()
+command -bar GitGutterRevertHunk echomsg 'GitGutterRevertHunk is deprecated. Use GitGutterUndoHunk'<Bar>call gitgutter#undo_hunk()
+command -bar GitGutterPreviewHunk call gitgutter#preview_hunk()
+
+" Hunk text object
+onoremap <silent> <Plug>GitGutterTextObjectInnerPending :<C-U>call gitgutter#hunk#text_object(1)<CR>
+onoremap <silent> <Plug>GitGutterTextObjectOuterPending :<C-U>call gitgutter#hunk#text_object(0)<CR>
+xnoremap <silent> <Plug>GitGutterTextObjectInnerVisual :<C-U>call gitgutter#hunk#text_object(1)<CR>
+xnoremap <silent> <Plug>GitGutterTextObjectOuterVisual :<C-U>call gitgutter#hunk#text_object(0)<CR>
+
+
+" Returns the git-diff hunks for the file or an empty list if there
+" aren't any hunks.
+"
+" The return value is a list of lists. There is one inner list per hunk.
+"
+" [
+" [from_line, from_count, to_line, to_count],
+" [from_line, from_count, to_line, to_count],
+" ...
+" ]
+"
+" where:
+"
+" `from` - refers to the staged file
+" `to` - refers to the working tree's file
+" `line` - refers to the line number where the change starts
+" `count` - refers to the number of lines the change covers
+function! GitGutterGetHunks()
+ return gitgutter#utility#is_active() ? gitgutter#hunk#hunks() : []
+endfunction
+
+" Returns an array that contains a summary of the hunk status for the current
+" window. The format is [ added, modified, removed ], where each value
+" represents the number of lines added/modified/removed respectively.
+function! GitGutterGetHunkSummary()
+ return gitgutter#hunk#summary(winbufnr(0))
+endfunction
+
+" }}}
+
+command -bar GitGutterDebug call gitgutter#debug#debug()
+
+" Maps {{{
+
+nnoremap <silent> <expr> <Plug>GitGutterNextHunk &diff ? ']c' : ":\<C-U>execute v:count1 . 'GitGutterNextHunk'\<CR>"
+nnoremap <silent> <expr> <Plug>GitGutterPrevHunk &diff ? '[c' : ":\<C-U>execute v:count1 . 'GitGutterPrevHunk'\<CR>"
+
+if g:gitgutter_map_keys
+ if !hasmapto('<Plug>GitGutterPrevHunk') && maparg('[c', 'n') ==# ''
+ nmap [c <Plug>GitGutterPrevHunk
+ endif
+ if !hasmapto('<Plug>GitGutterNextHunk') && maparg(']c', 'n') ==# ''
+ nmap ]c <Plug>GitGutterNextHunk
+ endif
+endif
+
+
+nnoremap <silent> <Plug>GitGutterStageHunk :GitGutterStageHunk<CR>
+nnoremap <silent> <Plug>GitGutterUndoHunk :GitGutterUndoHunk<CR>
+nnoremap <silent> <Plug>GitGutterPreviewHunk :GitGutterPreviewHunk<CR>
+
+if g:gitgutter_map_keys
+ if !hasmapto('<Plug>GitGutterStageHunk') && maparg('<Leader>hs', 'n') ==# ''
+ nmap <Leader>hs <Plug>GitGutterStageHunk
+ endif
+ if !hasmapto('<Plug>GitGutterUndoHunk') && maparg('<Leader>hu', 'n') ==# ''
+ nmap <Leader>hu <Plug>GitGutterUndoHunk
+ nmap <Leader>hr <Plug>GitGutterUndoHunk:echomsg '<Leader>hr is deprecated. Use <Leader>hu'<CR>
+ endif
+ if !hasmapto('<Plug>GitGutterPreviewHunk') && maparg('<Leader>hp', 'n') ==# ''
+ nmap <Leader>hp <Plug>GitGutterPreviewHunk
+ endif
+
+ if !hasmapto('<Plug>GitGutterTextObjectInnerPending') && maparg('ic', 'o') ==# ''
+ omap ic <Plug>GitGutterTextObjectInnerPending
+ endif
+ if !hasmapto('<Plug>GitGutterTextObjectOuterPending') && maparg('ac', 'o') ==# ''
+ omap ac <Plug>GitGutterTextObjectOuterPending
+ endif
+ if !hasmapto('<Plug>GitGutterTextObjectInnerVisual') && maparg('ic', 'x') ==# ''
+ xmap ic <Plug>GitGutterTextObjectInnerVisual
+ endif
+ if !hasmapto('<Plug>GitGutterTextObjectOuterVisual') && maparg('ac', 'x') ==# ''
+ xmap ac <Plug>GitGutterTextObjectOuterVisual
+ endif
+endif
+
+" }}}
+
+" Autocommands {{{
+
+augroup gitgutter
+ autocmd!
+
+ if g:gitgutter_realtime
+ autocmd CursorHold,CursorHoldI * call gitgutter#process_buffer(bufnr(''), 1)
+ endif
+
+ if g:gitgutter_eager
+ autocmd BufEnter,BufWritePost,FileChangedShellPost *
+ \ if gettabvar(tabpagenr(), 'gitgutter_didtabenter') |
+ \ call settabvar(tabpagenr(), 'gitgutter_didtabenter', 0) |
+ \ else |
+ \ call gitgutter#process_buffer(bufnr(''), 0) |
+ \ endif
+ autocmd TabEnter *
+ \ call settabvar(tabpagenr(), 'gitgutter_didtabenter', 1) |
+ \ call gitgutter#all()
+ if !has('gui_win32')
+ autocmd FocusGained * call gitgutter#all()
+ endif
+ else
+ autocmd BufRead,BufWritePost,FileChangedShellPost * call gitgutter#process_buffer(bufnr(''), 0)
+ endif
+
+ autocmd ColorScheme * call gitgutter#highlight#define_sign_column_highlight() | call gitgutter#highlight#define_highlights()
+
+ " Disable during :vimgrep
+ autocmd QuickFixCmdPre *vimgrep* let g:gitgutter_enabled = 0
+ autocmd QuickFixCmdPost *vimgrep* let g:gitgutter_enabled = 1
+augroup END
+
+" }}}
+
+" vim:set et sw=2 fdm=marker:
diff --git a/vim/bundle/vim-gitgutter/screenshot.png b/vim/bundle/vim-gitgutter/screenshot.png
new file mode 100644
index 0000000..6b50f83
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/screenshot.png
Binary files differ
diff --git a/vim/bundle/vim-gitgutter/test/=fixture=.txt b/vim/bundle/vim-gitgutter/test/=fixture=.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/=fixture=.txt
diff --git a/vim/bundle/vim-gitgutter/test/README.markdown b/vim/bundle/vim-gitgutter/test/README.markdown
new file mode 100644
index 0000000..2be0c37
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/README.markdown
@@ -0,0 +1,30 @@
+## Testing vim-gitgutter
+
+### Run the tests
+
+```sh
+$ cd test
+$ ./test
+```
+
+### Add a new test
+
+- Add a test file named like `testFoo.vim`. It should have this structure:
+
+```viml
+source helper.vim
+call Setup()
+
+" test code here
+```
+
+- Run the tests.
+- Inspect output (in `foo.actual`) from the new test. If good, copy it to `foo.expected`.
+- Run the tests to ensure new test's output is verified.
+- Commit changes.
+
+### Limitations
+
+- Currently tests are done by writing out a file and comparing it to a known good one.
+- There's no support for assertions within the testcase code.
+
diff --git a/vim/bundle/vim-gitgutter/test/addLines.expected b/vim/bundle/vim-gitgutter/test/addLines.expected
new file mode 100644
index 0000000..8e2c2ec
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/addLines.expected
@@ -0,0 +1,4 @@
+
+--- Signs ---
+Signs for fixture.txt:
+ line=2 id=3000 name=GitGutterLineAdded
diff --git a/vim/bundle/vim-gitgutter/test/addLinesFish.expected b/vim/bundle/vim-gitgutter/test/addLinesFish.expected
new file mode 100644
index 0000000..8e2c2ec
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/addLinesFish.expected
@@ -0,0 +1,4 @@
+
+--- Signs ---
+Signs for fixture.txt:
+ line=2 id=3000 name=GitGutterLineAdded
diff --git a/vim/bundle/vim-gitgutter/test/ambiguousFile.expected b/vim/bundle/vim-gitgutter/test/ambiguousFile.expected
new file mode 100644
index 0000000..1cd4e89
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/ambiguousFile.expected
@@ -0,0 +1,4 @@
+
+--- Signs ---
+Signs for fixture.txt:
+ line=5 id=3000 name=GitGutterLineModified
diff --git a/vim/bundle/vim-gitgutter/test/fileAddedToGit.expected b/vim/bundle/vim-gitgutter/test/fileAddedToGit.expected
new file mode 100644
index 0000000..bfd8eeb
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/fileAddedToGit.expected
@@ -0,0 +1,4 @@
+
+--- Signs ---
+Signs for fileAddedToGit.tmp:
+ line=1 id=3000 name=GitGutterLineAdded
diff --git a/vim/bundle/vim-gitgutter/test/filenameWithEquals.expected b/vim/bundle/vim-gitgutter/test/filenameWithEquals.expected
new file mode 100644
index 0000000..a78b977
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/filenameWithEquals.expected
@@ -0,0 +1,5 @@
+
+--- Signs ---
+Signs for =fixture=.txt:
+ line=1 id=3000 name=GitGutterLineAdded
+ line=2 id=3001 name=GitGutterLineAdded
diff --git a/vim/bundle/vim-gitgutter/test/filenameWithSquareBrackets.expected b/vim/bundle/vim-gitgutter/test/filenameWithSquareBrackets.expected
new file mode 100644
index 0000000..18f3022
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/filenameWithSquareBrackets.expected
@@ -0,0 +1,5 @@
+
+--- Signs ---
+Signs for fix[tu]re.txt:
+ line=1 id=3000 name=GitGutterLineAdded
+ line=2 id=3001 name=GitGutterLineAdded
diff --git a/vim/bundle/vim-gitgutter/test/fix[tu]re.txt b/vim/bundle/vim-gitgutter/test/fix[tu]re.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/fix[tu]re.txt
diff --git a/vim/bundle/vim-gitgutter/test/fixture.txt b/vim/bundle/vim-gitgutter/test/fixture.txt
new file mode 100644
index 0000000..f5c6aff
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/fixture.txt
@@ -0,0 +1,11 @@
+a
+b
+c
+d
+e
+f
+g
+h
+i
+j
+
diff --git a/vim/bundle/vim-gitgutter/test/followSymlink.expected b/vim/bundle/vim-gitgutter/test/followSymlink.expected
new file mode 100644
index 0000000..8f8fb4a
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/followSymlink.expected
@@ -0,0 +1,4 @@
+
+--- Signs ---
+Signs for symlink:
+ line=5 id=3000 name=GitGutterLineRemoved
diff --git a/vim/bundle/vim-gitgutter/test/helper.vim b/vim/bundle/vim-gitgutter/test/helper.vim
new file mode 100644
index 0000000..aaccf39
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/helper.vim
@@ -0,0 +1,27 @@
+set runtimepath+=../
+source ../plugin/gitgutter.vim
+
+function! Setup()
+ edit! fixture.txt
+ sign unplace *
+endfunction
+
+function! DumpSigns(filename)
+ execute 'redir! > ' a:filename.'.actual'
+ silent execute 'sign place'
+ redir END
+endfunction
+
+function! DumpGitDiff(filename)
+ call system('git diff fixture.txt > '.a:filename.'.actual')
+endfunction
+
+function! DumpGitDiffStaged(filename)
+ call system('git diff --staged fixture.txt > '.a:filename.'.actual')
+endfunction
+
+function! Dump(text, filename)
+ let msg = type(a:text) == 1 ? split(a:text, '\n') : a:text
+ call writefile(msg, a:filename.'.actual', 'a')
+endfunction
+
diff --git a/vim/bundle/vim-gitgutter/test/hunkHunkOutsideNoopStageGitDiffStaged.expected b/vim/bundle/vim-gitgutter/test/hunkHunkOutsideNoopStageGitDiffStaged.expected
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkHunkOutsideNoopStageGitDiffStaged.expected
diff --git a/vim/bundle/vim-gitgutter/test/hunkHunkOutsideNoopUndoGitDiffStaged.expected b/vim/bundle/vim-gitgutter/test/hunkHunkOutsideNoopUndoGitDiffStaged.expected
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkHunkOutsideNoopUndoGitDiffStaged.expected
diff --git a/vim/bundle/vim-gitgutter/test/hunkOutsideNoopStageSigns.expected b/vim/bundle/vim-gitgutter/test/hunkOutsideNoopStageSigns.expected
new file mode 100644
index 0000000..aa8cd86
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkOutsideNoopStageSigns.expected
@@ -0,0 +1,2 @@
+
+--- Signs ---
diff --git a/vim/bundle/vim-gitgutter/test/hunkOutsideNoopUndoSigns.expected b/vim/bundle/vim-gitgutter/test/hunkOutsideNoopUndoSigns.expected
new file mode 100644
index 0000000..aa8cd86
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkOutsideNoopUndoSigns.expected
@@ -0,0 +1,2 @@
+
+--- Signs ---
diff --git a/vim/bundle/vim-gitgutter/test/hunkStageGitDiff.expected b/vim/bundle/vim-gitgutter/test/hunkStageGitDiff.expected
new file mode 100644
index 0000000..6f6a7fa
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkStageGitDiff.expected
@@ -0,0 +1,13 @@
+diff --git a/test/fixture.txt b/test/fixture.txt
+index f5c6aff..ae8e546 100644
+--- a/test/fixture.txt
++++ b/test/fixture.txt
+@@ -2,7 +2,7 @@ a
+ b
+ c
+ d
+-e
++*e
+ f
+ g
+ h
diff --git a/vim/bundle/vim-gitgutter/test/hunkStageNearbyGitDiff.expected b/vim/bundle/vim-gitgutter/test/hunkStageNearbyGitDiff.expected
new file mode 100644
index 0000000..6a0b7f0
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkStageNearbyGitDiff.expected
@@ -0,0 +1,13 @@
+diff --git a/test/fixture.txt b/test/fixture.txt
+index 53b13df..8fdfda7 100644
+--- a/test/fixture.txt
++++ b/test/fixture.txt
+@@ -1,5 +1,8 @@
+ a
+ b
++x
++y
++z
+ c
+ e
+ f
diff --git a/vim/bundle/vim-gitgutter/test/hunkStageNearbyGitDiffStaged.expected b/vim/bundle/vim-gitgutter/test/hunkStageNearbyGitDiffStaged.expected
new file mode 100644
index 0000000..8806576
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkStageNearbyGitDiffStaged.expected
@@ -0,0 +1,12 @@
+diff --git a/test/fixture.txt b/test/fixture.txt
+index f5c6aff..53b13df 100644
+--- a/test/fixture.txt
++++ b/test/fixture.txt
+@@ -1,7 +1,6 @@
+ a
+ b
+ c
+-d
+ e
+ f
+ g
diff --git a/vim/bundle/vim-gitgutter/test/hunkStageNearbySigns.expected b/vim/bundle/vim-gitgutter/test/hunkStageNearbySigns.expected
new file mode 100644
index 0000000..edfebd2
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkStageNearbySigns.expected
@@ -0,0 +1,6 @@
+
+--- Signs ---
+Signs for fixture.txt:
+ line=3 id=3000 name=GitGutterLineAdded
+ line=4 id=3001 name=GitGutterLineAdded
+ line=5 id=3002 name=GitGutterLineAdded
diff --git a/vim/bundle/vim-gitgutter/test/hunkStageSigns.expected b/vim/bundle/vim-gitgutter/test/hunkStageSigns.expected
new file mode 100644
index 0000000..aa8cd86
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkStageSigns.expected
@@ -0,0 +1,2 @@
+
+--- Signs ---
diff --git a/vim/bundle/vim-gitgutter/test/hunkUndoGitDiff.expected b/vim/bundle/vim-gitgutter/test/hunkUndoGitDiff.expected
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkUndoGitDiff.expected
diff --git a/vim/bundle/vim-gitgutter/test/hunkUndoNearbyGitDiff.expected b/vim/bundle/vim-gitgutter/test/hunkUndoNearbyGitDiff.expected
new file mode 100644
index 0000000..d480c7b
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkUndoNearbyGitDiff.expected
@@ -0,0 +1,13 @@
+diff --git a/test/fixture.txt b/test/fixture.txt
+index f5c6aff..3fbde56 100644
+--- a/test/fixture.txt
++++ b/test/fixture.txt
+@@ -1,5 +1,8 @@
+ a
+ b
++x
++y
++z
+ c
+ d
+ e
diff --git a/vim/bundle/vim-gitgutter/test/hunkUndoNearbySigns.expected b/vim/bundle/vim-gitgutter/test/hunkUndoNearbySigns.expected
new file mode 100644
index 0000000..edfebd2
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkUndoNearbySigns.expected
@@ -0,0 +1,6 @@
+
+--- Signs ---
+Signs for fixture.txt:
+ line=3 id=3000 name=GitGutterLineAdded
+ line=4 id=3001 name=GitGutterLineAdded
+ line=5 id=3002 name=GitGutterLineAdded
diff --git a/vim/bundle/vim-gitgutter/test/hunkUndoSigns.expected b/vim/bundle/vim-gitgutter/test/hunkUndoSigns.expected
new file mode 100644
index 0000000..aa8cd86
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/hunkUndoSigns.expected
@@ -0,0 +1,2 @@
+
+--- Signs ---
diff --git a/vim/bundle/vim-gitgutter/test/keepAlt.expected b/vim/bundle/vim-gitgutter/test/keepAlt.expected
new file mode 100644
index 0000000..feee7b5
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/keepAlt.expected
@@ -0,0 +1,3 @@
+buffer: fixture.txt
+altbuffer:
+altbuffer:
diff --git a/vim/bundle/vim-gitgutter/test/keepModified.expected b/vim/bundle/vim-gitgutter/test/keepModified.expected
new file mode 100644
index 0000000..57a1bbf
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/keepModified.expected
@@ -0,0 +1,2 @@
+modified: 1
+modified: 1
diff --git a/vim/bundle/vim-gitgutter/test/keepOpMarks.expected b/vim/bundle/vim-gitgutter/test/keepOpMarks.expected
new file mode 100644
index 0000000..ed6b8c3
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/keepOpMarks.expected
@@ -0,0 +1,4 @@
+'[ mark: 0,6,1,0
+'] mark: 0,6,2,0
+'[ mark: 0,6,1,0
+'] mark: 0,6,2,0
diff --git a/vim/bundle/vim-gitgutter/test/modifyLines.expected b/vim/bundle/vim-gitgutter/test/modifyLines.expected
new file mode 100644
index 0000000..91ad42c
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/modifyLines.expected
@@ -0,0 +1,4 @@
+
+--- Signs ---
+Signs for fixture.txt:
+ line=1 id=3000 name=GitGutterLineModified
diff --git a/vim/bundle/vim-gitgutter/test/noModifications.expected b/vim/bundle/vim-gitgutter/test/noModifications.expected
new file mode 100644
index 0000000..aa8cd86
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/noModifications.expected
@@ -0,0 +1,2 @@
+
+--- Signs ---
diff --git a/vim/bundle/vim-gitgutter/test/orphanedSigns.expected b/vim/bundle/vim-gitgutter/test/orphanedSigns.expected
new file mode 100644
index 0000000..1beeb65
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/orphanedSigns.expected
@@ -0,0 +1,4 @@
+
+--- Signs ---
+Signs for fixture.txt:
+ line=6 id=3001 name=GitGutterLineAdded
diff --git a/vim/bundle/vim-gitgutter/test/removeFirstLines.expected b/vim/bundle/vim-gitgutter/test/removeFirstLines.expected
new file mode 100644
index 0000000..1cbfd76
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/removeFirstLines.expected
@@ -0,0 +1,4 @@
+
+--- Signs ---
+Signs for fixture.txt:
+ line=1 id=3000 name=GitGutterLineRemovedFirstLine
diff --git a/vim/bundle/vim-gitgutter/test/removeLines.expected b/vim/bundle/vim-gitgutter/test/removeLines.expected
new file mode 100644
index 0000000..94d8ee4
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/removeLines.expected
@@ -0,0 +1,4 @@
+
+--- Signs ---
+Signs for fixture.txt:
+ line=4 id=3000 name=GitGutterLineRemoved
diff --git a/vim/bundle/vim-gitgutter/test/signColumnAlways.expected b/vim/bundle/vim-gitgutter/test/signColumnAlways.expected
new file mode 100644
index 0000000..aeda456
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/signColumnAlways.expected
@@ -0,0 +1,4 @@
+
+--- Signs ---
+Signs for fixture.txt:
+ line=9999 id=2999 name=GitGutterDummy
diff --git a/vim/bundle/vim-gitgutter/test/test b/vim/bundle/vim-gitgutter/test/test
new file mode 100755
index 0000000..5c2d877
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/test
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+
+VIM="/Applications/MacVim.app/Contents/MacOS/Vim -v"
+
+status=0
+
+# Execute the tests.
+for editor in "$VIM" nvim; do
+
+ for testcase in test*.vim; do
+ $editor -N -u NONE --cmd 'let g:gitgutter_async=0' -S $testcase -c 'quit!'
+
+ git reset HEAD fixture.txt > /dev/null
+ git checkout fixture.txt
+ done
+
+ # Verify the results.
+ echo "$editor:"
+ echo
+
+ count_ok=0
+ count_fail=0
+
+ for expected in *.expected; do
+ name=${expected%.*}
+ actual=$name.actual
+
+ if diff $expected $actual; then
+ count_ok=$((count_ok + 1))
+ echo "$name ok"
+ rm $actual
+ else
+ count_fail=$((count_fail + 1))
+ echo "$name failed"
+ fi
+ done
+
+ # Print results.
+ echo
+ echo "$((count_ok + count_fail)) tests"
+ echo "$count_ok ok"
+ echo "$count_fail failed"
+ echo
+
+ status=$(($status + $count_fail))
+
+done
+
+exit $status
+
diff --git a/vim/bundle/vim-gitgutter/test/testAddLines.vim b/vim/bundle/vim-gitgutter/test/testAddLines.vim
new file mode 100644
index 0000000..6b0ec4a
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testAddLines.vim
@@ -0,0 +1,6 @@
+source helper.vim
+call Setup()
+
+normal ggo*
+write
+call DumpSigns('addLines')
diff --git a/vim/bundle/vim-gitgutter/test/testAddLinesFish.vim b/vim/bundle/vim-gitgutter/test/testAddLinesFish.vim
new file mode 100644
index 0000000..f1c6bab
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testAddLinesFish.vim
@@ -0,0 +1,7 @@
+set shell=/usr/local/bin/fish
+source helper.vim
+call Setup()
+
+normal ggo*
+write
+call DumpSigns('addLinesFish')
diff --git a/vim/bundle/vim-gitgutter/test/testEditAmbiguousFile.vim b/vim/bundle/vim-gitgutter/test/testEditAmbiguousFile.vim
new file mode 100644
index 0000000..693ecf7
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testEditAmbiguousFile.vim
@@ -0,0 +1,9 @@
+source helper.vim
+call Setup()
+
+normal 5Gi*
+call system('git checkout -b fixture.txt')
+write
+call DumpSigns('ambiguousFile')
+
+call system('git checkout - && git branch -d fixture.txt')
diff --git a/vim/bundle/vim-gitgutter/test/testFileAddedToGit.vim b/vim/bundle/vim-gitgutter/test/testFileAddedToGit.vim
new file mode 100644
index 0000000..91a2c14
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testFileAddedToGit.vim
@@ -0,0 +1,12 @@
+source helper.vim
+
+let tmpfile = 'fileAddedToGit.tmp'
+call system('touch '.tmpfile)
+call system('git add '.tmpfile)
+execute 'edit '.tmpfile
+normal ihello
+write
+call DumpSigns('fileAddedToGit')
+
+call system('git reset HEAD '.tmpfile)
+call system('rm '.tmpfile)
diff --git a/vim/bundle/vim-gitgutter/test/testFilenameWithEquals.vim b/vim/bundle/vim-gitgutter/test/testFilenameWithEquals.vim
new file mode 100644
index 0000000..082ff02
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testFilenameWithEquals.vim
@@ -0,0 +1,12 @@
+source helper.vim
+
+edit =fixture=.txt
+normal ggo*
+try
+ write
+ write
+ call DumpSigns('filenameWithEquals')
+finally
+ call system('git reset HEAD =fixture=.txt')
+ call system('git checkout =fixture=.txt')
+endtry
diff --git a/vim/bundle/vim-gitgutter/test/testFilenameWithSquareBrackets.vim b/vim/bundle/vim-gitgutter/test/testFilenameWithSquareBrackets.vim
new file mode 100644
index 0000000..85ae889
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testFilenameWithSquareBrackets.vim
@@ -0,0 +1,9 @@
+source helper.vim
+
+edit fix[tu]re.txt
+normal ggo*
+write
+call DumpSigns('filenameWithSquareBrackets')
+
+call system('git reset HEAD fix[tu]re.txt')
+call system('git checkout fix[tu]re.txt')
diff --git a/vim/bundle/vim-gitgutter/test/testFollowSymlink.vim b/vim/bundle/vim-gitgutter/test/testFollowSymlink.vim
new file mode 100644
index 0000000..fda33ec
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testFollowSymlink.vim
@@ -0,0 +1,10 @@
+source helper.vim
+
+let tmpfile = 'symlink'
+call system('ln -nfs fixture.txt '.tmpfile)
+execute 'edit '.tmpfile
+execute '6d'
+write
+call DumpSigns('followSymlink')
+
+call system('rm '.tmpfile)
diff --git a/vim/bundle/vim-gitgutter/test/testHunkOutsideNoop.vim b/vim/bundle/vim-gitgutter/test/testHunkOutsideNoop.vim
new file mode 100644
index 0000000..6601e6d
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testHunkOutsideNoop.vim
@@ -0,0 +1,13 @@
+source helper.vim
+call Setup()
+
+normal 5G
+
+execute 'GitGutterStageHunk'
+call DumpSigns('hunkOutsideNoopStageSigns')
+call DumpGitDiffStaged('hunkHunkOutsideNoopStageGitDiffStaged')
+
+execute 'GitGutterUndoHunk'
+call DumpSigns('hunkOutsideNoopUndoSigns')
+call DumpGitDiffStaged('hunkHunkOutsideNoopUndoGitDiffStaged')
+
diff --git a/vim/bundle/vim-gitgutter/test/testHunkStage.vim b/vim/bundle/vim-gitgutter/test/testHunkStage.vim
new file mode 100644
index 0000000..6f818fb
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testHunkStage.vim
@@ -0,0 +1,7 @@
+source helper.vim
+call Setup()
+
+normal 5Gi*
+execute 'GitGutterStageHunk'
+call DumpSigns('hunkStageSigns')
+call DumpGitDiffStaged('hunkStageGitDiff')
diff --git a/vim/bundle/vim-gitgutter/test/testHunkStageNearbyHunk.vim b/vim/bundle/vim-gitgutter/test/testHunkStageNearbyHunk.vim
new file mode 100644
index 0000000..9939103
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testHunkStageNearbyHunk.vim
@@ -0,0 +1,10 @@
+source helper.vim
+call Setup()
+
+execute "normal! 2Gox\<CR>y\<CR>z"
+normal 2jdd
+normal k
+execute 'GitGutterStageHunk'
+call DumpSigns('hunkStageNearbySigns')
+call DumpGitDiff('hunkStageNearbyGitDiff')
+call DumpGitDiffStaged('hunkStageNearbyGitDiffStaged')
diff --git a/vim/bundle/vim-gitgutter/test/testHunkUndo.vim b/vim/bundle/vim-gitgutter/test/testHunkUndo.vim
new file mode 100644
index 0000000..9d187a7
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testHunkUndo.vim
@@ -0,0 +1,7 @@
+source helper.vim
+call Setup()
+
+normal 5Gi*
+execute 'GitGutterUndoHunk'
+call DumpSigns('hunkUndoSigns')
+call DumpGitDiffStaged('hunkUndoGitDiff')
diff --git a/vim/bundle/vim-gitgutter/test/testHunkUndoNearbyHunk.vim b/vim/bundle/vim-gitgutter/test/testHunkUndoNearbyHunk.vim
new file mode 100644
index 0000000..5721f2d
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testHunkUndoNearbyHunk.vim
@@ -0,0 +1,9 @@
+source helper.vim
+call Setup()
+
+execute "normal! 2Gox\<CR>y\<CR>z"
+normal 2jdd
+normal k
+execute 'GitGutterUndoHunk'
+call DumpSigns('hunkUndoNearbySigns')
+call DumpGitDiff('hunkUndoNearbyGitDiff')
diff --git a/vim/bundle/vim-gitgutter/test/testKeepAlt.vim b/vim/bundle/vim-gitgutter/test/testKeepAlt.vim
new file mode 100644
index 0000000..303ff0f
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testKeepAlt.vim
@@ -0,0 +1,12 @@
+source helper.vim
+call Setup()
+
+enew
+execute "normal! \<C-^>"
+call Dump('buffer: '.bufname(''), 'keepAlt')
+call Dump('altbuffer: '.bufname('#'), 'keepAlt')
+
+normal ggx
+doautocmd CursorHold
+call Dump('altbuffer: '.bufname('#'), 'keepAlt')
+
diff --git a/vim/bundle/vim-gitgutter/test/testKeepModified.vim b/vim/bundle/vim-gitgutter/test/testKeepModified.vim
new file mode 100644
index 0000000..acb687f
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testKeepModified.vim
@@ -0,0 +1,8 @@
+source helper.vim
+call Setup()
+
+normal 5Go*
+call Dump("modified: ".getbufvar('', '&modified'), 'keepModified')
+doautocmd CursorHold
+call Dump("modified: ".getbufvar('', '&modified'), 'keepModified')
+
diff --git a/vim/bundle/vim-gitgutter/test/testKeepOpMarks.vim b/vim/bundle/vim-gitgutter/test/testKeepOpMarks.vim
new file mode 100644
index 0000000..1175c80
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testKeepOpMarks.vim
@@ -0,0 +1,10 @@
+source helper.vim
+call Setup()
+
+normal 5Go*
+call Dump("'[ mark: ".join(getpos("'["), ','), 'keepOpMarks')
+call Dump("'] mark: ".join(getpos("']"), ','), 'keepOpMarks')
+doautocmd CursorHold
+call Dump("'[ mark: ".join(getpos("'["), ','), 'keepOpMarks')
+call Dump("'] mark: ".join(getpos("']"), ','), 'keepOpMarks')
+
diff --git a/vim/bundle/vim-gitgutter/test/testModifyLines.vim b/vim/bundle/vim-gitgutter/test/testModifyLines.vim
new file mode 100644
index 0000000..d4a3d01
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testModifyLines.vim
@@ -0,0 +1,6 @@
+source helper.vim
+call Setup()
+
+normal ggi*
+write
+call DumpSigns('modifyLines')
diff --git a/vim/bundle/vim-gitgutter/test/testNoModifications.vim b/vim/bundle/vim-gitgutter/test/testNoModifications.vim
new file mode 100644
index 0000000..909639f
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testNoModifications.vim
@@ -0,0 +1,4 @@
+source helper.vim
+call Setup()
+
+call DumpSigns('noModifications')
diff --git a/vim/bundle/vim-gitgutter/test/testOrphanedSigns.vim b/vim/bundle/vim-gitgutter/test/testOrphanedSigns.vim
new file mode 100644
index 0000000..35992d2
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testOrphanedSigns.vim
@@ -0,0 +1,8 @@
+source helper.vim
+call Setup()
+
+execute "normal 5GoX\<CR>Y"
+write
+execute '6d'
+write
+call DumpSigns('orphanedSigns')
diff --git a/vim/bundle/vim-gitgutter/test/testRemoveFirstLines.vim b/vim/bundle/vim-gitgutter/test/testRemoveFirstLines.vim
new file mode 100644
index 0000000..4a29a73
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testRemoveFirstLines.vim
@@ -0,0 +1,6 @@
+source helper.vim
+call Setup()
+
+execute '1d'
+write
+call DumpSigns('removeFirstLines')
diff --git a/vim/bundle/vim-gitgutter/test/testRemoveLines.vim b/vim/bundle/vim-gitgutter/test/testRemoveLines.vim
new file mode 100644
index 0000000..23d672b
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testRemoveLines.vim
@@ -0,0 +1,6 @@
+source helper.vim
+call Setup()
+
+execute '5d'
+write
+call DumpSigns('removeLines')
diff --git a/vim/bundle/vim-gitgutter/test/testSignColumnAlways.vim b/vim/bundle/vim-gitgutter/test/testSignColumnAlways.vim
new file mode 100644
index 0000000..ff3eb94
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testSignColumnAlways.vim
@@ -0,0 +1,7 @@
+source helper.vim
+call Setup()
+
+let g:gitgutter_sign_column_always=1
+write
+
+call DumpSigns('signColumnAlways')
diff --git a/vim/bundle/vim-gitgutter/test/testUntrackedFileOutsideRepo.vim b/vim/bundle/vim-gitgutter/test/testUntrackedFileOutsideRepo.vim
new file mode 100644
index 0000000..f473d35
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testUntrackedFileOutsideRepo.vim
@@ -0,0 +1,6 @@
+source helper.vim
+
+let tmpfile = tempname()
+call system('touch '.tmpfile)
+execute 'edit '.tmpfile
+call DumpSigns('untrackedFileOutsideRepo')
diff --git a/vim/bundle/vim-gitgutter/test/testUntrackedFileSquareBracketsWithinRepo.vim b/vim/bundle/vim-gitgutter/test/testUntrackedFileSquareBracketsWithinRepo.vim
new file mode 100644
index 0000000..b1fd48a
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testUntrackedFileSquareBracketsWithinRepo.vim
@@ -0,0 +1,10 @@
+source helper.vim
+
+let tmpfile = '[un]trackedFileWithinRepo.tmp'
+call system('touch '.tmpfile)
+execute 'edit '.tmpfile
+normal ggo*
+doautocmd CursorHold
+call DumpSigns('untrackedFileSquareBracketsWithinRepo')
+
+call system('rm '.tmpfile)
diff --git a/vim/bundle/vim-gitgutter/test/testUntrackedFileWithinRepo.vim b/vim/bundle/vim-gitgutter/test/testUntrackedFileWithinRepo.vim
new file mode 100644
index 0000000..4fdd48e
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/testUntrackedFileWithinRepo.vim
@@ -0,0 +1,10 @@
+source helper.vim
+
+let tmpfile = 'untrackedFileWithinRepo.tmp'
+call system('touch '.tmpfile)
+execute 'edit '.tmpfile
+normal ggo*
+doautocmd CursorHold
+call DumpSigns('untrackedFileWithinRepo')
+
+call system('rm '.tmpfile)
diff --git a/vim/bundle/vim-gitgutter/test/untrackedFileOutsideRepo.expected b/vim/bundle/vim-gitgutter/test/untrackedFileOutsideRepo.expected
new file mode 100644
index 0000000..aa8cd86
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/untrackedFileOutsideRepo.expected
@@ -0,0 +1,2 @@
+
+--- Signs ---
diff --git a/vim/bundle/vim-gitgutter/test/untrackedFileSquareBracketsWithinRepo.expected b/vim/bundle/vim-gitgutter/test/untrackedFileSquareBracketsWithinRepo.expected
new file mode 100644
index 0000000..aa8cd86
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/untrackedFileSquareBracketsWithinRepo.expected
@@ -0,0 +1,2 @@
+
+--- Signs ---
diff --git a/vim/bundle/vim-gitgutter/test/untrackedFileWithinRepo.expected b/vim/bundle/vim-gitgutter/test/untrackedFileWithinRepo.expected
new file mode 100644
index 0000000..aa8cd86
--- /dev/null
+++ b/vim/bundle/vim-gitgutter/test/untrackedFileWithinRepo.expected
@@ -0,0 +1,2 @@
+
+--- Signs ---