From 5eb96da9eff2589af68d3f8da2a963ecf97b4a78 Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Wed, 21 Mar 2018 15:28:29 -0700 Subject: [PATCH] use window id instead of number in all async jobs Use window ids instead of window numbers to select windows in all async job callbacks so that the correct window is selected even when the user modifies the window layout between when the job is started and when the callback is executed. --- autoload/go/job.vim | 10 ++++++++-- autoload/go/jobcontrol.vim | 9 +++++++-- autoload/go/lint.vim | 9 ++++----- autoload/go/test.vim | 31 ++++++++++++++++++++----------- 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/autoload/go/job.vim b/autoload/go/job.vim index 62214b4169..f8cef6ced9 100644 --- a/autoload/go/job.vim +++ b/autoload/go/job.vim @@ -33,7 +33,7 @@ function go#job#Spawn(args) let cbs = {} let state = { - \ 'winnr': winnr(), + \ 'winid': win_getid(winnr()), \ 'dir': getcwd(), \ 'jobdir': fnameescape(expand("%:p:h")), \ 'messages': [], @@ -104,15 +104,20 @@ function go#job#Spawn(args) let cbs.close_cb = function('s:close_cb', [], state) function state.show_errors(job, exit_status, data) + let l:winid = win_getid(winnr()) + call win_gotoid(self.winid) + let l:listtype = go#list#Type(self.for) if a:exit_status == 0 call go#list#Clean(l:listtype) + call win_gotoid(l:winid) return endif let l:listtype = go#list#Type(self.for) if len(a:data) == 0 call go#list#Clean(l:listtype) + call win_gotoid(l:winid) return endif @@ -132,10 +137,11 @@ function go#job#Spawn(args) if empty(errors) " failed to parse errors, output the original content call go#util#EchoError(self.messages + [self.dir]) + call win_gotoid(l:winid) return endif - if self.winnr == winnr() + if self.winid == l:winid call go#list#Window(l:listtype, len(errors)) if !self.bang call go#list#JumpToFirst(l:listtype) diff --git a/autoload/go/jobcontrol.vim b/autoload/go/jobcontrol.vim index 25505812ff..e7d1e46f84 100644 --- a/autoload/go/jobcontrol.vim +++ b/autoload/go/jobcontrol.vim @@ -50,7 +50,7 @@ function! s:spawn(bang, desc, for, args) abort let job = { \ 'desc': a:desc, \ 'bang': a:bang, - \ 'winnr': winnr(), + \ 'winid': win_getid(winnr()), \ 'importpath': go#package#ImportPath(), \ 'state': "RUNNING", \ 'stderr' : [], @@ -98,6 +98,9 @@ endfunction " on_stderr handler. If there are no errors and a quickfix window is open, " it'll be closed. function! s:on_exit(job_id, exit_status, event) dict abort + let l:winid = win_getid(winnr()) + call win_gotoid(self.winid) + let status = { \ 'desc': 'last status', \ 'type': self.status_type, @@ -134,6 +137,7 @@ function! s:on_exit(job_id, exit_status, event) dict abort endif execute cd . fnameescape(dir) + call win_gotoid(l:winid) return endif @@ -152,11 +156,12 @@ function! s:on_exit(job_id, exit_status, event) dict abort if !len(errors) " failed to parse errors, output the original content call go#util#EchoError(std_combined[0]) + call win_gotoid(l:winid) return endif " if we are still in the same windows show the list - if self.winnr == winnr() + if self.winid == l:winid call go#list#Window(l:listtype, len(errors)) if !empty(errors) && !self.bang call go#list#JumpToFirst(l:listtype) diff --git a/autoload/go/lint.vim b/autoload/go/lint.vim index 4204694666..5b0a7d043e 100644 --- a/autoload/go/lint.vim +++ b/autoload/go/lint.vim @@ -251,7 +251,7 @@ function! s:lint_job(args, autosave) \ 'exited': 0, \ 'closed': 0, \ 'exit_status': 0, - \ 'winnr': winnr(), + \ 'winid': win_getid(winnr()), \ 'autosave': a:autosave \ } @@ -308,15 +308,14 @@ function! s:lint_job(args, autosave) endif endfunction - function state.show_errors() - let l:winnr = winnr() + let l:winid = win_getid(winnr()) " make sure the current window is the window from which gometalinter was " run when the listtype is locationlist so that the location list for the " correct window will be populated. if self.listtype == 'locationlist' - exe self.winnr . "wincmd w" + call win_gotoid(self.winid) endif let l:errorformat = '%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m' @@ -331,7 +330,7 @@ function! s:lint_job(args, autosave) " start of this function avoids the perception that the quickfix window " steals focus when linting takes a while. if self.autosave - exe l:winnr . "wincmd w" + call win_gotoid(self.winid) endif if get(g:, 'go_echo_command_info', 1) diff --git a/autoload/go/test.vim b/autoload/go/test.vim index c62f508f25..bd2b9c08ea 100644 --- a/autoload/go/test.vim +++ b/autoload/go/test.vim @@ -48,7 +48,7 @@ function! go#test#Test(bang, compile, ...) abort let job_args = { \ 'cmd': ['go'] + args, \ 'bang': a:bang, - \ 'winnr': winnr(), + \ 'winid': win_getid(winnr()), \ 'dir': getcwd(), \ 'compile_test': a:compile, \ 'jobdir': fnameescape(expand("%:p:h")), @@ -242,11 +242,16 @@ endfunction " a quickfix compatible list of errors. It's intended to be used only for go " test output. function! s:show_errors(args, exit_val, messages) abort - let l:listtype = go#list#Type("GoTest") - if a:exit_val == 0 - call go#list#Clean(l:listtype) - return - endif + let l:winid = win_getid(winnr()) + + call win_gotoid(a:args.winid) + + let l:listtype = go#list#Type("GoTest") + if a:exit_val == 0 + call go#list#Clean(l:listtype) + call win_gotoid(l:winid) + return + endif " TODO(bc): When messages is JSON, the JSON should be run through a " filter to produce lines that are more easily described by errorformat. @@ -266,14 +271,18 @@ function! s:show_errors(args, exit_val, messages) abort " failed to parse errors, output the original content call go#util#EchoError(a:messages) call go#util#EchoError(a:args.dir) + call win_gotoid(l:winid) return endif - if a:args.winnr == winnr() - call go#list#Window(l:listtype, len(errors)) - if !empty(errors) && !a:args.bang - call go#list#JumpToFirst(l:listtype) - endif + if a:args.winid != l:winid + call win_gotoid(l:winid) + return + endif + + call go#list#Window(l:listtype, len(errors)) + if !empty(errors) && !a:args.bang + call go#list#JumpToFirst(l:listtype) endif endfunction