1
0
mirror of https://github.com/amix/vimrc synced 2025-07-14 23:55:01 +08:00

Update plugins using update_plugins.py

This commit is contained in:
Geezus
2019-07-08 11:44:45 -05:00
parent a25315c274
commit 0502b849ed
115 changed files with 3723 additions and 1662 deletions

View File

@ -26,7 +26,6 @@ function! s:newlsp() abort
if has('nvim')
set shortmess-=F
endif
" TODO(bc): start the server in the background using a shell that waits for the right output before returning.
call go#util#EchoWarning('Features that rely on gopls will not work without either Vim 8.0.0087 or newer with +job or Neovim')
" Sleep one second to make sure people see the message. Otherwise it is
" often immediately overwritten by an async message.
@ -55,6 +54,7 @@ function! s:newlsp() abort
\ 'last_request_id': 0,
\ 'buf': '',
\ 'handlers': {},
\ 'workspaceDirectories': [],
\ }
function! l:lsp.readMessage(data) dict abort
@ -83,19 +83,17 @@ function! s:newlsp() abort
endif
" get the start of the rest
let l:rest_start_idx = l:body_start_idx + str2nr(l:length_match[1])
let l:next_start_idx = l:body_start_idx + str2nr(l:length_match[1])
if len(l:rest) < l:rest_start_idx
if len(l:rest) < l:next_start_idx
" incomplete response body
break
endif
if go#util#HasDebug('lsp')
let g:go_lsp_log = add(go#config#LspLog(), "<-\n" . l:rest[:l:rest_start_idx - 1])
endif
call s:debug('received', l:rest[:l:next_start_idx - 1])
let l:body = l:rest[l:body_start_idx : l:rest_start_idx - 1]
let l:rest = l:rest[l:rest_start_idx :]
let l:body = l:rest[l:body_start_idx : l:next_start_idx - 1]
let l:rest = l:rest[l:next_start_idx :]
try
" add the json body to the list.
@ -113,53 +111,77 @@ function! s:newlsp() abort
function! l:lsp.handleMessage(ch, data) dict abort
let self.buf .= a:data
let [self.buf, l:responses] = self.readMessage(self.buf)
let [self.buf, l:messages] = self.readMessage(self.buf)
" TODO(bc): handle notifications (e.g. window/showMessage).
for l:response in l:responses
if has_key(l:response, 'id') && has_key(self.handlers, l:response.id)
try
let l:handler = self.handlers[l:response.id]
let l:winid = win_getid(winnr())
" Always set the active window to the window that was active when
" the request was sent. Among other things, this makes sure that
" the correct window's location list will be populated when the
" list type is 'location' and the user has moved windows since
" sending the reques.
call win_gotoid(l:handler.winid)
if has_key(l:response, 'error')
call l:handler.requestComplete(0)
if has_key(l:handler, 'error')
call call(l:handler.error, [l:response.error.message])
else
call go#util#EchoError(l:response.error.message)
endif
call win_gotoid(l:winid)
return
endif
call l:handler.requestComplete(1)
let l:winidBeforeHandler = l:handler.winid
call call(l:handler.handleResult, [l:response.result])
" change the window back to the window that was active when
" starting to handle the response _only_ if the handler didn't
" update the winid, so that handlers can set the winid if needed
" (e.g. :GoDef).
if l:handler.winid == l:winidBeforeHandler
call win_gotoid(l:winid)
endif
finally
call remove(self.handlers, l:response.id)
endtry
for l:message in l:messages
if has_key(l:message, 'method')
if has_key(l:message, 'id')
call self.handleRequest(l:message)
else
call self.handleNotification(l:message)
endif
elseif has_key(l:message, 'result') || has_key(l:message, 'error')
call self.handleResponse(l:message)
endif
endfor
endfunction
function! l:lsp.handleRequest(req) dict abort
if a:req.method == 'workspace/workspaceFolders'
let l:resp = go#lsp#message#workspaceFolders(self.workspaceDirectories)
endif
let l:msg = self.newResponse(l:resp)
call self.write(l:msg)
endfunction
function! l:lsp.handleNotification(req) dict abort
" TODO(bc): handle notifications (e.g. window/showMessage).
endfunction
function! l:lsp.handleResponse(resp) dict abort
if has_key(a:resp, 'id') && has_key(self.handlers, a:resp.id)
try
let l:handler = self.handlers[a:resp.id]
let l:winid = win_getid(winnr())
" Always set the active window to the window that was active when
" the request was sent. Among other things, this makes sure that
" the correct window's location list will be populated when the
" list type is 'location' and the user has moved windows since
" sending the request.
call win_gotoid(l:handler.winid)
if has_key(a:resp, 'error')
call l:handler.requestComplete(0)
if has_key(l:handler, 'error')
call call(l:handler.error, [a:resp.error.message])
else
call go#util#EchoError(a:resp.error.message)
endif
call win_gotoid(l:winid)
return
endif
call l:handler.requestComplete(1)
let l:winidBeforeHandler = l:handler.winid
call call(l:handler.handleResult, [a:resp.result])
" change the window back to the window that was active when
" starting to handle the message _only_ if the handler didn't
" update the winid, so that handlers can set the winid if needed
" (e.g. :GoDef).
if l:handler.winid == l:winidBeforeHandler
call win_gotoid(l:winid)
endif
finally
call remove(self.handlers, a:resp.id)
endtry
endif
endfunction
function! l:lsp.handleInitializeResult(result) dict abort
call go#util#EchoProgress("initialized gopls")
let self.ready = 1
" TODO(bc): send initialized message to the server?
@ -173,7 +195,15 @@ function! s:newlsp() abort
endfunction
function! l:lsp.sendMessage(data, handler) dict abort
" block while waiting on any in flight initializations to avoid race
" conditions initializing gopls.
while get(self, 'checkingmodule', 0)
sleep 50 m
redraw
endwhile
if !self.last_request_id
call go#util#EchoProgress("initializing gopls")
" TODO(bc): run a server per module and one per GOPATH? (may need to
" keep track of servers by rootUri).
let l:wd = go#util#ModuleRoot()
@ -186,25 +216,7 @@ function! s:newlsp() abort
let l:wd = getcwd()
endif
" do not attempt to send a message to gopls when using neither GOPATH
" mode nor module mode.
if go#package#FromPath(l:wd) == -2
if go#config#NullModuleWarning() && (!has_key(self, 'warned') || !self.warned)
let l:oldshortmess=&shortmess
if has('nvim')
set shortmess-=F
endif
call go#util#EchoWarning('Features that rely on gopls will not work correctly outside of GOPATH or a module.')
let self.warned = 1
" Sleep one second to make sure people see the message. Otherwise it is
" often immediately overwritten by an async message.
sleep 1
let &shortmess=l:oldshortmess
endif
return -1
endif
let self.workspaceDirectories = add(self.workspaceDirectories, l:wd)
let l:msg = self.newMessage(go#lsp#message#Initialize(l:wd))
let l:state = s:newHandlerState('')
@ -235,7 +247,7 @@ function! s:newlsp() abort
let l:msg = {
\ 'method': a:data.method,
\ 'jsonrpc': '2.0',
\ }
\ }
if !a:data.notification
let self.last_request_id += 1
@ -249,13 +261,19 @@ function! s:newlsp() abort
return l:msg
endfunction
function l:lsp.newResponse(id, result) dict abort
let l:msg = {
\ 'jsonrpc': '2.0',
\ 'id': a:id,
\ 'result': a:result,
\ }
endfunction
function! l:lsp.write(msg) dict abort
let l:body = json_encode(a:msg)
let l:data = 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body
if go#util#HasDebug('lsp')
let g:go_lsp_log = add(go#config#LspLog(), "->\n" . l:data)
endif
call s:debug('sent', l:data)
if has('nvim')
call chansend(self.job, l:data)
@ -275,9 +293,7 @@ function! s:newlsp() abort
endfunction
function! l:lsp.err_cb(ch, msg) dict abort
if go#util#HasDebug('lsp')
let g:go_lsp_log = add(go#config#LspLog(), "<-stderr\n" . a:msg)
endif
call s:debug('stderr', a:msg)
endfunction
" explicitly bind callbacks to l:lsp so that within it, self will always refer
@ -303,7 +319,6 @@ function! s:newlsp() abort
" start in.
let l:lsp.job = go#job#Start([l:bin_path], l:opts)
" TODO(bc): send the initialize message now?
return l:lsp
endfunction
@ -363,16 +378,17 @@ function! s:requestComplete(ok) abort dict
endfunction
function! s:start() abort dict
if self.statustype != ''
let status = {
\ 'desc': 'current status',
\ 'type': self.statustype,
\ 'state': "started",
\ }
call go#statusline#Update(self.jobdir, status)
endif
let self.started_at = reltime()
if self.statustype == ''
return
endif
let status = {
\ 'desc': 'current status',
\ 'type': self.statustype,
\ 'state': "started",
\ }
call go#statusline#Update(self.jobdir, status)
endfunction
" go#lsp#Definition calls gopls to get the definition of the identifier at
@ -506,7 +522,17 @@ function! s:completionHandler(next, msg) abort dict
if has_key(l:item, 'detail')
let l:match.info = l:item.detail
if go#lsp#completionitemkind#IsFunction(l:item.kind) || go#lsp#completionitemkind#IsMethod(l:item.kind)
let l:match.info = printf('func %s %s', l:item.label, l:item.detail)
let l:match.info = printf('%s %s', l:item.label, l:item.detail)
" The detail provided by gopls hasn't always provided the the full
" signature including the return value. The label used to be the
" function signature and the detail was the return value. Handle
" that case for backward compatibility. This can be removed in the
" future once it's likely that the majority of users are on a recent
" version of gopls.
if l:item.detail !~ '^func'
let l:match.info = printf('func %s %s', l:item.label, l:item.detail)
endif
endif
endif
@ -561,13 +587,32 @@ function! go#lsp#Info(showstatus)
let l:state = s:newHandlerState('')
endif
let l:state.handleResult = funcref('s:infoDefinitionHandler', [a:showstatus], l:state)
let l:state.handleResult = funcref('s:infoDefinitionHandler', [function('s:info', [1], l:state), a:showstatus], l:state)
let l:state.error = funcref('s:noop')
let l:msg = go#lsp#message#Definition(l:fname, l:line, l:col)
return l:lsp.sendMessage(l:msg, l:state)
endfunction
function! s:infoDefinitionHandler(showstatus, msg) abort dict
function! go#lsp#GetInfo()
let l:fname = expand('%:p')
let [l:line, l:col] = getpos('.')[1:2]
call go#lsp#DidChange(l:fname)
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('')
let l:info = go#promise#New(function('s:info', [0], l:state), 10000, '')
let l:state.handleResult = funcref('s:infoDefinitionHandler', [l:info.wrapper, 0], l:state)
let l:state.error = funcref('s:noop')
let l:msg = go#lsp#message#Definition(l:fname, l:line, l:col)
call l:lsp.sendMessage(l:msg, l:state)
return l:info.await()
endfunction
function! s:infoDefinitionHandler(next, showstatus, msg) abort dict
" gopls returns a []Location; just take the first one.
let l:msg = a:msg[0]
@ -584,22 +629,101 @@ function! s:infoDefinitionHandler(showstatus, msg) abort dict
let l:state = s:newHandlerState('')
endif
let l:state.handleResult = funcref('s:hoverHandler', [function('s:info', [], l:state)], l:state)
let l:state.handleResult = funcref('s:hoverHandler', [a:next], l:state)
let l:state.error = funcref('s:noop')
return l:lsp.sendMessage(l:msg, l:state)
endfunction
function! s:info(content) abort dict
function! s:info(show, content) abort dict
let l:content = s:infoFromHoverContent(a:content)
if a:show
call go#util#ShowInfo(l:content)
endif
return l:content
endfunction
function! s:infoFromHoverContent(content) abort
if len(a:content) < 1
return ''
endif
let l:content = a:content[0]
" strip godoc summary
let l:content = substitute(l:content, '^[^\n]\+\n', '', '')
" Hover content with godoc summary will have the godoc summary in the first
" line, and the second line will not have leading whitespace. When there is
" leading whitespace on the second line, then the hover content is for a
" struct or interface without godoc.
let l:lines = split(l:content, '\n')
if len(l:lines) > 1 && (l:lines[1] !~# '^\s')
let l:content = substitute(l:content, '^[^\n]\+\n', '', '')
endif
" strip off the method set and fields of structs and interfaces.
if l:content =~# '^type [^ ]\+ \(struct\|interface\)'
if l:content =~# '^\(type \)\?[^ ]\+ \(struct\|interface\)'
let l:content = substitute(l:content, '{.*', '', '')
endif
call go#util#ShowInfo(l:content)
return l:content
endfunction
function! go#lsp#AddWorkspace(...) abort
if a:0 == 0
return
endif
let l:workspaces = []
for l:dir in a:000
let l:dir = fnamemodify(l:dir, ':p')
if !isdirectory(l:dir)
continue
endif
let l:workspaces = add(l:workspaces, l:dir)
endfor
let l:lsp = s:lspfactory.get()
let l:state = s:newHandlerState('')
let l:state.handleResult = funcref('s:noop')
let l:lsp.workspaceDirectories = extend(l:lsp.workspaceDirectories, l:workspaces)
let l:msg = go#lsp#message#AddWorkspaces(l:workspaces)
call l:lsp.sendMessage(l:msg, l:state)
return 0
endfunction
function! s:debug(event, data) abort
if !go#util#HasDebug('lsp')
return
endif
let l:winid = win_getid()
let l:name = '__GOLSP_LOG__'
let l:log_winid = bufwinid(l:name)
if l:log_winid == -1
silent keepalt botright 10new
silent file `='__GOLSP_LOG__'`
setlocal buftype=nofile bufhidden=wipe nomodified nobuflisted noswapfile nowrap nonumber nocursorline
setlocal filetype=golsplog
else
call win_gotoid(l:log_winid)
endif
try
setlocal modifiable
if getline(1) == ''
call setline('$', printf('%s: %s', a:event, a:data))
else
call append('$', printf('%s: %s', a:event, a:data))
endif
normal! G
setlocal nomodifiable
finally
call win_gotoid(l:winid)
endtry
endfunction
" restore Vi compatibility settings