Don't switch window in exit handler

Since we don't switch the window anymore, we can't simply refer to b:sy as we
used to do while Sy worked only synchronously.

Now we provide the buffer number to each job and the exit handler gets a pointer
to the b:sy of that buffer and passes it to all the subsequent functions.

References #209, #210.
This commit is contained in:
Marco Hinz 2017-01-30 14:50:32 +01:00
parent 68013238b4
commit 82d6df9f71
No known key found for this signature in database
GPG Key ID: 1C980A1B657B4A4F
3 changed files with 97 additions and 95 deletions

View File

@ -61,17 +61,17 @@ function! sy#start() abort
endfunction
" Function: #set_signs {{{1
function! sy#set_signs(diff, do_register) abort
call sy#verbose('set_signs()', b:sy.vcs)
function! sy#set_signs(sy, diff, do_register) abort
call sy#verbose('set_signs()', a:sy.vcs)
if a:do_register
let b:sy.stats = [0, 0, 0]
let dir = fnamemodify(b:sy.path, ':h')
let a:sy.stats = [0, 0, 0]
let dir = fnamemodify(a:sy.path, ':h')
if !has_key(g:sy_cache, dir)
let g:sy_cache[dir] = b:sy.vcs
let g:sy_cache[dir] = a:sy.vcs
endif
if empty(a:diff)
call sy#verbose('No changes found.', b:sy.vcs)
call sy#verbose('No changes found.', a:sy.vcs)
return
endif
endif
@ -82,7 +82,7 @@ function! sy#set_signs(diff, do_register) abort
call sy#highlight#line_disable()
endif
call sy#sign#process_diff(a:diff)
call sy#sign#process_diff(a:sy, a:diff)
if exists('#User#Signify')
execute 'doautocmd' (s:has_doau_modeline ? '<nomodeline>' : '') 'User Signify'

View File

