Updated plugins

pull/408/head
Amir Salihefendic 6 years ago
parent 7c643a2d9c
commit 02572caa95
  1. 2
      README.md
  2. 4
      sources_non_forked/ack.vim/autoload/ack.vim
  3. 8
      sources_non_forked/ctrlp.vim/autoload/ctrlp.vim
  4. 2
      sources_non_forked/ctrlp.vim/doc/ctrlp.cnx
  5. 2
      sources_non_forked/ctrlp.vim/doc/ctrlp.txt
  6. 4
      sources_non_forked/gruvbox/colors/gruvbox.vim
  7. 47
      sources_non_forked/nerdtree/.github/ISSUE_TEMPLATE.md
  8. 10
      sources_non_forked/nerdtree/doc/NERDTree.txt
  9. 2
      sources_non_forked/nerdtree/lib/nerdtree/creator.vim
  10. 12
      sources_non_forked/nerdtree/lib/nerdtree/path.vim
  11. 42
      sources_non_forked/vim-addon-mw-utils/autoload/glob_linux.vim
  12. 2
      sources_non_forked/vim-coffee-script/syntax/coffee.vim
  13. 10
      sources_non_forked/vim-fugitive/CONTRIBUTING.markdown
  14. 8
      sources_non_forked/vim-gitgutter/.github/issue_template.md
  15. 111
      sources_non_forked/vim-gitgutter/README.mkd
  16. 260
      sources_non_forked/vim-gitgutter/autoload/gitgutter.vim
  17. 58
      sources_non_forked/vim-gitgutter/autoload/gitgutter/async.vim
  18. 68
      sources_non_forked/vim-gitgutter/autoload/gitgutter/debug.vim
  19. 364
      sources_non_forked/vim-gitgutter/autoload/gitgutter/diff.vim
  20. 54
      sources_non_forked/vim-gitgutter/autoload/gitgutter/highlight.vim
  21. 224
      sources_non_forked/vim-gitgutter/autoload/gitgutter/hunk.vim
  22. 134
      sources_non_forked/vim-gitgutter/autoload/gitgutter/sign.vim
  23. 265
      sources_non_forked/vim-gitgutter/autoload/gitgutter/utility.vim
  24. 534
      sources_non_forked/vim-gitgutter/doc/gitgutter.txt
  25. 120
      sources_non_forked/vim-gitgutter/plugin/gitgutter.vim
  26. 8
      sources_non_forked/vim-gitgutter/test/cp932.txt
  27. 2
      sources_non_forked/vim-gitgutter/test/test
  28. 251
      sources_non_forked/vim-gitgutter/test/test_gitgutter.vim
  29. 27
      sources_non_forked/vim-gitgutter/unplace.vim
  30. 12
      sources_non_forked/vim-go/.codecov.yml
  31. 37
      sources_non_forked/vim-go/CHANGELOG.md
  32. 7
      sources_non_forked/vim-go/README.md
  33. 2
      sources_non_forked/vim-go/autoload/go/cmd.vim
  34. 30
      sources_non_forked/vim-go/autoload/go/cmd_test.vim
  35. 245
      sources_non_forked/vim-go/autoload/go/complete.vim
  36. 2
      sources_non_forked/vim-go/autoload/go/coverage.vim
  37. 904
      sources_non_forked/vim-go/autoload/go/debug.vim
  38. 1
      sources_non_forked/vim-go/autoload/go/fmt.vim
  39. 113
      sources_non_forked/vim-go/autoload/go/guru.vim
  40. 102
      sources_non_forked/vim-go/autoload/go/job.vim
  41. 8
      sources_non_forked/vim-go/autoload/go/jobcontrol.vim
  42. 95
      sources_non_forked/vim-go/autoload/go/lint.vim
  43. 32
      sources_non_forked/vim-go/autoload/go/lint_test.vim
  44. 39
      sources_non_forked/vim-go/autoload/go/list.vim
  45. 8
      sources_non_forked/vim-go/autoload/go/package.vim
  46. 51
      sources_non_forked/vim-go/autoload/go/rename.vim
  47. 2
      sources_non_forked/vim-go/autoload/go/template.vim
  48. 105
      sources_non_forked/vim-go/autoload/go/term.vim
  49. 50
      sources_non_forked/vim-go/autoload/go/term_test.vim
  50. 5
      sources_non_forked/vim-go/autoload/go/test-fixtures/cmd/bad.go
  51. 8
      sources_non_forked/vim-go/autoload/go/test-fixtures/lint/src/vet/vet.go
  52. 5
      sources_non_forked/vim-go/autoload/go/test-fixtures/term/term.go
  53. 65
      sources_non_forked/vim-go/autoload/go/test.vim
  54. 52
      sources_non_forked/vim-go/autoload/go/textobj.vim
  55. 9
      sources_non_forked/vim-go/autoload/go/util.vim
  56. 238
      sources_non_forked/vim-go/doc/vim-go.txt
  57. 7
      sources_non_forked/vim-go/ftplugin/go/commands.vim
  58. 2
      sources_non_forked/vim-go/ftplugin/go/snippets.vim
  59. 5
      sources_non_forked/vim-go/gosnippets/UltiSnips/go.snippets
  60. 4
      sources_non_forked/vim-go/gosnippets/snippets/go.snip
  61. 1
      sources_non_forked/vim-go/plugin/go.vim
  62. 2
      sources_non_forked/vim-go/syntax/go.vim
  63. 13
      sources_non_forked/vim-go/syntax/godebugoutput.vim
  64. 11
      sources_non_forked/vim-go/syntax/godebugstacktrace.vim
  65. 23
      sources_non_forked/vim-go/syntax/godebugvariables.vim
  66. 4
      sources_non_forked/vim-markdown/README.md
  67. 12
      sources_non_forked/vim-markdown/ftplugin/markdown.vim
  68. 15
      sources_non_forked/vim-multiple-cursors/README.md
  69. 67
      sources_non_forked/vim-multiple-cursors/autoload/multiple_cursors.vim
  70. 10
      sources_non_forked/vim-multiple-cursors/doc/multiple_cursors.txt
  71. 3
      sources_non_forked/vim-multiple-cursors/plugin/multiple_cursors.vim
  72. 123
      sources_non_forked/vim-multiple-cursors/spec/multiple_cursors_spec.rb
  73. 7
      sources_non_forked/vim-snippets/UltiSnips/all.snippets
  74. 2
      sources_non_forked/vim-snippets/UltiSnips/cpp.snippets
  75. 733
      sources_non_forked/vim-snippets/UltiSnips/plsql.snippets
  76. 19
      sources_non_forked/vim-snippets/UltiSnips/robot.snippets
  77. 20
      sources_non_forked/vim-snippets/UltiSnips/tex.snippets
  78. 12
      sources_non_forked/vim-snippets/snippets/cpp.snippets
  79. 76
      sources_non_forked/vim-snippets/snippets/ps1.snippets
  80. 95
      sources_non_forked/vim-snippets/snippets/puppet.snippets
  81. 6
      sources_non_forked/vim-snippets/snippets/python.snippets
  82. 16
      sources_non_forked/vim-snippets/snippets/rails.snippets
  83. 10
      sources_non_forked/vim-snippets/snippets/tex.snippets
  84. 25
      vimrcs/plugins_config.vim

