2016-11-22 08:36:31 +00:00
scriptencoding utf -8
if exists ( 'g:loaded_gitgutter' ) | | ! has ( 'signs' ) | | &cp
finish
endif
let g :loaded_gitgutter = 1
" Initialisation {{{
if v :version < 703 | | ( v :version = = 703 && ! has ( "patch105" ) )
2021-05-05 08:25:00 +00:00
call gitgutter #utility #warn ( 'Requires Vim 7.3.105' )
2018-03-31 14:56:26 +00:00
finish
2016-11-22 08:36:31 +00:00
endif
2020-12-04 21:15:32 +00:00
let s :nomodeline = ( v :version > 703 | | ( v :version = = 703 && has ( 'patch442' ) ) ) ? '<nomodeline>' : ''
2016-11-22 08:36:31 +00:00
2020-05-10 14:24:38 +00:00
function ! s :obsolete ( var )
if exists ( a :var )
call gitgutter #utility #warn ( a :var .' is obsolete and has no effect.' )
endif
endfunction
2020-12-04 21:15:32 +00:00
let g :gitgutter_preview_win_location = get ( g :, 'gitgutter_preview_win_location' , 'bo' )
2019-11-16 15:28:42 +00:00
if exists ( '*nvim_open_win' )
2020-12-04 21:15:32 +00:00
let g :gitgutter_preview_win_floating = get ( g :, 'gitgutter_preview_win_floating' , 1 )
2022-08-08 13:45:56 +00:00
let g :gitgutter_floating_window_options = get ( g :, 'gitgutter_floating_window_options' , {
\ 'relative' : 'cursor' ,
\ 'row' : 1 ,
\ 'col' : 0 ,
\ 'width' : 42 ,
\ 'height' : &previewheight ,
\ 'style' : 'minimal'
\ })
2019-11-16 15:28:42 +00:00
else
2021-05-05 08:25:00 +00:00
let default = exists ( '&previewpopup' ) ? ! empty ( &previewpopup ) : 0
let g :gitgutter_preview_win_floating = get ( g :, 'gitgutter_preview_win_floating' , default )
2022-08-08 13:45:56 +00:00
let g :gitgutter_floating_window_options = get ( g :, 'gitgutter_floating_window_options' , {
\ 'line' : 'cursor+1' ,
\ 'col' : 'cursor' ,
\ 'moved' : 'any'
\ })
2019-11-16 15:28:42 +00:00
endif
2020-12-04 21:15:32 +00:00
let g :gitgutter_enabled = get ( g :, 'gitgutter_enabled' , 1 )
2020-05-10 14:24:38 +00:00
if exists ( '*sign_unplace' )
2020-12-04 21:15:32 +00:00
let g :gitgutter_max_signs = get ( g :, 'gitgutter_max_signs' , -1 )
2020-05-10 14:24:38 +00:00
else
2020-12-04 21:15:32 +00:00
let g :gitgutter_max_signs = get ( g :, 'gitgutter_max_signs' , 500 )
2020-05-10 14:24:38 +00:00
endif
2020-12-04 21:15:32 +00:00
let g :gitgutter_signs = get ( g :, 'gitgutter_signs' , 1 )
let g :gitgutter_highlight_lines = get ( g :, 'gitgutter_highlight_lines' , 0 )
let g :gitgutter_highlight_linenrs = get ( g :, 'gitgutter_highlight_linenrs' , 0 )
let g :gitgutter_sign_priority = get ( g :, 'gitgutter_sign_priority' , 10 )
2019-08-22 15:36:17 +00:00
" 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
2017-09-02 10:43:18 +00:00
endif
2020-12-04 21:15:32 +00:00
let g :gitgutter_sign_allow_clobber = get ( g :, 'gitgutter_sign_allow_clobber' , 0 )
let g :gitgutter_set_sign_backgrounds = get ( g :, 'gitgutter_set_sign_backgrounds' , 0 )
let g :gitgutter_sign_added = get ( g :, 'gitgutter_sign_added' , '+' )
let g :gitgutter_sign_modified = get ( g :, 'gitgutter_sign_modified' , '~' )
let g :gitgutter_sign_removed = get ( g :, 'gitgutter_sign_removed' , '_' )
2018-03-31 14:56:26 +00:00
if gitgutter #utility #supports_overscore_sign ( )
2020-12-04 21:15:32 +00:00
let g :gitgutter_sign_removed_first_line = get ( g :, 'gitgutter_sign_removed_first_line' , '‾' )
2018-03-31 14:56:26 +00:00
else
2020-12-04 21:15:32 +00:00
let g :gitgutter_sign_removed_first_line = get ( g :, 'gitgutter_sign_removed_first_line' , '_^' )
2018-03-31 14:56:26 +00:00
endif
2016-11-22 08:36:31 +00:00
2020-12-04 21:15:32 +00:00
let g :gitgutter_sign_removed_above_and_below = get ( g :, 'gitgutter_sign_removed_above_and_below' , '_¯' )
let g :gitgutter_sign_modified_removed = get ( g :, 'gitgutter_sign_modified_removed' , '~_' )
let g :gitgutter_git_args = get ( g :, 'gitgutter_git_args' , '' )
let g :gitgutter_diff_relative_to = get ( g :, 'gitgutter_diff_relative_to' , 'index' )
let g :gitgutter_diff_args = get ( g :, 'gitgutter_diff_args' , '' )
let g :gitgutter_diff_base = get ( g :, 'gitgutter_diff_base' , '' )
let g :gitgutter_map_keys = get ( g :, 'gitgutter_map_keys' , 1 )
let g :gitgutter_terminal_reports_focus = get ( g :, 'gitgutter_terminal_reports_focus' , 1 )
let g :gitgutter_async = get ( g :, 'gitgutter_async' , 1 )
let g :gitgutter_log = get ( g :, 'gitgutter_log' , 0 )
let g :gitgutter_use_location_list = get ( g :, 'gitgutter_use_location_list' , 0 )
let g :gitgutter_close_preview_on_escape = get ( g :, 'gitgutter_close_preview_on_escape' , 0 )
let g :gitgutter_show_msg_on_hunk_jumping = get ( g :, 'gitgutter_show_msg_on_hunk_jumping' , 1 )
let g :gitgutter_git_executable = get ( g :, 'gitgutter_git_executable' , 'git' )
2016-11-22 08:36:31 +00:00
if ! executable ( g :gitgutter_git_executable )
2020-05-10 14:24:38 +00:00
if g :gitgutter_enabled
2021-05-05 08:25:00 +00:00
call gitgutter #utility #warn ( 'Cannot find git. Please set g:gitgutter_git_executable.' )
2020-05-10 14:24:38 +00:00
endif
finish
2016-11-22 08:36:31 +00:00
endif
2018-03-31 14:56:26 +00:00
let default_grep = 'grep'
2020-12-04 21:15:32 +00:00
let g :gitgutter_grep = get ( g :, 'gitgutter_grep' , default_grep )
2018-03-31 14:56:26 +00:00
if ! empty ( g :gitgutter_grep )
if executable ( split ( g :gitgutter_grep ) [0 ])
if $GREP_OPTIONS = ~ # '--color=always'
let g :gitgutter_grep .= ' --color=never'
endif
else
if g :gitgutter_grep ! = # default_grep
2021-05-05 08:25:00 +00:00
call gitgutter #utility #warn ( 'Cannot find ' .g :gitgutter_grep .'. Please check g:gitgutter_grep.' )
2018-03-31 14:56:26 +00:00
endif
let g :gitgutter_grep = ''
endif
endif
2016-11-22 08:36:31 +00:00
call gitgutter #highlight #define_highlights ( )
call gitgutter #highlight #define_signs ( )
2018-06-14 10:31:12 +00:00
" Prevent infinite loop where:
" - executing a job in the foreground launches a new window which takes the focus;
" - when the job finishes, focus returns to gvim;
" - the FocusGained event triggers a new job (see below).
if gitgutter #utility #windows ( ) && ! ( g :gitgutter_async && gitgutter #async #available ( ) )
set noshelltemp
endif
2016-11-22 08:36:31 +00:00
" }}}
" Primary functions {{{
2018-03-31 14:56:26 +00:00
command ! - bar GitGutterAll call gitgutter #all ( 1 )
command ! - bar GitGutter call gitgutter #process_buffer ( bufnr ( '' ) , 1 )
2016-11-22 08:36:31 +00:00
2018-03-31 14:56:26 +00:00
command ! - bar GitGutterDisable call gitgutter #disable ( )
command ! - bar GitGutterEnable call gitgutter #enable ( )
command ! - bar GitGutterToggle call gitgutter #toggle ( )
2016-11-22 08:36:31 +00:00
2019-03-08 11:04:56 +00:00
command ! - bar GitGutterBufferDisable call gitgutter #buffer_disable ( )
command ! - bar GitGutterBufferEnable call gitgutter #buffer_enable ( )
command ! - bar GitGutterBufferToggle call gitgutter #buffer_toggle ( )
2021-07-30 20:52:54 +00:00
command ! - bar GitGutterQuickFix call gitgutter #quickfix ( 0 )
command ! - bar GitGutterQuickFixCurrentFile call gitgutter #quickfix ( 1 )
2019-11-16 15:28:42 +00:00
2022-08-08 13:45:56 +00:00
command ! - bar GitGutterDiffOrig call gitgutter #difforig ( )
2016-11-22 08:36:31 +00:00
" }}}
" Line highlights {{{
2018-03-31 14:56:26 +00:00
command ! - bar GitGutterLineHighlightsDisable call gitgutter #highlight #line_disable ( )
command ! - bar GitGutterLineHighlightsEnable call gitgutter #highlight #line_enable ( )
command ! - bar GitGutterLineHighlightsToggle call gitgutter #highlight #line_toggle ( )
2016-11-22 08:36:31 +00:00
" }}}
2019-08-22 15:36:17 +00:00
" '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 ( )
" }}}
2016-11-22 08:36:31 +00:00
" Signs {{{
2018-03-31 14:56:26 +00:00
command ! - bar GitGutterSignsEnable call gitgutter #sign #enable ( )
command ! - bar GitGutterSignsDisable call gitgutter #sign #disable ( )
command ! - bar GitGutterSignsToggle call gitgutter #sign #toggle ( )
2016-11-22 08:36:31 +00:00
" }}}
" Hunks {{{
2018-03-31 14:56:26 +00:00
command ! - bar - count = 1 GitGutterNextHunk call gitgutter #hunk #next_hunk ( < count > )
command ! - bar - count = 1 GitGutterPrevHunk call gitgutter #hunk #prev_hunk ( < count > )
2016-11-22 08:36:31 +00:00
2019-08-22 15:36:17 +00:00
command ! - bar - range = % GitGutterStageHunk call gitgutter #hunk #stage ( < line1 > , < line2 > )
2018-03-31 14:56:26 +00:00
command ! - bar GitGutterUndoHunk call gitgutter #hunk #undo ( )
command ! - bar GitGutterPreviewHunk call gitgutter #hunk #preview ( )
2016-11-22 08:36:31 +00:00
" Hunk text object
2019-11-16 15:28:42 +00:00
onoremap < silent > < Plug > ( GitGutterTextObjectInnerPending ) :< C - U > call gitgutter #hunk #text_object ( 1 ) < CR >
onoremap < silent > < Plug > ( GitGutterTextObjectOuterPending ) :< C - U > call gitgutter #hunk #text_object ( 0 ) < CR >
xnoremap < silent > < Plug > ( GitGutterTextObjectInnerVisual ) :< C - U > call gitgutter #hunk #text_object ( 1 ) < CR >
xnoremap < silent > < Plug > ( GitGutterTextObjectOuterVisual ) :< C - U > call gitgutter #hunk #text_object ( 0 ) < CR >
2016-11-22 08:36:31 +00:00
" Returns the git-diff hunks for the file or an empty list if there
" aren't any hunks.
"
" The return value is a list of lists. There is one inner list per hunk.
"
" [
" [from_line, from_count, to_line, to_count],
" [from_line, from_count, to_line, to_count],
" ...
" ]
"
" where:
"
" `from` - refers to the staged file
" `to` - refers to the working tree's file
" `line` - refers to the line number where the change starts
" `count` - refers to the number of lines the change covers
function ! GitGutterGetHunks ( )
2018-03-31 14:56:26 +00:00
let bufnr = bufnr ( '' )
return gitgutter #utility #is_active ( bufnr ) ? gitgutter #hunk #hunks ( bufnr ) : []
2016-11-22 08:36:31 +00:00
endfunction
" Returns an array that contains a summary of the hunk status for the current
" window. The format is [ added, modified, removed ], where each value
" represents the number of lines added/modified/removed respectively.
function ! GitGutterGetHunkSummary ( )
return gitgutter #hunk #summary ( winbufnr ( 0 ) )
endfunction
" }}}
2019-03-08 11:04:56 +00:00
" Folds {{{
command ! - bar GitGutterFold call gitgutter #fold #toggle ( )
" }}}
2018-03-31 14:56:26 +00:00
command ! - bar GitGutterDebug call gitgutter #debug #debug ( )
2016-11-22 08:36:31 +00:00
" Maps {{{
2019-11-16 15:28:42 +00:00
nnoremap < silent > < expr > < Plug > ( GitGutterNextHunk ) &diff ? ']c' : ":\<C-U>execute v:count1 . 'GitGutterNextHunk'\<CR>"
2021-05-05 08:25:00 +00:00
nnoremap < silent > < expr > < Plug > GitGutterNextHunk &diff ? ']c' : ":\<C-U>call gitgutter#utility#warn('Please change your map \<lt>Plug>GitGutterNextHunk to \<lt>Plug>(GitGutterNextHunk)')\<CR>"
2019-11-16 15:28:42 +00:00
nnoremap < silent > < expr > < Plug > ( GitGutterPrevHunk ) &diff ? '[c' : ":\<C-U>execute v:count1 . 'GitGutterPrevHunk'\<CR>"
2021-05-05 08:25:00 +00:00
nnoremap < silent > < expr > < Plug > GitGutterPrevHunk &diff ? '[c' : ":\<C-U>call gitgutter#utility#warn('Please change your map \<lt>Plug>GitGutterPrevHunk to \<lt>Plug>(GitGutterPrevHunk)')\<CR>"
2016-11-22 08:36:31 +00:00
2019-11-16 15:28:42 +00:00
xnoremap < silent > < Plug > ( GitGutterStageHunk ) :GitGutterStageHunk < CR >
2021-05-05 08:25:00 +00:00
xnoremap < silent > < Plug > GitGutterStageHunk :call gitgutter #utility #warn ( 'Please change your map <lt>Plug>GitGutterStageHunk to <lt>Plug>(GitGutterStageHunk)' ) < CR >
2019-11-16 15:28:42 +00:00
nnoremap < silent > < Plug > ( GitGutterStageHunk ) :GitGutterStageHunk < CR >
2021-05-05 08:25:00 +00:00
nnoremap < silent > < Plug > GitGutterStageHunk :call gitgutter #utility #warn ( 'Please change your map <lt>Plug>GitGutterStageHunk to <lt>Plug>(GitGutterStageHunk)' ) < CR >
2019-11-16 15:28:42 +00:00
nnoremap < silent > < Plug > ( GitGutterUndoHunk ) :GitGutterUndoHunk < CR >
2021-05-05 08:25:00 +00:00
nnoremap < silent > < Plug > GitGutterUndoHunk :call gitgutter #utility #warn ( 'Please change your map <lt>Plug>GitGutterUndoHunk to <lt>Plug>(GitGutterUndoHunk)' ) < CR >
2019-11-16 15:28:42 +00:00
nnoremap < silent > < Plug > ( GitGutterPreviewHunk ) :GitGutterPreviewHunk < CR >
2021-05-05 08:25:00 +00:00
nnoremap < silent > < Plug > GitGutterPreviewHunk :call gitgutter #utility #warn ( 'Please change your map <lt>Plug>GitGutterPreviewHunk to <lt>Plug>(GitGutterPreviewHunk)' ) < CR >
2016-11-22 08:36:31 +00:00
2018-06-14 10:31:12 +00:00
" }}}
2016-11-22 08:36:31 +00:00
2018-06-14 10:31:12 +00:00
function ! s :on_bufenter ( )
2019-08-22 15:36:17 +00:00
call gitgutter #setup_maps ( )
2020-12-04 21:15:32 +00:00
" To keep vim's start-up fast, do not process the buffer when vim is starting.
" Instead process it a short time later. Normally we would rely on our
" CursorHold autocommand to handle this but it turns out CursorHold is not
" guaranteed to fire if the user has not typed anything yet; so set up a
" timer instead. The disadvantage is that if CursorHold does fire, the
" plugin will do a round of unnecessary work; but since there will not have
" been any changes to the buffer since the first round, the second round
" will be cheap.
if has ( 'vim_starting' ) && ! $VIM_GITGUTTER_TEST
2022-09-20 08:08:31 +00:00
if exists ( '*timer_start' ) && has ( 'lambda' )
call s :next_tick ( "call gitgutter#process_buffer(+" .bufnr ( '' ) .", 0)" )
else
call gitgutter #process_buffer ( bufnr ( '' ) , 0 )
2020-12-04 21:15:32 +00:00
endif
return
endif
2018-06-14 10:31:12 +00:00
if exists ( 't:gitgutter_didtabenter' ) && t :gitgutter_didtabenter
let t :gitgutter_didtabenter = 0
2018-07-19 12:52:53 +00:00
call gitgutter #all ( ! g :gitgutter_terminal_reports_focus )
2018-06-14 10:31:12 +00:00
else
call gitgutter #process_buffer ( bufnr ( '' ) , ! g :gitgutter_terminal_reports_focus )
endif
endfunction
2016-11-22 08:36:31 +00:00
2022-08-08 13:45:56 +00:00
function ! s :next_tick ( cmd )
call timer_start ( 1 , {- > execute ( a :cmd ) })
endfunction
2023-08-20 14:33:32 +00:00
function ! s :on_buffilepre ( bufnr )
if ! exists ( 's:renaming' )
let s :renaming = []
let s :gitgutter_was_enabled = gitgutter #utility #getbufvar ( a :bufnr , 'enabled' )
endif
let s :renaming + = [a :bufnr ]
endfunction
function ! s :on_buffilepost ( bufnr )
if len ( s :renaming ) > 1
if s :renaming [0 ] ! = a :bufnr
throw 'gitgutter rename error' s :renaming [0 ] a :bufnr
endif
unlet s :renaming [0 ]
return
endif
" reset cached values
GitGutterBufferDisable
if s :gitgutter_was_enabled
GitGutterBufferEnable
endif
unlet s :renaming
unlet s :gitgutter_was_enabled
endfunction
2016-11-22 08:36:31 +00:00
" Autocommands {{{
augroup gitgutter
autocmd !
2018-03-31 14:56:26 +00:00
autocmd TabEnter * let t :gitgutter_didtabenter = 1
2016-11-22 08:36:31 +00:00
2018-06-14 10:31:12 +00:00
autocmd BufEnter * call s :on_bufenter ( )
2016-11-22 08:36:31 +00:00
2020-12-04 21:15:32 +00:00
" Ensure Vim is always checking for CursorMoved to avoid CursorMoved
" being fired at the wrong time in floating preview window on Neovim.
" See vim/vim#2053.
autocmd CursorMoved * execute ''
2018-07-19 12:52:53 +00:00
autocmd CursorHold , CursorHoldI * call gitgutter #process_buffer ( bufnr ( '' ) , 0 )
2019-11-16 15:28:42 +00:00
if exists ( '*timer_start' ) && has ( 'lambda' )
2022-08-08 13:45:56 +00:00
autocmd FileChangedShellPost * call s :next_tick ( "call gitgutter#process_buffer(+" .expand ( '<abuf>' ) .", 1)" )
2019-11-16 15:28:42 +00:00
else
2022-08-08 13:45:56 +00:00
autocmd FileChangedShellPost * call gitgutter #process_buffer ( + expand ( '<abuf>' ) , 1 )
2019-11-16 15:28:42 +00:00
endif
2016-11-22 08:36:31 +00:00
2018-03-31 14:56:26 +00:00
" Ensure that all buffers are processed when opening vim with multiple files, e.g.:
"
" vim -o file1 file2
autocmd VimEnter * if winnr ( ) ! = winnr ( '$' ) | call gitgutter #all ( 0 ) | endif
2017-09-02 10:43:18 +00:00
2019-03-27 15:08:56 +00:00
autocmd ShellCmdPost * call gitgutter #all ( 1 )
2019-03-08 11:04:56 +00:00
autocmd BufLeave term :// * call gitgutter #all ( 1 )
2016-11-22 08:36:31 +00:00
2019-12-12 22:01:41 +00:00
autocmd User FugitiveChanged call gitgutter #all ( 1 )
2019-08-22 15:36:17 +00:00
2019-03-27 15:08:56 +00:00
" 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.
let s :focus_was_lost = 0
2020-12-04 21:15:32 +00:00
autocmd FocusGained * if s :focus_was_lost | let s :focus_was_lost = 0 | call gitgutter #all ( 1 ) | endif
2019-03-27 15:08:56 +00:00
autocmd FocusLost * let s :focus_was_lost = 1
2018-08-25 16:13:42 +00:00
if exists ( '##VimResume' )
autocmd VimResume * call gitgutter #all ( 1 )
endif
2020-05-10 14:24:38 +00:00
autocmd ColorScheme * call gitgutter #highlight #define_highlights ( )
2016-11-22 08:36:31 +00:00
2023-08-20 14:33:32 +00:00
autocmd BufFilePre * call s :on_buffilepre ( expand ( '<abuf>' ) )
autocmd BufFilePost * call s :on_buffilepost ( expand ( '<abuf>' ) )
2023-07-15 10:43:27 +00:00
autocmd QuickFixCmdPre *vimgrep * let b :gitgutter_was_enabled = gitgutter #utility #getbufvar ( expand ( '<abuf>' ) , 'enabled' ) | GitGutterBufferDisable
autocmd QuickFixCmdPost *vimgrep * if b :gitgutter_was_enabled | GitGutterBufferEnable | endif | unlet b :gitgutter_was_enabled
2016-11-22 08:36:31 +00:00
augroup END
" }}}
" vim:set et sw=2 fdm=marker: