mirror of
https://github.com/airblade/vim-gitgutter.git
synced 2025-11-09 12:03:48 -05:00
Neovim: run diffs asynchronously.
This commit is contained in:
@@ -5,6 +5,7 @@ A Vim plugin which shows a git diff in the 'gutter' (sign column). It shows whe
|
|||||||
Features:
|
Features:
|
||||||
|
|
||||||
* Shows signs for added, modified, and removed lines.
|
* Shows signs for added, modified, and removed lines.
|
||||||
|
* Neovim: runs the diffs asynchronously.
|
||||||
* Ensures signs are always as up to date as possible (but without running more than necessary).
|
* Ensures signs are always as up to date as possible (but without running more than necessary).
|
||||||
* Quick jumping between blocks of changed lines ("hunks").
|
* Quick jumping between blocks of changed lines ("hunks").
|
||||||
* Stage/revert/preview individual hunks.
|
* Stage/revert/preview individual hunks.
|
||||||
|
|||||||
@@ -20,7 +20,43 @@ function! gitgutter#process_buffer(bufnr, realtime)
|
|||||||
try
|
try
|
||||||
if !a:realtime || gitgutter#utility#has_fresh_changes()
|
if !a:realtime || gitgutter#utility#has_fresh_changes()
|
||||||
let diff = gitgutter#diff#run_diff(a:realtime || gitgutter#utility#has_unsaved_changes(), 1)
|
let diff = gitgutter#diff#run_diff(a:realtime || gitgutter#utility#has_unsaved_changes(), 1)
|
||||||
call gitgutter#hunk#set_hunks(gitgutter#diff#parse_diff(diff))
|
if diff != 'async'
|
||||||
|
call gitgutter#handle_diff(diff)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
catch /diff failed/
|
||||||
|
call gitgutter#hunk#reset()
|
||||||
|
endtry
|
||||||
|
else
|
||||||
|
call gitgutter#hunk#reset()
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
function! gitgutter#handle_diff_job(job_id, data, event)
|
||||||
|
if a:event == 'stdout'
|
||||||
|
" a:data is a list
|
||||||
|
call gitgutter#utility#job_output_received(a:job_id, 'stdout')
|
||||||
|
call gitgutter#handle_diff(join(a:data,"\n")."\n")
|
||||||
|
|
||||||
|
elseif a:event == 'exit'
|
||||||
|
" If the exit event is triggered without a preceding stdout event,
|
||||||
|
" the diff was empty.
|
||||||
|
if gitgutter#utility#is_pending_job(a:job_id)
|
||||||
|
call gitgutter#handle_diff("")
|
||||||
|
call gitgutter#utility#job_output_received(a:job_id, 'exit')
|
||||||
|
endif
|
||||||
|
|
||||||
|
else
|
||||||
|
call gitgutter#hunk#reset()
|
||||||
|
call gitgutter#utility#job_output_received(a:job_id, 'stderr')
|
||||||
|
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
function! gitgutter#handle_diff(diff)
|
||||||
|
call gitgutter#hunk#set_hunks(gitgutter#diff#parse_diff(a:diff))
|
||||||
let modified_lines = gitgutter#diff#process_hunks(gitgutter#hunk#hunks())
|
let modified_lines = gitgutter#diff#process_hunks(gitgutter#hunk#hunks())
|
||||||
|
|
||||||
if len(modified_lines) > g:gitgutter_max_signs
|
if len(modified_lines) > g:gitgutter_max_signs
|
||||||
@@ -34,13 +70,6 @@ function! gitgutter#process_buffer(bufnr, realtime)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
call gitgutter#utility#save_last_seen_change()
|
call gitgutter#utility#save_last_seen_change()
|
||||||
endif
|
|
||||||
catch /diff failed/
|
|
||||||
call gitgutter#hunk#reset()
|
|
||||||
endtry
|
|
||||||
else
|
|
||||||
call gitgutter#hunk#reset()
|
|
||||||
endif
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! gitgutter#disable()
|
function! gitgutter#disable()
|
||||||
|
|||||||
@@ -116,23 +116,35 @@ function! gitgutter#diff#run_diff(realtime, use_external_grep)
|
|||||||
endif
|
endif
|
||||||
end
|
end
|
||||||
|
|
||||||
let diff = gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file(cmd))
|
|
||||||
|
|
||||||
if a:realtime
|
|
||||||
call delete(blob_file)
|
|
||||||
call delete(buff_file)
|
|
||||||
endif
|
|
||||||
|
|
||||||
if gitgutter#utility#shell_error()
|
|
||||||
" A shell error indicates the file is not tracked by git (unless something bizarre is going on).
|
|
||||||
throw 'diff failed'
|
|
||||||
endif
|
|
||||||
|
|
||||||
if !tracked
|
if !tracked
|
||||||
call setbufvar(bufnr, 'gitgutter_tracked', 1)
|
call setbufvar(bufnr, 'gitgutter_tracked', 1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if has('nvim') && a:use_external_grep
|
||||||
|
let cmd = gitgutter#utility#command_in_directory_of_file(cmd)
|
||||||
|
" Note that when `cmd` doesn't produce any output, i.e. the diff is empty,
|
||||||
|
" the `stdout` event is not fired on the job handler. Therefore we keep
|
||||||
|
" track of the jobs ourselves so we can spot empty diffs.
|
||||||
|
let job_id = jobstart([&shell, '-c', cmd], {
|
||||||
|
\ 'on_stdout': function('gitgutter#handle_diff_job'),
|
||||||
|
\ 'on_stderr': function('gitgutter#handle_diff_job'),
|
||||||
|
\ 'on_exit': function('gitgutter#handle_diff_job')
|
||||||
|
\ })
|
||||||
|
call gitgutter#utility#pending_job(job_id)
|
||||||
|
return 'async'
|
||||||
|
else
|
||||||
|
let diff = gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file(cmd))
|
||||||
|
if gitgutter#utility#shell_error()
|
||||||
|
" A shell error indicates the file is not tracked by git (unless something bizarre is going on).
|
||||||
|
throw 'diff failed'
|
||||||
|
endif
|
||||||
return diff
|
return diff
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:realtime
|
||||||
|
" call delete(blob_file)
|
||||||
|
" call delete(buff_file)
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! gitgutter#diff#parse_diff(diff)
|
function! gitgutter#diff#parse_diff(diff)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ let s:file = ''
|
|||||||
let s:using_xolox_shell = -1
|
let s:using_xolox_shell = -1
|
||||||
let s:exit_code = 0
|
let s:exit_code = 0
|
||||||
let s:fish = &shell =~# 'fish'
|
let s:fish = &shell =~# 'fish'
|
||||||
|
let s:jobs = {}
|
||||||
|
|
||||||
function! gitgutter#utility#warn(message)
|
function! gitgutter#utility#warn(message)
|
||||||
echohl WarningMsg
|
echohl WarningMsg
|
||||||
@@ -162,3 +163,17 @@ endfunction
|
|||||||
function! gitgutter#utility#strip_trailing_new_line(line)
|
function! gitgutter#utility#strip_trailing_new_line(line)
|
||||||
return substitute(a:line, '\n$', '', '')
|
return substitute(a:line, '\n$', '', '')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! gitgutter#utility#pending_job(job_id)
|
||||||
|
let s:jobs[a:job_id] = 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! gitgutter#utility#is_pending_job(job_id)
|
||||||
|
return has_key(s:jobs, a:job_id)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! gitgutter#utility#job_output_received(job_id, event)
|
||||||
|
if has_key(s:jobs, a:job_id)
|
||||||
|
unlet s:jobs[a:job_id]
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|||||||
Reference in New Issue
Block a user