@ -37,14 +37,15 @@ function! s:callback_stdout_vim(_job_id, data) dict abort
endfunction
" Function: s:callback_exit {{{1
function! s:callback_exit(job_id, exitval, ...) dict abort
function! s:callback_exit(_job_id, exitval, ...) dict abort
call sy#verbose('callback_exit()', self.vcs)
call win_gotoid(self.winid)
if self.bufnr != bufnr('%')
let sy = getbufvar(self.bufnr, 'sy')
if empty(sy)
call sy#verbose(printf('No b:sy found for %s', bufname(self.bufnr)), self.vcs)
return
endif
call sy#repo#get_diff_{self.vcs}(a:exitval, self.stdoutbuf, self.do_register)
silent! unlet b:job_id_{self.vcs}
call sy#repo#get_diff_{self.vcs}(sy, a:exitval, self.stdoutbuf, self.do_register)
call setbufvar(self.bufnr, 'sy_job_id_'.self.vcs, 0)
endfunction
" Function: sy#get_diff_start {{{1
@ -53,8 +54,8 @@ function! sy#repo#get_diff_start(vcs, do_register) abort
" Neovim
if has('nvim')
if exists('b:job_id_'.a:vcs)
silent! call jobstop(b:job_id_{a:vcs})
if exists('b:sy_job_id_'.a:vcs) && b:sy_job_id_{a:vcs}
silent! call jobstop(b:sy_job_id_{a:vcs})
endif
let [cmd, options] = s:initialize_job(a:vcs, a:do_register)
@ -62,7 +63,7 @@ function! sy#repo#get_diff_start(vcs, do_register) abort
try
execute chdir fnameescape(b:sy_info.dir)
let b:job_id_{a:vcs} = jobstart(cmd, extend(options, {
let b:sy_job_id_{a:vcs} = jobstart(cmd, extend(options, {
\ 'on_stdout': function('s:callback_stdout_nvim'),
\ 'on_exit': function('s:callback_exit'),
\ }))
@ -72,8 +73,8 @@ function! sy#repo#get_diff_start(vcs, do_register) abort
" Newer Vim
elseif v:version > 704 || v:version == 704 && has('patch1967')
if exists('b:job_id_'.a:vcs)
silent! call job_stop(b:job_id_{a:vcs})
if exists('b:sy_job_id_'.a:vcs) && b:sy_job_id_{a:vcs}
silent! call job_stop(b:sy_job_id_{a:vcs})
endif
let [cmd, options] = s:initialize_job(a:vcs, a:do_register)
@ -81,7 +82,7 @@ function! sy#repo#get_diff_start(vcs, do_register) abort
try
execute chdir fnameescape(b:sy_info.dir)
let b:job_id_{a:vcs} = job_start(cmd, {
let b:sy_job_id_{a:vcs} = job_start(cmd, {
\ 'in_io': 'null',
\ 'out_cb': function('s:callback_stdout_vim', options),
\ 'exit_cb': function('s:callback_exit', options),
@ -98,58 +99,58 @@ function! sy#repo#get_diff_start(vcs, do_register) abort
endfunction
" Function: s:get_diff_end {{{1
function! s:get_diff_end(found_diff, vcs, diff, do_register) abort
function! s:get_diff_end(sy, found_diff, vcs, diff, do_register) abort
call sy#verbose('get_diff_end()', a:vcs)
if a:found_diff
let b:sy.vcs = a:vcs
call sy#set_signs(a:diff, a:do_register)
let a:sy.vcs = a:vcs
call sy#set_signs(a:sy, a:diff, a:do_register)
endif
endfunction
" Function: #get_diff_git {{{1
function! sy#repo#get_diff_git(exitval, diff, do_register) abort
function! sy#repo#get_diff_git(sy, exitval, diff, do_register) abort
call sy#verbose('get_diff_git()', 'git')
let [found_diff, diff] = a:exitval ? [0, ''] : [1, a:diff]
call s:get_diff_end(found_diff, 'git', diff, a:do_register)
call s:get_diff_end(a:sy, found_diff, 'git', diff, a:do_register)
endfunction
" Function: #get_diff_hg {{{1
function! sy#repo#get_diff_hg(exitval, diff, do_register) abort
function! sy#repo#get_diff_hg(sy, exitval, diff, do_register) abort
call sy#verbose('get_diff_hg()', 'hg')
let [found_diff, diff] = a:exitval ? [0, ''] : [1, a:diff]
call s:get_diff_end(found_diff, 'hg', diff, a:do_register)
call s:get_diff_end(a:sy, found_diff, 'hg', diff, a:do_register)
endfunction
" Function: #get_diff_svn {{{1
function! sy#repo#get_diff_svn(exitval, diff, do_register) abort
function! sy#repo#get_diff_svn(sy, exitval, diff, do_register) abort
call sy#verbose('get_diff_svn()', 'svn')
let [found_diff, diff] = a:exitval ? [0, ''] : [1, a:diff]
call s:get_diff_end(found_diff, 'svn', diff, a:do_register)
call s:get_diff_end(a:sy, found_diff, 'svn', diff, a:do_register)
endfunction
" Function: #get_diff_bzr {{{1
function! sy#repo#get_diff_bzr(exitval, diff, do_register) abort
function! sy#repo#get_diff_bzr(sy, exitval, diff, do_register) abort
call sy#verbose('get_diff_bzr()', 'bzr')
let [found_diff, diff] = (a:exitval =~ '[012]') ? [1, a:diff] : [0, '']
call s:get_diff_end(found_diff, 'bzr', diff, a:do_register)
call s:get_diff_end(a:sy, found_diff, 'bzr', diff, a:do_register)
endfunction
" Function: #get_diff_darcs {{{1
function! sy#repo#get_diff_darcs(exitval, diff, do_register) abort
function! sy#repo#get_diff_darcs(sy, exitval, diff, do_register) abort
call sy#verbose('get_diff_darcs()', 'darcs')
let [found_diff, diff] = a:exitval ? [0, ''] : [1, a:diff]
call s:get_diff_end(found_diff, 'darcs', diff, a:do_register)
call s:get_diff_end(a:sy, found_diff, 'darcs', diff, a:do_register)
endfunction
" Function: #get_diff_fossil {{{1
function! sy#repo#get_diff_fossil(exitval, diff, do_register) abort
function! sy#repo#get_diff_fossil(sy, exitval, diff, do_register) abort
call sy#verbose('get_diff_fossil()', 'fossil')
let [found_diff, diff] = a:exitval ? [0, ''] : [1, a:diff]
call s:get_diff_end(found_diff, 'fossil', diff, a:do_register)
call s:get_diff_end(a:sy, found_diff, 'fossil', diff, a:do_register)
endfunction
" Function: #get_diff_cvs {{{1
function! sy#repo#get_diff_cvs(exitval, diff, do_register) abort
function! sy#repo#get_diff_cvs(sy, exitval, diff, do_register) abort
call sy#verbose('get_diff_cvs()', 'cvs')
let [found_diff, diff] = [0, '']
if a:exitval == 1
@ -160,35 +161,35 @@ function! sy#repo#get_diff_cvs(exitval, diff, do_register) abort
endif
endfor
endif
call s:get_diff_end(found_diff, 'cvs', diff, a:do_register)
call s:get_diff_end(a:sy, found_diff, 'cvs', diff, a:do_register)
endfunction
" Function: #get_diff_rcs {{{1
function! sy#repo#get_diff_rcs(exitval, diff, do_register) abort
function! sy#repo#get_diff_rcs(sy, exitval, diff, do_register) abort
call sy#verbose('get_diff_rcs()', 'rcs')
let [found_diff, diff] = a:exitval ? [0, ''] : [1, a:diff]
call s:get_diff_end(found_diff, 'rcs', diff, a:do_register)
call s:get_diff_end(a:sy, found_diff, 'rcs', diff, a:do_register)
endfunction
" Function: #get_diff_accurev {{{1
function! sy#repo#get_diff_accurev(exitval, diff, do_register) abort
function! sy#repo#get_diff_accurev(sy, exitval, diff, do_register) abort
call sy#verbose('get_diff_accurev()', 'accurev')
let [found_diff, diff] = (a:exitval >= 2) ? [0, ''] : [1, a:diff]
call s:get_diff_end(found_diff, 'accurev', diff, a:do_register)
call s:get_diff_end(a:sy, found_diff, 'accurev', diff, a:do_register)
endfunction
" Function: #get_diff_perforce {{{1
function! sy#repo#get_diff_perforce(exitval, diff, do_register) abort
function! sy#repo#get_diff_perforce(sy, exitval, diff, do_register) abort
call sy#verbose('get_diff_perforce()', 'perforce')
let [found_diff, diff] = a:exitval ? [0, ''] : [1, a:diff]
call s:get_diff_end(found_diff, 'perforce', diff, a:do_register)
call s:get_diff_end(a:sy, found_diff, 'perforce', diff, a:do_register)
endfunction
" Function: #get_diff_tfs {{{1
function! sy#repo#get_diff_tfs(exitval, diff, do_register) abort
function! sy#repo#get_diff_tfs(sy, exitval, diff, do_register) abort
call sy#verbose('get_diff_tfs()', 'tfs')
let [found_diff, diff] = a:exitval ? [0, ''] : [1, s:strip_context(a:diff)]
call s:get_diff_end(found_diff, 'tfs', diff, a:do_register)
call s:get_diff_end(a:sy, found_diff, 'tfs', diff, a:do_register)
endfunction
" Function: #get_stats {{{1
@ -235,7 +236,6 @@ function! s:initialize_job(vcs, do_register) abort
\ 'vcs': a:vcs,
\ 'do_register': a:do_register,
\ 'bufnr': bufnr('%'),
\ 'winid': win_getid(),
\ }
return [cmd, options]
endfunction

View File

@ -13,19 +13,19 @@ endif
let s:delete_highlight = ['', 'SignifyLineDelete']
" Function: #id_next {{{1
function! sy#sign#id_next() abort
let id = b:sy.signid
let b:sy.signid += 1
function! sy#sign#id_next(sy) abort
let id = a:sy.signid
let a:sy.signid += 1
return id
endfunction
" Function: #get_current_signs {{{1
function! sy#sign#get_current_signs() abort
let b:sy.internal = {}
let b:sy.external = {}
function! sy#sign#get_current_signs(sy) abort
let a:sy.internal = {}
let a:sy.external = {}
redir => signlist
silent! execute 'sign place buffer='. b:sy.buffer
silent! execute 'sign place buffer='. a:sy.buffer
redir END
for signline in split(signlist, '\n')[2:]
@ -38,28 +38,28 @@ function! sy#sign#get_current_signs() abort
" Handle ambiguous signs. Assume you have signs on line 3 and 4.
" Removing line 3 would lead to the second sign to be shifted up
" to line 3. Now there are still 2 signs, both one line 3.
if has_key(b:sy.internal, line)
execute 'sign unplace' b:sy.internal[line].id 'buffer='.b:sy.buffer
if has_key(a:sy.internal, line)
execute 'sign unplace' a:sy.internal[line].id 'buffer='.a:sy.buffer
endif
let b:sy.internal[line] = { 'type': type, 'id': id }
let a:sy.internal[line] = { 'type': type, 'id': id }
else
let b:sy.external[line] = id
let a:sy.external[line] = id
endif
endfor
endfunction
" Function: #process_diff {{{1
function! sy#sign#process_diff(diff) abort
let b:sy.signtable = {}
let b:sy.hunks = []
function! sy#sign#process_diff(sy, diff) abort
let a:sy.signtable = {}
let a:sy.hunks = []
let [added, modified, deleted] = [0, 0, 0]
call sy#sign#get_current_signs()
call sy#sign#get_current_signs(a:sy)
" Determine where we have to put our signs.
for line in filter(a:diff, 'v:val =~ "^@@ "')
let b:sy.lines = []
let a:sy.lines = []
let ids = []
let tokens = matchlist(line, '^@@ -\v(\d+),?(\d*) \+(\d+),?(\d*)')
@ -81,8 +81,8 @@ function! sy#sign#process_diff(diff) abort
while offset < new_count
let line = new_line + offset
let offset += 1
if s:external_sign_present(line) | continue | endif
call add(ids, s:add_sign(line, 'SignifyAdd'))
if s:external_sign_present(a:sy, line) | continue | endif
call add(ids, s:add_sign(a:sy, line, 'SignifyAdd'))
endwhile
" 2 lines removed:
@ -91,19 +91,19 @@ function! sy#sign#process_diff(diff) abort
" -this is line 6
" -this is line 7
elseif (old_count >= 1) && (new_count == 0)
if s:external_sign_present(new_line) | continue | endif
if s:external_sign_present(a:sy, new_line) | continue | endif
let deleted += old_count
if new_line == 0
call add(ids, s:add_sign(1, 'SignifyRemoveFirstLine'))
call add(ids, s:add_sign(a:sy, 1, 'SignifyRemoveFirstLine'))
elseif s:sign_show_count
if old_count <= 99
let text = substitute(s:sign_delete . old_count, '.*\ze..$', '', '')
else
let text = s:sign_delete .'>'
endif
call add(ids, s:add_sign(new_line, 'SignifyDelete'. old_count, text))
call add(ids, s:add_sign(a:sy, new_line, 'SignifyDelete'. old_count, text))
else
call add(ids, s:add_sign(new_line, 'SignifyDeleteMore', s:sign_delete))
call add(ids, s:add_sign(a:sy, new_line, 'SignifyDeleteMore', s:sign_delete))
endif
" 2 lines changed:
@ -119,8 +119,8 @@ function! sy#sign#process_diff(diff) abort
while offset < new_count
let line = new_line + offset
let offset += 1
if s:external_sign_present(line) | continue | endif
call add(ids, s:add_sign(line, 'SignifyChange'))
if s:external_sign_present(a:sy, line) | continue | endif
call add(ids, s:add_sign(a:sy, line, 'SignifyChange'))
endwhile
else
@ -141,12 +141,14 @@ function! sy#sign#process_diff(diff) abort
while offset < new_count - 1
let line = new_line + offset
let offset += 1
if s:external_sign_present(line) | continue | endif
call add(ids, s:add_sign(line, 'SignifyChange'))
if s:external_sign_present(a:sy, line) | continue | endif
call add(ids, s:add_sign(a:sy, line, 'SignifyChange'))
endwhile
let line = new_line + offset
if s:external_sign_present(line) | continue | endif
call add(ids, s:add_sign(line, (removed > 9) ? 'SignifyChangeDeleteMore' : 'SignifyChangeDelete'. removed))
if s:external_sign_present(a:sy, line) | continue | endif
call add(ids, s:add_sign(a:sy, line, (removed > 9)
\ ? 'SignifyChangeDeleteMore'
\ : 'SignifyChangeDelete'. removed))
" lines changed and added:
@ -161,33 +163,33 @@ function! sy#sign#process_diff(diff) abort
while offset < old_count
let line = new_line + offset
let offset += 1
if s:external_sign_present(line) | continue | endif
call add(ids, s:add_sign(line, 'SignifyChange'))
if s:external_sign_present(a:sy, line) | continue | endif
call add(ids, s:add_sign(a:sy, line, 'SignifyChange'))
let added += 1
endwhile
while offset < new_count
let line = new_line + offset
let offset += 1
if s:external_sign_present(line) | continue | endif
call add(ids, s:add_sign(line, 'SignifyAdd'))
if s:external_sign_present(a:sy, line) | continue | endif
call add(ids, s:add_sign(a:sy, line, 'SignifyAdd'))
endwhile
endif
endif
if !empty(ids)
call add(b:sy.hunks, {
call add(a:sy.hunks, {
\ 'ids' : ids,
\ 'start': b:sy.lines[0],
\ 'end' : b:sy.lines[-1] })
\ 'start': a:sy.lines[0],
\ 'end' : a:sy.lines[-1] })
endif
endfor
" Remove obsoleted signs.
for line in filter(keys(b:sy.internal), '!has_key(b:sy.signtable, v:val)')
execute 'sign unplace' b:sy.internal[line].id 'buffer='.b:sy.buffer
for line in filter(keys(a:sy.internal), '!has_key(a:sy.signtable, v:val)')
execute 'sign unplace' a:sy.internal[line].id 'buffer='.a:sy.buffer
endfor
let b:sy.stats = [added, modified, deleted]
let a:sy.stats = [added, modified, deleted]
endfunction
" Function: #remove_all_signs {{{1
@ -204,23 +206,23 @@ function! sy#sign#remove_all_signs(bufnr) abort
endfunction
" Function: s:add_sign {{{1
function! s:add_sign(line, type, ...) abort
call add(b:sy.lines, a:line)
let b:sy.signtable[a:line] = 1
function! s:add_sign(sy, line, type, ...) abort
call add(a:sy.lines, a:line)
let a:sy.signtable[a:line] = 1
if has_key(b:sy.internal, a:line)
if has_key(a:sy.internal, a:line)
" There is a sign on this line already.
if a:type == b:sy.internal[a:line].type
if a:type == a:sy.internal[a:line].type
" Keep current sign since the new one is of the same type.
return b:sy.internal[a:line].id
return a:sy.internal[a:line].id
else
" Update sign by overwriting the ID of the current sign.
let id = b:sy.internal[a:line].id
let id = a:sy.internal[a:line].id
endif
endif
if !exists('id')
let id = sy#sign#id_next()
let id = sy#sign#id_next(a:sy)
endif
if a:type =~# 'SignifyDelete'
@ -233,17 +235,17 @@ function! s:add_sign(line, type, ...) abort
\ id,
\ a:line,
\ a:type,
\ b:sy.buffer)
\ a:sy.buffer)
return id
endfunction
" Function: s:external_sign_present {{{1
function! s:external_sign_present(line) abort
if has_key(b:sy.external, a:line)
if has_key(b:sy.internal, a:line)
function! s:external_sign_present(sy, line) abort
if has_key(a:sy.external, a:line)
if has_key(a:sy.internal, a:line)
" Remove Sy signs from lines with other signs.
execute 'sign unplace' b:sy.internal[a:line].id 'buffer='.b:sy.buffer
execute 'sign unplace' a:sy.internal[a:line].id 'buffer='.a:sy.buffer
endif
return 1
endif