diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim index 900d1871..33d9f658 100644 --- a/autoload/ale/completion.vim +++ b/autoload/ale/completion.vim @@ -424,6 +424,59 @@ function! ale#completion#HandleLSPResponse(conn_id, response) abort \) endfunction +function! s:OnReady(linter, lsp_details, ...) abort + let l:buffer = a:lsp_details.buffer + let l:id = a:lsp_details.connection_id + let l:root = a:lsp_details.project_root + + " If we have sent a completion request already, don't send another. + if b:ale_completion_info.request_id + return + endif + + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#completion#HandleTSServerResponse') + \ : function('ale#completion#HandleLSPResponse') + call ale#lsp#RegisterCallback(l:id, l:Callback) + + if a:linter.lsp is# 'tsserver' + let l:message = ale#lsp#tsserver_message#Completions( + \ l:buffer, + \ b:ale_completion_info.line, + \ b:ale_completion_info.column, + \ b:ale_completion_info.prefix, + \) + else + " Send a message saying the buffer has changed first, otherwise + " completions won't know what text is nearby. + call ale#lsp#NotifyForChanges(l:id, l:root, l:buffer) + + " For LSP completions, we need to clamp the column to the length of + " the line. python-language-server and perhaps others do not implement + " this correctly. + let l:message = ale#lsp#message#Completion( + \ l:buffer, + \ b:ale_completion_info.line, + \ min([ + \ b:ale_completion_info.line_length, + \ b:ale_completion_info.column, + \ ]), + \ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix), + \) + endif + + let l:request_id = ale#lsp#Send(l:id, l:message, l:root) + + if l:request_id + let b:ale_completion_info.conn_id = l:id + let b:ale_completion_info.request_id = l:request_id + + if has_key(a:linter, 'completion_filter') + let b:ale_completion_info.completion_filter = a:linter.completion_filter + endif + endif +endfunction + function! s:GetLSPCompletions(linter) abort let l:buffer = bufnr('') let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter) @@ -435,56 +488,9 @@ function! s:GetLSPCompletions(linter) abort let l:id = l:lsp_details.connection_id let l:root = l:lsp_details.project_root - function! OnReady(...) abort closure - " If we have sent a completion request already, don't send another. - if b:ale_completion_info.request_id - return - endif + let l:OnReady = function('s:OnReady', [a:linter, l:lsp_details]) - let l:Callback = a:linter.lsp is# 'tsserver' - \ ? function('ale#completion#HandleTSServerResponse') - \ : function('ale#completion#HandleLSPResponse') - call ale#lsp#RegisterCallback(l:id, l:Callback) - - if a:linter.lsp is# 'tsserver' - let l:message = ale#lsp#tsserver_message#Completions( - \ l:buffer, - \ b:ale_completion_info.line, - \ b:ale_completion_info.column, - \ b:ale_completion_info.prefix, - \) - else - " Send a message saying the buffer has changed first, otherwise - " completions won't know what text is nearby. - call ale#lsp#NotifyForChanges(l:id, l:root, l:buffer) - - " For LSP completions, we need to clamp the column to the length of - " the line. python-language-server and perhaps others do not implement - " this correctly. - let l:message = ale#lsp#message#Completion( - \ l:buffer, - \ b:ale_completion_info.line, - \ min([ - \ b:ale_completion_info.line_length, - \ b:ale_completion_info.column, - \ ]), - \ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix), - \) - endif - - let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) - - if l:request_id - let b:ale_completion_info.conn_id = l:id - let b:ale_completion_info.request_id = l:request_id - - if has_key(a:linter, 'completion_filter') - let b:ale_completion_info.completion_filter = a:linter.completion_filter - endif - endif - endfunction - - call ale#lsp#WaitForCapability(l:id, l:root, 'completion', function('OnReady')) + call ale#lsp#WaitForCapability(l:id, l:root, 'completion', l:OnReady) endfunction function! ale#completion#GetCompletions() abort diff --git a/autoload/ale/definition.vim b/autoload/ale/definition.vim index 3ef24e28..18bec988 100644 --- a/autoload/ale/definition.vim +++ b/autoload/ale/definition.vim @@ -57,6 +57,40 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort endif endfunction +function! s:OnReady(linter, lsp_details, line, column, options, ...) abort + let l:buffer = a:lsp_details.buffer + let l:id = a:lsp_details.connection_id + let l:root = a:lsp_details.project_root + + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#definition#HandleTSServerResponse') + \ : function('ale#definition#HandleLSPResponse') + call ale#lsp#RegisterCallback(l:id, l:Callback) + + if a:linter.lsp is# 'tsserver' + let l:message = ale#lsp#tsserver_message#Definition( + \ l:buffer, + \ a:line, + \ a:column + \) + else + " Send a message saying the buffer has changed first, or the + " definition position probably won't make sense. + call ale#lsp#NotifyForChanges(l:id, l:root, l:buffer) + + " For LSP completions, we need to clamp the column to the length of + " the line. python-language-server and perhaps others do not implement + " this correctly. + let l:message = ale#lsp#message#Definition(l:buffer, a:line, a:column) + endif + + let l:request_id = ale#lsp#Send(l:id, l:message, l:root) + + let s:go_to_definition_map[l:request_id] = { + \ 'open_in_tab': get(a:options, 'open_in_tab', 0), + \} +endfunction + function! s:GoToLSPDefinition(linter, options) abort let l:buffer = bufnr('') let [l:line, l:column] = getcurpos()[1:2] @@ -73,37 +107,11 @@ function! s:GoToLSPDefinition(linter, options) abort let l:id = l:lsp_details.connection_id let l:root = l:lsp_details.project_root - function! OnReady(...) abort closure - let l:Callback = a:linter.lsp is# 'tsserver' - \ ? function('ale#definition#HandleTSServerResponse') - \ : function('ale#definition#HandleLSPResponse') - call ale#lsp#RegisterCallback(l:id, l:Callback) + let l:OnReady = function('s:OnReady', [ + \ a:linter, l:lsp_details, l:line, l:column, a:options + \]) - if a:linter.lsp is# 'tsserver' - let l:message = ale#lsp#tsserver_message#Definition( - \ l:buffer, - \ l:line, - \ l:column - \) - else - " Send a message saying the buffer has changed first, or the - " definition position probably won't make sense. - call ale#lsp#NotifyForChanges(l:id, l:root, l:buffer) - - " For LSP completions, we need to clamp the column to the length of - " the line. python-language-server and perhaps others do not implement - " this correctly. - let l:message = ale#lsp#message#Definition(l:buffer, l:line, l:column) - endif - - let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) - - let s:go_to_definition_map[l:request_id] = { - \ 'open_in_tab': get(a:options, 'open_in_tab', 0), - \} - endfunction - - call ale#lsp#WaitForCapability(l:id, l:root, 'definition', function('OnReady')) + call ale#lsp#WaitForCapability(l:id, l:root, 'definition', l:OnReady) endfunction function! ale#definition#GoTo(options) abort diff --git a/autoload/ale/hover.vim b/autoload/ale/hover.vim index dc97ff41..7c7386f5 100644 --- a/autoload/ale/hover.vim +++ b/autoload/ale/hover.vim @@ -92,7 +92,45 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort endif endfunction -function! s:ShowDetails(linter, buffer, line, column, opt) abort +function! s:OnReady(linter, lsp_details, line, column, opt, ...) abort + let l:buffer = a:lsp_details.buffer + let l:id = a:lsp_details.connection_id + let l:root = a:lsp_details.project_root + + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#hover#HandleTSServerResponse') + \ : function('ale#hover#HandleLSPResponse') + call ale#lsp#RegisterCallback(l:id, l:Callback) + + if a:linter.lsp is# 'tsserver' + let l:column = a:column + + let l:message = ale#lsp#tsserver_message#Quickinfo( + \ l:buffer, + \ a:line, + \ l:column + \) + else + " Send a message saying the buffer has changed first, or the + " hover position probably won't make sense. + call ale#lsp#NotifyForChanges(l:id, l:root, l:buffer) + + let l:column = min([a:column, len(getbufline(l:buffer, a:line)[0])]) + + let l:message = ale#lsp#message#Hover(l:buffer, a:line, l:column) + endif + + let l:request_id = ale#lsp#Send(l:id, l:message, l:root) + + let s:hover_map[l:request_id] = { + \ 'buffer': l:buffer, + \ 'line': a:line, + \ 'column': l:column, + \ 'hover_from_balloonexpr': get(a:opt, 'called_from_balloonexpr', 0), + \} +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) @@ -101,43 +139,12 @@ function! s:ShowDetails(linter, buffer, line, column, opt) abort let l:id = l:lsp_details.connection_id let l:root = l:lsp_details.project_root - let l:language_id = l:lsp_details.language_id - function! OnReady(...) abort closure - let l:Callback = a:linter.lsp is# 'tsserver' - \ ? function('ale#hover#HandleTSServerResponse') - \ : function('ale#hover#HandleLSPResponse') - call ale#lsp#RegisterCallback(l:id, l:Callback) + let l:OnReady = function('s:OnReady', [ + \ a:linter, l:lsp_details, a:line, a:column, a:opt + \]) - if a:linter.lsp is# 'tsserver' - let l:column = a:column - - let l:message = ale#lsp#tsserver_message#Quickinfo( - \ a:buffer, - \ a:line, - \ l:column - \) - else - " Send a message saying the buffer has changed first, or the - " hover position probably won't make sense. - call ale#lsp#NotifyForChanges(l:id, l:root, a:buffer) - - let l:column = min([a:column, len(getbufline(a:buffer, a:line)[0])]) - - let l:message = ale#lsp#message#Hover(a:buffer, a:line, l:column) - endif - - let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) - - let s:hover_map[l:request_id] = { - \ 'buffer': a:buffer, - \ 'line': a:line, - \ 'column': l:column, - \ 'hover_from_balloonexpr': get(a:opt, 'called_from_balloonexpr', 0), - \} - endfunction - - call ale#lsp#WaitForCapability(l:id, l:root, 'hover', function('OnReady')) + call ale#lsp#WaitForCapability(l:id, l:root, 'hover', l:OnReady) endfunction " Obtain Hover information for the specified position diff --git a/autoload/ale/references.vim b/autoload/ale/references.vim index 3a710b7b..bcf486b4 100644 --- a/autoload/ale/references.vim +++ b/autoload/ale/references.vim @@ -64,6 +64,36 @@ function! ale#references#HandleLSPResponse(conn_id, response) abort endif endfunction +function! s:OnReady(linter, lsp_details, line, column, ...) abort + let l:buffer = a:lsp_details.buffer + let l:id = a:lsp_details.connection_id + let l:root = a:lsp_details.project_root + + let l:Callback = a:linter.lsp is# 'tsserver' + \ ? function('ale#references#HandleTSServerResponse') + \ : function('ale#references#HandleLSPResponse') + + call ale#lsp#RegisterCallback(l:id, l:Callback) + + if a:linter.lsp is# 'tsserver' + let l:message = ale#lsp#tsserver_message#References( + \ l:buffer, + \ a:line, + \ a:column + \) + else + " Send a message saying the buffer has changed first, or the + " references position probably won't make sense. + call ale#lsp#NotifyForChanges(l:id, l:root, l:buffer) + + let l:message = ale#lsp#message#References(l:buffer, a:line, a:column) + endif + + let l:request_id = ale#lsp#Send(l:id, l:message, a:lsp_details.project_root) + + let s:references_map[l:request_id] = {} +endfunction + function! s:FindReferences(linter) abort let l:buffer = bufnr('') let [l:line, l:column] = getcurpos()[1:2] @@ -81,33 +111,11 @@ function! s:FindReferences(linter) abort let l:id = l:lsp_details.connection_id let l:root = l:lsp_details.project_root - function! OnReady(...) abort closure - let l:Callback = a:linter.lsp is# 'tsserver' - \ ? function('ale#references#HandleTSServerResponse') - \ : function('ale#references#HandleLSPResponse') + let l:OnReady = function('s:OnReady', [ + \ a:linter, l:lsp_details, l:line, l:column + \]) - call ale#lsp#RegisterCallback(l:id, l:Callback) - - if a:linter.lsp is# 'tsserver' - let l:message = ale#lsp#tsserver_message#References( - \ l:buffer, - \ l:line, - \ l:column - \) - else - " Send a message saying the buffer has changed first, or the - " references position probably won't make sense. - call ale#lsp#NotifyForChanges(l:id, l:root, l:buffer) - - let l:message = ale#lsp#message#References(l:buffer, l:line, l:column) - endif - - let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) - - let s:references_map[l:request_id] = {} - endfunction - - call ale#lsp#WaitForCapability(l:id, l:root, 'references', function('OnReady')) + call ale#lsp#WaitForCapability(l:id, l:root, 'references', l:OnReady) endfunction function! ale#references#Find() abort