mirror of
1
0
Fork 0

Updated plugins

This commit is contained in:
Amir Salihefendic 2018-03-31 11:56:26 -03:00
parent 7c643a2d9c
commit 02572caa95
84 changed files with 4588 additions and 1749 deletions

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -1,4 +1,4 @@
*ctrlp.txt* 支持模糊匹配的 文件, 缓冲区, 最近最多使用, 标签, ... 检索. v1.79
*ctrlp.txt* 支持模糊匹配的 文件, 缓冲区, 最近最多使用, 标签, ... 检索. v1.80
*CtrlP* *ControlP* *'ctrlp'* *'ctrl-p'*
===============================================================================
# #

View File

@ -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'*
===============================================================================
# #

View File

@ -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: {{{

View File

@ -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. -->

View File

@ -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*

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

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

View File

@ -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
> 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
```
> Why can't I unstage staged changes?
Unstaging staged hunks is feasible but not quite as easy as it sounds. There are three relevant versions of a file at any one time:
1. The version at HEAD in the repo.
2. The version staged in the index.
3. The version in the working tree, in your vim buffer.
`git-diff` without arguments shows you how 3 and 2 differ; this is what vim-gitgutter shows too.
`git-diff --staged` shows you how 2 and 1 differ.
Let's say 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.
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

View File

@ -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
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
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()
endif
endif
endfunction
function! gitgutter#handle_diff(diff) abort
call gitgutter#debug#log(a:diff)
call gitgutter#utility#setbufvar(gitgutter#utility#bufnr(), 'tracked', 1)
call gitgutter#hunk#set_hunks(gitgutter#diff#parse_diff(a:diff))
let modified_lines = gitgutter#diff#process_hunks(gitgutter#hunk#hunks())
if len(modified_lines) > g:gitgutter_max_signs
call gitgutter#utility#warn_once('exceeded maximum number of signs (configured by g:gitgutter_max_signs).', 'max_signs')
call gitgutter#sign#clear_signs()
return
endif
if g:gitgutter_signs || g:gitgutter_highlight_lines
call gitgutter#sign#update_signs(modified_lines)
endif
call gitgutter#utility#save_last_seen_change()
endfunction
function! gitgutter#disable() abort
" get list of all buffers (across all tabs)
let buflist = []
@ -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

View File

@ -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

View File

@ -12,67 +12,67 @@ function! gitgutter#debug#debug()
setlocal bufhidden=delete
setlocal noswapfile
call gitgutter#debug#vim_version()
call gitgutter#debug#separator()
call s:vim_version()
call s:separator()
call gitgutter#debug#git_version()
call gitgutter#debug#separator()
call s:git_version()
call s:separator()
call gitgutter#debug#grep_version()
call gitgutter#debug#separator()
call s:grep_version()
call s: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: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

View File

@ -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:
"
" * Saved: the buffer contents is the same as the file on disk in the working
" tree so we simply do:
" git diff myfileA myfileB
"
" git diff myfile
" where myfileA comes from
"
" * 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 show :myfile > myfileA
"
" git diff myfileA myfileB
"
" The first instance is the file in the index which we obtain with:
"
" git show :myfile > myfileA
"
" The second instance is the buffer contents. Ideally we would pass this to
" git-diff on stdin via the second argument to vim's system() function.
" Unfortunately git-diff does not do CRLF conversion for input received on
" stdin, and git-show never performs CRLF conversion, so repos with CRLF
" conversion report that every line is modified due to mismatching EOLs.
"
" Instead, we write the buffer contents to a temporary file - myfileB in this
" example. Note the file extension must be preserved for the CRLF
" conversion to work.
"
" Before diffing a buffer for the first time, we check whether git knows about
" the file:
"
" git ls-files --error-unmatch myfile
" 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.
function! gitgutter#diff#run_diff(realtime, preserve_full_diff) abort
"
"
" 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 = '('
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.' && '
" 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.' && '
" 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("']")
" Write buffer to temporary file.
" Note: this is synchronous.
call s:write_buffer(a:bufnr, buff_file)
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
let cmd .= g:gitgutter_git_executable
" 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.' '
let cmd .= ' diff --no-ext-diff --no-color -U0 '.g:gitgutter_diff_args.' -- '.index_file.' '.buff_file
if a:realtime
let cmd .= ' -- '.blob_file.' '.buff_file
else
let cmd .= g:gitgutter_diff_base.' -- '.gitgutter#utility#shellescape(gitgutter#utility#filename())
" 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
let cmd .= ' | '.s:grep_command.' '.gitgutter#utility#shellescape('^@@ ')
endif
if (!a:preserve_full_diff && s:grep_available) || a:realtime
" grep exits with 1 when no matches are found; diff exits with 1 when
" differences are found. However we want to treat non-matches and
" differences as non-erroneous behaviour; so we OR the command with one
" which always exits with success (0).
let cmd .= ' || exit 0'
endif
" 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#cd_cmd(a:bufnr, cmd)
let cmd = gitgutter#utility#command_in_directory_of_file(cmd)
if g:gitgutter_async && gitgutter#async#available() && !a:preserve_full_diff
call gitgutter#async#execute(cmd)
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)
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 gitgutter#diff#is_modified(from_count, to_count)
call gitgutter#diff#process_modified(modifications, from_count, to_count, to_line)
call gitgutter#hunk#increment_lines_modified(to_count)
elseif 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 gitgutter#diff#is_modified_and_added(from_count, to_count)
call gitgutter#diff#process_modified_and_added(modifications, from_count, to_count, to_line)
call gitgutter#hunk#increment_lines_added(to_count - from_count)
call gitgutter#hunk#increment_lines_modified(from_count)
elseif 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 gitgutter#diff#is_modified_and_removed(from_count, to_count)
call gitgutter#diff#process_modified_and_removed(modifications, from_count, to_count, to_line)
call gitgutter#hunk#increment_lines_modified(to_count)
call gitgutter#hunk#increment_lines_removed(from_count - to_count)
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! gitgutter#diff#is_added(from_count, to_count) abort
function! s:is_added(from_count, to_count) abort
return a:from_count == 0 && a:to_count > 0
endfunction
function! gitgutter#diff#is_removed(from_count, to_count) abort
function! s:is_removed(from_count, to_count) abort
return a:from_count > 0 && a:to_count == 0
endfunction
function! gitgutter#diff#is_modified(from_count, to_count) abort
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! gitgutter#diff#is_modified_and_added(from_count, to_count) abort
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! gitgutter#diff#is_modified_and_removed(from_count, to_count) abort
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! gitgutter#diff#process_added(modifications, from_count, to_count, to_line) abort
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
@ -242,7 +268,7 @@ function! gitgutter#diff#process_added(modifications, from_count, to_count, to_l
endwhile
endfunction
function! gitgutter#diff#process_removed(modifications, from_count, to_count, to_line) abort
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
@ -250,7 +276,7 @@ function! gitgutter#diff#process_removed(modifications, from_count, to_count, to
endif
endfunction
function! gitgutter#diff#process_modified(modifications, from_count, to_count, to_line) abort
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
@ -259,7 +285,7 @@ function! gitgutter#diff#process_modified(modifications, from_count, to_count, t
endwhile
endfunction
function! gitgutter#diff#process_modified_and_added(modificat