mirror of
https://github.com/airblade/vim-gitgutter.git
synced 2025-11-08 11:33:48 -05:00
Move git-tracking check into diff command.
This avoids shelling out twice per buffer: once to check whether git knows about the file and once to perform the diff. Now we simply do both in one external call. Profiling showed external calls to git taking ~20ms. This doesn't seem too bad but it adds up.
This commit is contained in:
@@ -4,17 +4,25 @@ let s:hunk_re = '^@@ -\(\d\+\),\?\(\d*\) +\(\d\+\),\?\(\d*\) @@'
|
|||||||
|
|
||||||
|
|
||||||
function! diff#run_diff(realtime, use_external_grep)
|
function! diff#run_diff(realtime, use_external_grep)
|
||||||
|
let cmd = 'git ls-files --error-unmatch' . utility#discard_stdout_and_stderr() . ' ' . shellescape(utility#file()) . ' && '
|
||||||
|
|
||||||
if a:realtime
|
if a:realtime
|
||||||
let blob_name = ':./' . fnamemodify(utility#file(),':t')
|
let blob_name = ':./' . fnamemodify(utility#file(),':t')
|
||||||
let blob_file = tempname()
|
let blob_file = tempname()
|
||||||
let cmd = 'git show ' . blob_name . ' > ' . blob_file . ' && diff -U0 ' . g:gitgutter_diff_args . ' ' . blob_file . ' - '
|
let cmd .= 'git show ' . blob_name . ' > ' . blob_file .
|
||||||
|
\ ' && diff -U0 ' . g:gitgutter_diff_args . ' ' . blob_file . ' - '
|
||||||
else
|
else
|
||||||
let cmd = 'git diff --no-ext-diff --no-color -U0 ' . g:gitgutter_diff_args . ' ' . shellescape(utility#file())
|
let cmd .= 'git diff --no-ext-diff --no-color -U0 ' . g:gitgutter_diff_args . ' ' . shellescape(utility#file())
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if a:use_external_grep && s:grep_available
|
if a:use_external_grep && s:grep_available
|
||||||
let cmd .= s:grep_command
|
" grep exits with 1 when no matches are found. However we want to treat
|
||||||
|
" non-matches as non-erroneous behaviour; so we append ` || :`.
|
||||||
|
let cmd .= s:grep_command . ' || :'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let cmd = utility#escape(cmd)
|
let cmd = utility#escape(cmd)
|
||||||
|
|
||||||
if a:realtime
|
if a:realtime
|
||||||
if &fileformat ==# "dos"
|
if &fileformat ==# "dos"
|
||||||
let eol = "\r\n"
|
let eol = "\r\n"
|
||||||
@@ -28,6 +36,13 @@ function! diff#run_diff(realtime, use_external_grep)
|
|||||||
else
|
else
|
||||||
let diff = system(utility#command_in_directory_of_file(cmd))
|
let diff = system(utility#command_in_directory_of_file(cmd))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if v:shell_error
|
||||||
|
" A shell error indicates the file is not tracked by git (unless something
|
||||||
|
" bizarre is going on).
|
||||||
|
throw 'git-diff failed'
|
||||||
|
endif
|
||||||
|
|
||||||
return diff
|
return diff
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
let s:file = ''
|
let s:file = ''
|
||||||
|
|
||||||
function! utility#is_active()
|
function! utility#is_active()
|
||||||
return g:gitgutter_enabled && utility#exists_file() && utility#is_tracked_by_git()
|
return g:gitgutter_enabled && utility#exists_file()
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! utility#current_file()
|
function! utility#current_file()
|
||||||
@@ -64,12 +64,6 @@ function! utility#command_in_directory_of_file(cmd)
|
|||||||
return substitute(utility#cmd_in_dir, "'", '"', 'g')
|
return substitute(utility#cmd_in_dir, "'", '"', 'g')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! utility#is_tracked_by_git()
|
|
||||||
let cmd = utility#escape('git ls-files --error-unmatch' . utility#discard_stdout_and_stderr() . ' ' . shellescape(utility#file()))
|
|
||||||
call system(utility#command_in_directory_of_file(cmd))
|
|
||||||
return !v:shell_error
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! utility#differences(hunks)
|
function! utility#differences(hunks)
|
||||||
return len(a:hunks) != 0
|
return len(a:hunks) != 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|||||||
@@ -55,26 +55,30 @@ command GitGutterAll call GitGutterAll()
|
|||||||
function! GitGutter(file, realtime)
|
function! GitGutter(file, realtime)
|
||||||
call utility#set_file(a:file)
|
call utility#set_file(a:file)
|
||||||
if utility#is_active()
|
if utility#is_active()
|
||||||
if !a:realtime || utility#has_fresh_changes(a:file)
|
try
|
||||||
let diff = diff#run_diff(a:realtime || utility#has_unsaved_changes(a:file), 1)
|
if !a:realtime || utility#has_fresh_changes(a:file)
|
||||||
let s:hunks = diff#parse_diff(diff)
|
let diff = diff#run_diff(a:realtime || utility#has_unsaved_changes(a:file), 1)
|
||||||
let modified_lines = diff#process_hunks(s:hunks)
|
let s:hunks = diff#parse_diff(diff)
|
||||||
|
let modified_lines = diff#process_hunks(s:hunks)
|
||||||
|
|
||||||
if g:gitgutter_signs
|
if g:gitgutter_signs
|
||||||
if g:gitgutter_sign_column_always
|
if g:gitgutter_sign_column_always
|
||||||
call sign#add_dummy_sign()
|
call sign#add_dummy_sign()
|
||||||
else
|
|
||||||
if utility#differences(s:hunks)
|
|
||||||
call sign#add_dummy_sign() " prevent flicker
|
|
||||||
else
|
else
|
||||||
call sign#remove_dummy_sign()
|
if utility#differences(s:hunks)
|
||||||
|
call sign#add_dummy_sign() " prevent flicker
|
||||||
|
else
|
||||||
|
call sign#remove_dummy_sign()
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
call sign#update_signs(a:file, modified_lines)
|
||||||
endif
|
endif
|
||||||
call sign#update_signs(a:file, modified_lines)
|
|
||||||
endif
|
|
||||||
|
|
||||||
call utility#save_last_seen_change(a:file)
|
call utility#save_last_seen_change(a:file)
|
||||||
endif
|
endif
|
||||||
|
catch /git-diff failed/
|
||||||
|
call hunk#reset()
|
||||||
|
endtry
|
||||||
else
|
else
|
||||||
call hunk#reset()
|
call hunk#reset()
|
||||||
endif
|
endif
|
||||||
|
|||||||
Reference in New Issue
Block a user