FIX: gitgutter
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							@@ -148,3 +148,6 @@
 | 
			
		||||
[submodule "vim/plugins/fzf"]
 | 
			
		||||
	path = vim/plugins/fzf
 | 
			
		||||
	url = git://github.com/junegunn/fzf.vim
 | 
			
		||||
[submodule "vim/plugins/vim-markdown"]
 | 
			
		||||
	path = vim/plugins/vim-markdown
 | 
			
		||||
	url = https://github.com/plasticboy/vim-markdown.git
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								vim/plugins/vim-gitgutter/.github/issue_template.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vim/plugins/vim-gitgutter/.github/issue_template.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
> What is the latest commit SHA in your installed vim-gitgutter?
 | 
			
		||||
 | 
			
		||||
> What vim/nvim version are you on?
 | 
			
		||||
 | 
			
		||||
> If no signs are showing at all, what does `:echo b:gitgutter.path` give?
 | 
			
		||||
 | 
			
		||||
> If no signs are showing at all, and the `path` value is a path and not `-2`, does it work with `let g:gitgutter_grep=''`?
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								vim/plugins/vim-gitgutter/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vim/plugins/vim-gitgutter/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
/doc/tags
 | 
			
		||||
/misc
 | 
			
		||||
/test/*.actual
 | 
			
		||||
*.log
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								vim/plugins/vim-gitgutter/LICENCE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vim/plugins/vim-gitgutter/LICENCE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
MIT License
 | 
			
		||||
 | 
			
		||||
Copyright (c) Andrew Stewart
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
SOFTWARE.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										538
									
								
								vim/plugins/vim-gitgutter/README.mkd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										538
									
								
								vim/plugins/vim-gitgutter/README.mkd
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,538 @@
 | 
			
		||||
## vim-gitgutter
 | 
			
		||||
 | 
			
		||||
A Vim plugin which shows a git diff in the 'gutter' (sign column).  It shows which lines have been added, modified, or removed.  You can also preview, stage, and undo individual hunks.  The plugin also provides a hunk text object.
 | 
			
		||||
 | 
			
		||||
The signs are always up to date and the plugin never saves your buffer.
 | 
			
		||||
 | 
			
		||||
Features:
 | 
			
		||||
 | 
			
		||||
* Shows signs for added, modified, and removed lines.
 | 
			
		||||
* Runs the diffs asynchronously where possible.
 | 
			
		||||
* Ensures signs are always up to date.
 | 
			
		||||
* 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).
 | 
			
		||||
* Relies on the `FocusGained` event.  If your terminal doesn't report focus events, either use something like [Terminus][] or set `let g:gitgutter_terminal_reports_focus=0`.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Screenshot
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
In the screenshot above you can see:
 | 
			
		||||
 | 
			
		||||
* Line 15 has been modified.
 | 
			
		||||
* Lines 21-24 are new.
 | 
			
		||||
* A line or lines were removed between lines 25 and 26.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Installation
 | 
			
		||||
 | 
			
		||||
Before installation, please check your Vim supports signs by running `:echo has('signs')`.  `1` means you're all set; `0` means you need to install a Vim with signs support.  If you're compiling Vim yourself you need the 'big' or 'huge' feature set.  MacVim supports signs.
 | 
			
		||||
 | 
			
		||||
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`.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 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 `4000`, i.e. 4 seconds, but I suggest reducing it to around 100ms (add `set updatetime=100` 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 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 configure the sign column always to be there (see Sign Column section).
 | 
			
		||||
 | 
			
		||||
To keep your Vim snappy, vim-gitgutter will suppress the signs 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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 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.  To always have the sign column, add to your vimrc:
 | 
			
		||||
 | 
			
		||||
```viml
 | 
			
		||||
if exists('&signcolumn')  " Vim 7.4.2201
 | 
			
		||||
  set signcolumn=yes
 | 
			
		||||
else
 | 
			
		||||
  let g:gitgutter_sign_column_always = 1
 | 
			
		||||
endif
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### 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, you can tell vim-gitgutter to use it here.
 | 
			
		||||
 | 
			
		||||
```viml
 | 
			
		||||
" Default:
 | 
			
		||||
let g:gitgutter_grep = 'grep'
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### 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\+$//
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### Cycle through hunks in all buffers
 | 
			
		||||
 | 
			
		||||
`]c` and `[c` jump from one hunk to the next in the current buffer.  You can use this code to jump to the next hunk no matter which buffer it's in.
 | 
			
		||||
 | 
			
		||||
```viml
 | 
			
		||||
function! NextHunkAllBuffers()
 | 
			
		||||
  let line = line('.')
 | 
			
		||||
  GitGutterNextHunk
 | 
			
		||||
  if line('.') != line
 | 
			
		||||
    return
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  let bufnr = bufnr('')
 | 
			
		||||
  while 1
 | 
			
		||||
    bnext
 | 
			
		||||
    if bufnr('') == bufnr
 | 
			
		||||
      return
 | 
			
		||||
    endif
 | 
			
		||||
    if !empty(GitGutterGetHunks())
 | 
			
		||||
      normal! 1G
 | 
			
		||||
      GitGutterNextHunk
 | 
			
		||||
      return
 | 
			
		||||
    endif
 | 
			
		||||
  endwhile
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! PrevHunkAllBuffers()
 | 
			
		||||
  let line = line('.')
 | 
			
		||||
  GitGutterPrevHunk
 | 
			
		||||
  if line('.') != line
 | 
			
		||||
    return
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  let bufnr = bufnr('')
 | 
			
		||||
  while 1
 | 
			
		||||
    bprevious
 | 
			
		||||
    if bufnr('') == bufnr
 | 
			
		||||
      return
 | 
			
		||||
    endif
 | 
			
		||||
    if !empty(GitGutterGetHunks())
 | 
			
		||||
      normal! G
 | 
			
		||||
      GitGutterPrevHunk
 | 
			
		||||
      return
 | 
			
		||||
    endif
 | 
			
		||||
  endwhile
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
nmap <silent> ]c :call NextHunkAllBuffers()<CR>
 | 
			
		||||
nmap <silent> [c :call PrevHunkAllBuffers()<CR>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### FAQ
 | 
			
		||||
 | 
			
		||||
> How can I turn off realtime updates?
 | 
			
		||||
 | 
			
		||||
Add this to your vim configuration (in an `/after/plugin` directory):
 | 
			
		||||
 | 
			
		||||
```viml
 | 
			
		||||
" .vim/after/plugin/gitgutter.vim
 | 
			
		||||
autocmd! gitgutter CursorHold,CursorHoldI
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
> I turned off realtime updates, how can I have signs updated when I save a file?
 | 
			
		||||
 | 
			
		||||
If you really want to update the signs when you save a file, add this to your vimrc:
 | 
			
		||||
 | 
			
		||||
```viml
 | 
			
		||||
autocmd BufWritePost * GitGutter
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
> Why can't I unstage staged changes?
 | 
			
		||||
 | 
			
		||||
This plugin is for showing changes between the working tree and the index (and staging/undoing those changes).  Unstaging a staged hunk would require showing changes between the index and HEAD, which is out of scope.
 | 
			
		||||
 | 
			
		||||
> 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.
 | 
			
		||||
 | 
			
		||||
> 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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Troubleshooting
 | 
			
		||||
 | 
			
		||||
#### When no signs are showing at all
 | 
			
		||||
 | 
			
		||||
Here are some things you can check:
 | 
			
		||||
 | 
			
		||||
* Try adding `let g:gitgutter_grep=''` to your vimrc.  If it works, the problem is grep producing non-plain output; e.g. ANSI escape codes or colours.
 | 
			
		||||
* Verify `:echo system("git --version")` succeeds.
 | 
			
		||||
* Verify your git config is compatible with the version of git returned by the command above.
 | 
			
		||||
* Verify your Vim supports signs (`:echo has('signs')` should give `1`).
 | 
			
		||||
* Verify your file is being tracked by git and has unstaged changes.
 | 
			
		||||
 | 
			
		||||
#### When the whole file is marked as added
 | 
			
		||||
 | 
			
		||||
* If you use zsh, and you set `CDPATH`, make sure `CDPATH` doesn't include the current directory.
 | 
			
		||||
 | 
			
		||||
#### When signs take a few seconds to appear
 | 
			
		||||
 | 
			
		||||
* Try reducing `updatetime`, e.g. `set updatetime=100`.
 | 
			
		||||
 | 
			
		||||
#### When signs don't update after focusing Vim
 | 
			
		||||
 | 
			
		||||
* Your terminal probably isn't reporting focus events.  Either try installing [Terminus][] or set `let g:gitgutter_terminal_reports_focus=0`.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 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
 | 
			
		||||
  [terminus]: https://github.com/wincent/terminus
 | 
			
		||||
							
								
								
									
										139
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
let s:t_string = type('')
 | 
			
		||||
 | 
			
		||||
" Primary functions {{{
 | 
			
		||||
 | 
			
		||||
function! gitgutter#all(force) abort
 | 
			
		||||
  let visible = tabpagebuflist()
 | 
			
		||||
 | 
			
		||||
  for bufnr in range(1, bufnr('$') + 1)
 | 
			
		||||
    if buflisted(bufnr)
 | 
			
		||||
      let file = expand('#'.bufnr.':p')
 | 
			
		||||
      if !empty(file)
 | 
			
		||||
        if index(visible, bufnr) != -1
 | 
			
		||||
          call gitgutter#init_buffer(bufnr)
 | 
			
		||||
          call gitgutter#process_buffer(bufnr, a:force)
 | 
			
		||||
        elseif a:force
 | 
			
		||||
          call s:reset_tick(bufnr)
 | 
			
		||||
        endif
 | 
			
		||||
      endif
 | 
			
		||||
    endif
 | 
			
		||||
  endfor
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
" Finds the file's path relative to the repo root.
 | 
			
		||||
function! gitgutter#init_buffer(bufnr)
 | 
			
		||||
  if gitgutter#utility#is_active(a:bufnr)
 | 
			
		||||
    let p = gitgutter#utility#repo_path(a:bufnr, 0)
 | 
			
		||||
    if type(p) != s:t_string || empty(p)
 | 
			
		||||
      call gitgutter#utility#set_repo_path(a:bufnr)
 | 
			
		||||
      call s:setup_maps()
 | 
			
		||||
    endif
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! gitgutter#process_buffer(bufnr, force) abort
 | 
			
		||||
  " NOTE a:bufnr is not necessarily the current buffer.
 | 
			
		||||
 | 
			
		||||
  if gitgutter#utility#is_active(a:bufnr)
 | 
			
		||||
    if a:force || s:has_fresh_changes(a:bufnr)
 | 
			
		||||
 | 
			
		||||
      let diff = ''
 | 
			
		||||
      try
 | 
			
		||||
        let diff = gitgutter#diff#run_diff(a:bufnr, 0)
 | 
			
		||||
      catch /gitgutter not tracked/
 | 
			
		||||
        call gitgutter#debug#log('Not tracked: '.gitgutter#utility#file(a:bufnr))
 | 
			
		||||
      catch /gitgutter diff failed/
 | 
			
		||||
        call gitgutter#debug#log('Diff failed: '.gitgutter#utility#file(a:bufnr))
 | 
			
		||||
        call gitgutter#hunk#reset(a:bufnr)
 | 
			
		||||
      endtry
 | 
			
		||||
 | 
			
		||||
      if diff != 'async'
 | 
			
		||||
        call gitgutter#diff#handler(a:bufnr, diff)
 | 
			
		||||
      endif
 | 
			
		||||
 | 
			
		||||
    endif
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! gitgutter#disable() abort
 | 
			
		||||
  " get list of all buffers (across all tabs)
 | 
			
		||||
  for bufnr in range(1, bufnr('$') + 1)
 | 
			
		||||
    if buflisted(bufnr)
 | 
			
		||||
      let file = expand('#'.bufnr.':p')
 | 
			
		||||
      if !empty(file)
 | 
			
		||||
        call s:clear(bufnr)
 | 
			
		||||
      endif
 | 
			
		||||
    endif
 | 
			
		||||
  endfor
 | 
			
		||||
 | 
			
		||||
  let g:gitgutter_enabled = 0
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#enable() abort
 | 
			
		||||
  let g:gitgutter_enabled = 1
 | 
			
		||||
  call gitgutter#all(1)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#toggle() abort
 | 
			
		||||
  if g:gitgutter_enabled
 | 
			
		||||
    call gitgutter#disable()
 | 
			
		||||
  else
 | 
			
		||||
    call gitgutter#enable()
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
" }}}
 | 
			
		||||
 | 
			
		||||
function! s:setup_maps()
 | 
			
		||||
  if !g:gitgutter_map_keys
 | 
			
		||||
    return
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  if !hasmapto('<Plug>GitGutterPrevHunk') && maparg('[c', 'n') ==# ''
 | 
			
		||||
    nmap <buffer> [c <Plug>GitGutterPrevHunk
 | 
			
		||||
  endif
 | 
			
		||||
  if !hasmapto('<Plug>GitGutterNextHunk') && maparg(']c', 'n') ==# ''
 | 
			
		||||
    nmap <buffer> ]c <Plug>GitGutterNextHunk
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  if !hasmapto('<Plug>GitGutterStageHunk') && maparg('<Leader>hs', 'n') ==# ''
 | 
			
		||||
    nmap <buffer> <Leader>hs <Plug>GitGutterStageHunk
 | 
			
		||||
  endif
 | 
			
		||||
  if !hasmapto('<Plug>GitGutterUndoHunk') && maparg('<Leader>hu', 'n') ==# ''
 | 
			
		||||
    nmap <buffer> <Leader>hu <Plug>GitGutterUndoHunk
 | 
			
		||||
  endif
 | 
			
		||||
  if !hasmapto('<Plug>GitGutterPreviewHunk') && maparg('<Leader>hp', 'n') ==# ''
 | 
			
		||||
    nmap <buffer> <Leader>hp <Plug>GitGutterPreviewHunk
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  if !hasmapto('<Plug>GitGutterTextObjectInnerPending') && maparg('ic', 'o') ==# ''
 | 
			
		||||
    omap <buffer> ic <Plug>GitGutterTextObjectInnerPending
 | 
			
		||||
  endif
 | 
			
		||||
  if !hasmapto('<Plug>GitGutterTextObjectOuterPending') && maparg('ac', 'o') ==# ''
 | 
			
		||||
    omap <buffer> ac <Plug>GitGutterTextObjectOuterPending
 | 
			
		||||
  endif
 | 
			
		||||
  if !hasmapto('<Plug>GitGutterTextObjectInnerVisual') && maparg('ic', 'x') ==# ''
 | 
			
		||||
    xmap <buffer> ic <Plug>GitGutterTextObjectInnerVisual
 | 
			
		||||
  endif
 | 
			
		||||
  if !hasmapto('<Plug>GitGutterTextObjectOuterVisual') && maparg('ac', 'x') ==# ''
 | 
			
		||||
    xmap <buffer> ac <Plug>GitGutterTextObjectOuterVisual
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:has_fresh_changes(bufnr) abort
 | 
			
		||||
  return getbufvar(a:bufnr, 'changedtick') != gitgutter#utility#getbufvar(a:bufnr, 'tick')
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:reset_tick(bufnr) abort
 | 
			
		||||
  call gitgutter#utility#setbufvar(a:bufnr, 'tick', 0)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:clear(bufnr)
 | 
			
		||||
  call gitgutter#sign#clear_signs(a:bufnr)
 | 
			
		||||
  call gitgutter#sign#remove_dummy_sign(a:bufnr, 1)
 | 
			
		||||
  call gitgutter#hunk#reset(a:bufnr)
 | 
			
		||||
  call s:reset_tick(a:bufnr)
 | 
			
		||||
endfunction
 | 
			
		||||
							
								
								
									
										89
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/async.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/async.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
let s:available = has('nvim') || (
 | 
			
		||||
      \   has('job') && (
 | 
			
		||||
      \     (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, bufnr, handler) abort
 | 
			
		||||
  call gitgutter#debug#log('[async] '.a:cmd)
 | 
			
		||||
 | 
			
		||||
  let options = {
 | 
			
		||||
        \   'stdoutbuffer': [],
 | 
			
		||||
        \   'buffer': a:bufnr,
 | 
			
		||||
        \   'handler': a:handler
 | 
			
		||||
        \ }
 | 
			
		||||
  let command = s:build_command(a:cmd)
 | 
			
		||||
 | 
			
		||||
  if has('nvim')
 | 
			
		||||
    call jobstart(command, extend(options, {
 | 
			
		||||
          \   'on_stdout': function('s:on_stdout_nvim'),
 | 
			
		||||
          \   'on_stderr': function('s:on_stderr_nvim'),
 | 
			
		||||
          \   'on_exit':   function('s:on_exit_nvim')
 | 
			
		||||
          \ }))
 | 
			
		||||
  else
 | 
			
		||||
    call job_start(command, {
 | 
			
		||||
          \   'out_cb':   function('s:on_stdout_vim', options),
 | 
			
		||||
          \   'err_cb':   function('s:on_stderr_vim', options),
 | 
			
		||||
          \   'close_cb': function('s:on_exit_vim', options)
 | 
			
		||||
          \ })
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:build_command(cmd)
 | 
			
		||||
  if has('unix')
 | 
			
		||||
    return ['sh', '-c', a:cmd]
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  if has('win32')
 | 
			
		||||
    return has('nvim') ? ['cmd.exe', '/c', a:cmd] : 'cmd.exe /c '.a:cmd
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  throw 'unknown os'
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:on_stdout_nvim(_job_id, data, _event) dict abort
 | 
			
		||||
  if empty(self.stdoutbuffer)
 | 
			
		||||
    let self.stdoutbuffer = a:data
 | 
			
		||||
  else
 | 
			
		||||
    let self.stdoutbuffer = self.stdoutbuffer[:-2] +
 | 
			
		||||
          \ [self.stdoutbuffer[-1] . a:data[0]] +
 | 
			
		||||
          \ a:data[1:]
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:on_stderr_nvim(_job_id, _data, _event) dict abort
 | 
			
		||||
  call self.handler.err(self.buffer)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:on_exit_nvim(_job_id, exit_code, _event) dict abort
 | 
			
		||||
  if !a:exit_code
 | 
			
		||||
    call self.handler.out(self.buffer, join(self.stdoutbuffer, "\n"))
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:on_stdout_vim(_channel, data) dict abort
 | 
			
		||||
  call add(self.stdoutbuffer, a:data)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:on_stderr_vim(channel, _data) dict abort
 | 
			
		||||
  call self.handler.err(self.buffer)
 | 
			
		||||
  try
 | 
			
		||||
    call ch_close(a:channel)  " so close_cb and its 'out' handler are not triggered
 | 
			
		||||
  catch /E906/
 | 
			
		||||
    " noop
 | 
			
		||||
  endtry
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:on_exit_vim(_channel) dict abort
 | 
			
		||||
  call self.handler.out(self.buffer, join(self.stdoutbuffer, "\n"))
 | 
			
		||||
endfunction
 | 
			
		||||
							
								
								
									
										119
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/debug.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/debug.vim
									
									
									
									
									
										Normal file
									
								
							@@ -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 s:vim_version()
 | 
			
		||||
  call s:separator()
 | 
			
		||||
 | 
			
		||||
  call s:git_version()
 | 
			
		||||
  call s:separator()
 | 
			
		||||
 | 
			
		||||
  call s:grep_version()
 | 
			
		||||
  call s:separator()
 | 
			
		||||
 | 
			
		||||
  call s:option('updatetime')
 | 
			
		||||
  call s:option('shell')
 | 
			
		||||
  call s:option('shellcmdflag')
 | 
			
		||||
  call s:option('shellpipe')
 | 
			
		||||
  call s:option('shellquote')
 | 
			
		||||
  call s:option('shellredir')
 | 
			
		||||
  call s:option('shellslash')
 | 
			
		||||
  call s:option('shelltemp')
 | 
			
		||||
  call s:option('shelltype')
 | 
			
		||||
  call s:option('shellxescape')
 | 
			
		||||
  call s:option('shellxquote')
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:separator()
 | 
			
		||||
  call s:output('')
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:vim_version()
 | 
			
		||||
  redir => version_info
 | 
			
		||||
    silent execute 'version'
 | 
			
		||||
  redir END
 | 
			
		||||
  call s:output(split(version_info, '\n')[0:2])
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:git_version()
 | 
			
		||||
  let v = system(g:gitgutter_git_executable.' --version')
 | 
			
		||||
  call s:output( substitute(v, '\n$', '', '') )
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:grep_version()
 | 
			
		||||
  let v = system('grep --version')
 | 
			
		||||
  call s:output( substitute(v, '\n$', '', '') )
 | 
			
		||||
 | 
			
		||||
  let v = system('grep --help')
 | 
			
		||||
  call s:output( substitute(v, '\%x00', '', 'g') )
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:option(name)
 | 
			
		||||
  if exists('+' . a:name)
 | 
			
		||||
    let v = eval('&' . a:name)
 | 
			
		||||
    call s:output(a:name . '=' . v)
 | 
			
		||||
    " redir => output
 | 
			
		||||
    "   silent execute "verbose set " . a:name . "?"
 | 
			
		||||
    " redir END
 | 
			
		||||
    " call s:output(a:name . '=' . output)
 | 
			
		||||
  else
 | 
			
		||||
    call s:output(a:name . ' [n/a]')
 | 
			
		||||
  end
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s: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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										360
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/diff.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/diff.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,360 @@
 | 
			
		||||
let s:nomodeline = (v:version > 703 || (v:version == 703 && has('patch442'))) ? '<nomodeline>' : ''
 | 
			
		||||
 | 
			
		||||
let s:hunk_re = '^@@ -\(\d\+\),\?\(\d*\) +\(\d\+\),\?\(\d*\) @@'
 | 
			
		||||
 | 
			
		||||
" True for git v1.7.2+.
 | 
			
		||||
function! s:git_supports_command_line_config_override() abort
 | 
			
		||||
  call system(g:gitgutter_git_executable.' -c foo.bar=baz --version')
 | 
			
		||||
  return !v:shell_error
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
let s:c_flag = s:git_supports_command_line_config_override()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
let s:temp_index = tempname()
 | 
			
		||||
let s:temp_buffer = tempname()
 | 
			
		||||
 | 
			
		||||
" Returns a diff of the buffer.
 | 
			
		||||
"
 | 
			
		||||
" 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
 | 
			
		||||
"
 | 
			
		||||
" where myfileA comes from
 | 
			
		||||
"
 | 
			
		||||
"     git show :myfile > myfileA
 | 
			
		||||
"
 | 
			
		||||
" and myfileB is the buffer contents.
 | 
			
		||||
"
 | 
			
		||||
" 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.
 | 
			
		||||
"
 | 
			
		||||
"
 | 
			
		||||
" Regarding line endings:
 | 
			
		||||
"
 | 
			
		||||
" git-show does not convert line endings.
 | 
			
		||||
" git-diff FILE FILE does convert line endings for the given files.
 | 
			
		||||
"
 | 
			
		||||
" If a file has CRLF line endings and git's core.autocrlf is true,
 | 
			
		||||
" the file in git's object store will have LF line endings.  Writing
 | 
			
		||||
" it out via git-show will produce a file with LF line endings.
 | 
			
		||||
"
 | 
			
		||||
" If this last file is one of the files passed to git-diff, git-diff will
 | 
			
		||||
" convert its line endings to CRLF before diffing -- which is what we want --
 | 
			
		||||
" but also by default output a warning on stderr.
 | 
			
		||||
"
 | 
			
		||||
"   warning: LF will be replace by CRLF in <temp file>.
 | 
			
		||||
"   The file will have its original line endings in your working directory.
 | 
			
		||||
"
 | 
			
		||||
" When running the diff asynchronously, the warning message triggers the stderr
 | 
			
		||||
" callbacks which assume the overall command has failed and reset all the
 | 
			
		||||
" signs.  As this is not what we want, and we can safely ignore the warning,
 | 
			
		||||
" we turn it off by passing the '-c "core.safecrlf=false"' argument to
 | 
			
		||||
" git-diff.
 | 
			
		||||
"
 | 
			
		||||
" When writing the temporary files we preserve the original file's extension
 | 
			
		||||
" so that repos using .gitattributes to control EOL conversion continue to
 | 
			
		||||
" convert correctly.
 | 
			
		||||
function! gitgutter#diff#run_diff(bufnr, preserve_full_diff) abort
 | 
			
		||||
  while gitgutter#utility#repo_path(a:bufnr, 0) == -1
 | 
			
		||||
    sleep 5m
 | 
			
		||||
  endwhile
 | 
			
		||||
 | 
			
		||||
  if gitgutter#utility#repo_path(a:bufnr, 0) == -2
 | 
			
		||||
    throw 'gitgutter not tracked'
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  " Wrap compound commands in parentheses to make Windows happy.
 | 
			
		||||
  " bash doesn't mind the parentheses.
 | 
			
		||||
  let cmd = '('
 | 
			
		||||
 | 
			
		||||
  " Append buffer number to avoid race conditions between writing and reading
 | 
			
		||||
  " the files when asynchronously processing multiple buffers.
 | 
			
		||||
  "
 | 
			
		||||
  " Without the buffer number, index_file would have a race in the shell
 | 
			
		||||
  " between the second process writing it (with git-show) and the first
 | 
			
		||||
  " reading it (with git-diff).
 | 
			
		||||
  let index_file = s:temp_index.'.'.a:bufnr
 | 
			
		||||
 | 
			
		||||
  " Without the buffer number, buff_file would have a race between the
 | 
			
		||||
  " second gitgutter#process_buffer() writing the file (synchronously, below)
 | 
			
		||||
  " and the first gitgutter#process_buffer()'s async job reading it (with
 | 
			
		||||
  " git-diff).
 | 
			
		||||
  let buff_file = s:temp_buffer.'.'.a:bufnr
 | 
			
		||||
 | 
			
		||||
  let extension = gitgutter#utility#extension(a:bufnr)
 | 
			
		||||
  if !empty(extension)
 | 
			
		||||
    let index_file .= '.'.extension
 | 
			
		||||
    let buff_file .= '.'.extension
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  " Write file from index to temporary file.
 | 
			
		||||
  let index_name = g:gitgutter_diff_base.':'.gitgutter#utility#repo_path(a:bufnr, 1)
 | 
			
		||||
  let cmd .= g:gitgutter_git_executable.' --no-pager show '.index_name.' > '.index_file.' && '
 | 
			
		||||
 | 
			
		||||
  " Write buffer to temporary file.
 | 
			
		||||
  " Note: this is synchronous.
 | 
			
		||||
  call s:write_buffer(a:bufnr, buff_file)
 | 
			
		||||
 | 
			
		||||
  " Call git-diff with the temporary files.
 | 
			
		||||
  let cmd .= g:gitgutter_git_executable.' --no-pager'
 | 
			
		||||
  if s:c_flag
 | 
			
		||||
    let cmd .= ' -c "diff.autorefreshindex=0"'
 | 
			
		||||
    let cmd .= ' -c "diff.noprefix=false"'
 | 
			
		||||
    let cmd .= ' -c "core.safecrlf=false"'
 | 
			
		||||
  endif
 | 
			
		||||
  let cmd .= ' diff --no-ext-diff --no-color -U0 '.g:gitgutter_diff_args.' -- '.index_file.' '.buff_file
 | 
			
		||||
 | 
			
		||||
  " Pipe git-diff output into grep.
 | 
			
		||||
  if !a:preserve_full_diff && !empty(g:gitgutter_grep)
 | 
			
		||||
    let cmd .= ' | '.g:gitgutter_grep.' '.gitgutter#utility#shellescape('^@@ ')
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  " grep exits with 1 when no matches are found; git-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'
 | 
			
		||||
 | 
			
		||||
  let cmd .= ')'
 | 
			
		||||
 | 
			
		||||
  let cmd = gitgutter#utility#cd_cmd(a:bufnr, cmd)
 | 
			
		||||
 | 
			
		||||
  if g:gitgutter_async && gitgutter#async#available()
 | 
			
		||||
    call gitgutter#async#execute(cmd, a:bufnr, {
 | 
			
		||||
          \   'out': function('gitgutter#diff#handler'),
 | 
			
		||||
          \   'err': function('gitgutter#hunk#reset'),
 | 
			
		||||
          \ })
 | 
			
		||||
    return 'async'
 | 
			
		||||
 | 
			
		||||
  else
 | 
			
		||||
    let diff = gitgutter#utility#system(cmd)
 | 
			
		||||
 | 
			
		||||
    if v:shell_error
 | 
			
		||||
      call gitgutter#debug#log(diff)
 | 
			
		||||
      throw 'gitgutter diff failed'
 | 
			
		||||
    endif
 | 
			
		||||
 | 
			
		||||
    return diff
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! gitgutter#diff#handler(bufnr, diff) abort
 | 
			
		||||
  call gitgutter#debug#log(a:diff)
 | 
			
		||||
 | 
			
		||||
  if !bufexists(a:bufnr)
 | 
			
		||||
    return
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  call gitgutter#hunk#set_hunks(a:bufnr, gitgutter#diff#parse_diff(a:diff))
 | 
			
		||||
  let modified_lines = gitgutter#diff#process_hunks(a:bufnr, gitgutter#hunk#hunks(a:bufnr))
 | 
			
		||||
 | 
			
		||||
  let signs_count = len(modified_lines)
 | 
			
		||||
  if signs_count > g:gitgutter_max_signs
 | 
			
		||||
    call gitgutter#utility#warn_once(a:bufnr, printf(
 | 
			
		||||
          \ 'exceeded maximum number of signs (%d > %d, configured by g:gitgutter_max_signs).',
 | 
			
		||||
          \ signs_count, g:gitgutter_max_signs), 'max_signs')
 | 
			
		||||
    call gitgutter#sign#clear_signs(a:bufnr)
 | 
			
		||||
 | 
			
		||||
  else
 | 
			
		||||
    if g:gitgutter_signs || g:gitgutter_highlight_lines
 | 
			
		||||
      call gitgutter#sign#update_signs(a:bufnr, modified_lines)
 | 
			
		||||
    endif
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  call s:save_last_seen_change(a:bufnr)
 | 
			
		||||
  if exists('#User#GitGutter')
 | 
			
		||||
    let g:gitgutter_hook_context = {'bufnr': a:bufnr}
 | 
			
		||||
    execute 'doautocmd' s:nomodeline 'User GitGutter'
 | 
			
		||||
    unlet g:gitgutter_hook_context
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
" This function is public so it may be used by other plugins
 | 
			
		||||
" e.g. vim-signature.
 | 
			
		||||
function! gitgutter#diff#process_hunks(bufnr, hunks) abort
 | 
			
		||||
  let modified_lines = []
 | 
			
		||||
  for hunk in a:hunks
 | 
			
		||||
    call extend(modified_lines, s:process_hunk(a:bufnr, hunk))
 | 
			
		||||
  endfor
 | 
			
		||||
  return modified_lines
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
" Returns [ [<line_number (number)>, <name (string)>], ...]
 | 
			
		||||
function! s:process_hunk(bufnr, 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 s:is_added(from_count, to_count)
 | 
			
		||||
    call s:process_added(modifications, from_count, to_count, to_line)
 | 
			
		||||
    call gitgutter#hunk#increment_lines_added(a:bufnr, to_count)
 | 
			
		||||
 | 
			
		||||
  elseif s:is_removed(from_count, to_count)
 | 
			
		||||
    call s:process_removed(modifications, from_count, to_count, to_line)
 | 
			
		||||
    call gitgutter#hunk#increment_lines_removed(a:bufnr, from_count)
 | 
			
		||||
 | 
			
		||||
  elseif s:is_modified(from_count, to_count)
 | 
			
		||||
    call s:process_modified(modifications, from_count, to_count, to_line)
 | 
			
		||||
    call gitgutter#hunk#increment_lines_modified(a:bufnr, to_count)
 | 
			
		||||
 | 
			
		||||
  elseif s:is_modified_and_added(from_count, to_count)
 | 
			
		||||
    call s:process_modified_and_added(modifications, from_count, to_count, to_line)
 | 
			
		||||
    call gitgutter#hunk#increment_lines_added(a:bufnr, to_count - from_count)
 | 
			
		||||
    call gitgutter#hunk#increment_lines_modified(a:bufnr, from_count)
 | 
			
		||||
 | 
			
		||||
  elseif s:is_modified_and_removed(from_count, to_count)
 | 
			
		||||
    call s:process_modified_and_removed(modifications, from_count, to_count, to_line)
 | 
			
		||||
    call gitgutter#hunk#increment_lines_modified(a:bufnr, to_count)
 | 
			
		||||
    call gitgutter#hunk#increment_lines_removed(a:bufnr, from_count - to_count)
 | 
			
		||||
 | 
			
		||||
  endif
 | 
			
		||||
  return modifications
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:is_added(from_count, to_count) abort
 | 
			
		||||
  return a:from_count == 0 && a:to_count > 0
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:is_removed(from_count, to_count) abort
 | 
			
		||||
  return a:from_count > 0 && a:to_count == 0
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:is_modified(from_count, to_count) abort
 | 
			
		||||
  return a:from_count > 0 && a:to_count > 0 && a:from_count == a:to_count
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s: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! s: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! s: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! s: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! s: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! s: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! s: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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
" Returns a diff for the current hunk.
 | 
			
		||||
function! gitgutter#diff#hunk_diff(bufnr, full_diff)
 | 
			
		||||
  let modified_diff = []
 | 
			
		||||
  let keep_line = 1
 | 
			
		||||
  " Don't keepempty when splitting because the diff we want may not be the
 | 
			
		||||
  " final one.  Instead add trailing NL at end of function.
 | 
			
		||||
  for line in split(a:full_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
 | 
			
		||||
  return join(modified_diff, "\n")."\n"
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:write_buffer(bufnr, file)
 | 
			
		||||
  let bufcontents = getbufline(a:bufnr, 1, '$')
 | 
			
		||||
 | 
			
		||||
  if getbufvar(a:bufnr, '&fileformat') ==# 'dos'
 | 
			
		||||
    call map(bufcontents, 'v:val."\r"')
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  let fenc = getbufvar(a:bufnr, '&fileencoding')
 | 
			
		||||
  if fenc !=# &encoding
 | 
			
		||||
    call map(bufcontents, 'iconv(v:val, &encoding, "'.fenc.'")')
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  if getbufvar(a:bufnr, '&bomb')
 | 
			
		||||
    let bufcontents[0]=''.bufcontents[0]
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  call writefile(bufcontents, a:file)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:save_last_seen_change(bufnr) abort
 | 
			
		||||
  call gitgutter#utility#setbufvar(a:bufnr, 'tick', getbufvar(a:bufnr, 'changedtick'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										149
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/highlight.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/highlight.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
			
		||||
function! gitgutter#highlight#line_disable() abort
 | 
			
		||||
  let g:gitgutter_highlight_lines = 0
 | 
			
		||||
  call s:define_sign_line_highlights()
 | 
			
		||||
 | 
			
		||||
  if !g:gitgutter_signs
 | 
			
		||||
    call gitgutter#sign#clear_signs(bufnr(''))
 | 
			
		||||
    call gitgutter#sign#remove_dummy_sign(bufnr(''), 0)
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  redraw!
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#highlight#line_enable() abort
 | 
			
		||||
  let old_highlight_lines = g:gitgutter_highlight_lines
 | 
			
		||||
 | 
			
		||||
  let g:gitgutter_highlight_lines = 1
 | 
			
		||||
  call s:define_sign_line_highlights()
 | 
			
		||||
 | 
			
		||||
  if !old_highlight_lines && !g:gitgutter_signs
 | 
			
		||||
    call gitgutter#all(1)
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  redraw!
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#highlight#line_toggle() abort
 | 
			
		||||
  if g:gitgutter_highlight_lines
 | 
			
		||||
    call gitgutter#highlight#line_disable()
 | 
			
		||||
  else
 | 
			
		||||
    call gitgutter#highlight#line_enable()
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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] = s: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 GitGutterChangeInvisible
 | 
			
		||||
 | 
			
		||||
  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 s:define_sign_text()
 | 
			
		||||
  call gitgutter#highlight#define_sign_text_highlights()
 | 
			
		||||
  call s:define_sign_line_highlights()
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s: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! s: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! s: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 s:get_background_colors(link_matches[1])
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  let ctermbg = s:match_highlight(highlight, 'ctermbg=\([0-9A-Za-z]\+\)')
 | 
			
		||||
  let guibg   = s:match_highlight(highlight, 'guibg=\([#0-9A-Za-z]\+\)')
 | 
			
		||||
  return [guibg, ctermbg]
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:match_highlight(highlight, pattern) abort
 | 
			
		||||
  let matches = matchlist(a:highlight, a:pattern)
 | 
			
		||||
  if len(matches) == 0
 | 
			
		||||
    return 'NONE'
 | 
			
		||||
  endif
 | 
			
		||||
  return matches[1]
 | 
			
		||||
endfunction
 | 
			
		||||
							
								
								
									
										281
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/hunk.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/hunk.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,281 @@
 | 
			
		||||
function! gitgutter#hunk#set_hunks(bufnr, hunks) abort
 | 
			
		||||
  call gitgutter#utility#setbufvar(a:bufnr, 'hunks', a:hunks)
 | 
			
		||||
  call s:reset_summary(a:bufnr)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#hunk#hunks(bufnr) abort
 | 
			
		||||
  return gitgutter#utility#getbufvar(a:bufnr, 'hunks', [])
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#hunk#reset(bufnr) abort
 | 
			
		||||
  call gitgutter#utility#setbufvar(a:bufnr, 'hunks', [])
 | 
			
		||||
  call s:reset_summary(a:bufnr)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! gitgutter#hunk#summary(bufnr) abort
 | 
			
		||||
  return gitgutter#utility#getbufvar(a:bufnr, 'summary', [0,0,0])
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:reset_summary(bufnr) abort
 | 
			
		||||
  call gitgutter#utility#setbufvar(a:bufnr, 'summary', [0,0,0])
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#hunk#increment_lines_added(bufnr, count) abort
 | 
			
		||||
  let summary = gitgutter#hunk#summary(a:bufnr)
 | 
			
		||||
  let summary[0] += a:count
 | 
			
		||||
  call gitgutter#utility#setbufvar(a:bufnr, 'summary', summary)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#hunk#increment_lines_modified(bufnr, count) abort
 | 
			
		||||
  let summary = gitgutter#hunk#summary(a:bufnr)
 | 
			
		||||
  let summary[1] += a:count
 | 
			
		||||
  call gitgutter#utility#setbufvar(a:bufnr, 'summary', summary)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#hunk#increment_lines_removed(bufnr, count) abort
 | 
			
		||||
  let summary = gitgutter#hunk#summary(a:bufnr)
 | 
			
		||||
  let summary[2] += a:count
 | 
			
		||||
  call gitgutter#utility#setbufvar(a:bufnr, 'summary', summary)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! gitgutter#hunk#next_hunk(count) abort
 | 
			
		||||
  let bufnr = bufnr('')
 | 
			
		||||
  if gitgutter#utility#is_active(bufnr)
 | 
			
		||||
    let current_line = line('.')
 | 
			
		||||
    let hunk_count = 0
 | 
			
		||||
    for hunk in gitgutter#hunk#hunks(bufnr)
 | 
			
		||||
      if hunk[2] > current_line
 | 
			
		||||
        let hunk_count += 1
 | 
			
		||||
        if hunk_count == a:count
 | 
			
		||||
          execute 'normal!' hunk[2] . 'Gzv'
 | 
			
		||||
          return
 | 
			
		||||
        endif
 | 
			
		||||
      endif
 | 
			
		||||
    endfor
 | 
			
		||||
    call gitgutter#utility#warn('No more hunks')
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#hunk#prev_hunk(count) abort
 | 
			
		||||
  let bufnr = bufnr('')
 | 
			
		||||
  if gitgutter#utility#is_active(bufnr)
 | 
			
		||||
    let current_line = line('.')
 | 
			
		||||
    let hunk_count = 0
 | 
			
		||||
    for hunk in reverse(copy(gitgutter#hunk#hunks(bufnr)))
 | 
			
		||||
      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 . 'Gzv'
 | 
			
		||||
          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! s:current_hunk() abort
 | 
			
		||||
  let bufnr = bufnr('')
 | 
			
		||||
  let current_hunk = []
 | 
			
		||||
 | 
			
		||||
  for hunk in gitgutter#hunk#hunks(bufnr)
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
function! gitgutter#hunk#text_object(inner) abort
 | 
			
		||||
  let hunk = s: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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! gitgutter#hunk#stage() abort
 | 
			
		||||
  call s:hunk_op(function('s:stage'))
 | 
			
		||||
  silent! call repeat#set("\<Plug>GitGutterStageHunk", -1)<CR>
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#hunk#undo() abort
 | 
			
		||||
  call s:hunk_op(function('s:undo'))
 | 
			
		||||
  silent! call repeat#set("\<Plug>GitGutterUndoHunk", -1)<CR>
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#hunk#preview() abort
 | 
			
		||||
  call s:hunk_op(function('s:preview'))
 | 
			
		||||
  silent! call repeat#set("\<Plug>GitGutterPreviewHunk", -1)<CR>
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:hunk_op(op)
 | 
			
		||||
  let bufnr = bufnr('')
 | 
			
		||||
 | 
			
		||||
  if gitgutter#utility#is_active(bufnr)
 | 
			
		||||
    " Get a (synchronous) diff.
 | 
			
		||||
    let [async, g:gitgutter_async] = [g:gitgutter_async, 0]
 | 
			
		||||
    let diff = gitgutter#diff#run_diff(bufnr, 1)
 | 
			
		||||
    let g:gitgutter_async = async
 | 
			
		||||
 | 
			
		||||
    call gitgutter#hunk#set_hunks(bufnr, gitgutter#diff#parse_diff(diff))
 | 
			
		||||
 | 
			
		||||
    if empty(s:current_hunk())
 | 
			
		||||
      call gitgutter#utility#warn('cursor is not in a hunk')
 | 
			
		||||
    else
 | 
			
		||||
      call a:op(gitgutter#diff#hunk_diff(bufnr, diff))
 | 
			
		||||
    endif
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:stage(hunk_diff)
 | 
			
		||||
  let bufnr = bufnr('')
 | 
			
		||||
  let diff = s:adjust_header(bufnr, a:hunk_diff)
 | 
			
		||||
  " Apply patch to index.
 | 
			
		||||
  call gitgutter#utility#system(
 | 
			
		||||
        \ gitgutter#utility#cd_cmd(bufnr, g:gitgutter_git_executable.' apply --cached --unidiff-zero - '),
 | 
			
		||||
        \ diff)
 | 
			
		||||
 | 
			
		||||
  " Refresh gitgutter's view of buffer.
 | 
			
		||||
  call gitgutter#process_buffer(bufnr, 1)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:undo(hunk_diff)
 | 
			
		||||
  " Apply reverse patch to buffer.
 | 
			
		||||
  let hunk  = gitgutter#diff#parse_hunk(split(a:hunk_diff, '\n')[4])
 | 
			
		||||
  let lines = map(split(a:hunk_diff, '\n')[5:], 'v:val[1:]')
 | 
			
		||||
  let lnum  = hunk[2]
 | 
			
		||||
  let added_only   = hunk[1] == 0 && hunk[3]  > 0
 | 
			
		||||
  let removed_only = hunk[1]  > 0 && hunk[3] == 0
 | 
			
		||||
 | 
			
		||||
  if removed_only
 | 
			
		||||
    call append(lnum, lines)
 | 
			
		||||
  elseif added_only
 | 
			
		||||
    execute lnum .','. (lnum+len(lines)-1) .'d'
 | 
			
		||||
  else
 | 
			
		||||
    call append(lnum-1, lines[0:hunk[1]])
 | 
			
		||||
    execute (lnum+hunk[1]) .','. (lnum+hunk[1]+hunk[3]) .'d'
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:preview(hunk_diff)
 | 
			
		||||
  let hunk_lines = split(s:discard_header(a:hunk_diff), "\n")
 | 
			
		||||
  let hunk_lines_length = len(hunk_lines)
 | 
			
		||||
  let previewheight = min([hunk_lines_length, &previewheight])
 | 
			
		||||
 | 
			
		||||
  silent! wincmd P
 | 
			
		||||
  if !&previewwindow
 | 
			
		||||
    noautocmd execute 'bo' previewheight 'new'
 | 
			
		||||
    set previewwindow
 | 
			
		||||
  else
 | 
			
		||||
    execute 'resize' previewheight
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  setlocal noreadonly modifiable filetype=diff buftype=nofile bufhidden=delete noswapfile
 | 
			
		||||
  execute "%delete_"
 | 
			
		||||
  call append(0, hunk_lines)
 | 
			
		||||
  normal! gg
 | 
			
		||||
  setlocal readonly nomodifiable
 | 
			
		||||
 | 
			
		||||
  noautocmd wincmd p
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:adjust_header(bufnr, hunk_diff)
 | 
			
		||||
  let filepath = gitgutter#utility#repo_path(a:bufnr, 0)
 | 
			
		||||
  return s:adjust_hunk_summary(s:fix_file_references(filepath, a:hunk_diff))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
" Replaces references to temp files with the actual file.
 | 
			
		||||
function! s:fix_file_references(filepath, hunk_diff)
 | 
			
		||||
  let lines = split(a:hunk_diff, '\n')
 | 
			
		||||
 | 
			
		||||
  let left_prefix  = matchstr(lines[2], '[abciow12]').'/'
 | 
			
		||||
  let right_prefix = matchstr(lines[3], '[abciow12]').'/'
 | 
			
		||||
  let quote        = lines[0][11] == '"' ? '"' : ''
 | 
			
		||||
 | 
			
		||||
  let left_file  = quote.left_prefix.a:filepath.quote
 | 
			
		||||
  let right_file = quote.right_prefix.a:filepath.quote
 | 
			
		||||
 | 
			
		||||
  let lines[0] = 'diff --git '.left_file.' '.right_file
 | 
			
		||||
  let lines[2] = '--- '.left_file
 | 
			
		||||
  let lines[3] = '+++ '.right_file
 | 
			
		||||
 | 
			
		||||
  return join(lines, "\n")."\n"
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
if $VIM_GITGUTTER_TEST
 | 
			
		||||
  function! gitgutter#hunk#fix_file_references(filepath, hunk_diff)
 | 
			
		||||
    return s:fix_file_references(a:filepath, a:hunk_diff)
 | 
			
		||||
  endfunction
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:adjust_hunk_summary(hunk_diff) abort
 | 
			
		||||
  let line_adjustment = s:line_adjustment_for_current_hunk()
 | 
			
		||||
  let diff = split(a:hunk_diff, '\n', 1)
 | 
			
		||||
  let diff[4] = substitute(diff[4], '+\@<=\(\d\+\)', '\=submatch(1)+line_adjustment', '')
 | 
			
		||||
  return join(diff, "\n")
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:discard_header(hunk_diff)
 | 
			
		||||
  return join(split(a:hunk_diff, '\n', 1)[5:], "\n")
 | 
			
		||||
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! s:line_adjustment_for_current_hunk() abort
 | 
			
		||||
  let bufnr = bufnr('')
 | 
			
		||||
  let adj = 0
 | 
			
		||||
  for hunk in gitgutter#hunk#hunks(bufnr)
 | 
			
		||||
    if gitgutter#hunk#cursor_in_hunk(hunk)
 | 
			
		||||
      break
 | 
			
		||||
    else
 | 
			
		||||
      let adj += hunk[1] - hunk[3]
 | 
			
		||||
    endif
 | 
			
		||||
  endfor
 | 
			
		||||
  return adj
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										219
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/sign.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/sign.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,219 @@
 | 
			
		||||
" 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"))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! gitgutter#sign#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(1)
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#sign#disable() abort
 | 
			
		||||
  let g:gitgutter_signs = 0
 | 
			
		||||
  call gitgutter#highlight#define_sign_text_highlights()
 | 
			
		||||
 | 
			
		||||
  if !g:gitgutter_highlight_lines
 | 
			
		||||
    call gitgutter#sign#clear_signs(bufnr(''))
 | 
			
		||||
    call gitgutter#sign#remove_dummy_sign(bufnr(''), 0)
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#sign#toggle() abort
 | 
			
		||||
  if g:gitgutter_signs
 | 
			
		||||
    call gitgutter#sign#disable()
 | 
			
		||||
  else
 | 
			
		||||
    call gitgutter#sign#enable()
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
" Removes gitgutter's signs (excluding dummy sign) from the buffer being processed.
 | 
			
		||||
function! gitgutter#sign#clear_signs(bufnr) abort
 | 
			
		||||
  call s:find_current_signs(a:bufnr)
 | 
			
		||||
 | 
			
		||||
  let sign_ids = map(values(gitgutter#utility#getbufvar(a:bufnr, 'gitgutter_signs')), 'v:val.id')
 | 
			
		||||
  call s:remove_signs(a:bufnr, sign_ids, 1)
 | 
			
		||||
  call gitgutter#utility#setbufvar(a:bufnr, '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(bufnr, modified_lines) abort
 | 
			
		||||
  call s:find_current_signs(a:bufnr)
 | 
			
		||||
 | 
			
		||||
  let new_gitgutter_signs_line_numbers = map(copy(a:modified_lines), 'v:val[0]')
 | 
			
		||||
  let obsolete_signs = s:obsolete_gitgutter_signs_to_remove(a:bufnr, new_gitgutter_signs_line_numbers)
 | 
			
		||||
 | 
			
		||||
  let flicker_possible = s:remove_all_old_signs && !empty(a:modified_lines)
 | 
			
		||||
  if flicker_possible
 | 
			
		||||
    call s:add_dummy_sign(a:bufnr)
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  call s:remove_signs(a:bufnr, obsolete_signs, s:remove_all_old_signs)
 | 
			
		||||
  call s:upsert_new_gitgutter_signs(a:bufnr, a:modified_lines)
 | 
			
		||||
 | 
			
		||||
  if flicker_possible
 | 
			
		||||
    call gitgutter#sign#remove_dummy_sign(a:bufnr, 0)
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:add_dummy_sign(bufnr) abort
 | 
			
		||||
  if !gitgutter#utility#getbufvar(a:bufnr, 'dummy_sign')
 | 
			
		||||
    execute "sign place" s:dummy_sign_id "line=" . 9999 "name=GitGutterDummy buffer=" . a:bufnr
 | 
			
		||||
    call gitgutter#utility#setbufvar(a:bufnr, 'dummy_sign', 1)
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#sign#remove_dummy_sign(bufnr, force) abort
 | 
			
		||||
  if gitgutter#utility#getbufvar(a:bufnr, 'dummy_sign') && (a:force || !g:gitgutter_sign_column_always)
 | 
			
		||||
    execute "sign unplace" s:dummy_sign_id "buffer=" . a:bufnr
 | 
			
		||||
    call gitgutter#utility#setbufvar(a:bufnr, 'dummy_sign', 0)
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
"
 | 
			
		||||
" Internal functions
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:find_current_signs(bufnr) abort
 | 
			
		||||
  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=" . a: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 gitgutter#utility#setbufvar(a:bufnr, 'dummy_sign', dummy_sign_placed)
 | 
			
		||||
  call gitgutter#utility#setbufvar(a:bufnr, 'gitgutter_signs', gitgutter_signs)
 | 
			
		||||
  call gitgutter#utility#setbufvar(a:bufnr, 'other_signs', other_signs)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
" Returns a list of [<id (number)>, ...]
 | 
			
		||||
" Sets `s:remove_all_old_signs` as a side-effect.
 | 
			
		||||
function! s:obsolete_gitgutter_signs_to_remove(bufnr, new_gitgutter_signs_line_numbers) abort
 | 
			
		||||
  let signs_to_remove = []  " list of [<id (number)>, ...]
 | 
			
		||||
  let remove_all_signs = 1
 | 
			
		||||
  let old_gitgutter_signs = gitgutter#utility#getbufvar(a:bufnr, '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! s:remove_signs(bufnr, sign_ids, all_signs) abort
 | 
			
		||||
  if a:all_signs && s:supports_star && empty(gitgutter#utility#getbufvar(a:bufnr, 'other_signs'))
 | 
			
		||||
    let dummy_sign_present = gitgutter#utility#getbufvar(a:bufnr, 'dummy_sign')
 | 
			
		||||
    execute "sign unplace * buffer=" . a:bufnr
 | 
			
		||||
    if dummy_sign_present
 | 
			
		||||
      execute "sign place" s:dummy_sign_id "line=" . 9999 "name=GitGutterDummy buffer=" . a:bufnr
 | 
			
		||||
    endif
 | 
			
		||||
  else
 | 
			
		||||
    for id in a:sign_ids
 | 
			
		||||
      execute "sign unplace" id
 | 
			
		||||
    endfor
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:upsert_new_gitgutter_signs(bufnr, modified_lines) abort
 | 
			
		||||
  let other_signs         = gitgutter#utility#getbufvar(a:bufnr, 'other_signs')
 | 
			
		||||
  let old_gitgutter_signs = gitgutter#utility#getbufvar(a:bufnr, '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 = s:highlight_name_for_change(line[1])
 | 
			
		||||
      if !has_key(old_gitgutter_signs, line_number)  " insert
 | 
			
		||||
        let id = s:next_sign_id()
 | 
			
		||||
        execute "sign place" id "line=" . line_number "name=" . name "buffer=" . a: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=" . a:bufnr
 | 
			
		||||
        end
 | 
			
		||||
      endif
 | 
			
		||||
    endif
 | 
			
		||||
  endfor
 | 
			
		||||
  " At this point b:gitgutter_gitgutter_signs is out of date.
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:next_sign_id() abort
 | 
			
		||||
  let next_id = s:next_sign_id
 | 
			
		||||
  let s:next_sign_id += 1
 | 
			
		||||
  return next_id
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
" Only for testing.
 | 
			
		||||
function! gitgutter#sign#reset()
 | 
			
		||||
  let s:next_sign_id  = s:first_sign_id
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s: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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										210
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/utility.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								vim/plugins/vim-gitgutter/autoload/gitgutter/utility.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,210 @@
 | 
			
		||||
function! gitgutter#utility#supports_overscore_sign()
 | 
			
		||||
  if gitgutter#utility#windows()
 | 
			
		||||
    return &encoding ==? 'utf-8'
 | 
			
		||||
  else
 | 
			
		||||
    return &termencoding ==? &encoding || &termencoding == ''
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#utility#setbufvar(buffer, varname, val)
 | 
			
		||||
  let dict = get(getbufvar(a:buffer, ''), 'gitgutter', {})
 | 
			
		||||
  let needs_setting = empty(dict)
 | 
			
		||||
  let dict[a:varname] = a:val
 | 
			
		||||
  if needs_setting
 | 
			
		||||
    call setbufvar(+a:buffer, 'gitgutter', dict)
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#utility#getbufvar(buffer, varname, ...)
 | 
			
		||||
  let dict = get(getbufvar(a:buffer, ''), 'gitgutter', {})
 | 
			
		||||
  if has_key(dict, a:varname)
 | 
			
		||||
    return dict[a:varname]
 | 
			
		||||
  else
 | 
			
		||||
    if a:0
 | 
			
		||||
      return a:1
 | 
			
		||||
    endif
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
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(bufnr, message, key) abort
 | 
			
		||||
  if empty(gitgutter#utility#getbufvar(a:bufnr, a:key))
 | 
			
		||||
    call gitgutter#utility#setbufvar(a:bufnr, a:key, '1')
 | 
			
		||||
    echohl WarningMsg
 | 
			
		||||
    redraw | echom '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(bufnr) abort
 | 
			
		||||
  return g:gitgutter_enabled &&
 | 
			
		||||
        \ !pumvisible() &&
 | 
			
		||||
        \ s:is_file_buffer(a:bufnr) &&
 | 
			
		||||
        \ s:exists_file(a:bufnr) &&
 | 
			
		||||
        \ s:not_git_dir(a:bufnr)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:not_git_dir(bufnr) abort
 | 
			
		||||
  return s:dir(a:bufnr) !~ '[/\\]\.git\($\|[/\\]\)'
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:is_file_buffer(bufnr) abort
 | 
			
		||||
  return empty(getbufvar(a:bufnr, '&buftype'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
" From tpope/vim-fugitive
 | 
			
		||||
function! s:winshell()
 | 
			
		||||
  return &shell =~? 'cmd' || exists('+shellslash') && !&shellslash
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
" From tpope/vim-fugitive
 | 
			
		||||
function! gitgutter#utility#shellescape(arg) abort
 | 
			
		||||
  if a:arg =~ '^[A-Za-z0-9_/.-]\+$'
 | 
			
		||||
    return a:arg
 | 
			
		||||
  elseif s:winshell()
 | 
			
		||||
    return '"' . substitute(substitute(a:arg, '"', '""', 'g'), '%', '"%"', 'g') . '"'
 | 
			
		||||
  else
 | 
			
		||||
    return shellescape(a:arg)
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#utility#file(bufnr)
 | 
			
		||||
  return s:abs_path(a:bufnr, 1)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
" Not shellescaped
 | 
			
		||||
function! gitgutter#utility#extension(bufnr) abort
 | 
			
		||||
  return fnamemodify(s:abs_path(a:bufnr, 0), ':e')
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#utility#system(cmd, ...) abort
 | 
			
		||||
  call gitgutter#debug#log(a:cmd, a:000)
 | 
			
		||||
 | 
			
		||||
  call s:use_known_shell()
 | 
			
		||||
  silent let output = (a:0 == 0) ? system(a:cmd) : system(a:cmd, a:1)
 | 
			
		||||
  call s:restore_shell()
 | 
			
		||||
 | 
			
		||||
  return output
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
" Path of file relative to repo root.
 | 
			
		||||
"
 | 
			
		||||
" *     empty string - not set
 | 
			
		||||
" * non-empty string - path
 | 
			
		||||
" *               -1 - pending
 | 
			
		||||
" *               -2 - not tracked by git
 | 
			
		||||
function! gitgutter#utility#repo_path(bufnr, shellesc) abort
 | 
			
		||||
  let p = gitgutter#utility#getbufvar(a:bufnr, 'path')
 | 
			
		||||
  return a:shellesc ? gitgutter#utility#shellescape(p) : p
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#utility#set_repo_path(bufnr) abort
 | 
			
		||||
  " Values of path:
 | 
			
		||||
  " * non-empty string - path
 | 
			
		||||
  " *               -1 - pending
 | 
			
		||||
  " *               -2 - not tracked by git
 | 
			
		||||
 | 
			
		||||
  call gitgutter#utility#setbufvar(a:bufnr, 'path', -1)
 | 
			
		||||
  let cmd = gitgutter#utility#cd_cmd(a:bufnr, g:gitgutter_git_executable.' ls-files --error-unmatch --full-name -- '.gitgutter#utility#shellescape(s:filename(a:bufnr)))
 | 
			
		||||
 | 
			
		||||
  if g:gitgutter_async && gitgutter#async#available()
 | 
			
		||||
    if has('lambda')
 | 
			
		||||
      call gitgutter#async#execute(cmd, a:bufnr, {
 | 
			
		||||
            \   'out': {bufnr, path -> gitgutter#utility#setbufvar(bufnr, 'path', s:strip_trailing_new_line(path))},
 | 
			
		||||
            \   'err': {bufnr       -> gitgutter#utility#setbufvar(bufnr, 'path', -2)},
 | 
			
		||||
            \ })
 | 
			
		||||
    else
 | 
			
		||||
      if has('nvim') && !has('nvim-0.2.0')
 | 
			
		||||
        call gitgutter#async#execute(cmd, a:bufnr, {
 | 
			
		||||
              \   'out': function('s:set_path'),
 | 
			
		||||
              \   'err': function('s:not_tracked_by_git')
 | 
			
		||||
              \ })
 | 
			
		||||
      else
 | 
			
		||||
        call gitgutter#async#execute(cmd, a:bufnr, {
 | 
			
		||||
              \   'out': function('s:set_path'),
 | 
			
		||||
              \   'err': function('s:set_path', [-2])
 | 
			
		||||
              \ })
 | 
			
		||||
      endif
 | 
			
		||||
    endif
 | 
			
		||||
  else
 | 
			
		||||
    let path = gitgutter#utility#system(cmd)
 | 
			
		||||
    if v:shell_error
 | 
			
		||||
      call gitgutter#utility#setbufvar(a:bufnr, 'path', -2)
 | 
			
		||||
    else
 | 
			
		||||
      call gitgutter#utility#setbufvar(a:bufnr, 'path', s:strip_trailing_new_line(path))
 | 
			
		||||
    endif
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
if has('nvim') && !has('nvim-0.2.0')
 | 
			
		||||
  function! s:not_tracked_by_git(bufnr)
 | 
			
		||||
    call s:set_path(a:bufnr, -2)
 | 
			
		||||
  endfunction
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
function! s:set_path(bufnr, path)
 | 
			
		||||
  if a:bufnr == -2
 | 
			
		||||
    let [bufnr, path] = [a:path, a:bufnr]
 | 
			
		||||
    call gitgutter#utility#setbufvar(bufnr, 'path', path)
 | 
			
		||||
  else
 | 
			
		||||
    call gitgutter#utility#setbufvar(a:bufnr, 'path', s:strip_trailing_new_line(a:path))
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#utility#cd_cmd(bufnr, cmd) abort
 | 
			
		||||
  let cd = s:unc_path(a:bufnr) ? 'pushd' : (gitgutter#utility#windows() ? 'cd /d' : 'cd')
 | 
			
		||||
  return cd.' '.s:dir(a:bufnr).' && '.a:cmd
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:unc_path(bufnr)
 | 
			
		||||
  return s:abs_path(a:bufnr, 0) =~ '^\\\\'
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:use_known_shell() abort
 | 
			
		||||
  if has('unix') && &shell !=# 'sh'
 | 
			
		||||
    let [s:shell, s:shellcmdflag, s:shellredir] = [&shell, &shellcmdflag, &shellredir]
 | 
			
		||||
    let &shell = 'sh'
 | 
			
		||||
    set shellcmdflag=-c shellredir=>%s\ 2>&1
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:restore_shell() abort
 | 
			
		||||
  if has('unix') && exists('s:shell')
 | 
			
		||||
    let [&shell, &shellcmdflag, &shellredir] = [s:shell, s:shellcmdflag, s:shellredir]
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:abs_path(bufnr, shellesc)
 | 
			
		||||
  let p = resolve(expand('#'.a:bufnr.':p'))
 | 
			
		||||
  return a:shellesc ? gitgutter#utility#shellescape(p) : p
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:dir(bufnr) abort
 | 
			
		||||
  return gitgutter#utility#shellescape(fnamemodify(s:abs_path(a:bufnr, 0), ':h'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
" Not shellescaped.
 | 
			
		||||
function! s:filename(bufnr) abort
 | 
			
		||||
  return fnamemodify(s:abs_path(a:bufnr, 0), ':t')
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:exists_file(bufnr) abort
 | 
			
		||||
  return filereadable(s:abs_path(a:bufnr, 0))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! s:strip_trailing_new_line(line) abort
 | 
			
		||||
  return substitute(a:line, '\n$', '', '')
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! gitgutter#utility#windows()
 | 
			
		||||
  return has('win64') || has('win32') || has('win16')
 | 
			
		||||
endfunction
 | 
			
		||||
							
								
								
									
										529
									
								
								vim/plugins/vim-gitgutter/doc/gitgutter.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										529
									
								
								vim/plugins/vim-gitgutter/doc/gitgutter.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,529 @@
 | 
			
		||||
*gitgutter.txt*              A Vim plugin which shows a git diff in the gutter.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                           Vim Git Gutter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Author:            Andy Stewart <https://airbladesoftware.com/>
 | 
			
		||||
Plugin Homepage:   <https://github.com/airblade/vim-gitgutter>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
===============================================================================
 | 
			
		||||
CONTENTS                                                            *gitgutter*
 | 
			
		||||
 | 
			
		||||
  Introduction ................. |gitgutter-introduction|
 | 
			
		||||
  Installation ................. |gitgutter-installation|
 | 
			
		||||
  Commands ..................... |gitgutter-commands|
 | 
			
		||||
  Mappings ..................... |gitgutter-mappings|
 | 
			
		||||
  Autocommand .................. |gitgutter-autocommand|
 | 
			
		||||
  Options ...................... |gitgutter-options|
 | 
			
		||||
  Highlights ................... |gitgutter-highlights|
 | 
			
		||||
  FAQ .......................... |gitgutter-faq|
 | 
			
		||||
  TROUBLESHOOTING .............. |gitgutter-troubleshooting|
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
===============================================================================
 | 
			
		||||
INTRODUCTION                                           *gitgutter-introduction*
 | 
			
		||||
 | 
			
		||||
GitGutter is a Vim plugin which shows a git diff in the 'gutter' (sign column).
 | 
			
		||||
It shows which lines have been added, modified, or removed.  You can also
 | 
			
		||||
preview, stage, and undo individual hunks.  The plugin also provides a hunk
 | 
			
		||||
text object.
 | 
			
		||||
 | 
			
		||||
The signs are always up to date and the plugin never saves your buffer.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
===============================================================================
 | 
			
		||||
INSTALLATION                                           *gitgutter-installation*
 | 
			
		||||
 | 
			
		||||
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|.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
===============================================================================
 | 
			
		||||
COMMANDS                                                   *gitgutter-commands*
 | 
			
		||||
 | 
			
		||||
Commands for turning vim-gitgutter on and off:~
 | 
			
		||||
 | 
			
		||||
                                                  *gitgutter-:GitGutterDisable*
 | 
			
		||||
:GitGutterDisable       Turn vim-gitgutter off for all buffers.
 | 
			
		||||
 | 
			
		||||
                                                   *gitgutter-:GitGutterEnable*
 | 
			
		||||
:GitGutterEnable        Turn vim-gitgutter on for all buffers.
 | 
			
		||||
 | 
			
		||||
                                                   *gitgutter-:GitGutterToggle*
 | 
			
		||||
:GitGutterToggle        Toggle vim-gitgutter on or off for all buffers.
 | 
			
		||||
 | 
			
		||||
                                                         *gitgutter-:GitGutter*
 | 
			
		||||
:GitGutter              Update signs for the current buffer.  You shouldn't
 | 
			
		||||
                        need to run this.
 | 
			
		||||
 | 
			
		||||
                                                      *gitgutter-:GitGutterAll*
 | 
			
		||||
:GitGutterAll           Update signs for all buffers.  You shouldn't need to
 | 
			
		||||
                        run this.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Commands for turning signs on and off (defaults to on):~
 | 
			
		||||
 | 
			
		||||
                                              *gitgutter-:GitGutterSignsEnable*
 | 
			
		||||
:GitGutterSignsEnable   Show signs for the diff.
 | 
			
		||||
 | 
			
		||||
                                             *gitgutter-:GitGutterSignsDisable*
 | 
			
		||||
:GitGutterSignsDisable  Do not show signs for the diff.
 | 
			
		||||
 | 
			
		||||
                                              *gitgutter-:GitGutterSignsToggle*
 | 
			
		||||
:GitGutterSignsToggle   Toggle signs on or off.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Commands for turning line highlighting on and off (defaults to off):~
 | 
			
		||||
 | 
			
		||||
                                     *gitgutter-:GitGutterLineHighlightsEnable*
 | 
			
		||||
:GitGutterLineHighlightsEnable  Turn on line highlighting.
 | 
			
		||||
 | 
			
		||||
                                    *gitgutter-:GitGutterLineHighlightsDisable*
 | 
			
		||||
:GitGutterLineHighlightsDisable Turn off line highlighting.
 | 
			
		||||
 | 
			
		||||
                                     *gitgutter-:GitGutterLineHighlightsToggle*
 | 
			
		||||
:GitGutterLineHighlightsToggle  Turn line highlighting on or off.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Commands for jumping between hunks:~
 | 
			
		||||
 | 
			
		||||
                                                 *gitgutter-:GitGutterNextHunk*
 | 
			
		||||
:GitGutterNextHunk      Jump to the next [count] hunk.
 | 
			
		||||
 | 
			
		||||
                                                 *gitgutter-:GitGutterPrevHunk*
 | 
			
		||||
:GitGutterPrevHunk      Jump to the previous [count] hunk.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Commands for operating on a hunk:~
 | 
			
		||||
 | 
			
		||||
                                                *gitgutter-:GitGutterStageHunk*
 | 
			
		||||
:GitGutterStageHunk     Stage the hunk the cursor is in.
 | 
			
		||||
 | 
			
		||||
                                                 *gitgutter-:GitGutterUndoHunk*
 | 
			
		||||
:GitGutterUndoHunk      Undo the hunk the cursor is in.
 | 
			
		||||
 | 
			
		||||
                                              *gitgutter-:GitGutterPreviewHunk*
 | 
			
		||||
:GitGutterPreviewHunk   Preview the hunk the cursor is in.
 | 
			
		||||
                        Use |:pclose| or |CTRL-W_CTRL-Z| to close the preview
 | 
			
		||||
                        window.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
===============================================================================
 | 
			
		||||
AUTOCOMMAND                                             *gitgutter-autocommand*
 | 
			
		||||
 | 
			
		||||
User GitGutter~
 | 
			
		||||
 | 
			
		||||
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()
 | 
			
		||||
<
 | 
			
		||||
A dictionary `g:gitgutter_hook_context` is made available during its execution,
 | 
			
		||||
which contains an entry `bufnr` that contains the buffer number being updated.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
===============================================================================
 | 
			
		||||
MAPPINGS                                                   *gitgutter-mappings*
 | 
			
		||||
 | 
			
		||||
You can disable all these mappings with:
 | 
			
		||||
>
 | 
			
		||||
    let g:gitgutter_map_keys = 0
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
Hunk operations:~
 | 
			
		||||
 | 
			
		||||
These can be repeated with `.` if you have vim-repeat installed.
 | 
			
		||||
 | 
			
		||||
                                                         *gitgutter-<Leader>hp*
 | 
			
		||||
<Leader>hp              Preview the hunk under the cursor.
 | 
			
		||||
 | 
			
		||||
                                                         *gitgutter-<Leader>hs*
 | 
			
		||||
<Leader>hs              Stage the hunk under the cursor.
 | 
			
		||||
 | 
			
		||||
                                                         *gitgutter-<Leader>hu*
 | 
			
		||||
<Leader>hu              Undo the hunk under the cursor.
 | 
			
		||||
 | 
			
		||||
You can change these mappings like this:
 | 
			
		||||
>
 | 
			
		||||
    nmap ghp <Plug>GitGutterPreviewHunk
 | 
			
		||||
    nmap ghs <Plug>GitGutterStageHunk
 | 
			
		||||
    nmap ghu <Plug>GitGutterUndoHunk
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
Hunk jumping:~
 | 
			
		||||
 | 
			
		||||
                                                                 *gitgutter-]c*
 | 
			
		||||
]c                      Jump to the next [count] hunk.
 | 
			
		||||
 | 
			
		||||
                                                                 *gitgutter-[c*
 | 
			
		||||
[c                      Jump to the previous [count] hunk.
 | 
			
		||||
 | 
			
		||||
You can change these mappings like this:
 | 
			
		||||
>
 | 
			
		||||
    nmap [c <Plug>GitGutterPrevHunk
 | 
			
		||||
    nmap ]c <Plug>GitGutterNextHunk
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
Hunk text object:~
 | 
			
		||||
 | 
			
		||||
                          *gitgutter-ic* *gitgutter-ac* *gitgutter-text-object*
 | 
			
		||||
"ic" operates on the current hunk's lines.  "ac" does the same but also includes
 | 
			
		||||
trailing empty lines.
 | 
			
		||||
>
 | 
			
		||||
    omap ic <Plug>GitGutterTextObjectInnerPending
 | 
			
		||||
    omap ac <Plug>GitGutterTextObjectOuterPending
 | 
			
		||||
    xmap ic <Plug>GitGutterTextObjectInnerVisual
 | 
			
		||||
    xmap ac <Plug>GitGutterTextObjectOuterVisual
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
===============================================================================
 | 
			
		||||
OPTIONS                                                     *gitgutter-options*
 | 
			
		||||
 | 
			
		||||
The most important option is 'updatetime' which determines how long (in
 | 
			
		||||
milliseconds) the plugin will wait after you stop typing before it updates the
 | 
			
		||||
signs.  Vim's default is 4000.  I recommend 100.
 | 
			
		||||
 | 
			
		||||
Most important option:~
 | 
			
		||||
 | 
			
		||||
    'updatetime'
 | 
			
		||||
 | 
			
		||||
Git:~
 | 
			
		||||
 | 
			
		||||
    |g:gitgutter_git_executable|
 | 
			
		||||
    |g:gitgutter_diff_args|
 | 
			
		||||
    |g:gitgutter_diff_base|
 | 
			
		||||
 | 
			
		||||
Grep:~
 | 
			
		||||
 | 
			
		||||
    |g:gitgutter_grep|
 | 
			
		||||
 | 
			
		||||
Signs:~
 | 
			
		||||
 | 
			
		||||
    |g:gitgutter_signs|
 | 
			
		||||
    |g:gitgutter_highlight_lines|
 | 
			
		||||
    |g:gitgutter_max_signs|
 | 
			
		||||
    |g:gitgutter_sign_added|
 | 
			
		||||
    |g:gitgutter_sign_modified|
 | 
			
		||||
    |g:gitgutter_sign_removed|
 | 
			
		||||
    |g:gitgutter_sign_removed_first_line|
 | 
			
		||||
    |g:gitgutter_sign_modified_removed|
 | 
			
		||||
    |g:gitgutter_sign_column_always|
 | 
			
		||||
    |g:gitgutter_override_sign_column_highlight|
 | 
			
		||||
 | 
			
		||||
Terminal:~
 | 
			
		||||
 | 
			
		||||
    |g:gitgutter_terminal_reports_focus|
 | 
			
		||||
 | 
			
		||||
General:~
 | 
			
		||||
 | 
			
		||||
    |g:gitgutter_enabled|
 | 
			
		||||
    |g:gitgutter_map_keys|
 | 
			
		||||
    |g:gitgutter_async|
 | 
			
		||||
    |g:gitgutter_log|
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                                                   *g:gitgutter_git_executable*
 | 
			
		||||
Default: 'git'
 | 
			
		||||
 | 
			
		||||
This option determines what git binary to use.  Set this if git is not on your
 | 
			
		||||
path.
 | 
			
		||||
 | 
			
		||||
                                                        *g:gitgutter_diff_args*
 | 
			
		||||
Default: empty
 | 
			
		||||
 | 
			
		||||
Use this option to pass any extra arguments to git-diff.  For example:
 | 
			
		||||
>
 | 
			
		||||
    let g:gitgutter_diff_args = '-w'
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
                                                        *g:gitgutter_diff_base*
 | 
			
		||||
Default: empty
 | 
			
		||||
 | 
			
		||||
By default buffers are diffed against the index.  Use this option to diff against
 | 
			
		||||
a revision instead.  For example:
 | 
			
		||||
>
 | 
			
		||||
    let g:gitgutter_diff_base = '<some commit SHA>'
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
                                                             *g:gitgutter_grep*
 | 
			
		||||
Default: 'grep'
 | 
			
		||||
 | 
			
		||||
The plugin pipes the output of git-diff into grep to minimise the amount of data
 | 
			
		||||
vim has to process.  Set this option if grep is not on your path.
 | 
			
		||||
 | 
			
		||||
grep must produce plain-text output without any ANSI escape codes or colours.
 | 
			
		||||
Use this option to turn off colours if necessary.
 | 
			
		||||
>
 | 
			
		||||
    let g:gitgutter_grep = 'grep --color=never'
 | 
			
		||||
<
 | 
			
		||||
If you do not want to use grep at all (perhaps to debug why signs are not
 | 
			
		||||
showing), set this option to an empty string:
 | 
			
		||||
>
 | 
			
		||||
    let g:gitgutter_grep = ''
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
                                                            *g:gitgutter_signs*
 | 
			
		||||
Default: 1
 | 
			
		||||
 | 
			
		||||
Determines whether or not to show signs.
 | 
			
		||||
 | 
			
		||||
                                                  *g:gitgutter_highlight_lines*
 | 
			
		||||
Default: 0
 | 
			
		||||
 | 
			
		||||
Determines whether or not to show line highlights.
 | 
			
		||||
 | 
			
		||||
                                                        *g:gitgutter_max_signs*
 | 
			
		||||
Default: 500
 | 
			
		||||
 | 
			
		||||
Sets the maximum number of signs to show in a buffer.  Vim is slow at updating
 | 
			
		||||
signs, so to avoid slowing down the GUI the number of signs is capped.  When
 | 
			
		||||
the number of changed lines exceeds this value, the plugin removes all signs
 | 
			
		||||
and displays a warning message.
 | 
			
		||||
 | 
			
		||||
                                          *g:gitgutter_sign_added*
 | 
			
		||||
                                          *g:gitgutter_sign_modified*
 | 
			
		||||
                                          *g:gitgutter_sign_removed*
 | 
			
		||||
                                          *g:gitgutter_sign_removed_first_line*
 | 
			
		||||
                                          *g:gitgutter_sign_modified_removed*
 | 
			
		||||
Defaults:
 | 
			
		||||
>
 | 
			
		||||
    let g:gitgutter_sign_added              = '+'
 | 
			
		||||
    let g:gitgutter_sign_modified           = '~'
 | 
			
		||||
    let g:gitgutter_sign_removed            = '_'
 | 
			
		||||
    let g:gitgutter_sign_removed_first_line = '‾'
 | 
			
		||||
    let g:gitgutter_sign_modified_removed   = '~_'
 | 
			
		||||
<
 | 
			
		||||
You can use unicode characters but not images.  Signs must not take up more than
 | 
			
		||||
2 columns.
 | 
			
		||||
 | 
			
		||||
                                               *g:gitgutter_sign_column_always*
 | 
			
		||||
Default: 0
 | 
			
		||||
 | 
			
		||||
This legacy option controls whether the sign column should always be shown, even
 | 
			
		||||
if there are no signs to display.
 | 
			
		||||
 | 
			
		||||
From Vim 7.4.2201, use 'signcolumn' instead:
 | 
			
		||||
>
 | 
			
		||||
    set signcolumn=yes
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
                                   *g:gitgutter_override_sign_column_highlight*
 | 
			
		||||
Default: 1
 | 
			
		||||
 | 
			
		||||
Controls whether to 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}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                                           *g:gitgutter_terminal_reports_focus*
 | 
			
		||||
Default: 1
 | 
			
		||||
 | 
			
		||||
Normally the plugin uses |FocusGained| to force-update all buffers when Vim
 | 
			
		||||
receives focus.  However some terminals do not report focus events and so the
 | 
			
		||||
|FocusGained| autocommand never fires.
 | 
			
		||||
 | 
			
		||||
If this applies to you, either install something like Terminus
 | 
			
		||||
(https://github.com/wincent/terminus) to make |FocusGained| work or set this
 | 
			
		||||
option to 0.
 | 
			
		||||
 | 
			
		||||
When this option is 0, the plugin force-updates the buffer on |BufEnter|
 | 
			
		||||
(instead of only updating if the buffer's contents has changed since the last
 | 
			
		||||
update).
 | 
			
		||||
 | 
			
		||||
                                                          *g:gitgutter_enabled*
 | 
			
		||||
Default: 1
 | 
			
		||||
 | 
			
		||||
Controls whether or not the plugin is on at startup.
 | 
			
		||||
 | 
			
		||||
                                                         *g:gitgutter_map_keys*
 | 
			
		||||
Default: 1
 | 
			
		||||
 | 
			
		||||
Controls whether or not the plugin provides mappings.  See |gitgutter-mapppings|.
 | 
			
		||||
 | 
			
		||||
                                                            *g:gitgutter_async*
 | 
			
		||||
Default: 1
 | 
			
		||||
 | 
			
		||||
Controls whether or not diffs are run in the background.  This has no effect if
 | 
			
		||||
your Vim does not support background jobs.
 | 
			
		||||
 | 
			
		||||
                                                              *g:gitgutter_log*
 | 
			
		||||
Default: 0
 | 
			
		||||
 | 
			
		||||
When switched on, the plugin logs to gitgutter.log in the directory where it is
 | 
			
		||||
installed.  Additionally it logs channel activity to channel.log.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
===============================================================================
 | 
			
		||||
HIGHLIGHTS                                               *gitgutter-highlights*
 | 
			
		||||
 | 
			
		||||
To change the signs' 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 change the line highlights, 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
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
===============================================================================
 | 
			
		||||
FAQ                                                             *gitgutter-faq*
 | 
			
		||||
 | 
			
		||||
a. How do I turn off realtime updates?
 | 
			
		||||
 | 
			
		||||
  Add this to your vim configuration in an |after-directory|:
 | 
			
		||||
>
 | 
			
		||||
    autocmd! gitgutter CursorHold,CursorHoldI
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
b. I turned off realtime updates, how can I have signs updated when I save a
 | 
			
		||||
   file?
 | 
			
		||||
 | 
			
		||||
  If you really want to update the signs when you save a file, add this to your
 | 
			
		||||
  |vimrc|:
 | 
			
		||||
>
 | 
			
		||||
    autocmd BufWritePost * GitGutter
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
c. Why can't I unstage staged changes?
 | 
			
		||||
 | 
			
		||||
  This plugin is for showing changes between the working tree and the index
 | 
			
		||||
  (and staging/undoing those changes). Unstaging a staged hunk would require
 | 
			
		||||
  showing changes between the index and HEAD, which is out of scope.
 | 
			
		||||
 | 
			
		||||
d. Why are the colours in the sign column weird?
 | 
			
		||||
 | 
			
		||||
  Your colorscheme is configuring the |hl-SignColumn| highlight group weirdly.
 | 
			
		||||
  Please see |g:gitgutter_override_sign_column_highlight| on customising the
 | 
			
		||||
  sign column.
 | 
			
		||||
 | 
			
		||||
e. What happens if I also use another plugin which uses signs (e.g. Syntastic)?
 | 
			
		||||
 | 
			
		||||
  Vim only allows one sign per line.  Vim-gitgutter will not interfere with
 | 
			
		||||
  signs it did not add.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
===============================================================================
 | 
			
		||||
TROUBLESHOOTING                                     *gitgutter-troubleshooting*
 | 
			
		||||
 | 
			
		||||
When no signs are showing at all:~
 | 
			
		||||
 | 
			
		||||
1. Try bypassing grep with:
 | 
			
		||||
>
 | 
			
		||||
    let g:gitgutter_grep = ''
 | 
			
		||||
<
 | 
			
		||||
  If it works, the problem is grep outputting ANSI escape codes.  Use this
 | 
			
		||||
  option to pass arguments to grep to turn off the escape codes.
 | 
			
		||||
 | 
			
		||||
2. Verify git is on your path:
 | 
			
		||||
>
 | 
			
		||||
    :echo system('git --version')
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
3. Verify your git config is compatible with the version of git return by the
 | 
			
		||||
   command above.
 | 
			
		||||
 | 
			
		||||
4. Verify your Vim supports signs.  The following should give 1:
 | 
			
		||||
>
 | 
			
		||||
    :echo has('signs')
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
5. Check whether the plugin thinks git knows about your file:
 | 
			
		||||
>
 | 
			
		||||
    :echo getbufvar('','gitgutter').path
 | 
			
		||||
<
 | 
			
		||||
  If the result is -2, the plugin thinks your file is not tracked by git.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
When the whole file is marked as added:~
 | 
			
		||||
 | 
			
		||||
If you use zsh, and you set "CDPATH", make sure "CDPATH" does not include the
 | 
			
		||||
current directory.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
When signs take a few seconds to appear:~
 | 
			
		||||
 | 
			
		||||
Try reducing 'updatetime':
 | 
			
		||||
>
 | 
			
		||||
    set updatetime=100
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
When signs don't update after focusing Vim:~
 | 
			
		||||
 | 
			
		||||
Your terminal probably isn't reporting focus events.  Either try installing
 | 
			
		||||
Terminus (https://github.com/wincent/terminus) or set:
 | 
			
		||||
>
 | 
			
		||||
    let g:gitgutter_terminal_reports_focus = 0
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										214
									
								
								vim/plugins/vim-gitgutter/plugin/gitgutter.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								vim/plugins/vim-gitgutter/plugin/gitgutter.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,214 @@
 | 
			
		||||
scriptencoding utf-8
 | 
			
		||||
 | 
			
		||||
if exists('g:loaded_gitgutter') || !has('signs') || &cp
 | 
			
		||||
  finish
 | 
			
		||||
endif
 | 
			
		||||
let g:loaded_gitgutter = 1
 | 
			
		||||
 | 
			
		||||
" Initialisation {{{
 | 
			
		||||
 | 
			
		||||
if v:version < 703 || (v:version == 703 && !has("patch105"))
 | 
			
		||||
  call gitgutter#utility#warn('requires Vim 7.3.105')
 | 
			
		||||
  finish
 | 
			
		||||
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)
 | 
			
		||||
if g:gitgutter_sign_column_always && exists('&signcolumn')
 | 
			
		||||
  " Vim 7.4.2201.
 | 
			
		||||
  set signcolumn=yes
 | 
			
		||||
  let g:gitgutter_sign_column_always = 0
 | 
			
		||||
  call gitgutter#utility#warn('please replace "let g:gitgutter_sign_column_always=1" with "set signcolumn=yes"')
 | 
			
		||||
endif
 | 
			
		||||
call s:set('g:gitgutter_override_sign_column_highlight', 1)
 | 
			
		||||
call s:set('g:gitgutter_sign_added',                '+')
 | 
			
		||||
call s:set('g:gitgutter_sign_modified',             '~')
 | 
			
		||||
call s:set('g:gitgutter_sign_removed',              '_')
 | 
			
		||||
 | 
			
		||||
if gitgutter#utility#supports_overscore_sign()
 | 
			
		||||
  call s:set('g:gitgutter_sign_removed_first_line', '‾')
 | 
			
		||||
else
 | 
			
		||||
  call s:set('g:gitgutter_sign_removed_first_line', '_^')
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
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_terminal_reports_focus',      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
 | 
			
		||||
 | 
			
		||||
let default_grep = 'grep'
 | 
			
		||||
call s:set('g:gitgutter_grep', default_grep)
 | 
			
		||||
if !empty(g:gitgutter_grep)
 | 
			
		||||
  if executable(split(g:gitgutter_grep)[0])
 | 
			
		||||
    if $GREP_OPTIONS =~# '--color=always'
 | 
			
		||||
      let g:gitgutter_grep .= ' --color=never'
 | 
			
		||||
    endif
 | 
			
		||||
  else
 | 
			
		||||
    if g:gitgutter_grep !=# default_grep
 | 
			
		||||
      call gitgutter#utility#warn('cannot find '.g:gitgutter_grep.'. Please check g:gitgutter_grep.')
 | 
			
		||||
    endif
 | 
			
		||||
    let g:gitgutter_grep = ''
 | 
			
		||||
  endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
call gitgutter#highlight#define_sign_column_highlight()
 | 
			
		||||
call gitgutter#highlight#define_highlights()
 | 
			
		||||
call gitgutter#highlight#define_signs()
 | 
			
		||||
 | 
			
		||||
" Prevent infinite loop where:
 | 
			
		||||
" - executing a job in the foreground launches a new window which takes the focus;
 | 
			
		||||
" - when the job finishes, focus returns to gvim;
 | 
			
		||||
" - the FocusGained event triggers a new job (see below).
 | 
			
		||||
if gitgutter#utility#windows() && !(g:gitgutter_async && gitgutter#async#available())
 | 
			
		||||
  set noshelltemp
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
" }}}
 | 
			
		||||
 | 
			
		||||
" Primary functions {{{
 | 
			
		||||
 | 
			
		||||
command! -bar GitGutterAll call gitgutter#all(1)
 | 
			
		||||
command! -bar GitGutter    call gitgutter#process_buffer(bufnr(''), 1)
 | 
			
		||||
 | 
			
		||||
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#highlight#line_disable()
 | 
			
		||||
command! -bar GitGutterLineHighlightsEnable  call gitgutter#highlight#line_enable()
 | 
			
		||||
command! -bar GitGutterLineHighlightsToggle  call gitgutter#highlight#line_toggle()
 | 
			
		||||
 | 
			
		||||
" }}}
 | 
			
		||||
 | 
			
		||||
" Signs {{{
 | 
			
		||||
 | 
			
		||||
command! -bar GitGutterSignsEnable  call gitgutter#sign#enable()
 | 
			
		||||
command! -bar GitGutterSignsDisable call gitgutter#sign#disable()
 | 
			
		||||
command! -bar GitGutterSignsToggle  call gitgutter#sign#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#hunk#stage()
 | 
			
		||||
command! -bar GitGutterUndoHunk    call gitgutter#hunk#undo()
 | 
			
		||||
command! -bar GitGutterPreviewHunk call gitgutter#hunk#preview()
 | 
			
		||||
 | 
			
		||||
" 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()
 | 
			
		||||
  let bufnr = bufnr('')
 | 
			
		||||
  return gitgutter#utility#is_active(bufnr) ? gitgutter#hunk#hunks(bufnr) : []
 | 
			
		||||
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>"
 | 
			
		||||
 | 
			
		||||
nnoremap <silent> <Plug>GitGutterStageHunk   :GitGutterStageHunk<CR>
 | 
			
		||||
nnoremap <silent> <Plug>GitGutterUndoHunk    :GitGutterUndoHunk<CR>
 | 
			
		||||
nnoremap <silent> <Plug>GitGutterPreviewHunk :GitGutterPreviewHunk<CR>
 | 
			
		||||
 | 
			
		||||
" }}}
 | 
			
		||||
 | 
			
		||||
function! s:on_bufenter()
 | 
			
		||||
  if exists('t:gitgutter_didtabenter') && t:gitgutter_didtabenter
 | 
			
		||||
    let t:gitgutter_didtabenter = 0
 | 
			
		||||
    call gitgutter#all(!g:gitgutter_terminal_reports_focus)
 | 
			
		||||
  else
 | 
			
		||||
    call gitgutter#init_buffer(bufnr(''))
 | 
			
		||||
    call gitgutter#process_buffer(bufnr(''), !g:gitgutter_terminal_reports_focus)
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
" Autocommands {{{
 | 
			
		||||
 | 
			
		||||
augroup gitgutter
 | 
			
		||||
  autocmd!
 | 
			
		||||
 | 
			
		||||
  autocmd TabEnter * let t:gitgutter_didtabenter = 1
 | 
			
		||||
 | 
			
		||||
  autocmd BufEnter * call s:on_bufenter()
 | 
			
		||||
 | 
			
		||||
  autocmd CursorHold,CursorHoldI * call gitgutter#process_buffer(bufnr(''), 0)
 | 
			
		||||
  autocmd FileChangedShellPost   * call gitgutter#process_buffer(bufnr(''), 1)
 | 
			
		||||
 | 
			
		||||
  " Ensure that all buffers are processed when opening vim with multiple files, e.g.:
 | 
			
		||||
  "
 | 
			
		||||
  "   vim -o file1 file2
 | 
			
		||||
  autocmd VimEnter * if winnr() != winnr('$') | call gitgutter#all(0) | endif
 | 
			
		||||
 | 
			
		||||
  autocmd FocusGained,ShellCmdPost * call gitgutter#all(1)
 | 
			
		||||
 | 
			
		||||
  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:
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								vim/plugins/vim-gitgutter/screenshot.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								vim/plugins/vim-gitgutter/screenshot.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 16 KiB  | 
							
								
								
									
										8
									
								
								vim/plugins/vim-gitgutter/test/cp932.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vim/plugins/vim-gitgutter/test/cp932.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
The quick brown fox jumps
 | 
			
		||||
over the lazy dog
 | 
			
		||||
 | 
			
		||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͂ɂقւƂ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʂ<EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
<EFBFBD>킩<EFBFBD>悽<EFBFBD>ꂻ<EFBFBD>˂Ȃ<EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD>ӂ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߂݂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ђ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								vim/plugins/vim-gitgutter/test/fixture.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vim/plugins/vim-gitgutter/test/fixture.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
a
 | 
			
		||||
b
 | 
			
		||||
c
 | 
			
		||||
d
 | 
			
		||||
e
 | 
			
		||||
f
 | 
			
		||||
g
 | 
			
		||||
h
 | 
			
		||||
i
 | 
			
		||||
j
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										162
									
								
								vim/plugins/vim-gitgutter/test/runner.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								vim/plugins/vim-gitgutter/test/runner.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,162 @@
 | 
			
		||||
"
 | 
			
		||||
" Adapted from https://github.com/vim/vim/blob/master/src/testdir/runtest.vim
 | 
			
		||||
"
 | 
			
		||||
" When debugging tests it can help to write debug output:
 | 
			
		||||
"    call Log('oh noes')
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
function RunTest(test)
 | 
			
		||||
  if exists("*SetUp")
 | 
			
		||||
    call SetUp()
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  try
 | 
			
		||||
    execute 'call '.a:test
 | 
			
		||||
  catch
 | 
			
		||||
    call Exception()
 | 
			
		||||
    let s:errored = 1
 | 
			
		||||
  endtry
 | 
			
		||||
 | 
			
		||||
  if exists("*TearDown")
 | 
			
		||||
    call TearDown()
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function Log(msg)
 | 
			
		||||
  if type(a:msg) == type('')
 | 
			
		||||
    call add(s:messages, a:msg)
 | 
			
		||||
  elseif type(a:msg) == type([])
 | 
			
		||||
    call extend(s:messages, a:msg)
 | 
			
		||||
  else
 | 
			
		||||
    call add(v:errors, 'Exception: unsupported type: '.type(a:msg))
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function Exception()
 | 
			
		||||
  call add(v:errors, v:throwpoint.'..'.'Exception: '.v:exception)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
" Shuffles list in place.
 | 
			
		||||
function Shuffle(list)
 | 
			
		||||
  " Fisher-Yates-Durstenfeld-Knuth
 | 
			
		||||
  let n = len(a:list)
 | 
			
		||||
  if n < 2
 | 
			
		||||
    return a:list
 | 
			
		||||
  endif
 | 
			
		||||
  for i in range(0, n-2)
 | 
			
		||||
    let j = Random(0, n-i-1)
 | 
			
		||||
    let e = a:list[i]
 | 
			
		||||
    let a:list[i] = a:list[i+j]
 | 
			
		||||
    let a:list[i+j] = e
 | 
			
		||||
  endfor
 | 
			
		||||
  return a:list
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
" Returns a pseudorandom integer i such that 0 <= i <= max
 | 
			
		||||
function Random(min, max)
 | 
			
		||||
  if has('unix')
 | 
			
		||||
    let i = system('echo $RANDOM')  " 0 <= i <= 32767
 | 
			
		||||
  else
 | 
			
		||||
    let i = system('echo %RANDOM%')  " 0 <= i <= 32767
 | 
			
		||||
  endif
 | 
			
		||||
  return i * (a:max - a:min + 1) / 32768 + a:min
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function FriendlyName(test_name)
 | 
			
		||||
  return substitute(a:test_name[5:-3], '_', ' ', 'g')
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function Align(left, right)
 | 
			
		||||
  if type(a:right) == type([])
 | 
			
		||||
    let result = []
 | 
			
		||||
    for s in a:right
 | 
			
		||||
      if empty(result)
 | 
			
		||||
        call add(result, printf('%-'.s:indent.'S', a:left).s)
 | 
			
		||||
      else
 | 
			
		||||
        call add(result, printf('%-'.s:indent.'S',     '').s)
 | 
			
		||||
      endif
 | 
			
		||||
    endfor
 | 
			
		||||
    return result
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  return printf('%-'.s:indent.'S', a:left).a:right
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
let g:testname = expand('%')
 | 
			
		||||
let s:errored = 0
 | 
			
		||||
let s:done = 0
 | 
			
		||||
let s:fail = 0
 | 
			
		||||
let s:errors = 0
 | 
			
		||||
let s:messages = []
 | 
			
		||||
let s:indent = ''
 | 
			
		||||
 | 
			
		||||
call Log(g:testname.':')
 | 
			
		||||
 | 
			
		||||
" Source the test script.
 | 
			
		||||
try
 | 
			
		||||
  source %
 | 
			
		||||
catch
 | 
			
		||||
  let s:errors += 1
 | 
			
		||||
  call Exception()
 | 
			
		||||
endtry
 | 
			
		||||
 | 
			
		||||
" Locate the test functions.
 | 
			
		||||
set nomore
 | 
			
		||||
redir @q
 | 
			
		||||
silent function /^Test_
 | 
			
		||||
redir END
 | 
			
		||||
let s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g'))
 | 
			
		||||
 | 
			
		||||
" If there is another argument, filter test-functions' names against it.
 | 
			
		||||
if argc() > 1
 | 
			
		||||
  let s:tests = filter(s:tests, 'v:val =~ argv(1)')
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
let s:indent = max(map(copy(s:tests), {_, val -> len(FriendlyName(val))}))
 | 
			
		||||
 | 
			
		||||
" Run the tests in random order.
 | 
			
		||||
for test in Shuffle(s:tests)
 | 
			
		||||
  call RunTest(test)
 | 
			
		||||
  let s:done += 1
 | 
			
		||||
 | 
			
		||||
  let friendly_name = FriendlyName(test)
 | 
			
		||||
  if len(v:errors) == 0
 | 
			
		||||
    call Log(Align(friendly_name, ' - ok'))
 | 
			
		||||
  else
 | 
			
		||||
    if s:errored
 | 
			
		||||
      let s:errors += 1
 | 
			
		||||
      let s:errored = 0
 | 
			
		||||
    else
 | 
			
		||||
      let s:fail += 1
 | 
			
		||||
    endif
 | 
			
		||||
    call Log(Align(friendly_name, ' - not ok'))
 | 
			
		||||
 | 
			
		||||
    let i = 0
 | 
			
		||||
    for error in v:errors
 | 
			
		||||
      if i != 0
 | 
			
		||||
        call Log(Align('','   ! ----'))
 | 
			
		||||
      endif
 | 
			
		||||
      for trace in reverse(split(error, '\.\.'))
 | 
			
		||||
        call Log(Align('', '   ! '.trace))
 | 
			
		||||
      endfor
 | 
			
		||||
      let i += 1
 | 
			
		||||
    endfor
 | 
			
		||||
 | 
			
		||||
    let v:errors = []
 | 
			
		||||
  endif
 | 
			
		||||
endfor
 | 
			
		||||
 | 
			
		||||
let summary = [
 | 
			
		||||
      \ s:done.(  s:done   == 1 ? ' test'    : ' tests'),
 | 
			
		||||
      \ s:errors.(s:errors == 1 ? ' error'   : ' errors'),
 | 
			
		||||
      \ s:fail.(  s:fail   == 1 ? ' failure' : ' failures'),
 | 
			
		||||
      \ ]
 | 
			
		||||
call Log('')
 | 
			
		||||
call Log(join(summary, ', '))
 | 
			
		||||
 | 
			
		||||
split messages.log
 | 
			
		||||
call append(line('$'), s:messages)
 | 
			
		||||
write
 | 
			
		||||
 | 
			
		||||
qall!
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								vim/plugins/vim-gitgutter/test/test
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										21
									
								
								vim/plugins/vim-gitgutter/test/test
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
VIM="/Applications/MacVim.app/Contents/MacOS/Vim -v"
 | 
			
		||||
 | 
			
		||||
export VIM_GITGUTTER_TEST=1
 | 
			
		||||
 | 
			
		||||
$VIM -u NONE -U NONE -N                      \
 | 
			
		||||
  --cmd 'set rtp+=../'                       \
 | 
			
		||||
  --cmd 'let g:gitgutter_async=0'            \
 | 
			
		||||
  --cmd 'source ../plugin/gitgutter.vim'     \
 | 
			
		||||
  -S runner.vim                              \
 | 
			
		||||
  test_*.vim                                 \
 | 
			
		||||
  $*
 | 
			
		||||
 | 
			
		||||
cat messages.log
 | 
			
		||||
 | 
			
		||||
grep -q "0 errors, 0 failures" messages.log
 | 
			
		||||
status=$?
 | 
			
		||||
rm messages.log
 | 
			
		||||
exit $status
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										589
									
								
								vim/plugins/vim-gitgutter/test/test_gitgutter.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										589
									
								
								vim/plugins/vim-gitgutter/test/test_gitgutter.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,589 @@
 | 
			
		||||
let s:current_dir = expand('%:p:h')
 | 
			
		||||
let s:test_repo   = s:current_dir.'/test-repo'
 | 
			
		||||
let s:bufnr       = bufnr('')
 | 
			
		||||
 | 
			
		||||
"
 | 
			
		||||
" Helpers
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
function s:signs(filename)
 | 
			
		||||
  redir => signs
 | 
			
		||||
    silent execute 'sign place'
 | 
			
		||||
  redir END
 | 
			
		||||
 | 
			
		||||
  let signs = split(signs, '\n')
 | 
			
		||||
 | 
			
		||||
  " filter out signs for this test file
 | 
			
		||||
  " assumes a:filename's signs are last set listed
 | 
			
		||||
  let i = index(signs, 'Signs for '.a:filename.':')
 | 
			
		||||
  let signs = (i > -1 ? signs[i+1:] : [])
 | 
			
		||||
 | 
			
		||||
  call map(signs, {_, v -> substitute(v, '    ', '', '')})
 | 
			
		||||
 | 
			
		||||
  return signs
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function s:git_diff()
 | 
			
		||||
  return split(system('git diff -U0 fixture.txt'), '\n')
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function s:git_diff_staged()
 | 
			
		||||
  return split(system('git diff -U0 --staged fixture.txt'), '\n')
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function s:trigger_gitgutter()
 | 
			
		||||
  doautocmd CursorHold
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
"
 | 
			
		||||
" SetUp / TearDown
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
function SetUp()
 | 
			
		||||
  call system("git init ".s:test_repo.
 | 
			
		||||
        \ " && cd ".s:test_repo.
 | 
			
		||||
        \ " && cp ../fixture.txt .".
 | 
			
		||||
        \ " && git add . && git commit -m 'initial'".
 | 
			
		||||
        \ " && git config diff.mnemonicPrefix false")
 | 
			
		||||
  execute ':cd' s:test_repo
 | 
			
		||||
  edit! fixture.txt
 | 
			
		||||
  call gitgutter#sign#reset()
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function TearDown()
 | 
			
		||||
  " delete all buffers except this one
 | 
			
		||||
  " TODO: move to runner.vim, accounting for multiple test files
 | 
			
		||||
  if s:bufnr > 1
 | 
			
		||||
    silent! execute '1,'.s:bufnr-1.'bdelete!'
 | 
			
		||||
  endif
 | 
			
		||||
  silent! execute s:bufnr+1.',$bdelete!'
 | 
			
		||||
 | 
			
		||||
  execute ':cd' s:current_dir
 | 
			
		||||
  call system("rm -rf ".s:test_repo)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
"
 | 
			
		||||
" The tests
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
function Test_add_lines()
 | 
			
		||||
  normal ggo*
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = ["line=2  id=3000  name=GitGutterLineAdded"]
 | 
			
		||||
  call assert_equal(expected, s:signs('fixture.txt'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_add_lines_fish()
 | 
			
		||||
  let _shell = &shell
 | 
			
		||||
  set shell=/usr/local/bin/fish
 | 
			
		||||
 | 
			
		||||
  normal ggo*
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = ["line=2  id=3000  name=GitGutterLineAdded"]
 | 
			
		||||
  call assert_equal(expected, s:signs('fixture.txt'))
 | 
			
		||||
 | 
			
		||||
  let &shell = _shell
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_modify_lines()
 | 
			
		||||
  normal ggi*
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = ["line=1  id=3000  name=GitGutterLineModified"]
 | 
			
		||||
  call assert_equal(expected, s:signs('fixture.txt'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_remove_lines()
 | 
			
		||||
  execute '5d'
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = ["line=4  id=3000  name=GitGutterLineRemoved"]
 | 
			
		||||
  call assert_equal(expected, s:signs('fixture.txt'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_remove_first_lines()
 | 
			
		||||
  execute '1d'
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = ["line=1  id=3000  name=GitGutterLineRemovedFirstLine"]
 | 
			
		||||
  call assert_equal(expected, s:signs('fixture.txt'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_edit_file_with_same_name_as_a_branch()
 | 
			
		||||
  normal 5Gi*
 | 
			
		||||
  call system('git checkout -b fixture.txt')
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = ["line=5  id=3000  name=GitGutterLineModified"]
 | 
			
		||||
  call assert_equal(expected, s:signs('fixture.txt'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_file_added_to_git()
 | 
			
		||||
  let tmpfile = 'fileAddedToGit.tmp'
 | 
			
		||||
  call system('touch '.tmpfile.' && git add '.tmpfile)
 | 
			
		||||
  execute 'edit '.tmpfile
 | 
			
		||||
  normal ihello
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = ["line=1  id=3000  name=GitGutterLineAdded"]
 | 
			
		||||
  call assert_equal(expected, s:signs('fileAddedToGit.tmp'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_filename_with_equals()
 | 
			
		||||
  call system('touch =fixture=.txt && git add =fixture=.txt')
 | 
			
		||||
  edit =fixture=.txt
 | 
			
		||||
  normal ggo*
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = [
 | 
			
		||||
        \ 'line=1  id=3000  name=GitGutterLineAdded',
 | 
			
		||||
        \ 'line=2  id=3001  name=GitGutterLineAdded'
 | 
			
		||||
        \ ]
 | 
			
		||||
  call assert_equal(expected, s:signs('=fixture=.txt'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_filename_with_square_brackets()
 | 
			
		||||
  call system('touch fix[tu]re.txt && git add fix[tu]re.txt')
 | 
			
		||||
  edit fix[tu]re.txt
 | 
			
		||||
  normal ggo*
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = [
 | 
			
		||||
        \ 'line=1  id=3000  name=GitGutterLineAdded',
 | 
			
		||||
        \ 'line=2  id=3001  name=GitGutterLineAdded'
 | 
			
		||||
        \ ]
 | 
			
		||||
  call assert_equal(expected, s:signs('fix[tu]re.txt'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_filename_leading_dash()
 | 
			
		||||
  call system('touch -- -fixture.txt && git add -- -fixture.txt')
 | 
			
		||||
  edit -fixture.txt
 | 
			
		||||
  normal ggo*
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = [
 | 
			
		||||
        \ 'line=1  id=3000  name=GitGutterLineAdded',
 | 
			
		||||
        \ 'line=2  id=3001  name=GitGutterLineAdded'
 | 
			
		||||
        \ ]
 | 
			
		||||
  call assert_equal(expected, s:signs('-fixture.txt'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
" FIXME: this test fails when it is the first (or only) test to be run
 | 
			
		||||
function Test_follow_symlink()
 | 
			
		||||
  let tmp = 'symlink'
 | 
			
		||||
  call system('ln -nfs fixture.txt '.tmp)
 | 
			
		||||
  execute 'edit '.tmp
 | 
			
		||||
  6d
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = ['line=5  id=3000  name=GitGutterLineRemoved']
 | 
			
		||||
  call assert_equal(expected, s:signs('symlink'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_keep_alt()
 | 
			
		||||
  enew
 | 
			
		||||
  execute "normal! \<C-^>"
 | 
			
		||||
 | 
			
		||||
  call assert_equal('fixture.txt', bufname(''))
 | 
			
		||||
  call assert_equal('',            bufname('#'))
 | 
			
		||||
 | 
			
		||||
  normal ggx
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  call assert_equal('', bufname('#'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_keep_modified()
 | 
			
		||||
  normal 5Go*
 | 
			
		||||
  call assert_equal(1, getbufvar('', '&modified'))
 | 
			
		||||
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  call assert_equal(1, getbufvar('', '&modified'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_keep_op_marks()
 | 
			
		||||
  normal 5Go*
 | 
			
		||||
  call assert_equal([0,6,1,0], getpos("'["))
 | 
			
		||||
  call assert_equal([0,6,2,0], getpos("']"))
 | 
			
		||||
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  call assert_equal([0,6,1,0], getpos("'["))
 | 
			
		||||
  call assert_equal([0,6,2,0], getpos("']"))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_no_modifications()
 | 
			
		||||
  call assert_equal([], s:signs('fixture.txt'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_orphaned_signs()
 | 
			
		||||
  execute "normal 5GoX\<CR>Y"
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
  6d
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = ['line=6  id=3001  name=GitGutterLineAdded']
 | 
			
		||||
  call assert_equal(expected, s:signs('fixture.txt'))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_untracked_file_outside_repo()
 | 
			
		||||
  let tmp = tempname()
 | 
			
		||||
  call system('touch '.tmp)
 | 
			
		||||
  execute 'edit '.tmp
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:signs(tmp))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_untracked_file_within_repo()
 | 
			
		||||
  let tmp = 'untrackedFileWithinRepo.tmp'
 | 
			
		||||
  call system('touch '.tmp)
 | 
			
		||||
  execute 'edit '.tmp
 | 
			
		||||
  normal ggo*
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:signs(tmp))
 | 
			
		||||
 | 
			
		||||
  call system('rm '.tmp)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_untracked_file_square_brackets_within_repo()
 | 
			
		||||
  let tmp = '[un]trackedFileWithinRepo.tmp'
 | 
			
		||||
  call system('touch '.tmp)
 | 
			
		||||
  execute 'edit '.tmp
 | 
			
		||||
  normal ggo*
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:signs(tmp))
 | 
			
		||||
 | 
			
		||||
  call system('rm '.tmp)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_hunk_outside_noop()
 | 
			
		||||
  normal 5G
 | 
			
		||||
  GitGutterStageHunk
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:signs('fixture.txt'))
 | 
			
		||||
  call assert_equal([], s:git_diff())
 | 
			
		||||
  call assert_equal([], s:git_diff_staged())
 | 
			
		||||
 | 
			
		||||
  GitGutterUndoHunk
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:signs('fixture.txt'))
 | 
			
		||||
  call assert_equal([], s:git_diff())
 | 
			
		||||
  call assert_equal([], s:git_diff_staged())
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_hunk_stage()
 | 
			
		||||
  let _shell = &shell
 | 
			
		||||
  set shell=foo
 | 
			
		||||
 | 
			
		||||
  normal 5Gi*
 | 
			
		||||
  GitGutterStageHunk
 | 
			
		||||
 | 
			
		||||
  call assert_equal('foo', &shell)
 | 
			
		||||
  let &shell = _shell
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:signs('fixture.txt'))
 | 
			
		||||
 | 
			
		||||
  " Buffer is unsaved
 | 
			
		||||
  let expected = [
 | 
			
		||||
        \ 'diff --git a/fixture.txt b/fixture.txt',
 | 
			
		||||
        \ 'index ae8e546..f5c6aff 100644',
 | 
			
		||||
        \ '--- a/fixture.txt',
 | 
			
		||||
        \ '+++ b/fixture.txt',
 | 
			
		||||
        \ '@@ -5 +5 @@ d',
 | 
			
		||||
        \ '-*e',
 | 
			
		||||
        \ '+e'
 | 
			
		||||
        \ ]
 | 
			
		||||
  call assert_equal(expected, s:git_diff())
 | 
			
		||||
 | 
			
		||||
  " Index has been updated
 | 
			
		||||
  let expected = [
 | 
			
		||||
        \ 'diff --git a/fixture.txt b/fixture.txt',
 | 
			
		||||
        \ 'index f5c6aff..ae8e546 100644',
 | 
			
		||||
        \ '--- a/fixture.txt',
 | 
			
		||||
        \ '+++ b/fixture.txt',
 | 
			
		||||
        \ '@@ -5 +5 @@ d',
 | 
			
		||||
        \ '-e',
 | 
			
		||||
        \ '+*e'
 | 
			
		||||
        \ ]
 | 
			
		||||
  call assert_equal(expected, s:git_diff_staged())
 | 
			
		||||
 | 
			
		||||
  " Save the buffer
 | 
			
		||||
  write
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:git_diff())
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_hunk_stage_nearby_hunk()
 | 
			
		||||
  execute "normal! 2Gox\<CR>y\<CR>z"
 | 
			
		||||
  normal 2jdd
 | 
			
		||||
  normal k
 | 
			
		||||
  GitGutterStageHunk
 | 
			
		||||
 | 
			
		||||
  let expected = [
 | 
			
		||||
        \ 'line=3  id=3000  name=GitGutterLineAdded',
 | 
			
		||||
        \ 'line=4  id=3001  name=GitGutterLineAdded',
 | 
			
		||||
        \ 'line=5  id=3002  name=GitGutterLineAdded'
 | 
			
		||||
        \ ]
 | 
			
		||||
  call assert_equal(expected, s:signs('fixture.txt'))
 | 
			
		||||
 | 
			
		||||
  " Buffer is unsaved
 | 
			
		||||
  let expected = [
 | 
			
		||||
        \ 'diff --git a/fixture.txt b/fixture.txt',
 | 
			
		||||
        \ 'index 53b13df..f5c6aff 100644',
 | 
			
		||||
        \ '--- a/fixture.txt',
 | 
			
		||||
        \ '+++ b/fixture.txt',
 | 
			
		||||
        \ '@@ -3,0 +4 @@ c',
 | 
			
		||||
        \ '+d',
 | 
			
		||||
        \ ]
 | 
			
		||||
  call assert_equal(expected, s:git_diff())
 | 
			
		||||
 | 
			
		||||
  " Index has been updated
 | 
			
		||||
  let expected = [
 | 
			
		||||
        \ 'diff --git a/fixture.txt b/fixture.txt',
 | 
			
		||||
        \ 'index f5c6aff..53b13df 100644',
 | 
			
		||||
        \ '--- a/fixture.txt',
 | 
			
		||||
        \ '+++ b/fixture.txt',
 | 
			
		||||
        \ '@@ -4 +3,0 @@ c',
 | 
			
		||||
        \ '-d',
 | 
			
		||||
        \ ]
 | 
			
		||||
  call assert_equal(expected, s:git_diff_staged())
 | 
			
		||||
 | 
			
		||||
  " Save the buffer
 | 
			
		||||
  write
 | 
			
		||||
 | 
			
		||||
  let expected = [
 | 
			
		||||
        \ 'diff --git a/fixture.txt b/fixture.txt',
 | 
			
		||||
        \ 'index 53b13df..8fdfda7 100644',
 | 
			
		||||
        \ '--- a/fixture.txt',
 | 
			
		||||
        \ '+++ b/fixture.txt',
 | 
			
		||||
        \ '@@ -2,0 +3,3 @@ b',
 | 
			
		||||
        \ '+x',
 | 
			
		||||
        \ '+y',
 | 
			
		||||
        \ '+z',
 | 
			
		||||
        \ ]
 | 
			
		||||
  call assert_equal(expected, s:git_diff())
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_hunk_undo()
 | 
			
		||||
  let _shell = &shell
 | 
			
		||||
  set shell=foo
 | 
			
		||||
 | 
			
		||||
  normal 5Gi*
 | 
			
		||||
  GitGutterUndoHunk
 | 
			
		||||
 | 
			
		||||
  call assert_equal('foo', &shell)
 | 
			
		||||
  let &shell = _shell
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:signs('fixture.txt'))
 | 
			
		||||
  call assert_equal([], s:git_diff())
 | 
			
		||||
  call assert_equal([], s:git_diff_staged())
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_undo_nearby_hunk()
 | 
			
		||||
  execute "normal! 2Gox\<CR>y\<CR>z"
 | 
			
		||||
  normal 2jdd
 | 
			
		||||
  normal k
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
  GitGutterUndoHunk
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = [
 | 
			
		||||
        \ 'line=3  id=3000  name=GitGutterLineAdded',
 | 
			
		||||
        \ 'line=4  id=3001  name=GitGutterLineAdded',
 | 
			
		||||
        \ 'line=5  id=3002  name=GitGutterLineAdded'
 | 
			
		||||
        \ ]
 | 
			
		||||
  call assert_equal(expected, s:signs('fixture.txt'))
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:git_diff())
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:git_diff_staged())
 | 
			
		||||
 | 
			
		||||
  " Save the buffer
 | 
			
		||||
  write
 | 
			
		||||
 | 
			
		||||
  let expected = [
 | 
			
		||||
        \ 'diff --git a/fixture.txt b/fixture.txt',
 | 
			
		||||
        \ 'index f5c6aff..3fbde56 100644',
 | 
			
		||||
        \ '--- a/fixture.txt',
 | 
			
		||||
        \ '+++ b/fixture.txt',
 | 
			
		||||
        \ '@@ -2,0 +3,3 @@ b',
 | 
			
		||||
        \ '+x',
 | 
			
		||||
        \ '+y',
 | 
			
		||||
        \ '+z',
 | 
			
		||||
        \ ]
 | 
			
		||||
  call assert_equal(expected, s:git_diff())
 | 
			
		||||
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_write_option()
 | 
			
		||||
  set nowrite
 | 
			
		||||
 | 
			
		||||
  normal ggo*
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  let expected = ["line=2  id=3000  name=GitGutterLineAdded"]
 | 
			
		||||
  call assert_equal(expected, s:signs('fixture.txt'))
 | 
			
		||||
 | 
			
		||||
  set write
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_inner_text_object()
 | 
			
		||||
  execute "normal! 2Gox\<CR>y\<CR>z\<CR>\<CR>"
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
  normal dic
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:signs('fixture.txt'))
 | 
			
		||||
  call assert_equal(readfile('fixture.txt'), getline(1,'$'))
 | 
			
		||||
 | 
			
		||||
  " Excludes trailing lines
 | 
			
		||||
  normal 9Gi*
 | 
			
		||||
  normal 10Gi*
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
  execute "normal vic\<Esc>"
 | 
			
		||||
  call assert_equal([9, 10], [line("'<"), line("'>")])
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_around_text_object()
 | 
			
		||||
  execute "normal! 2Gox\<CR>y\<CR>z\<CR>\<CR>"
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
  normal dac
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:signs('fixture.txt'))
 | 
			
		||||
  call assert_equal(readfile('fixture.txt'), getline(1,'$'))
 | 
			
		||||
 | 
			
		||||
  " Includes trailing lines
 | 
			
		||||
  normal 9Gi*
 | 
			
		||||
  normal 10Gi*
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
  execute "normal vac\<Esc>"
 | 
			
		||||
  call assert_equal([9, 11], [line("'<"), line("'>")])
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_user_autocmd()
 | 
			
		||||
  autocmd User GitGutter let s:autocmd_user = g:gitgutter_hook_context.bufnr
 | 
			
		||||
 | 
			
		||||
  " Verify not fired when nothing changed.
 | 
			
		||||
  let s:autocmd_user = 0
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
  call assert_equal(0, s:autocmd_user)
 | 
			
		||||
 | 
			
		||||
  " Verify fired when there was a change.
 | 
			
		||||
  normal ggo*
 | 
			
		||||
  let bufnr = bufnr('')
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
  call assert_equal(bufnr, s:autocmd_user)
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_fix_file_references()
 | 
			
		||||
  " No special characters
 | 
			
		||||
  let hunk_diff = join([
 | 
			
		||||
        \ 'diff --git a/fixture.txt b/fixture.txt',
 | 
			
		||||
        \ 'index f5c6aff..3fbde56 100644',
 | 
			
		||||
        \ '--- a/fixture.txt',
 | 
			
		||||
        \ '+++ b/fixture.txt',
 | 
			
		||||
        \ '@@ -2,0 +3,1 @@ b',
 | 
			
		||||
        \ '+x'
 | 
			
		||||
        \ ], "\n")."\n"
 | 
			
		||||
  let filepath = 'blah.txt'
 | 
			
		||||
 | 
			
		||||
  let expected = join([
 | 
			
		||||
        \ 'diff --git a/blah.txt b/blah.txt',
 | 
			
		||||
        \ 'index f5c6aff..3fbde56 100644',
 | 
			
		||||
        \ '--- a/blah.txt',
 | 
			
		||||
        \ '+++ b/blah.txt',
 | 
			
		||||
        \ '@@ -2,0 +3,1 @@ b',
 | 
			
		||||
        \ '+x'
 | 
			
		||||
        \ ], "\n")."\n"
 | 
			
		||||
 | 
			
		||||
  call assert_equal(expected, gitgutter#hunk#fix_file_references(filepath, hunk_diff))
 | 
			
		||||
 | 
			
		||||
  " diff.mnemonicPrefix; spaces in filename
 | 
			
		||||
  let hunk_diff = join([
 | 
			
		||||
        \ 'diff --git i/x/cat dog w/x/cat dog',
 | 
			
		||||
        \ 'index f5c6aff..3fbde56 100644',
 | 
			
		||||
        \ '--- i/x/cat dog',
 | 
			
		||||
        \ '+++ w/x/cat dog',
 | 
			
		||||
        \ '@@ -2,0 +3,1 @@ b',
 | 
			
		||||
        \ '+x'
 | 
			
		||||
        \ ], "\n")."\n"
 | 
			
		||||
  let filepath = 'blah.txt'
 | 
			
		||||
 | 
			
		||||
  let expected = join([
 | 
			
		||||
        \ 'diff --git i/blah.txt w/blah.txt',
 | 
			
		||||
        \ 'index f5c6aff..3fbde56 100644',
 | 
			
		||||
        \ '--- i/blah.txt',
 | 
			
		||||
        \ '+++ w/blah.txt',
 | 
			
		||||
        \ '@@ -2,0 +3,1 @@ b',
 | 
			
		||||
        \ '+x'
 | 
			
		||||
        \ ], "\n")."\n"
 | 
			
		||||
 | 
			
		||||
  call assert_equal(expected, gitgutter#hunk#fix_file_references(filepath, hunk_diff))
 | 
			
		||||
 | 
			
		||||
  " Backslashes in filename; quotation marks
 | 
			
		||||
  let hunk_diff = join([
 | 
			
		||||
        \ 'diff --git "a/C:\\Users\\FOO~1.PAR\\AppData\\Local\\Temp\\nvimJcmSv9\\11.1.vim" "b/C:\\Users\\FOO~1.PAR\\AppData\\Local\\Temp\\nvimJcmSv9\\12.1.vim"',
 | 
			
		||||
        \ 'index f42aeb0..4930403 100644',
 | 
			
		||||
        \ '--- "a/C:\\Users\\FOO~1.PAR\\AppData\\Local\\Temp\\nvimJcmSv9\\11.1.vim"',
 | 
			
		||||
        \ '+++ "b/C:\\Users\\FOO~1.PAR\\AppData\\Local\\Temp\\nvimJcmSv9\\12.1.vim"',
 | 
			
		||||
        \ '@@ -172,0 +173 @@ stuff',
 | 
			
		||||
        \ '+x'
 | 
			
		||||
        \ ], "\n")."\n"
 | 
			
		||||
  let filepath = 'init.vim'
 | 
			
		||||
 | 
			
		||||
  let expected = join([
 | 
			
		||||
        \ 'diff --git "a/init.vim" "b/init.vim"',
 | 
			
		||||
        \ 'index f42aeb0..4930403 100644',
 | 
			
		||||
        \ '--- "a/init.vim"',
 | 
			
		||||
        \ '+++ "b/init.vim"',
 | 
			
		||||
        \ '@@ -172,0 +173 @@ stuff',
 | 
			
		||||
        \ '+x'
 | 
			
		||||
        \ ], "\n")."\n"
 | 
			
		||||
 | 
			
		||||
  call assert_equal(expected, gitgutter#hunk#fix_file_references(filepath, hunk_diff))
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Test_encoding()
 | 
			
		||||
  call system('cp ../cp932.txt . && git add cp932.txt')
 | 
			
		||||
  edit ++enc=cp932 cp932.txt
 | 
			
		||||
 | 
			
		||||
  call s:trigger_gitgutter()
 | 
			
		||||
 | 
			
		||||
  call assert_equal([], s:signs('cp932.txt'))
 | 
			
		||||
endfunction
 | 
			
		||||
							
								
								
									
										27
									
								
								vim/plugins/vim-gitgutter/unplace.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vim/plugins/vim-gitgutter/unplace.vim
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
" Measure how long it takes to unplace signs.
 | 
			
		||||
"
 | 
			
		||||
" Source this file with `:source %` or `vim -S unplace.vim`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
let num = 500
 | 
			
		||||
sign define Foo text=*
 | 
			
		||||
 | 
			
		||||
new
 | 
			
		||||
 | 
			
		||||
call append(0, range(1, num))
 | 
			
		||||
 | 
			
		||||
for i in range(1, num)
 | 
			
		||||
  execute "sign place ".i." line=".i." name=Foo buffer=".bufnr('')
 | 
			
		||||
endfor
 | 
			
		||||
 | 
			
		||||
let start = reltime()
 | 
			
		||||
for i in range(1, num)
 | 
			
		||||
  execute "sign unplace ".i
 | 
			
		||||
endfor
 | 
			
		||||
let elapsed = reltime(start)
 | 
			
		||||
 | 
			
		||||
bdelete!
 | 
			
		||||
 | 
			
		||||
echom split(reltimestr(elapsed))[0]."s to remove ".num." signs"
 | 
			
		||||
echom string(reltimefloat(elapsed) * 1000 / num).' ms/sign'
 | 
			
		||||
echom string(float2nr(num / reltimefloat(elapsed))).' sign/s'
 | 
			
		||||
							
								
								
									
										1
									
								
								vim/plugins/vim-markdown
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								vim/plugins/vim-markdown
									
									
									
									
									
										Submodule
									
								
							 Submodule vim/plugins/vim-markdown added at 6d2cb3c06c
									
								
							
		Reference in New Issue
	
	Block a user