#2132 Use an on-init callback for all LSP logic
This commit is contained in:
parent
e88243687a
commit
1ee56713b8
14 changed files with 181 additions and 192 deletions
|
@ -446,10 +446,15 @@ function! ale#completion#HandleLSPResponse(conn_id, response) abort
|
|||
\)
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(linter, lsp_details, ...) abort
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
function! s:OnReady(linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if !ale#lsp#HasCapability(l:id, 'completion')
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
" If we have sent a completion request already, don't send another.
|
||||
if b:ale_completion_info.request_id
|
||||
return
|
||||
|
@ -498,21 +503,6 @@ function! s:OnReady(linter, lsp_details, ...) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! s:GetLSPCompletions(linter) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter)
|
||||
|
||||
if empty(l:lsp_details)
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:id = l:lsp_details.connection_id
|
||||
|
||||
let l:OnReady = function('s:OnReady', [a:linter, l:lsp_details])
|
||||
|
||||
call ale#lsp#WaitForCapability(l:id, 'completion', l:OnReady)
|
||||
endfunction
|
||||
|
||||
function! ale#completion#GetCompletions() abort
|
||||
if !g:ale_completion_enabled
|
||||
return
|
||||
|
@ -543,9 +533,12 @@ function! ale#completion#AlwaysGetCompletions(need_prefix) abort
|
|||
\ 'request_id': 0,
|
||||
\}
|
||||
|
||||
let l:buffer = bufnr('')
|
||||
let l:Callback = function('s:OnReady')
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call s:GetLSPCompletions(l:linter)
|
||||
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
|
|
@ -57,10 +57,15 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(linter, lsp_details, line, column, options, capability, ...) abort
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
function! s:OnReady(line, column, options, capability, linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if !ale#lsp#HasCapability(l:id, a:capability)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
let l:Callback = a:linter.lsp is# 'tsserver'
|
||||
\ ? function('ale#definition#HandleTSServerResponse')
|
||||
\ : function('ale#definition#HandleLSPResponse')
|
||||
|
@ -100,21 +105,13 @@ endfunction
|
|||
function! s:GoToLSPDefinition(linter, options, capability) abort
|
||||
let l:buffer = bufnr('')
|
||||
let [l:line, l:column] = getcurpos()[1:2]
|
||||
let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter)
|
||||
let l:column = min([l:column, len(getline(l:line))])
|
||||
|
||||
if a:linter.lsp isnot# 'tsserver'
|
||||
let l:column = min([l:column, len(getline(l:line))])
|
||||
endif
|
||||
|
||||
if empty(l:lsp_details)
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:id = l:lsp_details.connection_id
|
||||
|
||||
call ale#lsp#WaitForCapability(l:id, a:capability, function('s:OnReady', [
|
||||
\ a:linter, l:lsp_details, l:line, l:column, a:options, a:capability
|
||||
\]))
|
||||
let l:Callback = function(
|
||||
\ 's:OnReady',
|
||||
\ [l:line, l:column, a:options, a:capability]
|
||||
\)
|
||||
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||
endfunction
|
||||
|
||||
function! ale#definition#GoTo(options) abort
|
||||
|
|
|
@ -106,10 +106,15 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(linter, lsp_details, line, column, opt, ...) abort
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
function! s:OnReady(line, column, opt, linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if !ale#lsp#HasCapability(l:id, 'hover')
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
let l:Callback = a:linter.lsp is# 'tsserver'
|
||||
\ ? function('ale#hover#HandleTSServerResponse')
|
||||
\ : function('ale#hover#HandleLSPResponse')
|
||||
|
@ -144,20 +149,6 @@ function! s:OnReady(linter, lsp_details, line, column, opt, ...) abort
|
|||
\}
|
||||
endfunction
|
||||
|
||||
function! s:ShowDetails(linter, buffer, line, column, opt, ...) abort
|
||||
let l:lsp_details = ale#lsp_linter#StartLSP(a:buffer, a:linter)
|
||||
|
||||
if empty(l:lsp_details)
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:id = l:lsp_details.connection_id
|
||||
|
||||
call ale#lsp#WaitForCapability(l:id, 'hover', function('s:OnReady', [
|
||||
\ a:linter, l:lsp_details, a:line, a:column, a:opt
|
||||
\]))
|
||||
endfunction
|
||||
|
||||
" Obtain Hover information for the specified position
|
||||
" Pass optional arguments in the dictionary opt.
|
||||
" Currently, only one key/value is useful:
|
||||
|
@ -169,12 +160,13 @@ endfunction
|
|||
" - as status message otherwise
|
||||
function! ale#hover#Show(buffer, line, col, opt) abort
|
||||
let l:show_documentation = get(a:opt, 'show_documentation', 0)
|
||||
let l:Callback = function('s:OnReady', [a:line, a:col, a:opt])
|
||||
|
||||
for l:linter in ale#linter#Get(getbufvar(a:buffer, '&filetype'))
|
||||
" Only tsserver supports documentation requests at the moment.
|
||||
if !empty(l:linter.lsp)
|
||||
\&& (!l:show_documentation || l:linter.lsp is# 'tsserver')
|
||||
call s:ShowDetails(l:linter, a:buffer, a:line, a:col, a:opt)
|
||||
call ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
|
|
@ -36,7 +36,7 @@ function! ale#lsp#Register(executable_or_address, project, init_options) abort
|
|||
\ 'config': {},
|
||||
\ 'callback_list': [],
|
||||
\ 'message_queue': [],
|
||||
\ 'capabilities_queue': [],
|
||||
\ 'init_queue': [],
|
||||
\ 'capabilities': {
|
||||
\ 'hover': 0,
|
||||
\ 'references': 0,
|
||||
|
@ -259,13 +259,11 @@ function! ale#lsp#HandleInitResponse(conn, response) abort
|
|||
let a:conn.message_queue = []
|
||||
|
||||
" Call capabilities callbacks queued for the project.
|
||||
for [l:capability, l:Callback] in a:conn.capabilities_queue
|
||||
if a:conn.capabilities[l:capability]
|
||||
call call(l:Callback, [a:conn.id])
|
||||
endif
|
||||
for [l:Callback] in a:conn.init_queue
|
||||
call l:Callback()
|
||||
endfor
|
||||
|
||||
let a:conn.capabilities_queue = []
|
||||
let a:conn.init_queue = []
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#HandleMessage(conn_id, message) abort
|
||||
|
@ -501,26 +499,32 @@ function! ale#lsp#NotifyForChanges(conn_id, buffer) abort
|
|||
return l:notified
|
||||
endfunction
|
||||
|
||||
" Given some LSP details that must contain at least `connection_id` and
|
||||
" `project_root` keys,
|
||||
function! ale#lsp#WaitForCapability(conn_id, capability, callback) abort
|
||||
" Wait for an LSP server to be initialized.
|
||||
function! ale#lsp#OnInit(conn_id, Callback) abort
|
||||
let l:conn = get(s:connections, a:conn_id, {})
|
||||
|
||||
if empty(l:conn)
|
||||
return
|
||||
endif
|
||||
|
||||
if l:conn.initialized
|
||||
call a:Callback()
|
||||
else
|
||||
call add(l:conn.init_queue, a:Callback)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Check if an LSP has a given capability.
|
||||
function! ale#lsp#HasCapability(conn_id, capability) abort
|
||||
let l:conn = get(s:connections, a:conn_id, {})
|
||||
|
||||
if empty(l:conn)
|
||||
return 0
|
||||
endif
|
||||
|
||||
if type(get(l:conn.capabilities, a:capability, v:null)) isnot v:t_number
|
||||
throw 'Invalid capability ' . a:capability
|
||||
endif
|
||||
|
||||
if l:conn.initialized
|
||||
if l:conn.capabilities[a:capability]
|
||||
" The project has been initialized, so call the callback now.
|
||||
call call(a:callback, [a:conn_id])
|
||||
endif
|
||||
else
|
||||
" Call the callback later, once we have the information we need.
|
||||
call add(l:conn.capabilities_queue, [a:capability, a:callback])
|
||||
endif
|
||||
return l:conn.capabilities[a:capability]
|
||||
endfunction
|
||||
|
|
|
@ -187,7 +187,7 @@ endfunction
|
|||
|
||||
" Given a buffer, an LSP linter, start up an LSP linter and get ready to
|
||||
" receive messages for the document.
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
|
||||
let l:command = ''
|
||||
let l:address = ''
|
||||
let l:root = ale#lsp_linter#FindProjectRoot(a:buffer, a:linter)
|
||||
|
@ -195,7 +195,7 @@ function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
|||
if empty(l:root) && a:linter.lsp isnot# 'tsserver'
|
||||
" If there's no project root, then we can't check files with LSP,
|
||||
" unless we are using tsserver, which doesn't use project roots.
|
||||
return {}
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:init_options = ale#lsp_linter#GetOptions(a:buffer, a:linter)
|
||||
|
@ -208,7 +208,7 @@ function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
|||
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
||||
|
||||
if empty(l:executable) || !executable(l:executable)
|
||||
return {}
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:conn_id = ale#lsp#Register(l:executable, l:root, l:init_options)
|
||||
|
@ -225,7 +225,7 @@ function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
|||
call ale#history#Add(a:buffer, 'failed', l:conn_id, l:command)
|
||||
endif
|
||||
|
||||
return {}
|
||||
return 0
|
||||
endif
|
||||
|
||||
" tsserver behaves differently, so tell the LSP API that it is tsserver.
|
||||
|
@ -257,18 +257,20 @@ function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
|||
call ale#lsp#NotifyForChanges(l:conn_id, a:buffer)
|
||||
endif
|
||||
|
||||
return l:details
|
||||
call ale#lsp#OnInit(l:conn_id, {-> a:Callback(a:linter, l:details)})
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort
|
||||
let l:info = g:ale_buffer_info[a:buffer]
|
||||
let l:lsp_details = ale#lsp_linter#StartLSP(a:buffer, a:linter)
|
||||
function! s:CheckWithLSP(linter, details) abort
|
||||
let l:buffer = a:details.buffer
|
||||
let l:info = get(g:ale_buffer_info, l:buffer)
|
||||
|
||||
if empty(l:lsp_details)
|
||||
return 0
|
||||
if empty(l:info)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:id = l:lsp_details.connection_id
|
||||
let l:id = a:details.connection_id
|
||||
|
||||
" Register a callback now for handling errors now.
|
||||
let l:Callback = function('ale#lsp_linter#HandleLSPResponse')
|
||||
|
@ -278,16 +280,16 @@ function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort
|
|||
let s:lsp_linter_map[l:id] = a:linter.name
|
||||
|
||||
if a:linter.lsp is# 'tsserver'
|
||||
let l:message = ale#lsp#tsserver_message#Geterr(a:buffer)
|
||||
let l:message = ale#lsp#tsserver_message#Geterr(l:buffer)
|
||||
let l:notified = ale#lsp#Send(l:id, l:message) != 0
|
||||
else
|
||||
let l:notified = ale#lsp#NotifyForChanges(l:id, a:buffer)
|
||||
let l:notified = ale#lsp#NotifyForChanges(l:id, l:buffer)
|
||||
endif
|
||||
|
||||
" If this was a file save event, also notify the server of that.
|
||||
if a:linter.lsp isnot# 'tsserver'
|
||||
\&& getbufvar(a:buffer, 'ale_save_event_fired', 0)
|
||||
let l:save_message = ale#lsp#message#DidSave(a:buffer)
|
||||
\&& getbufvar(l:buffer, 'ale_save_event_fired', 0)
|
||||
let l:save_message = ale#lsp#message#DidSave(l:buffer)
|
||||
let l:notified = ale#lsp#Send(l:id, l:save_message) != 0
|
||||
endif
|
||||
|
||||
|
@ -305,8 +307,10 @@ function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort
|
|||
call add(l:info.active_linter_list, a:linter)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
return l:notified
|
||||
function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort
|
||||
return ale#lsp_linter#StartLSP(a:buffer, a:linter, function('s:CheckWithLSP'))
|
||||
endfunction
|
||||
|
||||
" Clear LSP linter data for the linting engine.
|
||||
|
|
|
@ -65,10 +65,15 @@ function! ale#references#HandleLSPResponse(conn_id, response) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(linter, lsp_details, line, column, options, ...) abort
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
function! s:OnReady(line, column, options, linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if !ale#lsp#HasCapability(l:id, 'references')
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
let l:Callback = a:linter.lsp is# 'tsserver'
|
||||
\ ? function('ale#references#HandleTSServerResponse')
|
||||
\ : function('ale#references#HandleLSPResponse')
|
||||
|
@ -96,27 +101,6 @@ function! s:OnReady(linter, lsp_details, line, column, options, ...) abort
|
|||
\}
|
||||
endfunction
|
||||
|
||||
function! s:FindReferences(linter, options) abort
|
||||
let l:buffer = bufnr('')
|
||||
let [l:line, l:column] = getcurpos()[1:2]
|
||||
|
||||
if a:linter.lsp isnot# 'tsserver'
|
||||
let l:column = min([l:column, len(getline(l:line))])
|
||||
endif
|
||||
|
||||
let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter)
|
||||
|
||||
if empty(l:lsp_details)
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:id = l:lsp_details.connection_id
|
||||
|
||||
call ale#lsp#WaitForCapability(l:id, 'references', function('s:OnReady', [
|
||||
\ a:linter, l:lsp_details, l:line, l:column, a:options
|
||||
\]))
|
||||
endfunction
|
||||
|
||||
function! ale#references#Find(...) abort
|
||||
let l:options = {}
|
||||
|
||||
|
@ -128,9 +112,14 @@ function! ale#references#Find(...) abort
|
|||
endfor
|
||||
endif
|
||||
|
||||
let l:buffer = bufnr('')
|
||||
let [l:line, l:column] = getcurpos()[1:2]
|
||||
let l:column = min([l:column, len(getline(l:line))])
|
||||
let l:Callback = function('s:OnReady', [l:line, l:column, l:options])
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call s:FindReferences(l:linter, l:options)
|
||||
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
|
|
@ -57,7 +57,13 @@ function! ale#symbol#HandleLSPResponse(conn_id, response) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(linter, lsp_details, query, options, ...) abort
|
||||
function! s:OnReady(query, options, linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if !ale#lsp#HasCapability(l:id, 'symbol_search')
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
" If we already made a request, stop here.
|
||||
|
@ -65,8 +71,6 @@ function! s:OnReady(linter, lsp_details, query, options, ...) abort
|
|||
return
|
||||
endif
|
||||
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
let l:Callback = function('ale#symbol#HandleLSPResponse')
|
||||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
|
||||
|
@ -80,18 +84,6 @@ function! s:OnReady(linter, lsp_details, query, options, ...) abort
|
|||
\}
|
||||
endfunction
|
||||
|
||||
function! s:Search(linter, buffer, query, options) abort
|
||||
let l:lsp_details = ale#lsp_linter#StartLSP(a:buffer, a:linter)
|
||||
|
||||
if !empty(l:lsp_details)
|
||||
call ale#lsp#WaitForCapability(
|
||||
\ l:lsp_details.connection_id,
|
||||
\ 'symbol_search',
|
||||
\ function('s:OnReady', [a:linter, l:lsp_details, a:query, a:options]),
|
||||
\)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#symbol#Search(args) abort
|
||||
let [l:opts, l:query] = ale#args#Parse(['relative'], a:args)
|
||||
|
||||
|
@ -108,10 +100,11 @@ function! ale#symbol#Search(args) abort
|
|||
|
||||
" Set a flag so we only make one request.
|
||||
call setbufvar(l:buffer, 'ale_symbol_request_made', 0)
|
||||
let l:Callback = function('s:OnReady', [l:query, l:options])
|
||||
|
||||
for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype'))
|
||||
if !empty(l:linter.lsp) && l:linter.lsp isnot# 'tsserver'
|
||||
call s:Search(l:linter, l:buffer, l:query, l:options)
|
||||
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
|
|
@ -16,18 +16,20 @@ Before:
|
|||
let g:capability_checked = ''
|
||||
let g:conn_id = v:null
|
||||
let g:Callback = ''
|
||||
let g:wait_callback_list = []
|
||||
let g:init_callback_list = []
|
||||
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
|
||||
let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {})
|
||||
call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer)
|
||||
|
||||
return {
|
||||
let l:details = {
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'connection_id': g:conn_id,
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'language_id': 'python',
|
||||
\}
|
||||
|
||||
call add(g:init_callback_list, {-> a:Callback(a:linter, l:details)})
|
||||
endfunction
|
||||
|
||||
" Pretend we're in insert mode for most tests.
|
||||
|
@ -35,9 +37,10 @@ Before:
|
|||
return 'i'
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#WaitForCapability(conn_id, capability, callback) abort
|
||||
function! ale#lsp#HasCapability(conn_id, capability) abort
|
||||
let g:capability_checked = a:capability
|
||||
call add(g:wait_callback_list, a:callback)
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#RegisterCallback(conn_id, callback) abort
|
||||
|
@ -60,7 +63,7 @@ After:
|
|||
|
||||
unlet! g:message_list
|
||||
unlet! g:capability_checked
|
||||
unlet! g:wait_callback_list
|
||||
unlet! g:init_callback_list
|
||||
unlet! g:conn_id
|
||||
unlet! g:Callback
|
||||
unlet! b:ale_old_omnifunc
|
||||
|
@ -104,9 +107,10 @@ Execute(The right message should be sent for the initial tsserver request):
|
|||
" We shouldn't register the callback yet.
|
||||
AssertEqual '''''', string(g:Callback)
|
||||
|
||||
AssertEqual 1, len(g:wait_callback_list)
|
||||
AssertEqual 1, len(g:init_callback_list)
|
||||
call map(g:init_callback_list, 'v:val()')
|
||||
|
||||
AssertEqual 'completion', g:capability_checked
|
||||
call map(g:wait_callback_list, 'v:val([g:conn_id, ''/foo/bar''])')
|
||||
|
||||
" We should send the right callback.
|
||||
AssertEqual
|
||||
|
@ -191,9 +195,10 @@ Execute(The right message should be sent for the initial LSP request):
|
|||
" We shouldn't register the callback yet.
|
||||
AssertEqual '''''', string(g:Callback)
|
||||
|
||||
AssertEqual 1, len(g:wait_callback_list)
|
||||
AssertEqual 1, len(g:init_callback_list)
|
||||
call map(g:init_callback_list, 'v:val()')
|
||||
|
||||
AssertEqual 'completion', g:capability_checked
|
||||
call map(g:wait_callback_list, 'v:val([g:conn_id, ''/foo/bar''])')
|
||||
|
||||
" We should send the right callback.
|
||||
AssertEqual
|
||||
|
@ -258,9 +263,10 @@ Execute(Two completion requests shouldn't be sent in a row):
|
|||
" We shouldn't register the callback yet.
|
||||
AssertEqual '''''', string(g:Callback)
|
||||
|
||||
AssertEqual 2, len(g:wait_callback_list)
|
||||
AssertEqual 2, len(g:init_callback_list)
|
||||
call map(g:init_callback_list, 'v:val()')
|
||||
|
||||
AssertEqual 'completion', g:capability_checked
|
||||
call map(g:wait_callback_list, 'v:val([347, ''/foo/bar''])')
|
||||
|
||||
" We should only send one completion message for two LSP servers.
|
||||
AssertEqual
|
||||
|
|
|
@ -34,16 +34,19 @@ Before:
|
|||
\ })
|
||||
let g:ale_linters = {'foobar': ['dummy_linter']}
|
||||
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
|
||||
let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {})
|
||||
call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer)
|
||||
|
||||
return {
|
||||
let l:details = {
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'connection_id': g:conn_id,
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'language_id': 'foobar',
|
||||
\}
|
||||
|
||||
call a:Callback(a:linter, l:details)
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
" Replace the Send function for LSP, so we can monitor calls to it.
|
||||
|
@ -61,6 +64,7 @@ After:
|
|||
unlet! b:ale_enabled
|
||||
unlet! b:ale_linters
|
||||
unlet! g:message_list
|
||||
unlet! b:ale_save_event_fired
|
||||
|
||||
delfunction LanguageCallback
|
||||
delfunction ProjectRootCallback
|
||||
|
|
|
@ -24,6 +24,7 @@ Execute(Command formatting should be applied correctly for LSP linters):
|
|||
\ 'executable': has('win32') ? 'cmd': 'true',
|
||||
\ 'command': '%e --foo',
|
||||
\ },
|
||||
\ {-> 0}
|
||||
\)
|
||||
|
||||
if has('win32')
|
||||
|
|
|
@ -10,7 +10,7 @@ Before:
|
|||
\ 'config': {},
|
||||
\ 'callback_list': [],
|
||||
\ 'message_queue': [],
|
||||
\ 'capabilities_queue': [],
|
||||
\ 'init_queue': [],
|
||||
\ 'capabilities': {
|
||||
\ 'hover': 0,
|
||||
\ 'references': 0,
|
||||
|
|
|
@ -11,28 +11,30 @@ Before:
|
|||
let g:options = {}
|
||||
let g:capability_checked = ''
|
||||
let g:conn_id = v:null
|
||||
let g:WaitCallback = v:null
|
||||
let g:InitCallback = v:null
|
||||
|
||||
runtime autoload/ale/linter.vim
|
||||
runtime autoload/ale/lsp.vim
|
||||
runtime autoload/ale/util.vim
|
||||
runtime autoload/ale/preview.vim
|
||||
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
|
||||
let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {})
|
||||
call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer)
|
||||
|
||||
return {
|
||||
let l:details = {
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'connection_id': g:conn_id,
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'language_id': 'python',
|
||||
\}
|
||||
|
||||
let g:InitCallback = {-> a:Callback(a:linter, l:details)}
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#WaitForCapability(conn_id, capability, callback) abort
|
||||
function! ale#lsp#HasCapability(conn_id, capability) abort
|
||||
let g:capability_checked = a:capability
|
||||
let g:WaitCallback = a:callback
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#RegisterCallback(conn_id, callback) abort
|
||||
|
@ -65,7 +67,7 @@ After:
|
|||
call ale#linter#Reset()
|
||||
|
||||
unlet! g:capability_checked
|
||||
unlet! g:WaitCallback
|
||||
unlet! g:InitCallback
|
||||
unlet! g:old_filename
|
||||
unlet! g:conn_id
|
||||
unlet! g:Callback
|
||||
|
@ -173,10 +175,10 @@ Execute(tsserver reference requests should be sent):
|
|||
" We shouldn't register the callback yet.
|
||||
AssertEqual '''''', string(g:Callback)
|
||||
|
||||
AssertEqual type(function('type')), type(g:WaitCallback)
|
||||
AssertEqual 'references', g:capability_checked
|
||||
call call(g:WaitCallback, [g:conn_id, '/foo/bar'])
|
||||
AssertEqual type(function('type')), type(g:InitCallback)
|
||||
call g:InitCallback()
|
||||
|
||||
AssertEqual 'references', g:capability_checked
|
||||
AssertEqual
|
||||
\ 'function(''ale#references#HandleTSServerResponse'')',
|
||||
\ string(g:Callback)
|
||||
|
@ -191,7 +193,7 @@ Execute('-relative' argument should enable 'use_relative_paths' in HandleTSServe
|
|||
|
||||
ALEFindReferences -relative
|
||||
|
||||
call call(g:WaitCallback, [g:conn_id, '/foo/bar'])
|
||||
call g:InitCallback()
|
||||
|
||||
AssertEqual {'42': {'use_relative_paths': 1}}, ale#references#GetMap()
|
||||
|
||||
|
@ -264,10 +266,10 @@ Execute(LSP reference requests should be sent):
|
|||
" We shouldn't register the callback yet.
|
||||
AssertEqual '''''', string(g:Callback)
|
||||
|
||||
AssertEqual type(function('type')), type(g:WaitCallback)
|
||||
AssertEqual 'references', g:capability_checked
|
||||
call call(g:WaitCallback, [g:conn_id, '/foo/bar'])
|
||||
AssertEqual type(function('type')), type(g:InitCallback)
|
||||
call g:InitCallback()
|
||||
|
||||
AssertEqual 'references', g:capability_checked
|
||||
AssertEqual
|
||||
\ 'function(''ale#references#HandleLSPResponse'')',
|
||||
\ string(g:Callback)
|
||||
|
@ -298,6 +300,6 @@ Execute('-relative' argument should enable 'use_relative_paths' in HandleLSPResp
|
|||
|
||||
ALEFindReferences -relative
|
||||
|
||||
call call(g:WaitCallback, [g:conn_id, '/foo/bar'])
|
||||
call g:InitCallback()
|
||||
|
||||
AssertEqual {'42': {'use_relative_paths': 1}}, ale#references#GetMap()
|
||||
|
|
|
@ -8,27 +8,29 @@ Before:
|
|||
let g:expr_list = []
|
||||
let g:capability_checked = ''
|
||||
let g:conn_id = v:null
|
||||
let g:WaitCallback = v:null
|
||||
let g:InitCallback = v:null
|
||||
|
||||
runtime autoload/ale/linter.vim
|
||||
runtime autoload/ale/lsp.vim
|
||||
runtime autoload/ale/util.vim
|
||||
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
|
||||
let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {})
|
||||
call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer)
|
||||
|
||||
return {
|
||||
let l:details = {
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'connection_id': g:conn_id,
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'language_id': 'python',
|
||||
\}
|
||||
|
||||
let g:InitCallback = {-> a:Callback(a:linter, l:details)}
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#WaitForCapability(conn_id, capability, callback) abort
|
||||
function! ale#lsp#HasCapability(conn_id, capability) abort
|
||||
let g:capability_checked = a:capability
|
||||
let g:WaitCallback = a:callback
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#RegisterCallback(conn_id, callback) abort
|
||||
|
@ -55,7 +57,7 @@ After:
|
|||
call ale#linter#Reset()
|
||||
|
||||
unlet! g:capability_checked
|
||||
unlet! g:WaitCallback
|
||||
unlet! g:InitCallback
|
||||
unlet! g:old_filename
|
||||
unlet! g:conn_id
|
||||
unlet! g:Callback
|
||||
|
@ -205,10 +207,10 @@ Execute(tsserver definition requests should be sent):
|
|||
" We shouldn't register the callback yet.
|
||||
AssertEqual '''''', string(g:Callback)
|
||||
|
||||
AssertEqual type(function('type')), type(g:WaitCallback)
|
||||
AssertEqual 'definition', g:capability_checked
|
||||
call call(g:WaitCallback, [g:conn_id, '/foo/bar'])
|
||||
AssertEqual type(function('type')), type(g:InitCallback)
|
||||
call g:InitCallback()
|
||||
|
||||
AssertEqual 'definition', g:capability_checked
|
||||
AssertEqual
|
||||
\ 'function(''ale#definition#HandleTSServerResponse'')',
|
||||
\ string(g:Callback)
|
||||
|
@ -226,10 +228,10 @@ Execute(tsserver tab definition requests should be sent):
|
|||
" We shouldn't register the callback yet.
|
||||
AssertEqual '''''', string(g:Callback)
|
||||
|
||||
AssertEqual type(function('type')), type(g:WaitCallback)
|
||||
AssertEqual 'definition', g:capability_checked
|
||||
call call(g:WaitCallback, [g:conn_id, '/foo/bar'])
|
||||
AssertEqual type(function('type')), type(g:InitCallback)
|
||||
call g:InitCallback()
|
||||
|
||||
AssertEqual 'definition', g:capability_checked
|
||||
AssertEqual
|
||||
\ 'function(''ale#definition#HandleTSServerResponse'')',
|
||||
\ string(g:Callback)
|
||||
|
@ -358,10 +360,10 @@ Execute(LSP definition requests should be sent):
|
|||
" We shouldn't register the callback yet.
|
||||
AssertEqual '''''', string(g:Callback)
|
||||
|
||||
AssertEqual type(function('type')), type(g:WaitCallback)
|
||||
AssertEqual 'definition', g:capability_checked
|
||||
call call(g:WaitCallback, [g:conn_id, '/foo/bar'])
|
||||
AssertEqual type(function('type')), type(g:InitCallback)
|
||||
call g:InitCallback()
|
||||
|
||||
AssertEqual 'definition', g:capability_checked
|
||||
AssertEqual
|
||||
\ 'function(''ale#definition#HandleLSPResponse'')',
|
||||
\ string(g:Callback)
|
||||
|
@ -394,10 +396,10 @@ Execute(LSP type definition requests should be sent):
|
|||
" We shouldn't register the callback yet.
|
||||
AssertEqual '''''', string(g:Callback)
|
||||
|
||||
AssertEqual type(function('type')), type(g:WaitCallback)
|
||||
AssertEqual 'typeDefinition', g:capability_checked
|
||||
call call(g:WaitCallback, [g:conn_id, '/foo/bar'])
|
||||
AssertEqual type(function('type')), type(g:InitCallback)
|
||||
call g:InitCallback()
|
||||
|
||||
AssertEqual 'typeDefinition', g:capability_checked
|
||||
AssertEqual
|
||||
\ 'function(''ale#definition#HandleLSPResponse'')',
|
||||
\ string(g:Callback)
|
||||
|
@ -430,10 +432,10 @@ Execute(LSP tab definition requests should be sent):
|
|||
" We shouldn't register the callback yet.
|
||||
AssertEqual '''''', string(g:Callback)
|
||||
|
||||
AssertEqual type(function('type')), type(g:WaitCallback)
|
||||
AssertEqual 'definition', g:capability_checked
|
||||
call call(g:WaitCallback, [g:conn_id, '/foo/bar'])
|
||||
AssertEqual type(function('type')), type(g:InitCallback)
|
||||
call g:InitCallback()
|
||||
|
||||
AssertEqual 'definition', g:capability_checked
|
||||
AssertEqual
|
||||
\ 'function(''ale#definition#HandleLSPResponse'')',
|
||||
\ string(g:Callback)
|
||||
|
@ -466,10 +468,10 @@ Execute(LSP tab type definition requests should be sent):
|
|||
" We shouldn't register the callback yet.
|
||||
AssertEqual '''''', string(g:Callback)
|
||||
|
||||
AssertEqual type(function('type')), type(g:WaitCallback)
|
||||
AssertEqual 'typeDefinition', g:capability_checked
|
||||
call call(g:WaitCallback, [g:conn_id, '/foo/bar'])
|
||||
AssertEqual type(function('type')), type(g:InitCallback)
|
||||
call g:InitCallback()
|
||||
|
||||
AssertEqual 'typeDefinition', g:capability_checked
|
||||
AssertEqual
|
||||
\ 'function(''ale#definition#HandleLSPResponse'')',
|
||||
\ string(g:Callback)
|
||||
|
|
|
@ -10,28 +10,30 @@ Before:
|
|||
let g:options = {}
|
||||
let g:capability_checked = ''
|
||||
let g:conn_id = v:null
|
||||
let g:WaitCallback = v:null
|
||||
let g:InitCallback = v:null
|
||||
|
||||
runtime autoload/ale/lsp_linter.vim
|
||||
runtime autoload/ale/lsp.vim
|
||||
runtime autoload/ale/util.vim
|
||||
runtime autoload/ale/preview.vim
|
||||
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
|
||||
let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {})
|
||||
call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer)
|
||||
|
||||
return {
|
||||
let l:details = {
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'connection_id': g:conn_id,
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'language_id': 'python',
|
||||
\}
|
||||
|
||||
let g:InitCallback = {-> a:Callback(a:linter, l:details)}
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#WaitForCapability(conn_id, capability, callback) abort
|
||||
function! ale#lsp#HasCapability(conn_id, capability) abort
|
||||
let g:capability_checked = a:capability
|
||||
let g:WaitCallback = a:callback
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#RegisterCallback(conn_id, callback) abort
|
||||
|
@ -59,7 +61,7 @@ After:
|
|||
call ale#linter#Reset()
|
||||
|
||||
unlet! g:capability_checked
|
||||
unlet! g:WaitCallback
|
||||
unlet! g:InitCallback
|
||||
unlet! g:conn_id
|
||||
unlet! g:Callback
|
||||
unlet! g:message_list
|
||||
|
@ -159,10 +161,10 @@ Execute(LSP symbol requests should be sent):
|
|||
" We shouldn't register the callback yet.
|
||||
AssertEqual '''''', string(g:Callback)
|
||||
|
||||
AssertEqual 'symbol_search', g:capability_checked
|
||||
AssertEqual type(function('type')), type(g:WaitCallback)
|
||||
call call(g:WaitCallback, [g:conn_id, '/foo/bar'])
|
||||
AssertEqual type(function('type')), type(g:InitCallback)
|
||||
call g:InitCallback()
|
||||
|
||||
AssertEqual 'symbol_search', g:capability_checked
|
||||
AssertEqual
|
||||
\ 'function(''ale#symbol#HandleLSPResponse'')',
|
||||
\ string(g:Callback)
|
||||
|
@ -182,6 +184,6 @@ Execute('-relative' argument should enable 'use_relative_paths' in HandleLSPResp
|
|||
|
||||
ALESymbolSearch -relative foo bar
|
||||
|
||||
call call(g:WaitCallback, [g:conn_id, '/foo/bar'])
|
||||
call g:InitCallback()
|
||||
|
||||
AssertEqual {'42': {'buffer': bufnr(''), 'use_relative_paths': 1}}, ale#symbol#GetMap()
|
||||
|
|
Reference in a new issue