mirror of
https://github.com/amix/vimrc
synced 2025-06-23 06:35:01 +08:00
Updated plugins
This commit is contained in:
@ -2,7 +2,3 @@
|
||||
|
||||
> 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=''`?
|
||||
|
||||
|
@ -12,12 +12,14 @@ Features:
|
||||
* Never saves the buffer.
|
||||
* Quick jumping between blocks of changed lines ("hunks").
|
||||
* Stage/undo/preview individual hunks.
|
||||
* Stage partial hunks.
|
||||
* Provides a hunk text object.
|
||||
* Diffs against index (default) or any commit.
|
||||
* Allows folding all unchanged text.
|
||||
* Handles line endings correctly, even with repos that do CRLF conversion.
|
||||
* Optional line highlighting.
|
||||
* Fully customisable (signs, sign column, line highlights, mappings, extra git-diff arguments, etc).
|
||||
* Optional line number highlighting. (Only available in Neovim 0.3.2 or higher)
|
||||
* Fully customisable (signs, sign column, line (number) highlights, mappings, extra git-diff arguments, etc).
|
||||
* Can be toggled on/off, globally or per buffer.
|
||||
* Preserves signs from other plugins.
|
||||
* Easy to integrate diff stats into status line; built-in integration with [vim-airline](https://github.com/bling/vim-airline/).
|
||||
@ -26,7 +28,7 @@ Features:
|
||||
Constraints:
|
||||
|
||||
* Supports git only. If you work with other version control systems, I recommend [vim-signify](https://github.com/mhinz/vim-signify).
|
||||
* Relies on the `FocusGained` event. If your terminal doesn't report focus events, either use something like [Terminus][] or set `let g:gitgutter_terminal_reports_focus=0`.
|
||||
* 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`. For tmux, `set -g focus-events on` in your tmux.conf.
|
||||
|
||||
|
||||
### Screenshot
|
||||
@ -103,6 +105,17 @@ cp -r vim-gitgutter/* ~/.vim/
|
||||
See `:help add-global-plugin`.
|
||||
|
||||
|
||||
### Windows
|
||||
|
||||
I recommend configuring vim-gitgutter with the full path to your git executable. For example:
|
||||
|
||||
```viml
|
||||
let g:gitgutter_git_executable = 'C:\Program Files\Git\bin\git.exe'
|
||||
```
|
||||
|
||||
This is to avoid a problem which occurs if you have file named `git.*` (i.e. with any extension in `PATHEXT`) in your current folder. `cmd.exe` prioritises the current folder over folders in `PATH` and will try to execute your file instead of the `git` binary.
|
||||
|
||||
|
||||
### Getting started
|
||||
|
||||
When you make a change to a file tracked by git, the diff markers should appear automatically. The delay is governed by vim's `updatetime` option; the default value is `4000`, i.e. 4 seconds, but I suggest reducing it to around 100ms (add `set updatetime=100` to your vimrc).
|
||||
@ -138,9 +151,15 @@ And you can turn line highlighting on and off (defaults to off):
|
||||
* turn off with `:GitGutterLineHighlightsDisable`
|
||||
* toggle with `:GitGutterLineHighlightsToggle`.
|
||||
|
||||
With Neovim 0.3.2 or higher, you can turn line number highlighting on and off (defaults to off):
|
||||
|
||||
* turn on with `:GitGutterLineNrHighlightsEnable`
|
||||
* turn off with `:GitGutterLineNrHighlightsDisable`
|
||||
* toggle with `:GitGutterLineNrHighlightsToggle`.
|
||||
|
||||
Note that if you have line highlighting on and signs off, you will have an empty sign column – more accurately, a sign column with invisible signs. This is because line highlighting requires signs and Vim always shows the sign column even if the signs are invisible.
|
||||
|
||||
If you switch off both line highlighting and signs, you won't see the sign column. That is unless you configure the sign column always to be there (see Sign Column section).
|
||||
If you switch off both line highlighting and signs, you won't see the sign column.
|
||||
|
||||
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:
|
||||
|
||||
@ -169,6 +188,18 @@ You can stage or undo an individual hunk when your cursor is in it:
|
||||
* stage the hunk with `<Leader>hs` or
|
||||
* undo it with `<Leader>hu`.
|
||||
|
||||
To stage part of an additions-only hunk by:
|
||||
|
||||
* either visually selecting the part you want and staging with your mapping, e.g. `<Leader>hs`;
|
||||
* or using a range with the `GitGutterStageHunk` command, e.g. `:42,45GitGutterStageHunk`.
|
||||
|
||||
To stage part of any hunk:
|
||||
|
||||
* preview the hunk, e.g. `<Leader>hp`;
|
||||
* move to the preview window, e.g. `:wincmd P`;
|
||||
* delete the lines you do not want to stage;
|
||||
* stage the remaining lines: either write (`:w`) the window or stage via `<Leader>hs` or `:GitGutterStageHunk`.
|
||||
|
||||
See the FAQ if you want to unstage staged changes.
|
||||
|
||||
The `.` command will work with both these if you install [repeat.vim](https://github.com/tpope/vim-repeat).
|
||||
@ -180,7 +211,7 @@ nmap <Leader>ha <Plug>GitGutterStageHunk
|
||||
nmap <Leader>hr <Plug>GitGutterUndoHunk
|
||||
```
|
||||
|
||||
And you can preview a hunk's changes with `<Leader>hp`. You can of course change this mapping, e.g:
|
||||
And you can preview a hunk's changes with `<Leader>hp`. The location of the preview window is configured with `g:gitgutter_preview_win_location` (default `'bo'`). You can of course change this mapping, e.g:
|
||||
|
||||
```viml
|
||||
nmap <Leader>hv <Plug>GitGutterPreviewHunk
|
||||
@ -224,18 +255,20 @@ You can customise:
|
||||
|
||||
* The sign column's colours
|
||||
* Whether or not the sign column is shown when there aren't any signs (defaults to no)
|
||||
* How to handle non-gitgutter signs
|
||||
* The signs' colours and symbols
|
||||
* Line highlights
|
||||
* The base of the diff
|
||||
* Extra arguments for `git` when running `git diff`
|
||||
* Extra arguments for `git diff`
|
||||
* Key mappings
|
||||
* Whether or not vim-gitgutter is on initially (defaults to on)
|
||||
* Whether or not signs are shown (defaults to yes)
|
||||
* Whether or not line highlighting is on initially (defaults to off)
|
||||
* Whether or not vim-gitgutter runs in "realtime" (defaults to yes)
|
||||
* Whether or not vim-gitgutter runs eagerly (defaults to yes)
|
||||
* Whether or not vim-gitgutter runs asynchronously (defaults to yes)
|
||||
* Whether vim-gitgutter is on initially (defaults to on)
|
||||
* Whether signs are shown (defaults to yes)
|
||||
* Whether line highlighting is on initially (defaults to off)
|
||||
* Whether line number highlighting is on initially (defaults to off)
|
||||
* Whether vim-gitgutter runs asynchronously (defaults to yes)
|
||||
* Whether to clobber or preserve non-gitgutter signs
|
||||
* The priority of gitgutter's signs.
|
||||
|
||||
Please note that vim-gitgutter won't override any colours or highlights you've set in your colorscheme.
|
||||
|
||||
@ -260,11 +293,14 @@ highlight SignColumn guibg=whatever " gVim/MacVim
|
||||
By default the sign column will appear when there are signs to show and disappear when there aren't. To always have the sign column, add to your vimrc:
|
||||
|
||||
```viml
|
||||
if exists('&signcolumn') " Vim 7.4.2201
|
||||
set signcolumn=yes
|
||||
else
|
||||
let g:gitgutter_sign_column_always = 1
|
||||
endif
|
||||
" Vim 7.4.2201
|
||||
set signcolumn=yes
|
||||
```
|
||||
|
||||
GitGutter can preserve or ignore non-gitgutter signs. For Vim v8.1.0614 and later you can set gitgutter's signs' priorities with `g:gitgutter_sign_priority`, so gitgutter defaults to clobbering other signs. For Neovim v0.4.0 and later you can set an expanding sign column so gitgutter again defaults to clobbering other signs. Otherwise, gitgutter defaults to preserving other signs. You can configure this with:
|
||||
|
||||
```viml
|
||||
let g:gitgutter_sign_allow_clobber = 1
|
||||
```
|
||||
|
||||
|
||||
@ -324,6 +360,26 @@ highlight link GitGutterChangeLine DiffText
|
||||
```
|
||||
|
||||
|
||||
#### Line number highlights
|
||||
|
||||
NOTE: This feature requires Neovim 0.3.2 or higher.
|
||||
|
||||
Similarly to the signs' colours, set up the following highlight groups in your colorscheme or `~/.vimrc`:
|
||||
|
||||
```viml
|
||||
GitGutterAddLineNr " default: links to CursorLineNr
|
||||
GitGutterChangeLineNr " default: links to CursorLineNr
|
||||
GitGutterDeleteLineNr " default: links to CursorLineNr
|
||||
GitGutterChangeDeleteLineNr " default: links to CursorLineNr
|
||||
```
|
||||
|
||||
Maybe you think `CursorLineNr` is a bit annoying. For example, you could use `Underlined` for this:
|
||||
|
||||
```viml
|
||||
highlight link GitGutterChangeLineNr Underlined
|
||||
```
|
||||
|
||||
|
||||
#### The base of the diff
|
||||
|
||||
By default buffers are diffed against the index. However you can diff against any commit by setting:
|
||||
@ -384,6 +440,11 @@ Add `let g:gitgutter_signs = 0` to your `~/.vimrc`.
|
||||
Add `let g:gitgutter_highlight_lines = 1` to your `~/.vimrc`.
|
||||
|
||||
|
||||
#### To turn on line number highlighting by default
|
||||
|
||||
Add `let g:gitgutter_highlight_linenrs = 1` to your `~/.vimrc`.
|
||||
|
||||
|
||||
#### To turn off asynchronous updates
|
||||
|
||||
By default diffs are run asynchronously. To run diffs synchronously instead:
|
||||
@ -532,7 +593,7 @@ Your colorscheme is configuring the `SignColumn` highlight group weirdly. Pleas
|
||||
|
||||
> 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.
|
||||
You can configure whether GitGutter preserves or clobbers other signs using `g:gitgutter_sign_allow_clobber`. Set to `1` to clobber other signs (default on Vim >= 8.1.0614 and NeoVim >= 0.4.0) or `0` to preserve them.
|
||||
|
||||
|
||||
### Troubleshooting
|
||||
@ -557,7 +618,7 @@ Here are some things you can check:
|
||||
|
||||
#### 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`.
|
||||
* Your terminal probably isn't reporting focus events. Either try installing [Terminus][] or set `let g:gitgutter_terminal_reports_focus=0`. For tmux, try `set -g focus-events on` in your tmux.conf.
|
||||
|
||||
|
||||
### Shameless Plug
|
||||
|
@ -10,7 +10,6 @@ function! gitgutter#all(force) abort
|
||||
let file = expand('#'.bufnr.':p')
|
||||
if !empty(file)
|
||||
if index(visible, bufnr) != -1
|
||||
call gitgutter#init_buffer(bufnr)
|
||||
call gitgutter#process_buffer(bufnr, a:force)
|
||||
elseif a:force
|
||||
call s:reset_tick(bufnr)
|
||||
@ -21,22 +20,21 @@ function! gitgutter#all(force) abort
|
||||
endfunction
|
||||
|
||||
|
||||
" Finds the file's path relative to the repo root.
|
||||
function! gitgutter#init_buffer(bufnr)
|
||||
if gitgutter#utility#is_active(a:bufnr)
|
||||
let p = gitgutter#utility#repo_path(a:bufnr, 0)
|
||||
if type(p) != s:t_string || empty(p)
|
||||
call gitgutter#utility#set_repo_path(a:bufnr)
|
||||
call s:setup_maps()
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! gitgutter#process_buffer(bufnr, force) abort
|
||||
" NOTE a:bufnr is not necessarily the current buffer.
|
||||
|
||||
if gitgutter#utility#is_active(a:bufnr)
|
||||
|
||||
if has('patch-7.4.1559')
|
||||
let l:Callback = function('gitgutter#process_buffer', [a:bufnr, a:force])
|
||||
else
|
||||
let l:Callback = {'function': 'gitgutter#process_buffer', 'arguments': [a:bufnr, a:force]}
|
||||
endif
|
||||
let how = s:setup_path(a:bufnr, l:Callback)
|
||||
if [how] == ['async'] " avoid string-to-number conversion if how is a number
|
||||
return
|
||||
endif
|
||||
|
||||
if a:force || s:has_fresh_changes(a:bufnr)
|
||||
|
||||
let diff = ''
|
||||
@ -108,11 +106,19 @@ endfunction
|
||||
|
||||
" }}}
|
||||
|
||||
function! s:setup_maps()
|
||||
function! gitgutter#setup_maps()
|
||||
if !g:gitgutter_map_keys
|
||||
return
|
||||
endif
|
||||
|
||||
" Note hasmapto() and maparg() operate on the current buffer.
|
||||
|
||||
let bufnr = bufnr('')
|
||||
|
||||
if gitgutter#utility#getbufvar(bufnr, 'mapped', 0)
|
||||
return
|
||||
endif
|
||||
|
||||
if !hasmapto('<Plug>GitGutterPrevHunk') && maparg('[c', 'n') ==# ''
|
||||
nmap <buffer> [c <Plug>GitGutterPrevHunk
|
||||
endif
|
||||
@ -120,7 +126,10 @@ function! s:setup_maps()
|
||||
nmap <buffer> ]c <Plug>GitGutterNextHunk
|
||||
endif
|
||||
|
||||
if !hasmapto('<Plug>GitGutterStageHunk') && maparg('<Leader>hs', 'n') ==# ''
|
||||
if !hasmapto('<Plug>GitGutterStageHunk', 'v') && maparg('<Leader>hs', 'x') ==# ''
|
||||
xmap <buffer> <Leader>hs <Plug>GitGutterStageHunk
|
||||
endif
|
||||
if !hasmapto('<Plug>GitGutterStageHunk', 'n') && maparg('<Leader>hs', 'n') ==# ''
|
||||
nmap <buffer> <Leader>hs <Plug>GitGutterStageHunk
|
||||
endif
|
||||
if !hasmapto('<Plug>GitGutterUndoHunk') && maparg('<Leader>hu', 'n') ==# ''
|
||||
@ -142,6 +151,18 @@ function! s:setup_maps()
|
||||
if !hasmapto('<Plug>GitGutterTextObjectOuterVisual') && maparg('ac', 'x') ==# ''
|
||||
xmap <buffer> ac <Plug>GitGutterTextObjectOuterVisual
|
||||
endif
|
||||
|
||||
call gitgutter#utility#setbufvar(bufnr, 'mapped', 1)
|
||||
endfunction
|
||||
|
||||
function! s:setup_path(bufnr, continuation)
|
||||
let p = gitgutter#utility#repo_path(a:bufnr, 0)
|
||||
|
||||
if type(p) == s:t_string && !empty(p) " if path is known
|
||||
return
|
||||
endif
|
||||
|
||||
return gitgutter#utility#set_repo_path(a:bufnr, a:continuation)
|
||||
endfunction
|
||||
|
||||
function! s:has_fresh_changes(bufnr) abort
|
||||
@ -154,7 +175,7 @@ endfunction
|
||||
|
||||
function! s:clear(bufnr)
|
||||
call gitgutter#sign#clear_signs(a:bufnr)
|
||||
call gitgutter#sign#remove_dummy_sign(a:bufnr, 1)
|
||||
call gitgutter#hunk#reset(a:bufnr)
|
||||
call s:reset_tick(a:bufnr)
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'path', '')
|
||||
endfunction
|
||||
|
@ -4,7 +4,7 @@ let s:hunk_re = '^@@ -\(\d\+\),\?\(\d*\) +\(\d\+\),\?\(\d*\) @@'
|
||||
|
||||
" True for git v1.7.2+.
|
||||
function! s:git_supports_command_line_config_override() abort
|
||||
call system(g:gitgutter_git_executable.' -c foo.bar=baz --version')
|
||||
call system(g:gitgutter_git_executable.' '.g:gitgutter_git_args.' -c foo.bar=baz --version')
|
||||
return !v:shell_error
|
||||
endfunction
|
||||
|
||||
@ -68,9 +68,9 @@ let s:counter = 0
|
||||
" the hunk headers (@@ -x,y +m,n @@); only possible if
|
||||
" grep is available.
|
||||
function! gitgutter#diff#run_diff(bufnr, from, preserve_full_diff) abort
|
||||
while gitgutter#utility#repo_path(a:bufnr, 0) == -1
|
||||
sleep 5m
|
||||
endwhile
|
||||
if gitgutter#utility#repo_path(a:bufnr, 0) == -1
|
||||
throw 'gitgutter author fail'
|
||||
endif
|
||||
|
||||
if gitgutter#utility#repo_path(a:bufnr, 0) == -2
|
||||
throw 'gitgutter not tracked'
|
||||
@ -119,14 +119,14 @@ function! gitgutter#diff#run_diff(bufnr, from, preserve_full_diff) abort
|
||||
|
||||
" 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.' > '.from_file.' && '
|
||||
let cmd .= g:gitgutter_git_executable.' '.g:gitgutter_git_args.' --no-pager show '.index_name.' > '.from_file.' && '
|
||||
|
||||
elseif a:from ==# 'working_tree'
|
||||
let from_file = gitgutter#utility#repo_path(a:bufnr, 1)
|
||||
endif
|
||||
|
||||
" Call git-diff.
|
||||
let cmd .= g:gitgutter_git_executable.' --no-pager '.g:gitgutter_git_args
|
||||
let cmd .= g:gitgutter_git_executable.' '.g:gitgutter_git_args.' --no-pager '.g:gitgutter_git_args
|
||||
if s:c_flag
|
||||
let cmd .= ' -c "diff.autorefreshindex=0"'
|
||||
let cmd .= ' -c "diff.noprefix=false"'
|
||||
|
@ -4,7 +4,6 @@ function! gitgutter#highlight#line_disable() abort
|
||||
|
||||
if !g:gitgutter_signs
|
||||
call gitgutter#sign#clear_signs(bufnr(''))
|
||||
call gitgutter#sign#remove_dummy_sign(bufnr(''), 0)
|
||||
endif
|
||||
|
||||
redraw!
|
||||
@ -31,6 +30,38 @@ function! gitgutter#highlight#line_toggle() abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! gitgutter#highlight#linenr_disable() abort
|
||||
let g:gitgutter_highlight_linenrs = 0
|
||||
call s:define_sign_linenr_highlights()
|
||||
|
||||
if !g:gitgutter_signs
|
||||
call gitgutter#sign#clear_signs(bufnr(''))
|
||||
endif
|
||||
|
||||
redraw!
|
||||
endfunction
|
||||
|
||||
function! gitgutter#highlight#linenr_enable() abort
|
||||
let old_highlight_lines = g:gitgutter_highlight_linenrs
|
||||
|
||||
let g:gitgutter_highlight_linenrs = 1
|
||||
call s:define_sign_linenr_highlights()
|
||||
|
||||
if !old_highlight_lines && !g:gitgutter_signs
|
||||
call gitgutter#all(1)
|
||||
endif
|
||||
|
||||
redraw!
|
||||
endfunction
|
||||
|
||||
function! gitgutter#highlight#linenr_toggle() abort
|
||||
if g:gitgutter_highlight_linenrs
|
||||
call gitgutter#highlight#linenr_disable()
|
||||
else
|
||||
call gitgutter#highlight#linenr_enable()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! gitgutter#highlight#define_sign_column_highlight() abort
|
||||
if g:gitgutter_override_sign_column_highlight
|
||||
@ -66,6 +97,11 @@ function! gitgutter#highlight#define_highlights() abort
|
||||
highlight default link GitGutterChangeLine DiffChange
|
||||
highlight default link GitGutterDeleteLine DiffDelete
|
||||
highlight default link GitGutterChangeDeleteLine GitGutterChangeLine
|
||||
|
||||
highlight default link GitGutterAddLineNr CursorLineNr
|
||||
highlight default link GitGutterChangeLineNr CursorLineNr
|
||||
highlight default link GitGutterDeleteLineNr CursorLineNr
|
||||
highlight default link GitGutterChangeDeleteLineNr CursorLineNr
|
||||
endfunction
|
||||
|
||||
function! gitgutter#highlight#define_signs() abort
|
||||
@ -75,11 +111,11 @@ function! gitgutter#highlight#define_signs() abort
|
||||
sign define GitGutterLineRemovedFirstLine
|
||||
sign define GitGutterLineRemovedAboveAndBelow
|
||||
sign define GitGutterLineModifiedRemoved
|
||||
sign define GitGutterDummy
|
||||
|
||||
call s:define_sign_text()
|
||||
call gitgutter#highlight#define_sign_text_highlights()
|
||||
call s:define_sign_line_highlights()
|
||||
call s:define_sign_linenr_highlights()
|
||||
endfunction
|
||||
|
||||
function! s:define_sign_text() abort
|
||||
@ -131,40 +167,45 @@ function! s:define_sign_line_highlights() abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:get_foreground_colors(group) abort
|
||||
redir => highlight
|
||||
silent execute 'silent highlight ' . a:group
|
||||
redir END
|
||||
|
||||
let link_matches = matchlist(highlight, 'links to \(\S\+\)')
|
||||
if len(link_matches) > 0 " follow the link
|
||||
return s:get_foreground_colors(link_matches[1])
|
||||
function! s:define_sign_linenr_highlights() abort
|
||||
if has('nvim-0.3.2')
|
||||
try
|
||||
if g:gitgutter_highlight_linenrs
|
||||
sign define GitGutterLineAdded numhl=GitGutterAddLineNr
|
||||
sign define GitGutterLineModified numhl=GitGutterChangeLineNr
|
||||
sign define GitGutterLineRemoved numhl=GitGutterDeleteLineNr
|
||||
sign define GitGutterLineRemovedFirstLine numhl=GitGutterDeleteLineNr
|
||||
sign define GitGutterLineRemovedAboveAndBelow numhl=GitGutterDeleteLineNr
|
||||
sign define GitGutterLineModifiedRemoved numhl=GitGutterChangeDeleteLineNr
|
||||
else
|
||||
sign define GitGutterLineAdded numhl=
|
||||
sign define GitGutterLineModified numhl=
|
||||
sign define GitGutterLineRemoved numhl=
|
||||
sign define GitGutterLineRemovedFirstLine numhl=
|
||||
sign define GitGutterLineRemovedAboveAndBelow numhl=
|
||||
sign define GitGutterLineModifiedRemoved numhl=
|
||||
endif
|
||||
catch /E475/
|
||||
endtry
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let ctermfg = s:match_highlight(highlight, 'ctermfg=\([0-9A-Za-z]\+\)')
|
||||
let guifg = s:match_highlight(highlight, 'guifg=\([#0-9A-Za-z]\+\)')
|
||||
function! s:get_hl(group, what, mode) abort
|
||||
let r = synIDattr(synIDtrans(hlID(a:group)), a:what, a:mode)
|
||||
if empty(r) || r == -1
|
||||
return 'NONE'
|
||||
endif
|
||||
return r
|
||||
endfunction
|
||||
|
||||
function! s:get_foreground_colors(group) abort
|
||||
let ctermfg = s:get_hl(a:group, 'fg', 'cterm')
|
||||
let guifg = s:get_hl(a:group, 'fg', 'gui')
|
||||
return [guifg, ctermfg]
|
||||
endfunction
|
||||
|
||||
function! s:get_background_colors(group) abort
|
||||
redir => highlight
|
||||
silent execute 'silent highlight ' . a:group
|
||||
redir END
|
||||
|
||||
let link_matches = matchlist(highlight, 'links to \(\S\+\)')
|
||||
if len(link_matches) > 0 " follow the link
|
||||
return s:get_background_colors(link_matches[1])
|
||||
endif
|
||||
|
||||
let ctermbg = s:match_highlight(highlight, 'ctermbg=\([0-9A-Za-z]\+\)')
|
||||
let guibg = s:match_highlight(highlight, 'guibg=\([#0-9A-Za-z]\+\)')
|
||||
let ctermbg = s:get_hl(a:group, 'bg', 'cterm')
|
||||
let guibg = s:get_hl(a:group, 'bg', 'gui')
|
||||
return [guibg, ctermbg]
|
||||
endfunction
|
||||
|
||||
function! s:match_highlight(highlight, pattern) abort
|
||||
let matches = matchlist(a:highlight, a:pattern)
|
||||
if len(matches) == 0
|
||||
return 'NONE'
|
||||
endif
|
||||
return matches[1]
|
||||
endfunction
|
||||
|
@ -169,8 +169,12 @@ function! gitgutter#hunk#text_object(inner) abort
|
||||
endfunction
|
||||
|
||||
|
||||
function! gitgutter#hunk#stage() abort
|
||||
call s:hunk_op(function('s:stage'))
|
||||
function! gitgutter#hunk#stage(...) abort
|
||||
if a:0 && (a:1 != 1 || a:2 != line('$'))
|
||||
call s:hunk_op(function('s:stage'), a:1, a:2)
|
||||
else
|
||||
call s:hunk_op(function('s:stage'))
|
||||
endif
|
||||
silent! call repeat#set("\<Plug>GitGutterStageHunk", -1)
|
||||
endfunction
|
||||
|
||||
@ -185,9 +189,39 @@ function! gitgutter#hunk#preview() abort
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:hunk_op(op)
|
||||
function! s:hunk_op(op, ...)
|
||||
let bufnr = bufnr('')
|
||||
|
||||
if &previewwindow
|
||||
if string(a:op) =~ '_stage'
|
||||
" combine hunk-body in preview window with updated hunk-header
|
||||
let hunk_body = getline(1, '$')
|
||||
|
||||
let [removed, added] = [0, 0]
|
||||
for line in hunk_body
|
||||
if line[0] == '-'
|
||||
let removed += 1
|
||||
elseif line[0] == '+'
|
||||
let added += 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
let hunk_header = b:hunk_header
|
||||
" from count
|
||||
let hunk_header[4] = substitute(hunk_header[4], '\(-\d\+\)\(,\d\+\)\?', '\=submatch(1).",".removed', '')
|
||||
" to count
|
||||
let hunk_header[4] = substitute(hunk_header[4], '\(+\d\+\)\(,\d\+\)\?', '\=submatch(1).",".added', '')
|
||||
|
||||
let hunk_diff = join(hunk_header + hunk_body, "\n")."\n"
|
||||
|
||||
wincmd p
|
||||
pclose
|
||||
call s:stage(hunk_diff)
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
if gitgutter#utility#is_active(bufnr)
|
||||
" Get a (synchronous) diff.
|
||||
let [async, g:gitgutter_async] = [g:gitgutter_async, 0]
|
||||
@ -210,7 +244,14 @@ function! s:hunk_op(op)
|
||||
call gitgutter#utility#warn('did not recognise your choice')
|
||||
endif
|
||||
else
|
||||
call a:op(gitgutter#diff#hunk_diff(bufnr, diff))
|
||||
let hunk_diff = gitgutter#diff#hunk_diff(bufnr, diff)
|
||||
|
||||
if a:0
|
||||
let hunk_first_line = s:current_hunk()[2]
|
||||
let hunk_diff = s:part_of_diff(hunk_diff, a:1-hunk_first_line, a:2-hunk_first_line)
|
||||
endif
|
||||
|
||||
call a:op(hunk_diff)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
@ -221,8 +262,11 @@ function! s:stage(hunk_diff)
|
||||
let diff = s:adjust_header(bufnr, a:hunk_diff)
|
||||
" Apply patch to index.
|
||||
call gitgutter#utility#system(
|
||||
\ gitgutter#utility#cd_cmd(bufnr, g:gitgutter_git_executable.' apply --cached --unidiff-zero - '),
|
||||
\ gitgutter#utility#cd_cmd(bufnr, g:gitgutter_git_executable.' '.g:gitgutter_git_args.' apply --cached --unidiff-zero - '),
|
||||
\ diff)
|
||||
if v:shell_error
|
||||
call gitgutter#utility#warn('patch does not apply')
|
||||
endif
|
||||
|
||||
" Refresh gitgutter's view of buffer.
|
||||
call gitgutter#process_buffer(bufnr, 1)
|
||||
@ -240,37 +284,58 @@ function! s:undo(hunk_diff)
|
||||
if removed_only
|
||||
call append(lnum, lines)
|
||||
elseif added_only
|
||||
execute lnum .','. (lnum+len(lines)-1) .'d'
|
||||
execute lnum .','. (lnum+len(lines)-1) .'d _'
|
||||
else
|
||||
call append(lnum-1, lines[0:hunk[1]])
|
||||
execute (lnum+hunk[1]) .','. (lnum+hunk[1]+hunk[3]) .'d'
|
||||
execute (lnum+hunk[1]) .','. (lnum+hunk[1]+hunk[3]) .'d _'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:preview(hunk_diff)
|
||||
let hunk_lines = split(s:discard_header(a:hunk_diff), "\n")
|
||||
let hunk_lines_length = len(hunk_lines)
|
||||
let previewheight = min([hunk_lines_length, &previewheight])
|
||||
let lines = split(a:hunk_diff, '\n')
|
||||
let header = lines[0:4]
|
||||
let body = lines[5:]
|
||||
|
||||
let body_length = len(body)
|
||||
let previewheight = min([body_length, &previewheight])
|
||||
|
||||
silent! wincmd P
|
||||
if !&previewwindow
|
||||
noautocmd execute 'bo' previewheight 'new'
|
||||
noautocmd execute g:gitgutter_preview_win_location previewheight 'new'
|
||||
set previewwindow
|
||||
else
|
||||
execute 'resize' previewheight
|
||||
endif
|
||||
|
||||
let b:hunk_header = header
|
||||
|
||||
setlocal noreadonly modifiable filetype=diff buftype=nofile bufhidden=delete noswapfile
|
||||
execute "%delete_"
|
||||
call append(0, hunk_lines)
|
||||
call setline(1, body)
|
||||
normal! gg
|
||||
setlocal readonly nomodifiable
|
||||
|
||||
cnoreabbrev <buffer> <expr> w getcmdtype() == ':' && getcmdline() == 'w' ? 'GitGutterStageHunk' : 'w'
|
||||
" Staging hunk from the preview window closes the window anyway.
|
||||
cnoreabbrev <buffer> <expr> wq getcmdtype() == ':' && getcmdline() == 'wq' ? 'GitGutterStageHunk' : 'wq'
|
||||
|
||||
noautocmd wincmd p
|
||||
endfunction
|
||||
|
||||
|
||||
" Returns a new hunk diff using the specified lines from the given one.
|
||||
" Assumes all lines are additions.
|
||||
" a:first, a:last - 0-based indexes into the body of the hunk.
|
||||
function! s:part_of_diff(hunk_diff, first, last)
|
||||
let diff_lines = split(a:hunk_diff, '\n', 1)
|
||||
|
||||
" adjust 'to' line count in header
|
||||
let diff_lines[4] = substitute(diff_lines[4], '\(+\d\+\)\(,\d\+\)\?', '\=submatch(1).",".(a:last-a:first+1)', '')
|
||||
|
||||
return join(diff_lines[0:4] + diff_lines[5+a:first:5+a:last], "\n")."\n"
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:adjust_header(bufnr, hunk_diff)
|
||||
let filepath = gitgutter#utility#repo_path(a:bufnr, 0)
|
||||
return s:adjust_hunk_summary(s:fix_file_references(filepath, a:hunk_diff))
|
||||
@ -305,16 +370,11 @@ endif
|
||||
function! s:adjust_hunk_summary(hunk_diff) abort
|
||||
let line_adjustment = s:line_adjustment_for_current_hunk()
|
||||
let diff = split(a:hunk_diff, '\n', 1)
|
||||
let diff[4] = substitute(diff[4], '+\@<=\(\d\+\)', '\=submatch(1)+line_adjustment', '')
|
||||
let diff[4] = substitute(diff[4], '+\zs\(\d\+\)', '\=submatch(1)+line_adjustment', '')
|
||||
return join(diff, "\n")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:discard_header(hunk_diff)
|
||||
return join(split(a:hunk_diff, '\n', 1)[5:], "\n")
|
||||
endfunction
|
||||
|
||||
|
||||
" Returns the number of lines the current hunk is offset from where it would
|
||||
" be if any changes above it in the file didn't exist.
|
||||
function! s:line_adjustment_for_current_hunk() abort
|
||||
|
@ -1,11 +1,6 @@
|
||||
" Vim doesn't namespace sign ids so every plugin shares the same
|
||||
" namespace. Sign ids are simply integers so to avoid clashes with other
|
||||
" signs we guess at a clear run.
|
||||
"
|
||||
" Note also we currently never reset s:next_sign_id.
|
||||
" For older Vims without sign_place() the plugin has to manaage the sign ids.
|
||||
let s:first_sign_id = 3000
|
||||
let s:next_sign_id = s:first_sign_id
|
||||
let s:dummy_sign_id = s:first_sign_id - 1
|
||||
" Remove-all-signs optimisation requires Vim 7.3.596+.
|
||||
let s:supports_star = v:version > 703 || (v:version == 703 && has("patch596"))
|
||||
|
||||
@ -27,7 +22,6 @@ function! gitgutter#sign#disable() abort
|
||||
|
||||
if !g:gitgutter_highlight_lines
|
||||
call gitgutter#sign#clear_signs(bufnr(''))
|
||||
call gitgutter#sign#remove_dummy_sign(bufnr(''), 0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@ -40,8 +34,14 @@ function! gitgutter#sign#toggle() abort
|
||||
endfunction
|
||||
|
||||
|
||||
" Removes gitgutter's signs (excluding dummy sign) from the buffer being processed.
|
||||
" Removes gitgutter's signs from the buffer being processed.
|
||||
function! gitgutter#sign#clear_signs(bufnr) abort
|
||||
if exists('*sign_unplace')
|
||||
call sign_unplace('gitgutter', {'buffer': a:bufnr})
|
||||
return
|
||||
endif
|
||||
|
||||
|
||||
call s:find_current_signs(a:bufnr)
|
||||
|
||||
let sign_ids = map(values(gitgutter#utility#getbufvar(a:bufnr, 'gitgutter_signs')), 'v:val.id')
|
||||
@ -55,37 +55,42 @@ endfunction
|
||||
" modified_lines: list of [<line_number (number)>, <name (string)>]
|
||||
" where name = 'added|removed|modified|modified_removed'
|
||||
function! gitgutter#sign#update_signs(bufnr, modified_lines) abort
|
||||
if exists('*sign_unplace')
|
||||
" Vim is (hopefully) now quick enough to remove all signs then place new ones.
|
||||
call sign_unplace('gitgutter', {'buffer': a:bufnr})
|
||||
|
||||
let modified_lines = s:handle_double_hunk(a:modified_lines)
|
||||
let signs = map(copy(modified_lines), '{'.
|
||||
\ '"buffer": a:bufnr,'.
|
||||
\ '"group": "gitgutter",'.
|
||||
\ '"name": s:highlight_name_for_change(v:val[1]),'.
|
||||
\ '"lnum": v:val[0],'.
|
||||
\ '"priority": g:gitgutter_sign_priority'.
|
||||
\ '}')
|
||||
|
||||
if exists('*sign_placelist')
|
||||
call sign_placelist(signs)
|
||||
return
|
||||
endif
|
||||
|
||||
for sign in signs
|
||||
call sign_place(0, sign.group, sign.name, sign.buffer, {'lnum': sign.lnum, 'priority': sign.priority})
|
||||
endfor
|
||||
return
|
||||
endif
|
||||
|
||||
|
||||
" Derive a delta between the current signs and the ones we want.
|
||||
" Remove signs from lines that no longer need a sign.
|
||||
" Upsert the remaining signs.
|
||||
|
||||
call s:find_current_signs(a:bufnr)
|
||||
|
||||
let new_gitgutter_signs_line_numbers = map(copy(a:modified_lines), 'v:val[0]')
|
||||
let obsolete_signs = s:obsolete_gitgutter_signs_to_remove(a:bufnr, new_gitgutter_signs_line_numbers)
|
||||
|
||||
let flicker_possible = s:remove_all_old_signs && !empty(a:modified_lines)
|
||||
if flicker_possible
|
||||
call s:add_dummy_sign(a:bufnr)
|
||||
endif
|
||||
|
||||
call s:remove_signs(a:bufnr, obsolete_signs, s:remove_all_old_signs)
|
||||
call s:upsert_new_gitgutter_signs(a:bufnr, a:modified_lines)
|
||||
|
||||
if flicker_possible
|
||||
call gitgutter#sign#remove_dummy_sign(a:bufnr, 0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:add_dummy_sign(bufnr) abort
|
||||
if !gitgutter#utility#getbufvar(a:bufnr, 'dummy_sign')
|
||||
execute "sign place" s:dummy_sign_id "line=" . 9999 "name=GitGutterDummy buffer=" . a:bufnr
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'dummy_sign', 1)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! gitgutter#sign#remove_dummy_sign(bufnr, force) abort
|
||||
if gitgutter#utility#getbufvar(a:bufnr, 'dummy_sign') && (a:force || !g:gitgutter_sign_column_always)
|
||||
execute "sign unplace" s:dummy_sign_id "buffer=" . a:bufnr
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'dummy_sign', 0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
@ -96,40 +101,52 @@ endfunction
|
||||
|
||||
function! s:find_current_signs(bufnr) abort
|
||||
let gitgutter_signs = {} " <line_number (string)>: {'id': <id (number)>, 'name': <name (string)>}
|
||||
let other_signs = [] " [<line_number (number),...]
|
||||
let dummy_sign_placed = 0
|
||||
if !g:gitgutter_sign_allow_clobber
|
||||
let other_signs = [] " [<line_number (number),...]
|
||||
endif
|
||||
|
||||
redir => signs
|
||||
silent execute "sign place buffer=" . a:bufnr
|
||||
redir END
|
||||
if exists('*getbufinfo')
|
||||
let bufinfo = getbufinfo(a:bufnr)[0]
|
||||
let signs = has_key(bufinfo, 'signs') ? bufinfo.signs : []
|
||||
else
|
||||
let signs = []
|
||||
|
||||
for sign_line in filter(split(signs, '\n')[2:], 'v:val =~# "="')
|
||||
" Typical sign line: line=88 id=1234 name=GitGutterLineAdded
|
||||
" We assume splitting is faster than a regexp.
|
||||
let components = split(sign_line)
|
||||
let name = split(components[2], '=')[1]
|
||||
if name =~# 'GitGutterDummy'
|
||||
let dummy_sign_placed = 1
|
||||
else
|
||||
let line_number = str2nr(split(components[0], '=')[1])
|
||||
if name =~# 'GitGutter'
|
||||
let id = str2nr(split(components[1], '=')[1])
|
||||
" Remove orphaned signs (signs placed on lines which have been deleted).
|
||||
" (When a line is deleted its sign lingers. Subsequent lines' signs'
|
||||
" line numbers are decremented appropriately.)
|
||||
if has_key(gitgutter_signs, line_number)
|
||||
execute "sign unplace" gitgutter_signs[line_number].id
|
||||
endif
|
||||
let gitgutter_signs[line_number] = {'id': id, 'name': name}
|
||||
else
|
||||
call add(other_signs, line_number)
|
||||
redir => signlines
|
||||
silent execute "sign place buffer=" . a:bufnr
|
||||
redir END
|
||||
|
||||
for signline in filter(split(signlines, '\n')[2:], 'v:val =~# "="')
|
||||
" Typical sign line before v8.1.0614: line=88 id=1234 name=GitGutterLineAdded
|
||||
" We assume splitting is faster than a regexp.
|
||||
let components = split(signline)
|
||||
call add(signs, {
|
||||
\ 'lnum': str2nr(split(components[0], '=')[1]),
|
||||
\ 'id': str2nr(split(components[1], '=')[1]),
|
||||
\ 'name': split(components[2], '=')[1]
|
||||
\ })
|
||||
endfor
|
||||
endif
|
||||
|
||||
for sign in signs
|
||||
if sign.name =~# 'GitGutter'
|
||||
" Remove orphaned signs (signs placed on lines which have been deleted).
|
||||
" (When a line is deleted its sign lingers. Subsequent lines' signs'
|
||||
" line numbers are decremented appropriately.)
|
||||
if has_key(gitgutter_signs, sign.lnum)
|
||||
execute "sign unplace" gitgutter_signs[sign.lnum].id
|
||||
endif
|
||||
end
|
||||
let gitgutter_signs[sign.lnum] = {'id': sign.id, 'name': sign.name}
|
||||
else
|
||||
if !g:gitgutter_sign_allow_clobber
|
||||
call add(other_signs, sign.lnum)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'dummy_sign', dummy_sign_placed)
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'gitgutter_signs', gitgutter_signs)
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'other_signs', other_signs)
|
||||
if !g:gitgutter_sign_allow_clobber
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'other_signs', other_signs)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
@ -152,12 +169,8 @@ endfunction
|
||||
|
||||
|
||||
function! s:remove_signs(bufnr, sign_ids, all_signs) abort
|
||||
if a:all_signs && s:supports_star && empty(gitgutter#utility#getbufvar(a:bufnr, 'other_signs'))
|
||||
let dummy_sign_present = gitgutter#utility#getbufvar(a:bufnr, 'dummy_sign')
|
||||
if a:all_signs && s:supports_star && (g:gitgutter_sign_allow_clobber || empty(gitgutter#utility#getbufvar(a:bufnr, 'other_signs')))
|
||||
execute "sign unplace * buffer=" . a:bufnr
|
||||
if dummy_sign_present
|
||||
execute "sign place" s:dummy_sign_id "line=" . 9999 "name=GitGutterDummy buffer=" . a:bufnr
|
||||
endif
|
||||
else
|
||||
for id in a:sign_ids
|
||||
execute "sign unplace" id
|
||||
@ -167,21 +180,16 @@ endfunction
|
||||
|
||||
|
||||
function! s:upsert_new_gitgutter_signs(bufnr, modified_lines) abort
|
||||
let other_signs = gitgutter#utility#getbufvar(a:bufnr, 'other_signs')
|
||||
if !g:gitgutter_sign_allow_clobber
|
||||
let other_signs = gitgutter#utility#getbufvar(a:bufnr, 'other_signs')
|
||||
endif
|
||||
let old_gitgutter_signs = gitgutter#utility#getbufvar(a:bufnr, 'gitgutter_signs')
|
||||
|
||||
" Handle special case where the first line is the site of two hunks:
|
||||
" lines deleted above at the start of the file, and lines deleted
|
||||
" immediately below.
|
||||
if a:modified_lines[0:1] == [[1, 'removed_first_line'], [1, 'removed']]
|
||||
let modified_lines = [[1, 'removed_above_and_below']] + a:modified_lines[2:]
|
||||
else
|
||||
let modified_lines = a:modified_lines
|
||||
endif
|
||||
let modified_lines = s:handle_double_hunk(a:modified_lines)
|
||||
|
||||
for line in modified_lines
|
||||
let line_number = line[0] " <number>
|
||||
if index(other_signs, line_number) == -1 " don't clobber others' signs
|
||||
if g:gitgutter_sign_allow_clobber || index(other_signs, line_number) == -1 " don't clobber others' signs
|
||||
let name = s:highlight_name_for_change(line[1])
|
||||
if !has_key(old_gitgutter_signs, line_number) " insert
|
||||
let id = s:next_sign_id()
|
||||
@ -198,6 +206,18 @@ function! s:upsert_new_gitgutter_signs(bufnr, modified_lines) abort
|
||||
endfunction
|
||||
|
||||
|
||||
" Handle special case where the first line is the site of two hunks:
|
||||
" lines deleted above at the start of the file, and lines deleted
|
||||
" immediately below.
|
||||
function! s:handle_double_hunk(modified_lines)
|
||||
if a:modified_lines[0:1] == [[1, 'removed_first_line'], [1, 'removed']]
|
||||
return [[1, 'removed_above_and_below']] + a:modified_lines[2:]
|
||||
endif
|
||||
|
||||
return a:modified_lines
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:next_sign_id() abort
|
||||
let next_id = s:next_sign_id
|
||||
let s:next_sign_id += 1
|
||||
|
@ -22,14 +22,16 @@ function! gitgutter#utility#setbufvar(buffer, varname, val)
|
||||
endfunction
|
||||
|
||||
function! gitgutter#utility#getbufvar(buffer, varname, ...)
|
||||
let dict = get(getbufvar(a:buffer, ''), 'gitgutter', {})
|
||||
if has_key(dict, a:varname)
|
||||
return dict[a:varname]
|
||||
else
|
||||
if a:0
|
||||
return a:1
|
||||
let bvars = getbufvar(a:buffer, '')
|
||||
if !empty(bvars)
|
||||
let dict = get(bvars, 'gitgutter', {})
|
||||
if has_key(dict, a:varname)
|
||||
return dict[a:varname]
|
||||
endif
|
||||
endif
|
||||
if a:0
|
||||
return a:1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! gitgutter#utility#warn(message) abort
|
||||
@ -114,58 +116,52 @@ function! gitgutter#utility#repo_path(bufnr, shellesc) abort
|
||||
return a:shellesc ? gitgutter#utility#shellescape(p) : p
|
||||
endfunction
|
||||
|
||||
function! gitgutter#utility#set_repo_path(bufnr) abort
|
||||
|
||||
let s:set_path_handler = {}
|
||||
|
||||
function! s:set_path_handler.out(buffer, path) abort
|
||||
let path = s:strip_trailing_new_line(a:path)
|
||||
call gitgutter#utility#setbufvar(a:buffer, 'path', path)
|
||||
|
||||
if type(self.continuation) == type(function('tr'))
|
||||
call self.continuation()
|
||||
else
|
||||
call call(self.continuation.function, self.continuation.arguments)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:set_path_handler.err(buffer) abort
|
||||
call gitgutter#utility#setbufvar(a:buffer, 'path', -2)
|
||||
endfunction
|
||||
|
||||
|
||||
" continuation - a funcref or hash to call after setting the repo path asynchronously.
|
||||
"
|
||||
" Returns 'async' if the the path is set asynchronously, 0 otherwise.
|
||||
function! gitgutter#utility#set_repo_path(bufnr, continuation) abort
|
||||
" Values of path:
|
||||
" * non-empty string - path
|
||||
" * -1 - pending
|
||||
" * -2 - not tracked by git
|
||||
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'path', -1)
|
||||
let cmd = gitgutter#utility#cd_cmd(a:bufnr, g:gitgutter_git_executable.' ls-files --error-unmatch --full-name -z -- '.gitgutter#utility#shellescape(s:filename(a:bufnr)))
|
||||
let cmd = gitgutter#utility#cd_cmd(a:bufnr, g:gitgutter_git_executable.' '.g:gitgutter_git_args.' ls-files --error-unmatch --full-name -z -- '.gitgutter#utility#shellescape(s:filename(a:bufnr)))
|
||||
|
||||
if g:gitgutter_async && gitgutter#async#available()
|
||||
if has('lambda')
|
||||
call gitgutter#async#execute(cmd, a:bufnr, {
|
||||
\ 'out': {bufnr, path -> gitgutter#utility#setbufvar(bufnr, 'path', s:strip_trailing_new_line(path))},
|
||||
\ 'err': {bufnr -> gitgutter#utility#setbufvar(bufnr, 'path', -2)},
|
||||
\ })
|
||||
else
|
||||
if has('nvim') && !has('nvim-0.2.0')
|
||||
call gitgutter#async#execute(cmd, a:bufnr, {
|
||||
\ 'out': function('s:set_path'),
|
||||
\ 'err': function('s:not_tracked_by_git')
|
||||
\ })
|
||||
else
|
||||
call gitgutter#async#execute(cmd, a:bufnr, {
|
||||
\ 'out': function('s:set_path'),
|
||||
\ 'err': function('s:set_path', [-2])
|
||||
\ })
|
||||
endif
|
||||
endif
|
||||
if g:gitgutter_async && gitgutter#async#available() && !has('vim_starting')
|
||||
let handler = copy(s:set_path_handler)
|
||||
let handler.continuation = a:continuation
|
||||
call gitgutter#async#execute(cmd, a:bufnr, handler)
|
||||
return 'async'
|
||||
endif
|
||||
|
||||
let path = gitgutter#utility#system(cmd)
|
||||
if v:shell_error
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'path', -2)
|
||||
else
|
||||
let path = gitgutter#utility#system(cmd)
|
||||
if v:shell_error
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'path', -2)
|
||||
else
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'path', s:strip_trailing_new_line(path))
|
||||
endif
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'path', s:strip_trailing_new_line(path))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
if has('nvim') && !has('nvim-0.2.0')
|
||||
function! s:not_tracked_by_git(bufnr)
|
||||
call s:set_path(a:bufnr, -2)
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! s:set_path(bufnr, path)
|
||||
if a:bufnr == -2
|
||||
let [bufnr, path] = [a:path, a:bufnr]
|
||||
call gitgutter#utility#setbufvar(bufnr, 'path', path)
|
||||
else
|
||||
call gitgutter#utility#setbufvar(a:bufnr, 'path', s:strip_trailing_new_line(a:path))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! gitgutter#utility#cd_cmd(bufnr, cmd) abort
|
||||
let cd = s:unc_path(a:bufnr) ? 'pushd' : (gitgutter#utility#windows() ? 'cd /d' : 'cd')
|
||||
|
@ -79,6 +79,19 @@ Copy vim-gitgutter's subdirectories into your vim configuration directory:
|
||||
See |add-global-plugin|.
|
||||
|
||||
|
||||
WINDOWS *gitgutter-windows*
|
||||
|
||||
I recommend configuring vim-gitgutter with the full path to your git executable.
|
||||
For example:
|
||||
>
|
||||
let g:gitgutter_git_executable = 'C:\Program Files\Git\bin\git.exe'
|
||||
<
|
||||
This is to avoid a problem which occurs if you have file named "git.*" (i.e.
|
||||
with any extension in "PATHEXT") in your current folder. "cmd.exe" prioritises
|
||||
the current folder over folders in 'PATH' and will try to execute your file
|
||||
instead of the "git" binary.
|
||||
|
||||
|
||||
===============================================================================
|
||||
COMMANDS *gitgutter-commands*
|
||||
|
||||
@ -126,6 +139,19 @@ Commands for turning line highlighting on and off (defaults to off):~
|
||||
:GitGutterLineHighlightsToggle Turn line highlighting on or off.
|
||||
|
||||
|
||||
Commands for turning line number highlighting on and off (defaults to off):~
|
||||
NOTE: This feature requires Neovim 0.3.2 or higher.
|
||||
|
||||
*gitgutter-:GitGutterLineNrHighlightsEnable*
|
||||
:GitGutterLineNrHighlightsEnable Turn on line highlighting.
|
||||
|
||||
*gitgutter-:GitGutterLineNrHighlightsDisable*
|
||||
:GitGutterLineNrHighlightsDisable Turn off line highlighting.
|
||||
|
||||
*gitgutter-:GitGutterLineNrHighlightsToggle*
|
||||
:GitGutterLineNrHighlightsToggle Turn line highlighting on or off.
|
||||
|
||||
|
||||
Commands for jumping between hunks:~
|
||||
|
||||
*gitgutter-:GitGutterNextHunk*
|
||||
@ -138,7 +164,14 @@ Commands for jumping between hunks:~
|
||||
Commands for operating on a hunk:~
|
||||
|
||||
*gitgutter-:GitGutterStageHunk*
|
||||
:GitGutterStageHunk Stage the hunk the cursor is in.
|
||||
:GitGutterStageHunk Stage the hunk the cursor is in. Use a visual selection
|
||||
to stage part of an (additions-only) hunk; or use a
|
||||
range.
|
||||
|
||||
To stage part of any hunk, first |GitGutterPreviewHunk|
|
||||
it, then move to the preview window, delete the lines
|
||||
you do not want to stage, and |write| or
|
||||
|GitGutterStageHunk|.
|
||||
|
||||
*gitgutter-:GitGutterUndoHunk*
|
||||
:GitGutterUndoHunk Undo the hunk the cursor is in.
|
||||
@ -148,6 +181,10 @@ Commands for operating on a hunk:~
|
||||
Use |:pclose| or |CTRL-W_CTRL-Z| to close the preview
|
||||
window.
|
||||
|
||||
To stage part of the hunk, move to the preview window,
|
||||
delete any lines you do not want to stage, and
|
||||
|GitGutterStageHunk|.
|
||||
|
||||
Commands for folds:~
|
||||
|
||||
*gitgutter-:GitGutterFold*
|
||||
@ -249,13 +286,15 @@ Signs:~
|
||||
|
||||
|g:gitgutter_signs|
|
||||
|g:gitgutter_highlight_lines|
|
||||
|g:gitgutter_highlight_linenrs|
|
||||
|g:gitgutter_max_signs|
|
||||
|g:gitgutter_sign_priority|
|
||||
|g:gitgutter_sign_allow_clobber|
|
||||
|g:gitgutter_sign_added|
|
||||
|g:gitgutter_sign_modified|
|
||||
|g:gitgutter_sign_removed|
|
||||
|g:gitgutter_sign_removed_first_line|
|
||||
|g:gitgutter_sign_modified_removed|
|
||||
|g:gitgutter_sign_column_always|
|
||||
|g:gitgutter_override_sign_column_highlight|
|
||||
|
||||
Terminal:~
|
||||
@ -270,6 +309,13 @@ General:~
|
||||
|g:gitgutter_log|
|
||||
|
||||
|
||||
*g:gitgutter_preview_win_location*
|
||||
Default: 'bo'
|
||||
|
||||
This option determines where the preview window pops up as a result of the
|
||||
:GitGutterPreviewHunk command. Other plausible values are 'to', 'bel', 'abo'.
|
||||
See the end of the |opening-window| docs.
|
||||
|
||||
*g:gitgutter_git_executable*
|
||||
Default: 'git'
|
||||
|
||||
@ -329,6 +375,11 @@ Default: 0
|
||||
|
||||
Determines whether or not to show line highlights.
|
||||
|
||||
*g:gitgutter_highlight_linenrs*
|
||||
Default: 0
|
||||
|
||||
Determines whether or not to show line number highlights.
|
||||
|
||||
*g:gitgutter_max_signs*
|
||||
Default: 500
|
||||
|
||||
@ -337,6 +388,18 @@ signs, so to avoid slowing down the GUI the number of signs is capped. When
|
||||
the number of changed lines exceeds this value, the plugin removes all signs
|
||||
and displays a warning message.
|
||||
|
||||
*g:gitgutter_sign_priority*
|
||||
Default: 10
|
||||
|
||||
Sets the |sign-priority| gitgutter assigns to its signs.
|
||||
|
||||
*g:gitgutter_sign_allow_clobber*
|
||||
Default: 0 (Vim < 8.1.0614, Neovim < 0.4.0)
|
||||
1 (otherwise)
|
||||
|
||||
Determines whether gitgutter preserves non-gitgutter signs. When 1, gitgutter
|
||||
will not preserve non-gitgutter signs.
|
||||
|
||||
*g:gitgutter_sign_added*
|
||||
*g:gitgutter_sign_modified*
|
||||
*g:gitgutter_sign_removed*
|
||||
@ -353,17 +416,6 @@ Defaults:
|
||||
You can use unicode characters but not images. Signs must not take up more than
|
||||
2 columns.
|
||||
|
||||
*g:gitgutter_sign_column_always*
|
||||
Default: 0
|
||||
|
||||
This legacy option controls whether the sign column should always be shown, even
|
||||
if there are no signs to display.
|
||||
|
||||
From Vim 7.4.2201, use 'signcolumn' instead:
|
||||
>
|
||||
set signcolumn=yes
|
||||
<
|
||||
|
||||
*g:gitgutter_override_sign_column_highlight*
|
||||
Default: 1
|
||||
|
||||
@ -396,6 +448,11 @@ If this applies to you, either install something like Terminus
|
||||
(https://github.com/wincent/terminus) to make |FocusGained| work or set this
|
||||
option to 0.
|
||||
|
||||
If you use tmux, try this in your tmux.conf:
|
||||
>
|
||||
set -g focus-events on
|
||||
<
|
||||
|
||||
When this option is 0, the plugin force-updates the buffer on |BufEnter|
|
||||
(instead of only updating if the buffer's contents has changed since the last
|
||||
update).
|
||||
@ -452,7 +509,19 @@ colorscheme or |vimrc|:
|
||||
|
||||
For example, to use |hl-DiffText| instead of |hl-DiffChange|:
|
||||
>
|
||||
highlight link GitGutterChangeLine DiffChange
|
||||
highlight link GitGutterChangeLine DiffText
|
||||
<
|
||||
To change the line number highlights, set up the following highlight groups in
|
||||
your colorscheme or |vimrc|:
|
||||
>
|
||||
GitGutterAddLineNr " default: links to CursorLineNr
|
||||
GitGutterChangeLineNr " default: links to CursorLineNr
|
||||
GitGutterDeleteLineNr " default: links to CursorLineNr
|
||||
GitGutterChangeDeleteLineNr " default: links to CursorLineNr
|
||||
<
|
||||
For example, to use |hl-Underlined| instead of |hl-CursorLineNr|:
|
||||
>
|
||||
highlight link GitGutterChangeLineNr Underlined
|
||||
<
|
||||
|
||||
|
||||
|
@ -22,17 +22,19 @@ function! s:set(var, default) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
call s:set('g:gitgutter_preview_win_location', 'bo')
|
||||
call s:set('g:gitgutter_enabled', 1)
|
||||
call s:set('g:gitgutter_max_signs', 500)
|
||||
call s:set('g:gitgutter_signs', 1)
|
||||
call s:set('g:gitgutter_highlight_lines', 0)
|
||||
call s:set('g:gitgutter_sign_column_always', 0)
|
||||
if g:gitgutter_sign_column_always && exists('&signcolumn')
|
||||
" Vim 7.4.2201.
|
||||
set signcolumn=yes
|
||||
let g:gitgutter_sign_column_always = 0
|
||||
call gitgutter#utility#warn('please replace "let g:gitgutter_sign_column_always=1" with "set signcolumn=yes"')
|
||||
call s:set('g:gitgutter_highlight_linenrs', 0)
|
||||
call s:set('g:gitgutter_sign_priority', 10)
|
||||
" Nvim 0.4.0 has an expanding sign column
|
||||
" The sign_place() function supports sign priority.
|
||||
if (has('nvim-0.4.0') || exists('*sign_place')) && !exists('g:gitgutter_sign_allow_clobber')
|
||||
let g:gitgutter_sign_allow_clobber = 1
|
||||
endif
|
||||
call s:set('g:gitgutter_sign_allow_clobber', 0)
|
||||
call s:set('g:gitgutter_override_sign_column_highlight', 1)
|
||||
call s:set('g:gitgutter_sign_added', '+')
|
||||
call s:set('g:gitgutter_sign_modified', '~')
|
||||
@ -111,6 +113,12 @@ command! -bar GitGutterLineHighlightsToggle call gitgutter#highlight#line_toggl
|
||||
|
||||
" }}}
|
||||
|
||||
" 'number' column highlights {{{
|
||||
command! -bar GitGutterLineNrHighlightsDisable call gitgutter#highlight#linenr_disable()
|
||||
command! -bar GitGutterLineNrHighlightsEnable call gitgutter#highlight#linenr_enable()
|
||||
command! -bar GitGutterLineNrHighlightsToggle call gitgutter#highlight#linenr_toggle()
|
||||
" }}}
|
||||
|
||||
" Signs {{{
|
||||
|
||||
command! -bar GitGutterSignsEnable call gitgutter#sign#enable()
|
||||
@ -124,7 +132,7 @@ command! -bar GitGutterSignsToggle call gitgutter#sign#toggle()
|
||||
command! -bar -count=1 GitGutterNextHunk call gitgutter#hunk#next_hunk(<count>)
|
||||
command! -bar -count=1 GitGutterPrevHunk call gitgutter#hunk#prev_hunk(<count>)
|
||||
|
||||
command! -bar GitGutterStageHunk call gitgutter#hunk#stage()
|
||||
command! -bar -range=% GitGutterStageHunk call gitgutter#hunk#stage(<line1>,<line2>)
|
||||
command! -bar GitGutterUndoHunk call gitgutter#hunk#undo()
|
||||
command! -bar GitGutterPreviewHunk call gitgutter#hunk#preview()
|
||||
|
||||
@ -179,6 +187,7 @@ command! -bar GitGutterDebug call gitgutter#debug#debug()
|
||||
nnoremap <silent> <expr> <Plug>GitGutterNextHunk &diff ? ']c' : ":\<C-U>execute v:count1 . 'GitGutterNextHunk'\<CR>"
|
||||
nnoremap <silent> <expr> <Plug>GitGutterPrevHunk &diff ? '[c' : ":\<C-U>execute v:count1 . 'GitGutterPrevHunk'\<CR>"
|
||||
|
||||
xnoremap <silent> <Plug>GitGutterStageHunk :GitGutterStageHunk<CR>
|
||||
nnoremap <silent> <Plug>GitGutterStageHunk :GitGutterStageHunk<CR>
|
||||
nnoremap <silent> <Plug>GitGutterUndoHunk :GitGutterUndoHunk<CR>
|
||||
nnoremap <silent> <Plug>GitGutterPreviewHunk :GitGutterPreviewHunk<CR>
|
||||
@ -186,11 +195,12 @@ nnoremap <silent> <Plug>GitGutterPreviewHunk :GitGutterPreviewHunk<CR>
|
||||
" }}}
|
||||
|
||||
function! s:on_bufenter()
|
||||
call gitgutter#setup_maps()
|
||||
|
||||
if exists('t:gitgutter_didtabenter') && t:gitgutter_didtabenter
|
||||
let t:gitgutter_didtabenter = 0
|
||||
call gitgutter#all(!g:gitgutter_terminal_reports_focus)
|
||||
else
|
||||
call gitgutter#init_buffer(bufnr(''))
|
||||
call gitgutter#process_buffer(bufnr(''), !g:gitgutter_terminal_reports_focus)
|
||||
endif
|
||||
endfunction
|
||||
@ -215,6 +225,11 @@ augroup gitgutter
|
||||
autocmd ShellCmdPost * call gitgutter#all(1)
|
||||
autocmd BufLeave term://* call gitgutter#all(1)
|
||||
|
||||
autocmd BufWritePost fugitive://*//0/* call gitgutter#all(1)
|
||||
|
||||
autocmd BufFilePre * GitGutterBufferDisable
|
||||
autocmd BufFilePost * GitGutterBufferEnable
|
||||
|
||||
" Handle all buffers when focus is gained, but only after it was lost.
|
||||
" FocusGained gets triggered on startup with Neovim at least already.
|
||||
" Therefore this tracks also if it was lost before.
|
||||
|
@ -10,7 +10,7 @@ $VIM -u NONE -U NONE -N \
|
||||
--cmd 'source ../plugin/gitgutter.vim' \
|
||||
-S runner.vim \
|
||||
test_*.vim \
|
||||
$*
|
||||
"$@"
|
||||
|
||||
cat messages.log
|
||||
|
||||
|
@ -6,21 +6,27 @@ let s:bufnr = bufnr('')
|
||||
" Helpers
|
||||
"
|
||||
|
||||
function s:signs(filename)
|
||||
redir => signs
|
||||
silent execute 'sign place'
|
||||
redir END
|
||||
" Ignores unexpected keys.
|
||||
"
|
||||
" expected - list of signs
|
||||
function s:assert_signs(expected, filename)
|
||||
if empty(a:expected)
|
||||
call assert_equal(a:expected, [])
|
||||
return
|
||||
endif
|
||||
|
||||
let signs = split(signs, '\n')
|
||||
let expected_keys = keys(a:expected[0])
|
||||
let actual = sign_getplaced(a:filename, {'group': 'gitgutter'})[0].signs
|
||||
|
||||
" filter out signs for this test file
|
||||
" assumes a:filename's signs are last set listed
|
||||
let i = index(signs, 'Signs for '.a:filename.':')
|
||||
let signs = (i > -1 ? signs[i+1:] : [])
|
||||
for sign in actual
|
||||
for k in keys(sign)
|
||||
if index(expected_keys, k) == -1
|
||||
call remove(sign, k)
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
call map(signs, {_, v -> substitute(v, ' ', '', '')})
|
||||
|
||||
return signs
|
||||
call assert_equal(a:expected, actual)
|
||||
endfunction
|
||||
|
||||
function s:git_diff()
|
||||
@ -71,8 +77,8 @@ function Test_add_lines()
|
||||
normal ggo*
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = ["line=2 id=3000 name=GitGutterLineAdded"]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
let expected = [{'lnum': 2, 'name': 'GitGutterLineAdded', 'group': 'gitgutter', 'priority': 10}]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -83,8 +89,8 @@ function Test_add_lines_fish()
|
||||
normal ggo*
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = ["line=2 id=3000 name=GitGutterLineAdded"]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
let expected = [{'lnum': 2, 'name': 'GitGutterLineAdded'}]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
|
||||
let &shell = _shell
|
||||
endfunction
|
||||
@ -94,8 +100,8 @@ function Test_modify_lines()
|
||||
normal ggi*
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = ["line=1 id=3000 name=GitGutterLineModified"]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
let expected = [{'lnum': 1, 'name': 'GitGutterLineModified'}]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -103,8 +109,8 @@ function Test_remove_lines()
|
||||
execute '5d'
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = ["line=4 id=3000 name=GitGutterLineRemoved"]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
let expected = [{'lnum': 4, 'name': 'GitGutterLineRemoved'}]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -112,8 +118,20 @@ function Test_remove_first_lines()
|
||||
execute '1d'
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = ["line=1 id=3000 name=GitGutterLineRemovedFirstLine"]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
let expected = [{'lnum': 1, 'name': 'GitGutterLineRemovedFirstLine'}]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
function Test_priority()
|
||||
let g:gitgutter_sign_priority = 5
|
||||
|
||||
execute '1d'
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
call s:assert_signs([{'priority': 5}], 'fixture.txt')
|
||||
|
||||
let g:gitgutter_sign_priority = 10
|
||||
endfunction
|
||||
|
||||
|
||||
@ -122,8 +140,8 @@ function Test_overlapping_hunks()
|
||||
execute '1d'
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = ["line=1 id=3000 name=GitGutterLineRemovedAboveAndBelow"]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
let expected = [{'lnum': 1, 'name': 'GitGutterLineRemovedAboveAndBelow'}]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -132,8 +150,8 @@ function Test_edit_file_with_same_name_as_a_branch()
|
||||
call system('git checkout -b fixture.txt')
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = ["line=5 id=3000 name=GitGutterLineModified"]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
let expected = [{'lnum': 5, 'name': 'GitGutterLineModified'}]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -144,8 +162,8 @@ function Test_file_added_to_git()
|
||||
normal ihello
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = ["line=1 id=3000 name=GitGutterLineAdded"]
|
||||
call assert_equal(expected, s:signs('fileAddedToGit.tmp'))
|
||||
let expected = [{'lnum': 1, 'name': 'GitGutterLineAdded'}]
|
||||
call s:assert_signs(expected, 'fileAddedToGit.tmp')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -156,10 +174,10 @@ function Test_filename_with_equals()
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = [
|
||||
\ 'line=1 id=3000 name=GitGutterLineAdded',
|
||||
\ 'line=2 id=3001 name=GitGutterLineAdded'
|
||||
\ {'lnum': 1, 'name': 'GitGutterLineAdded'},
|
||||
\ {'lnum': 2, 'name': 'GitGutterLineAdded'}
|
||||
\ ]
|
||||
call assert_equal(expected, s:signs('=fixture=.txt'))
|
||||
call s:assert_signs(expected, '=fixture=.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -170,10 +188,10 @@ function Test_filename_with_square_brackets()
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = [
|
||||
\ 'line=1 id=3000 name=GitGutterLineAdded',
|
||||
\ 'line=2 id=3001 name=GitGutterLineAdded'
|
||||
\ {'lnum': 1, 'name': 'GitGutterLineAdded'},
|
||||
\ {'lnum': 2, 'name': 'GitGutterLineAdded'}
|
||||
\ ]
|
||||
call assert_equal(expected, s:signs('fix[tu]re.txt'))
|
||||
call s:assert_signs(expected, 'fix[tu]re.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -184,10 +202,10 @@ function Test_filename_leading_dash()
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = [
|
||||
\ 'line=1 id=3000 name=GitGutterLineAdded',
|
||||
\ 'line=2 id=3001 name=GitGutterLineAdded'
|
||||
\ {'lnum': 1, 'name': 'GitGutterLineAdded'},
|
||||
\ {'lnum': 2, 'name': 'GitGutterLineAdded'}
|
||||
\ ]
|
||||
call assert_equal(expected, s:signs('-fixture.txt'))
|
||||
call s:assert_signs(expected, '-fixture.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -198,10 +216,10 @@ function Test_filename_umlaut()
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = [
|
||||
\ 'line=1 id=3000 name=GitGutterLineAdded',
|
||||
\ 'line=2 id=3001 name=GitGutterLineAdded'
|
||||
\ {'lnum': 1, 'name': 'GitGutterLineAdded'},
|
||||
\ {'lnum': 2, 'name': 'GitGutterLineAdded'}
|
||||
\ ]
|
||||
call assert_equal(expected, s:signs('fixtüre.txt'))
|
||||
call s:assert_signs(expected, 'fixtüre.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -213,8 +231,8 @@ function Test_follow_symlink()
|
||||
6d
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = ['line=5 id=3000 name=GitGutterLineRemoved']
|
||||
call assert_equal(expected, s:signs('symlink'))
|
||||
let expected = [{'lnum': 5, 'name': 'GitGutterLineRemoved'}]
|
||||
call s:assert_signs(expected, 'symlink')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -255,7 +273,7 @@ endfunction
|
||||
|
||||
|
||||
function Test_no_modifications()
|
||||
call assert_equal([], s:signs('fixture.txt'))
|
||||
call s:assert_signs([], 'fixture.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -265,8 +283,8 @@ function Test_orphaned_signs()
|
||||
6d
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = ['line=6 id=3001 name=GitGutterLineAdded']
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
let expected = [{'lnum': 6, 'name': 'GitGutterLineAdded'}]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -275,7 +293,7 @@ function Test_untracked_file_outside_repo()
|
||||
call system('touch '.tmp)
|
||||
execute 'edit '.tmp
|
||||
|
||||
call assert_equal([], s:signs(tmp))
|
||||
call s:assert_signs([], tmp)
|
||||
endfunction
|
||||
|
||||
|
||||
@ -286,7 +304,7 @@ function Test_untracked_file_within_repo()
|
||||
normal ggo*
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
call assert_equal([], s:signs(tmp))
|
||||
call s:assert_signs([], tmp)
|
||||
call assert_equal(-2, b:gitgutter.path)
|
||||
|
||||
call system('rm '.tmp)
|
||||
@ -300,23 +318,23 @@ function Test_untracked_file_square_brackets_within_repo()
|
||||
normal ggo*
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
call assert_equal([], s:signs(tmp))
|
||||
call s:assert_signs([], tmp)
|
||||
|
||||
call system('rm '.tmp)
|
||||
endfunction
|
||||
|
||||
|
||||
function Test_hunk_outside_noop()
|
||||
normal 5G
|
||||
5
|
||||
GitGutterStageHunk
|
||||
|
||||
call assert_equal([], s:signs('fixture.txt'))
|
||||
call s:assert_signs([], 'fixture.txt')
|
||||
call assert_equal([], s:git_diff())
|
||||
call assert_equal([], s:git_diff_staged())
|
||||
|
||||
GitGutterUndoHunk
|
||||
|
||||
call assert_equal([], s:signs('fixture.txt'))
|
||||
call s:assert_signs([], 'fixture.txt')
|
||||
call assert_equal([], s:git_diff())
|
||||
call assert_equal([], s:git_diff_staged())
|
||||
endfunction
|
||||
@ -332,7 +350,7 @@ function Test_hunk_stage()
|
||||
call assert_equal('foo', &shell)
|
||||
let &shell = _shell
|
||||
|
||||
call assert_equal([], s:signs('fixture.txt'))
|
||||
call s:assert_signs([], 'fixture.txt')
|
||||
|
||||
" Buffer is unsaved
|
||||
let expected = [
|
||||
@ -372,11 +390,11 @@ function Test_hunk_stage_nearby_hunk()
|
||||
GitGutterStageHunk
|
||||
|
||||
let expected = [
|
||||
\ 'line=3 id=3000 name=GitGutterLineAdded',
|
||||
\ 'line=4 id=3001 name=GitGutterLineAdded',
|
||||
\ 'line=5 id=3002 name=GitGutterLineAdded'
|
||||
\ {'lnum': 3, 'name': 'GitGutterLineAdded'},
|
||||
\ {'lnum': 4, 'name': 'GitGutterLineAdded'},
|
||||
\ {'lnum': 5, 'name': 'GitGutterLineAdded'}
|
||||
\ ]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
|
||||
" Buffer is unsaved
|
||||
let expected = [
|
||||
@ -417,6 +435,203 @@ function Test_hunk_stage_nearby_hunk()
|
||||
endfunction
|
||||
|
||||
|
||||
function Test_hunk_stage_partial_visual_added()
|
||||
call append(5, ['A','B','C','D'])
|
||||
execute "normal 7GVj:GitGutterStageHunk\<CR>"
|
||||
|
||||
let expected = [
|
||||
\ {'lnum': 6, 'name': 'GitGutterLineAdded'},
|
||||
\ {'lnum': 9, 'name': 'GitGutterLineAdded'},
|
||||
\ ]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
|
||||
let expected = [
|
||||
\ 'diff --git a/fixture.txt b/fixture.txt',
|
||||
\ 'index 8a7026e..f5c6aff 100644',
|
||||
\ '--- a/fixture.txt',
|
||||
\ '+++ b/fixture.txt',
|
||||
\ '@@ -6,2 +5,0 @@ e',
|
||||
\ '-B',
|
||||
\ '-C',
|
||||
\ ]
|
||||
call assert_equal(expected, s:git_diff())
|
||||
|
||||
let expected = [
|
||||
\ 'diff --git a/fixture.txt b/fixture.txt',
|
||||
\ 'index f5c6aff..8a7026e 100644',
|
||||
\ '--- a/fixture.txt',
|
||||
\ '+++ b/fixture.txt',
|
||||
\ '@@ -5,0 +6,2 @@ e',
|
||||
\ '+B',
|
||||
\ '+C',
|
||||
\ ]
|
||||
call assert_equal(expected, s:git_diff_staged())
|
||||
endfunction
|
||||
|
||||
|
||||
function Test_hunk_stage_partial_cmd_added()
|
||||
call append(5, ['A','B','C','D'])
|
||||
6
|
||||
7,8GitGutterStageHunk
|
||||
|
||||
let expected = [
|
||||
\ {'lnum': 6, 'name': 'GitGutterLineAdded'},
|
||||
\ {'lnum': 9, 'name': 'GitGutterLineAdded'},
|
||||
\ ]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
|
||||
let expected = [
|
||||
\ 'diff --git a/fixture.txt b/fixture.txt',
|
||||
\ 'index 8a7026e..f5c6aff 100644',
|
||||
\ '--- a/fixture.txt',
|
||||
\ '+++ b/fixture.txt',
|
||||
\ '@@ -6,2 +5,0 @@ e',
|
||||
\ '-B',
|
||||
\ '-C',
|
||||
\ ]
|
||||
call assert_equal(expected, s:git_diff())
|
||||
|
||||
let expected = [
|
||||
\ 'diff --git a/fixture.txt b/fixture.txt',
|
||||
\ 'index f5c6aff..8a7026e 100644',
|
||||
\ '--- a/fixture.txt',
|
||||
\ '+++ b/fixture.txt',
|
||||
\ '@@ -5,0 +6,2 @@ e',
|
||||
\ '+B',
|
||||
\ '+C',
|
||||
\ ]
|
||||
call assert_equal(expected, s:git_diff_staged())
|
||||
endfunction
|
||||
|
||||
|
||||
function Test_hunk_stage_partial_preview_added()
|
||||
call append(5, ['A','B','C','D'])
|
||||
6
|
||||
GitGutterPreviewHunk
|
||||
wincmd P
|
||||
|
||||
" remove C and A so we stage B and D
|
||||
3delete
|
||||
1delete
|
||||
|
||||
GitGutterStageHunk
|
||||
write
|
||||
|
||||
let expected = [
|
||||
\ {'lnum': 6, 'name': 'GitGutterLineAdded'},
|
||||
\ {'lnum': 8, 'name': 'GitGutterLineAdded'},
|
||||
\ ]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
|
||||
let expected = [
|
||||
\ 'diff --git a/fixture.txt b/fixture.txt',
|
||||
\ 'index 975852f..3dd23a3 100644',
|
||||
\ '--- a/fixture.txt',
|
||||
\ '+++ b/fixture.txt',
|
||||
\ '@@ -5,0 +6 @@ e',
|
||||
\ '+A',
|
||||
\ '@@ -6,0 +8 @@ B',
|
||||
\ '+C',
|
||||
\ ]
|
||||
call assert_equal(expected, s:git_diff())
|
||||
|
||||
let expected = [
|
||||
\ 'diff --git a/fixture.txt b/fixture.txt',
|
||||
\ 'index f5c6aff..975852f 100644',
|
||||
\ '--- a/fixture.txt',
|
||||
\ '+++ b/fixture.txt',
|
||||
\ '@@ -5,0 +6,2 @@ e',
|
||||
\ '+B',
|
||||
\ '+D',
|
||||
\ ]
|
||||
call assert_equal(expected, s:git_diff_staged())
|
||||
endfunction
|
||||
|
||||
|
||||
function Test_hunk_stage_preview_write()
|
||||
call append(5, ['A','B','C','D'])
|
||||
6
|
||||
GitGutterPreviewHunk
|
||||
wincmd P
|
||||
|
||||
" preview window
|
||||
call feedkeys(":w\<CR>", 'tx')
|
||||
" original window
|
||||
write
|
||||
|
||||
call s:assert_signs([], 'fixture.txt')
|
||||
|
||||
call assert_equal([], s:git_diff())
|
||||
|
||||
let expected = [
|
||||
\ 'diff --git a/fixture.txt b/fixture.txt',
|
||||
\ 'index f5c6aff..3dd23a3 100644',
|
||||
\ '--- a/fixture.txt',
|
||||
\ '+++ b/fixture.txt',
|
||||
\ '@@ -5,0 +6,4 @@ e',
|
||||
\ '+A',
|
||||
\ '+B',
|
||||
\ '+C',
|
||||
\ '+D',
|
||||
\ ]
|
||||
call assert_equal(expected, s:git_diff_staged())
|
||||
endfunction
|
||||
|
||||
|
||||
function Test_hunk_stage_partial_preview_added_removed()
|
||||
4,5delete
|
||||
call append(3, ['A','B','C','D'])
|
||||
4
|
||||
GitGutterPreviewHunk
|
||||
wincmd P
|
||||
|
||||
" -d
|
||||
" -e
|
||||
" +A
|
||||
" +B
|
||||
" +C
|
||||
" +D
|
||||
|
||||
" remove D and d so they do not get staged
|
||||
6delete
|
||||
1delete
|
||||
|
||||
GitGutterStageHunk
|
||||
write
|
||||
|
||||
let expected = [
|
||||
\ {'lnum': 3, 'name': 'GitGutterLineRemoved'},
|
||||
\ {'lnum': 7, 'name': 'GitGutterLineAdded'},
|
||||
\ ]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
|
||||
let expected = [
|
||||
\ 'diff --git a/fixture.txt b/fixture.txt',
|
||||
\ 'index 9a19589..e63fb0a 100644',
|
||||
\ '--- a/fixture.txt',
|
||||
\ '+++ b/fixture.txt',
|
||||
\ '@@ -4 +3,0 @@ c',
|
||||
\ '-d',
|
||||
\ '@@ -7,0 +7 @@ C',
|
||||
\ '+D',
|
||||
\ ]
|
||||
call assert_equal(expected, s:git_diff())
|
||||
|
||||
let expected = [
|
||||
\ 'diff --git a/fixture.txt b/fixture.txt',
|
||||
\ 'index f5c6aff..9a19589 100644',
|
||||
\ '--- a/fixture.txt',
|
||||
\ '+++ b/fixture.txt',
|
||||
\ '@@ -5 +5,3 @@ d',
|
||||
\ '-e',
|
||||
\ '+A',
|
||||
\ '+B',
|
||||
\ '+C',
|
||||
\ ]
|
||||
call assert_equal(expected, s:git_diff_staged())
|
||||
endfunction
|
||||
|
||||
|
||||
function Test_hunk_undo()
|
||||
let _shell = &shell
|
||||
set shell=foo
|
||||
@ -427,7 +642,7 @@ function Test_hunk_undo()
|
||||
call assert_equal('foo', &shell)
|
||||
let &shell = _shell
|
||||
|
||||
call assert_equal([], s:signs('fixture.txt'))
|
||||
call s:assert_signs([], 'fixture.txt')
|
||||
call assert_equal([], s:git_diff())
|
||||
call assert_equal([], s:git_diff_staged())
|
||||
endfunction
|
||||
@ -442,11 +657,11 @@ function Test_undo_nearby_hunk()
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = [
|
||||
\ 'line=3 id=3000 name=GitGutterLineAdded',
|
||||
\ 'line=4 id=3001 name=GitGutterLineAdded',
|
||||
\ 'line=5 id=3002 name=GitGutterLineAdded'
|
||||
\ {'lnum': 3, 'name': 'GitGutterLineAdded'},
|
||||
\ {'lnum': 4, 'name': 'GitGutterLineAdded'},
|
||||
\ {'lnum': 5, 'name': 'GitGutterLineAdded'}
|
||||
\ ]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
|
||||
call assert_equal([], s:git_diff())
|
||||
|
||||
@ -485,10 +700,8 @@ function Test_overlapping_hunk_op()
|
||||
GitGutterUndoHunk
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = [
|
||||
\ 'line=2 id=3000 name=GitGutterLineRemoved',
|
||||
\ ]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
let expected = [{'lnum': 2, 'name': 'GitGutterLineRemoved'}]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
|
||||
" Undo lower
|
||||
|
||||
@ -499,10 +712,8 @@ function Test_overlapping_hunk_op()
|
||||
GitGutterUndoHunk
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = [
|
||||
\ 'line=1 id=3000 name=GitGutterLineRemovedFirstLine',
|
||||
\ ]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
let expected = [{'lnum': 1, 'name': 'GitGutterLineRemovedFirstLine'}]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -512,8 +723,8 @@ function Test_write_option()
|
||||
normal ggo*
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = ["line=2 id=3000 name=GitGutterLineAdded"]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
let expected = [{'lnum': 2, 'name': 'GitGutterLineAdded'}]
|
||||
call s:assert_signs(expected, 'fixture.txt')
|
||||
|
||||
set write
|
||||
endfunction
|
||||
@ -525,7 +736,7 @@ function Test_inner_text_object()
|
||||
normal dic
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
call assert_equal([], s:signs('fixture.txt'))
|
||||
call s:assert_signs([], 'fixture.txt')
|
||||
call assert_equal(readfile('fixture.txt'), getline(1,'$'))
|
||||
|
||||
" Excludes trailing lines
|
||||
@ -543,7 +754,7 @@ function Test_around_text_object()
|
||||
normal dac
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
call assert_equal([], s:signs('fixture.txt'))
|
||||
call s:assert_signs([], 'fixture.txt')
|
||||
call assert_equal(readfile('fixture.txt'), getline(1,'$'))
|
||||
|
||||
" Includes trailing lines
|
||||
@ -646,7 +857,7 @@ function Test_encoding()
|
||||
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
call assert_equal([], s:signs('cp932.txt'))
|
||||
call s:assert_signs([], 'cp932.txt')
|
||||
endfunction
|
||||
|
||||
|
||||
@ -656,7 +867,7 @@ function Test_empty_file()
|
||||
edit empty.txt
|
||||
|
||||
call s:trigger_gitgutter()
|
||||
call assert_equal([], s:signs('empty.txt'))
|
||||
call s:assert_signs([], 'empty.txt')
|
||||
|
||||
|
||||
" File consisting only of a newline
|
||||
@ -664,7 +875,7 @@ function Test_empty_file()
|
||||
edit newline.txt
|
||||
|
||||
call s:trigger_gitgutter()
|
||||
call assert_equal([], s:signs('newline.txt'))
|
||||
call s:assert_signs([], 'newline.txt')
|
||||
|
||||
|
||||
" 1 line file without newline
|
||||
@ -674,7 +885,7 @@ function Test_empty_file()
|
||||
edit! oneline.txt
|
||||
|
||||
call s:trigger_gitgutter()
|
||||
call assert_equal([], s:signs('oneline.txt'))
|
||||
call s:assert_signs([], 'oneline.txt')
|
||||
|
||||
set eol fixeol
|
||||
endfunction
|
||||
|
Reference in New Issue
Block a user