Skip to content

Commit 54fc278

Browse files
committed
lsp: restart when gopls is updated
1 parent ed63c87 commit 54fc278

File tree

3 files changed

+68
-11
lines changed

3 files changed

+68
-11
lines changed

autoload/go/lsp.vim

+42-3
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,29 @@ function! s:newlsp() abort
305305
call ch_sendraw(self.job, l:data)
306306
endfunction
307307

308-
function! l:lsp.exit_cb(job, exit_status) dict abort
308+
function! l:lsp.exit_cb(job, exit_status) dict
309+
let l:queue = []
310+
if !get(self, 'ready', 0)
311+
let l:queue = self.queue
312+
endif
313+
314+
let l:workspaces = self.workspaceDirectories
315+
309316
call s:lspfactory.reset()
317+
let l:lsp = s:lspfactory.get()
318+
319+
" restore workspaces
320+
call call('go#lsp#AddWorkspaceDirectory', l:workspaces)
321+
" * send DidOpen messages for all buffers that have b:did_lsp_open set
322+
" TODO(bc): check modifiable and filetype, too?
323+
bufdo if get(b:, 'go_lsp_did_open', 0) | if &modified | call go#lsp#DidOpen(expand('%:p')) | else | call go#lsp#DidChange(expand('%:p')) | endif | endif
324+
let l:lsp.queue = extend(l:lsp.queue, l:queue)
325+
return
310326
endfunction
311-
" explicitly bind close_cb to state so that within it, self will always refer
312327

313328
function! l:lsp.close_cb(ch) dict abort
314-
" TODO(bc): does anything need to be done here?
329+
" TODO(bc): remove the buffer variables that indicate that gopls has been
330+
" informed that the file is open
315331
endfunction
316332

317333
function! l:lsp.err_cb(ch, msg) dict abort
@@ -767,6 +783,29 @@ function! go#lsp#DebugBrowser() abort
767783
call go#util#OpenBrowser(printf('http://localhost:%d', l:port))
768784
endfunction
769785

786+
function! go#lsp#Restart() abort
787+
if !go#util#has_job() || len(s:lspfactory) == 0 || !has_key(s:lspfactory, 'current')
788+
return
789+
endif
790+
791+
let l:lsp = s:lspfactory.get()
792+
793+
let l:state = s:newHandlerState('exit')
794+
795+
let l:msg = go#lsp#message#Shutdown()
796+
let l:state.handleResult = funcref('s:noop')
797+
let l:retval = l:lsp.sendMessage(l:msg, l:state)
798+
799+
let l:msg = go#lsp#message#Exit()
800+
let l:retval = l:lsp.sendMessage(l:msg, l:state)
801+
802+
" clear ready so that any messages will be queued instead of being sent to
803+
" the process that is being asked to exit.
804+
let l:lsp.ready = 0
805+
806+
return l:retval
807+
endfunction
808+
770809
function! s:debug(event, data) abort
771810
if !go#util#HasDebug('lsp')
772811
return

autoload/go/lsp/message.vim

+14
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,20 @@ function! go#lsp#message#Initialized() abort
3636
\ }
3737
endfunction
3838

39+
function! go#lsp#message#Shutdown() abort
40+
return {
41+
\ 'notification': 0,
42+
\ 'method': 'shutdown',
43+
\ }
44+
endfunction
45+
46+
function! go#lsp#message#Exit() abort
47+
return {
48+
\ 'notification': 1,
49+
\ 'method': 'exit',
50+
\ }
51+
endfunction
52+
3953
function! go#lsp#message#WorkspaceFoldersResult(dirs) abort
4054
return map(copy(a:dirs), function('s:workspaceFolder', []))
4155
endfunction

plugin/go.vim

+12-8
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ let s:packages = {
5656
\ 'gogetdoc': ['github.com/zmb3/gogetdoc'],
5757
\ 'goimports': ['golang.org/x/tools/cmd/goimports'],
5858
\ 'golint': ['golang.org/x/lint/golint'],
59-
\ 'gopls': ['golang.org/x/tools/gopls@latest'],
59+
\ 'gopls': ['golang.org/x/tools/gopls@latest', {}, {'after': function('go#lsp#Restart', [])}],
6060
\ 'gometalinter': ['github.com/alecthomas/gometalinter'],
6161
\ 'golangci-lint': ['github.com/golangci/golangci-lint/cmd/golangci-lint'],
6262
\ 'gomodifytags': ['github.com/fatih/gomodifytags'],
@@ -136,29 +136,29 @@ function! s:GoInstallBinaries(updateBinaries, ...)
136136
let l:platform = 'windows'
137137
endif
138138

139-
for [binary, pkg] in items(l:packages)
140-
let l:importPath = pkg[0]
139+
for [l:binary, l:pkg] in items(l:packages)
140+
let l:importPath = l:pkg[0]
141141

142142
" TODO(bc): how to support this with modules? Do we have to clone and then
143143
" install manually? Probably not. I suspect that we can just use GOPATH
144144
" mode and then do the legacy method.
145-
let bin_setting_name = "go_" . binary . "_bin"
145+
let bin_setting_name = "go_" . l:binary . "_bin"
146146

147147
if exists("g:{bin_setting_name}")
148148
let bin = g:{bin_setting_name}
149149
else
150150
if go#util#IsWin()
151-
let bin = binary . '.exe'
151+
let bin = l:binary . '.exe'
152152
else
153-
let bin = binary
153+
let bin = l:binary
154154
endif
155155
endif
156156

157157
if !executable(bin) || a:updateBinaries == 1
158158
if a:updateBinaries == 1
159-
echo "vim-go: Updating " . binary . ". Reinstalling ". importPath . " to folder " . go_bin_path
159+
echo "vim-go: Updating " . l:binary . ". Reinstalling ". importPath . " to folder " . go_bin_path
160160
else
161-
echo "vim-go: ". binary ." not found. Installing ". importPath . " to folder " . go_bin_path
161+
echo "vim-go: ". l:binary ." not found. Installing ". importPath . " to folder " . go_bin_path
162162
endif
163163

164164
if l:importPath =~ "@"
@@ -208,9 +208,13 @@ function! s:GoInstallBinaries(updateBinaries, ...)
208208
echom "Error installing " . l:importPath . ": " . l:out
209209
endif
210210

211+
211212
call call(Restore_modules, [])
212213
endif
213214

215+
if len(l:pkg) > 2
216+
call call(get(l:pkg[2], 'after', function('s:noop', [])), [])
217+
endif
214218
endif
215219
endfor
216220

0 commit comments

Comments
 (0)