@ -89,7 +89,7 @@ I recommend reading the docs of these plugins to understand them better. Each pl
* [open_file_under_cursor.vim](https://github.com/amix/open_file_under_cursor.vim): Open file under cursor when pressing `gf`
* [pathogen.vim](https://github.com/tpope/vim-pathogen): Manage your vim runtimepath
* [snipmate.vim](https://github.com/garbas/vim-snipmate): snipmate.vim aims to be a concise vim script that implements some of TextMate's snippets features in Vim
* [syntastic](https://github.com/scrooloose/syntastic): Syntax checking hacks for vim
* [ale](https://github.com/w0rp/ale): Syntax and lint checking for vim (async)
* [vim-commentary](https://github.com/tpope/vim-commentary): Comment stuff out. Use `gcc` to comment out a line (takes a count), `gc` to comment out the target of a motion. `gcu` uncomments a set of adjacent commented lines.
* [vim-expand-region](https://github.com/terryma/vim-expand-region): Allows you to visually select increasingly larger regions of text using the same key combination
* [vim-fugitive](https://github.com/tpope/vim-fugitive): A Git wrapper so awesome, it should be illegal

@ -130,8 +130,8 @@ function! s:ApplyMappings() "{{{
endif
if exists("g:ackpreview") " if auto preview in on, remap j and k keys
nnoremap <buffer> <silent> j j<CR><C-W><C-W>
nnoremap <buffer> <silent> k k<CR><C-W><C-W>
nnoremap <buffer> <silent> j j<CR><C-W><C-P>
nnoremap <buffer> <silent> k k<CR><C-W><C-P>
nmap <buffer> <silent> <Down> j
nmap <buffer> <silent> <Up> k
endif

@ -540,7 +540,7 @@ fu! s:bufparts(bufnr)
endf
fu! ctrlp#buffers(...)
let ids = sort(filter(range(1, bufnr('$')), '(empty(getbufvar(v:val, "&bt"))'
\ .' || s:isneovimterminal(v:val)) && getbufvar(v:val, "&bl")'), 's:compmreb')
\ .' || s:isterminal(v:val)) && getbufvar(v:val, "&bl")'), 's:compmreb')
if a:0 && a:1 == 'id'
retu ids
el
@ -2031,7 +2031,7 @@ fu! ctrlp#normcmd(cmd, ...)
let buftypes = [ 'quickfix', 'help' ]
if a:0 < 2 && s:nosplit() | retu a:cmd | en
let norwins = filter(range(1, winnr('$')),
\ 'index(buftypes, getbufvar(winbufnr(v:val), "&bt")) == -1 || s:isneovimterminal(winbufnr(v:val))')
\ 'index(buftypes, getbufvar(winbufnr(v:val), "&bt")) == -1 || s:isterminal(winbufnr(v:val))')
for each in norwins
let bufnr = winbufnr(each)
if empty(bufname(bufnr)) && empty(getbufvar(bufnr, '&ft'))
@ -2305,8 +2305,8 @@ fu! s:delbuf()
cal s:PrtClearCache()
endf
fu! s:isneovimterminal(buf)
retu has('nvim') && getbufvar(a:buf, "&bt") == "terminal"
fu! s:isterminal(buf)
retu getbufvar(a:buf, "&bt") == "terminal"
endf
" Entering & Exiting {{{2
fu! s:getenv()

@ -1,4 +1,4 @@
*ctrlp.txt* ๆ”ฏๆŒๆจก็ณŠๅŒน้…็š„ ๆ–‡ไปถ, ็ผ“ๅ†ฒๅŒบ, ๆœ€่ฟ‘ๆœ€ๅคšไฝฟ็”จ, ๆ ‡็ญพ, ... ๆฃ€็ดข. v1.79
*ctrlp.txt* ๆ”ฏๆŒๆจก็ณŠๅŒน้…็š„ ๆ–‡ไปถ, ็ผ“ๅ†ฒๅŒบ, ๆœ€่ฟ‘ๆœ€ๅคšไฝฟ็”จ, ๆ ‡็ญพ, ... ๆฃ€็ดข. v1.80
*CtrlP* *ControlP* *'ctrlp'* *'ctrl-p'*
===============================================================================
# #

@ -1,4 +1,4 @@
*ctrlp.txt* Fuzzy file, buffer, mru, tag, ... finder. v1.79
*ctrlp.txt* Fuzzy file, buffer, mru, tag, ... finder. v1.80
*CtrlP* *ControlP* *'ctrlp'* *'ctrl-p'*
===============================================================================
# #

@ -688,8 +688,8 @@ hi! link EasyMotionShade Comment
" }}}
" Sneak: {{{
autocmd ColorScheme gruvbox hi! link Sneak Search
autocmd ColorScheme gruvbox hi! link SneakLabel Search
hi! link Sneak Search
hi! link SneakLabel Search
" }}}
" Indent Guides: {{{

@ -1,37 +1,28 @@
_To assist in resolving your issue, provide as much information as possible, in place of the ellipses (`โ€ฆ`) below._
<!--- To assist in resolving your issue, provide as much information as possible. -->
---
**Environment:** _Describe your Vim/NERDTree setup._
### Environment
<!--- Describe your Vim/NERDTree setup. -->
>* Operating System: โ€ฆ
>* Vim version `:version`: โ€ฆ
>* NERDTree version `git rev-parse --short HEAD`: โ€ฆ
>* NERDTree settings applied in your vimrc, if any:
>
> ```
> โ€ฆ
> ```
* Operating System:
* Vim version `:version`:
* NERDTree version `git rev-parse --short HEAD`:
* NERDTree settings applied in your vimrc, if any:
```vim
```
**Process:** _List the steps that will recreate the issue._
### Process
<!--- List the steps that will recreate the issue. -->
>1. โ€ฆ
1.
**Current Result:** _Describe what you you currently experience from this process._
### Current Result
<!--- Describe what you you currently experience from this process. -->
>โ€ฆ
### Expected Result
<!--- Describe what you would have expected from this process. -->
**Expected Result:** _Describe what you would expect to have resulted from this process._
### Screenshot(s)
>โ€ฆ
---
**Optional**
**Screenshot(s):**
>โ€ฆ
**Possible Fix:** _(Have you poked around in the code?)_
>โ€ฆ
### Possible Fix
<!--- If you have explored the code, share what you've found. -->

@ -694,6 +694,16 @@ NERD tree. These options should be set in your vimrc.
|'NERDTreeCreatePrefix'| Specify a prefix to be used when creating the
NERDTree window.
|'NERDTreeRemoveFileCmd'| Specify a custom shell command to be used when
deleting files. Note that it should include
one space character at the end of the command
and it applies only to files.
|'NERDTreeRemoveDirCmd'| Specify a custom shell command to be used when
deleting directories. Note that it should
include one space character at the end of the
command and it applies only to directories.
------------------------------------------------------------------------------
3.2. Customisation details *NERDTreeOptionDetails*

@ -185,7 +185,7 @@ function! s:Creator._createTreeWin()
let splitLocation = g:NERDTreeWinPos ==# "left" ? "topleft " : "botright "
let splitSize = g:NERDTreeWinSize
if !exists('t:NERDTreeBufName')
if !g:NERDTree.ExistsForTab()
let t:NERDTreeBufName = self._nextBufferName()
silent! exec splitLocation . 'vertical ' . splitSize . ' new'
silent! exec "edit " . t:NERDTreeBufName

@ -246,7 +246,13 @@ function! s:Path.delete()
throw "NERDTree.PathDeletionError: Could not delete directory: '" . self.str() . "'"
endif
else
let success = delete(self.str())
if exists('g:NERDTreeRemoveFileCmd')
let cmd = g:NERDTreeRemoveFileCmd . self.str({'escape': 1})
let success = system(cmd)
else
let success = delete(self.str())
endif
if success != 0
throw "NERDTree.PathDeletionError: Could not delete file: '" . self.str() . "'"
endif
@ -409,7 +415,7 @@ endfunction
" FUNCTION: Path.isHiddenUnder(path) {{{1
function! s:Path.isHiddenUnder(path)
if !self.isUnder(a:path)
return 0
endif
@ -418,7 +424,7 @@ function! s:Path.isHiddenUnder(path)
let l:segments = self.pathSegments[l:startIndex : ]
for l:segment in l:segments
if l:segment =~# '^\.'
return 1
endif

@ -0,0 +1,42 @@
" TODO refactor: create glob function
" noremap \og :call<space>glob_linux#FileByGlobCurrentDir('**/*'.input('glob open '),"\\.git\\<bar>\\.hg\\<bar>node_modules\\<bar>\\.pyc" )<cr>
" noremap \og :call<space>glob_linux#FileByGlobCurrentDir('**/*'.input('glob open '),"default" )<cr>
function! glob_linux#FileByGlobCurrentDir(glob, exclude_pattern)
if a:exclude_pattern == "default"
let exclude_pattern = '\.git\|\.hg\|node_modules\|\.pyc'
else
let exclude_pattern = a:exclude_pattern
endif
" let files = split(glob(a:glob),"\n")
let g = a:glob
let replace = {'**': '.*','*': '[^/\]*','.': '\.'}
let g = substitute(g, '\(\*\*\|\*\|\.\)', '\='.string(replace).'[submatch(1)]','g')
let exclude = exclude_pattern == '' ? '' : ' | grep -v -e '.shellescape(exclude_pattern)
let cmd = 'find | grep -e '.shellescape(g).exclude
let files = split(system(cmd),"\n")
" for nom in a:excludes
" call filter(files,nom)
" endfor
if len(files) > 1000
echoe "more than ".2000." files - would be too slow. Open the file in another way"
else
if empty(files)
echoe "no file found"
elseif len(files) == 1
exec 'e '.fnameescape(files[0])
else
let g:abc=7
call tovl#ui#filter_list#ListView({
\ 'number' : 1,
\ 'selectByIdOrFilter' : 1,
\ 'Continuation' : funcref#Function('exec "e ".fnameescape(ARGS[0])'),
\ 'items' : files,
\ 'cmds' : ['wincmd J']
\ })
endif
endif
endfunction

@ -32,7 +32,7 @@ hi def link coffeeConditional Conditional
syn match coffeeException /\<\%(try\|catch\|finally\)\>/ display
hi def link coffeeException Exception
syn match coffeeKeyword /\<\%(new\|in\|of\|by\|and\|or\|not\|is\|isnt\|class\|extends\|super\|do\|yield\|debugger\|import\|export\|default\|await\)\>/
syn match coffeeKeyword /\<\%(new\|in\|of\|from\|by\|and\|or\|not\|is\|isnt\|class\|extends\|super\|do\|yield\|debugger\|import\|export\|default\|await\)\>/
\ display
" The `own` keyword is only a keyword after `for`.
syn match coffeeKeyword /\<for\s\+own\>/ contained containedin=coffeeRepeat

@ -8,8 +8,14 @@ platform issues, and interactions with other plugins. I end up bisecting a
lot more than other projects, and thus I'm especially meticulous here about
maintaining a clean, readable, history. Squash and force push any requested
changes to a pull request. And if your [commit message
sucks](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html),
I'm not going to accept it. Period.
sucks](https://commit.style), I'm not going to accept it. Period.
If your contribution involves adding a configuration option, you are going to
need a very compelling justification for it. Options add a maintenance
burden, support burden, and documentation bloat, and oftentimes can be
achieved much more simply with a custom map or autocommand. If your option
controls an underlying Git command, ask yourself why Git itself does not offer
such configuration.
Beyond that, don't be shy about asking before patching. What takes you hours
might take me minutes simply because I have both domain knowledge and a

@ -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=''`?

@ -1,12 +1,14 @@
## vim-gitgutter
A Vim plugin which shows a git diff in the 'gutter' (sign column). It shows whether each line has been added, modified, and where lines have been removed. You can also stage and undo individual hunks.
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 in terminal Vim/MacVim (7.4.1826+), gVim (7.4.1850+), MacVim GUI (7.4.1832+), and NeoVim.
* Ensures signs are always as up to date as possible (but without running more than necessary).
* 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.
@ -21,9 +23,8 @@ Features:
Constraints:
* Supports git only.
If you work with other version control systems, I recommend [vim-signify](https://github.com/mhinz/vim-signify).
* 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
@ -39,7 +40,7 @@ In the screenshot above you can see:
### 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.
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.
@ -100,16 +101,13 @@ cp -r vim-gitgutter/* ~/.vim/
See `:help add-global-plugin`.
If you are on Windows you may find the command prompt pops up briefly every time vim-gitgutter runs. You can avoid this by installing both [vim-misc](https://github.com/xolox/vim-misc) and [vim-shell](https://github.com/xolox/vim-shell). If you have those two plugins but don't want vim-gitgutter to use them, you can opt out with `let g:gitgutter_avoid_cmd_prompt_on_windows = 0` in your `~/.vimrc`.
### Getting started
When you make a change to a file tracked by git, the diff markers should appear automatically. The delay is governed by vim's `updatetime` option; the default value is 4 seconds but I suggest reducing it to around 250ms (add `set updatetime=250` to your vimrc).
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 currently unstage a staged hunk.
You cannot unstage a staged hunk.
#### Activation
@ -136,7 +134,7 @@ Note that if you have line highlighting on and signs off, you will have an empty
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 itself when a file has more than 500 changes. As soon as the number of changes falls below the limit vim-gitgutter will show the signs again. You can configure the threshold with:
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
@ -205,33 +203,6 @@ Finally, you can force vim-gitgutter to update its signs across all visible buff
See the customisation section below for how to change the defaults.
### When are the signs updated?
By default the signs are updated as follows:
| Event | Reason for update | Configuration |
|---------------------------|--------------------------------------|------------------------|
| Stop typing | So the signs are real time | `g:gitgutter_realtime` |
| Switch buffer | To notice change to git index | `g:gitgutter_eager` |
| Switch tab | To notice change to git index | `g:gitgutter_eager` |
| Focus the GUI | To notice change to git index | `g:gitgutter_eager` (not gVim on Windows) |
| After shell command | To notice change to git index | `g:gitgutter_eager` |
| Read a file into a buffer | To display initial signs | [always] |
| Save a buffer | So non-realtime signs are up to date | [always] |
| Change a file outside Vim | To notice `git stash` | [always] |
The length of time Vim waits after you stop typing before it triggers the plugin is governed by the setting `updatetime`. This defaults to `4000` milliseconds which is rather too long. I recommend around `250` milliseconds but it depends on your system and your preferences. Note that in terminal Vim pre-7.4.427 an `updatetime` of less than approximately `1000` milliseconds can lead to random highlighting glitches; the lower the `updatetime`, the more glitches.
If you experience a lag, you can trade speed for accuracy:
```viml
let g:gitgutter_realtime = 0
let g:gitgutter_eager = 0
```
Note the realtime updating requires Vim 7.3.105 or higher.
### Customisation
You can customise:
@ -351,7 +322,7 @@ If you use an alternative to grep, you can tell vim-gitgutter to use it here.
```viml
" Default:
let g:gitgutter_grep_command = 'grep'
let g:gitgutter_grep = 'grep'
```
#### To turn off vim-gitgutter by default
@ -490,57 +461,53 @@ nmap <silent> [c :call PrevHunkAllBuffers()<CR>
### FAQ
> Why can't I unstage staged changes?
Unstaging staged hunks is feasible but not quite as easy as it sounds. There are three relevant versions of a file at any one time:
> How can I turn off realtime updates?
1. The version at HEAD in the repo.
2. The version staged in the index.
3. The version in the working tree, in your vim buffer.
Add this to your vim configuration (in an `/after/plugin` directory):
`git-diff` without arguments shows you how 3 and 2 differ; this is what vim-gitgutter shows too.
`git-diff --staged` shows you how 2 and 1 differ.
```viml
" .vim/after/plugin/gitgutter.vim
autocmd! gitgutter CursorHold,CursorHoldI
```
Let's say you are looking at a file in vim which has some unstaged changes. Now you stage a hunk, either via vim-gitgutter or another means. The hunk is no longer marked in vim-gitgutter because it is the same in 3 and 2.
Now you want to unstage that hunk. To see it, you need the difference between 2 and 1. For vim-gitgutter to show those differences, it would need to show you 2 instead of 3 in your vim buffer. But 2 is virtual so vim-gitgutter would need to handle it without touching 3.
> Why can't I unstage staged changes?
I intend to implement this but I can't commit to any deadline.
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.
> There's a noticeable lag when vim-gitter runs; how can I avoid it?
By default vim-gitgutter runs often so the signs are as accurate as possible. The delay is governed by `updatetime`; see [above](#when-are-the-signs-updated) for more information.
If you don't want realtime updates and would like to trade a little accuracy for speed, add this to your `~/.vimrc`:
```viml
let g:gitgutter_realtime = 0
let g:gitgutter_eager = 0
```
> What happens if I also use another plugin which uses signs (e.g. Syntastic)?
Vim only allows one sign per line. Before adding a sign to a line, vim-gitgutter checks whether a sign has already been added by somebody else. If so it doesn't do anything. In other words vim-gitgutter won't overwrite another plugin's signs. It also won't remove another plugin's signs.
> Why aren't any signs showing at all?
### Troubleshooting
#### When no signs are showing at all
Here are some things you can check:
* `:echo system("git --version")` succeeds.
* Your git config is compatible with the version of git returned by the command above.
* Your Vim supports signs (`:echo has('signs')` should give `1`).
* Your file is being tracked by git and has unstaged changes.
* If you have aliased or configured `grep` to use any flags, add `let g:gitgutter_grep_command = 'grep'` to your `~/.vimrc`.
* 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.
> Why is the whole file marked as added when I edit it?
#### 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
@ -561,4 +528,4 @@ Copyright Andrew Stewart, AirBlade Software Ltd. Released under the MIT licence
[pathogen]: https://github.com/tpope/vim-pathogen
[siv]: http://pluralsight.com/training/Courses/TableOfContents/smash-into-vim
[airblade]: http://airbladesoftware.com/peepcode-vim
[macvim]: http://code.google.com/p/macvim/
[terminus]: https://github.com/wincent/terminus

@ -1,67 +1,54 @@
let s:nomodeline = (v:version > 703 || (v:version == 703 && has('patch442'))) ? '<nomodeline>' : ''
let s:t_string = type('')
" Primary functions {{{
function! gitgutter#all() abort
for buffer_id in gitgutter#utility#dedup(tabpagebuflist())
let file = expand('#' . buffer_id . ':p')
function! gitgutter#all(force) abort
for bufnr in s:uniq(tabpagebuflist())
let file = expand('#'.bufnr.':p')
if !empty(file)
call gitgutter#process_buffer(buffer_id, 0)
call gitgutter#init_buffer(bufnr)
call gitgutter#process_buffer(bufnr, a:force)
endif
endfor
endfunction
" bufnr: (integer) the buffer to process.
" realtime: (boolean) when truthy, do a realtime diff; otherwise do a disk-based diff.
function! gitgutter#process_buffer(bufnr, realtime) abort
call gitgutter#utility#use_known_shell()
call gitgutter#utility#set_buffer(a:bufnr)
if gitgutter#utility#is_active()
if g:gitgutter_sign_column_always
call gitgutter#sign#add_dummy_sign()
" 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)
endif
try
if !a:realtime || gitgutter#utility#has_fresh_changes()
let diff = gitgutter#diff#run_diff(a:realtime || gitgutter#utility#has_unsaved_changes(), 0)
if diff != 'async'
call gitgutter#handle_diff(diff)
endif
endif
catch /diff failed/
call gitgutter#debug#log('diff failed')
call gitgutter#hunk#reset()
endtry
execute "silent doautocmd" s:nomodeline "User GitGutter"
else
call gitgutter#hunk#reset()
endif
call gitgutter#utility#restore_shell()
endfunction
function! gitgutter#handle_diff(diff) abort
call gitgutter#debug#log(a:diff)
function! gitgutter#process_buffer(bufnr, force) abort
" NOTE a:bufnr is not necessarily the current buffer.
call gitgutter#utility#setbufvar(gitgutter#utility#bufnr(), 'tracked', 1)
if gitgutter#utility#is_active(a:bufnr)
if a:force || s:has_fresh_changes(a:bufnr)
call gitgutter#hunk#set_hunks(gitgutter#diff#parse_diff(a:diff))
let modified_lines = gitgutter#diff#process_hunks(gitgutter#hunk#hunks())
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 len(modified_lines) > g:gitgutter_max_signs
call gitgutter#utility#warn_once('exceeded maximum number of signs (configured by g:gitgutter_max_signs).', 'max_signs')
call gitgutter#sign#clear_signs()
return
endif
if diff != 'async'
call gitgutter#diff#handler(a:bufnr, diff)
endif
if g:gitgutter_signs || g:gitgutter_highlight_lines
call gitgutter#sign#update_signs(modified_lines)
endif
endif
call gitgutter#utility#save_last_seen_change()
endfunction
function! gitgutter#disable() abort
" get list of all buffers (across all tabs)
let buflist = []
@ -69,13 +56,10 @@ function! gitgutter#disable() abort
call extend(buflist, tabpagebuflist(i + 1))
endfor
for buffer_id in gitgutter#utility#dedup(buflist)
let file = expand('#' . buffer_id . ':p')
for bufnr in s:uniq(buflist)
let file = expand('#'.bufnr.':p')
if !empty(file)
call gitgutter#utility#set_buffer(buffer_id)
call gitgutter#sign#clear_signs()
call gitgutter#sign#remove_dummy_sign(1)
call gitgutter#hunk#reset()
call s:clear(bufnr)
endif
endfor
@ -84,7 +68,7 @@ endfunction
function! gitgutter#enable() abort
let g:gitgutter_enabled = 1
call gitgutter#all()
call gitgutter#all(1)
endfunction
function! gitgutter#toggle() abort
@ -97,163 +81,33 @@ endfunction
" }}}
" Line highlights {{{
function! gitgutter#line_highlights_disable() abort
let g:gitgutter_highlight_lines = 0
call gitgutter#highlight#define_sign_line_highlights()
if !g:gitgutter_signs
call gitgutter#sign#clear_signs()
call gitgutter#sign#remove_dummy_sign(0)
endif
redraw!
function! s:has_fresh_changes(bufnr) abort
return getbufvar(a:bufnr, 'changedtick') != gitgutter#utility#getbufvar(a:bufnr, 'tick')
endfunction
function! gitgutter#line_highlights_enable() abort
let old_highlight_lines = g:gitgutter_highlight_lines
let g:gitgutter_highlight_lines = 1
call gitgutter#highlight#define_sign_line_highlights()
if !old_highlight_lines && !g:gitgutter_signs
call gitgutter#all()
endif
redraw!
function! s:reset_tick(bufnr) abort
call gitgutter#utility#setbufvar(a:bufnr, 'tick', 0)
endfunction
function! gitgutter#line_highlights_toggle() abort
if g:gitgutter_highlight_lines
call gitgutter#line_highlights_disable()
else
call gitgutter#line_highlights_enable()
endif
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
" }}}
" Signs {{{
function! gitgutter#signs_enable() abort
let old_signs = g:gitgutter_signs
let g:gitgutter_signs = 1
call gitgutter#highlight#define_sign_text_highlights()
if !old_signs && !g:gitgutter_highlight_lines
call gitgutter#all()
endif
endfunction
function! gitgutter#signs_disable() abort
let g:gitgutter_signs = 0
call gitgutter#highlight#define_sign_text_highlights()
if !g:gitgutter_highlight_lines
call gitgutter#sign#clear_signs()
call gitgutter#sign#remove_dummy_sign(0)
endif
endfunction
function! gitgutter#signs_toggle() abort
if g:gitgutter_signs
call gitgutter#signs_disable()
else
call gitgutter#signs_enable()
endif
endfunction
" }}}
" Hunks {{{
function! gitgutter#stage_hunk() abort
call gitgutter#utility#use_known_shell()
if gitgutter#utility#is_active()
" Ensure the working copy of the file is up to date.
" It doesn't make sense to stage a hunk otherwise.
noautocmd silent write
let diff = gitgutter#diff#run_diff(0, 1)
call gitgutter#handle_diff(diff)
if empty(gitgutter#hunk#current_hunk())
call gitgutter#utility#warn('cursor is not in a hunk')
else
let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk(diff, 'stage')
call gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file(g:gitgutter_git_executable.' apply --cached --unidiff-zero - '), diff_for_hunk)
" refresh gitgutter's view of buffer
silent execute "GitGutter"
endif
silent! call repeat#set("\<Plug>GitGutterStageHunk", -1)<CR>
endif
call gitgutter#utility#restore_shell()
endfunction
function! gitgutter#undo_hunk() abort
call gitgutter#utility#use_known_shell()
if gitgutter#utility#is_active()
" Ensure the working copy of the file is up to date.
" It doesn't make sense to stage a hunk otherwise.
noautocmd silent write
let diff = gitgutter#diff#run_diff(0, 1)
call gitgutter#handle_diff(diff)
if empty(gitgutter#hunk#current_hunk())
call gitgutter#utility#warn('cursor is not in a hunk')
else
let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk(diff, 'undo')
call gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file(g:gitgutter_git_executable.' apply --reverse --unidiff-zero - '), diff_for_hunk)
" reload file preserving screen line position
" CTRL-Y and CTRL-E treat negative counts as positive counts.
let x = line('w0')
silent edit
let y = line('w0')
let z = x - y
if z > 0
execute "normal! ".z."\<C-E>"
else
execute "normal! ".z."\<C-Y>"
if exists('*uniq') " Vim 7.4.218
function! s:uniq(list)
return uniq(sort(a:list))
endfunction
else
function! s:uniq(list)
let processed = []
for e in a:list
if index(processed, e) == -1
call add(processed, e)
endif
endif
silent! call repeat#set("\<Plug>GitGutterUndoHunk", -1)<CR>
endif
call gitgutter#utility#restore_shell()
endfunction
function! gitgutter#preview_hunk() abort
call gitgutter#utility#use_known_shell()
if gitgutter#utility#is_active()
" Ensure the working copy of the file is up to date.
" It doesn't make sense to stage a hunk otherwise.
noautocmd silent write
let diff = gitgutter#diff#run_diff(0, 1)
call gitgutter#handle_diff(diff)
if empty(gitgutter#hunk#current_hunk())
call gitgutter#utility#warn('cursor is not in a hunk')
else
let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk(diff, 'preview')
silent! wincmd P
if !&previewwindow
noautocmd execute 'bo' &previewheight 'new'
set previewwindow
endif
setlocal noro modifiable filetype=diff buftype=nofile bufhidden=delete noswapfile
execute "%delete_"
call append(0, split(diff_for_hunk, "\n"))
noautocmd wincmd p
endif
endif
call gitgutter#utility#restore_shell()
endfunction
" }}}
endfor
return processed
endfunction
endif

@ -11,10 +11,13 @@ function! gitgutter#async#available()
endfunction
function! gitgutter#async#execute(cmd) abort
function! gitgutter#async#execute(cmd, bufnr, handler) abort
call gitgutter#debug#log('[async] '.a:cmd)
let options = {
\ 'stdoutbuffer': [],
\ 'buffer': gitgutter#utility#bufnr()
\ 'buffer': a:bufnr,
\ 'handler': a:handler
\ }
let command = s:build_command(a:cmd)
@ -58,33 +61,13 @@ function! s:on_stdout_nvim(_job_id, data, _event) dict abort
endfunction
function! s:on_stderr_nvim(_job_id, _data, _event) dict abort
" Backward compatibility for nvim < 0.2.0
if !has('nvim-0.2.0')
let current_buffer = gitgutter#utility#bufnr()
call gitgutter#utility#set_buffer(self.buffer)
if gitgutter#utility#is_active()
call gitgutter#hunk#reset()
endif
call gitgutter#utility#set_buffer(current_buffer)
return
endif
call s:buffer_exec(self.buffer, function('gitgutter#hunk#reset'))
call self.handler.err(self.buffer)
endfunction
function! s:on_exit_nvim(_job_id, _data, _event) dict abort
" Backward compatibility for nvim < 0.2.0
if !has('nvim-0.2.0')
let current_buffer = gitgutter#utility#bufnr()
call gitgutter#utility#set_buffer(self.buffer)
if gitgutter#utility#is_active()
call gitgutter#handle_diff(gitgutter#utility#stringify(self.stdoutbuffer))
endif
call gitgutter#utility#set_buffer(current_buffer)
return
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
call s:buffer_exec(self.buffer, function('gitgutter#handle_diff', [gitgutter#utility#stringify(self.stdoutbuffer)]))
endfunction
@ -92,22 +75,15 @@ 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 s:buffer_exec(self.buffer, function('gitgutter#hunk#reset'))
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 s:buffer_exec(self.buffer, function('gitgutter#handle_diff', [gitgutter#utility#stringify(self.stdoutbuffer)]))
endfunction
function! s:buffer_exec(buffer, fn)
let current_buffer = gitgutter#utility#bufnr()
call gitgutter#utility#set_buffer(a:buffer)
if gitgutter#utility#is_active()
call a:fn()
endif
call gitgutter#utility#set_buffer(current_buffer)
call self.handler.out(self.buffer, join(self.stdoutbuffer, "\n"))
endfunction

@ -12,67 +12,67 @@ function! gitgutter#debug#debug()
setlocal bufhidden=delete
setlocal noswapfile
call gitgutter#debug#vim_version()
call gitgutter#debug#separator()
call gitgutter#debug#git_version()
call gitgutter#debug#separator()
call gitgutter#debug#grep_version()
call gitgutter#debug#separator()
call gitgutter#debug#option('updatetime')
call gitgutter#debug#option('shell')
call gitgutter#debug#option('shellcmdflag')
call gitgutter#debug#option('shellpipe')
call gitgutter#debug#option('shellquote')
call gitgutter#debug#option('shellredir')
call gitgutter#debug#option('shellslash')
call gitgutter#debug#option('shelltemp')
call gitgutter#debug#option('shelltype')
call gitgutter#debug#option('shellxescape')
call gitgutter#debug#option('shellxquote')
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! gitgutter#debug#separator()
call gitgutter#debug#output('')
function! s:separator()
call s:output('')
endfunction
function! gitgutter#debug#vim_version()
function! s:vim_version()
redir => version_info
silent execute 'version'
redir END
call gitgutter#debug#output(split(version_info, '\n')[0:2])
call s:output(split(version_info, '\n')[0:2])
endfunction
function! gitgutter#debug#git_version()
function! s:git_version()
let v = system(g:gitgutter_git_executable.' --version')
call gitgutter#debug#output( substitute(v, '\n$', '', '') )
call s:output( substitute(v, '\n$', '', '') )
endfunction
function! gitgutter#debug#grep_version()
function! s:grep_version()
let v = system('grep --version')
call gitgutter#debug#output( substitute(v, '\n$', '', '') )
call s:output( substitute(v, '\n$', '', '') )
let v = system('grep --help')
call gitgutter#debug#output( substitute(v, '\%x00', '', 'g') )
call s:output( substitute(v, '\%x00', '', 'g') )
endfunction
function! gitgutter#debug#option(name)
function! s:option(name)
if exists('+' . a:name)
let v = eval('&' . a:name)
call gitgutter#debug#output(a:name . '=' . v)
call s:output(a:name . '=' . v)
" redir => output
" silent execute "verbose set " . a:name . "?"
" redir END
" call gitgutter#debug#output(a:name . '=' . output)
" call s:output(a:name . '=' . output)
else
call gitgutter#debug#output(a:name . ' [n/a]')
call s:output(a:name . ' [n/a]')
end
endfunction
function! gitgutter#debug#output(text)
function! s:output(text)
call append(line('$'), a:text)
endfunction

@ -1,152 +1,176 @@
if exists('g:gitgutter_grep_command')
let s:grep_available = 1
let s:grep_command = g:gitgutter_grep_command
else
let s:grep_available = executable('grep')
if s:grep_available
let s:grep_command = 'grep'
if $GREP_OPTIONS =~# '--color=always'
let s:grep_command .= ' --color=never'
endif
endif
endif
let s:nomodeline = (v:version > 703 || (v:version == 703 && has('patch442'))) ? '<nomodeline>' : ''
let s:hunk_re = '^@@ -\(\d\+\),\?\(\d*\) +\(\d\+\),\?\(\d*\) @@'
let s:c_flag = gitgutter#utility#git_supports_command_line_config_override()
" 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 way to get the diff depends on whether the buffer is saved or unsaved.
" The buffer contents is not the same as the file on disk so we need to pass
" two instances of the file to git-diff:
"
" git diff myfileA myfileB
"
" where myfileA comes from
"
" * Saved: the buffer contents is the same as the file on disk in the working
" tree so we simply do:
" git show :myfile > myfileA
"
" git diff myfile
" and myfileB is the buffer contents.
"
" * Unsaved: the buffer contents is not the same as the file on disk so we
" need to pass two instances of the file to git-diff:
" 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.
"
" git diff myfileA myfileB
"
" The first instance is the file in the index which we obtain with:
" Regarding line endings:
"
" git show :myfile > myfileA
" git-show does not convert line endings.
" git-diff FILE FILE does convert line endings for the given files.
"
" The second instance is the buffer contents. Ideally we would pass this to
" git-diff on stdin via the second argument to vim's system() function.
" Unfortunately git-diff does not do CRLF conversion for input received on
" stdin, and git-show never performs CRLF conversion, so repos with CRLF
" conversion report that every line is modified due to mismatching EOLs.
" 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.
"
" Instead, we write the buffer contents to a temporary file - myfileB in this
" example. Note the file extension must be preserved for the CRLF
" conversion to work.
" 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.
"
" Before diffing a buffer for the first time, we check whether git knows about
" the file:
" warning: LF will be replace by CRLF in <temp file>.
" The file will have its original line endings in your working directory.
"
" git ls-files --error-unmatch myfile
" 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.
"
" After running the diff we pass it through grep where available to reduce
" subsequent processing by the plugin. If grep is not available the plugin
" does the filtering instead.
function! gitgutter#diff#run_diff(realtime, preserve_full_diff) abort
" 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 = '('
let bufnr = gitgutter#utility#bufnr()
let tracked = gitgutter#utility#getbufvar(bufnr, 'tracked', 0) " i.e. tracked by git
if !tracked
" Don't bother trying to realtime-diff an untracked file.
" NOTE: perhaps we should pull this guard up to the caller?
if a:realtime
throw 'diff failed'
else
let cmd .= g:gitgutter_git_executable.' ls-files --error-unmatch '.gitgutter#utility#shellescape(gitgutter#utility#filename()).' && ('
endif
" 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
if a:realtime
let blob_name = g:gitgutter_diff_base.':'.gitgutter#utility#shellescape(gitgutter#utility#file_relative_to_repo_root())
let blob_file = s:temp_index
let buff_file = s:temp_buffer
let extension = gitgutter#utility#extension()
if !empty(extension)
let blob_file .= '.'.extension
let buff_file .= '.'.extension
endif
let cmd .= g:gitgutter_git_executable.' show '.blob_name.' > '.blob_file.' && '
" Writing the whole buffer resets the '[ and '] marks and also the
" 'modified' flag (if &cpoptions includes '+'). These are unwanted
" side-effects so we save and restore the values ourselves.
let modified = getbufvar(bufnr, "&mod")
let op_mark_start = getpos("'[")
let op_mark_end = getpos("']")
let current_buffer = bufnr('')
execute 'buffer '.bufnr
execute 'keepalt noautocmd silent write!' buff_file
execute 'buffer '.current_buffer
call setbufvar(bufnr, "&mod", modified)
call setpos("'[", op_mark_start)
call setpos("']", op_mark_end)
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.' && '
let cmd .= g:gitgutter_git_executable
" 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.' '
if a:realtime
let cmd .= ' -- '.blob_file.' '.buff_file
else
let cmd .= g:gitgutter_diff_base.' -- '.gitgutter#utility#shellescape(gitgutter#utility#filename())
endif
let cmd .= ' diff --no-ext-diff --no-color -U0 '.g:gitgutter_diff_args.' -- '.index_file.' '.buff_file
if !a:preserve_full_diff && s:grep_available
let cmd .= ' | '.s:grep_command.' '.gitgutter#utility#shellescape('^@@ ')
" Pipe git-diff output into grep.
if !a:preserve_full_diff && !empty(g:gitgutter_grep)
let cmd .= ' | '.g:gitgutter_grep.' '.gitgutter#utility#shellescape('^@@ ')
endif
if (!a:preserve_full_diff && s:grep_available) || a:realtime
" grep exits with 1 when no matches are found; diff exits with 1 when
" differences are found. However we want to treat non-matches and
" differences as non-erroneous behaviour; so we OR the command with one
" which always exits with success (0).
let cmd .= ' || exit 0'
endif
" 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 .= ')'
if !tracked
let cmd .= ')'
endif
let cmd = gitgutter#utility#command_in_directory_of_file(cmd)
let cmd = gitgutter#utility#cd_cmd(a:bufnr, cmd)
if g:gitgutter_async && gitgutter#async#available() && !a:preserve_full_diff
call gitgutter#async#execute(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 gitgutter#utility#shell_error()
" A shell error indicates the file is not tracked by git (unless something bizarre is going on).
throw 'diff failed'
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)
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')
@ -171,69 +195,71 @@ function! gitgutter#diff#parse_hunk(line) abort
end
endfunction
function! gitgutter#diff#process_hunks(hunks) abort
" 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, gitgutter#diff#process_hunk(hunk))
call extend(modified_lines, s:process_hunk(a:bufnr, hunk))
endfor
return modified_lines
endfunction
" Returns [ [<line_number (number)>, <name (string)>], ...]
function! gitgutter#diff#process_hunk(hunk) abort
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 gitgutter#diff#is_added(from_count, to_count)
call gitgutter#diff#process_added(modifications, from_count, to_count, to_line)
call gitgutter#hunk#increment_lines_added(to_count)
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 gitgutter#diff#is_removed(from_count, to_count)
call gitgutter#diff#process_removed(modifications, from_count, to_count, to_line)
call gitgutter#hunk#increment_lines_removed(from_count)