mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-29 15:26:52 +08:00
#517 Add more code LSP support which makes the tssserver linter behave more like the LSP linters
This commit is contained in:
@@ -31,13 +31,15 @@ endfunction
|
||||
|
||||
function! ale#engine#InitBufferInfo(buffer) abort
|
||||
if !has_key(g:ale_buffer_info, a:buffer)
|
||||
" job_list will hold the list of jobs
|
||||
" job_list will hold the list of job IDs
|
||||
" active_linter_list will hold the list of active linter names
|
||||
" loclist holds the loclist items after all jobs have completed.
|
||||
" temporary_file_list holds temporary files to be cleaned up
|
||||
" temporary_directory_list holds temporary directories to be cleaned up
|
||||
" history holds a list of previously run commands for this buffer
|
||||
let g:ale_buffer_info[a:buffer] = {
|
||||
\ 'job_list': [],
|
||||
\ 'active_linter_list': [],
|
||||
\ 'loclist': [],
|
||||
\ 'temporary_file_list': [],
|
||||
\ 'temporary_directory_list': [],
|
||||
@@ -114,6 +116,16 @@ function! s:GatherOutput(job_id, line) abort
|
||||
endfunction
|
||||
|
||||
function! s:HandleLoclist(linter_name, buffer, loclist) abort
|
||||
let l:buffer_info = get(g:ale_buffer_info, a:buffer, {})
|
||||
|
||||
if empty(l:buffer_info)
|
||||
return
|
||||
endif
|
||||
|
||||
" Remove this linter from the list of active linters.
|
||||
" This may have already been done when the job exits.
|
||||
call filter(l:buffer_info.active_linter_list, 'v:val !=# a:linter_name')
|
||||
|
||||
" Make some adjustments to the loclists to fix common problems, and also
|
||||
" to set default values for loclist items.
|
||||
let l:linter_loclist = ale#engine#FixLocList(a:buffer, a:linter_name, a:loclist)
|
||||
@@ -154,6 +166,7 @@ function! s:HandleExit(job_id, exit_code) abort
|
||||
call ale#job#Stop(a:job_id)
|
||||
call remove(s:job_info_map, a:job_id)
|
||||
call filter(g:ale_buffer_info[l:buffer].job_list, 'v:val !=# a:job_id')
|
||||
call filter(g:ale_buffer_info[l:buffer].active_linter_list, 'v:val !=# l:linter.name')
|
||||
|
||||
" Stop here if we land in the handle for a job completing if we're in
|
||||
" a sandbox.
|
||||
@@ -180,29 +193,32 @@ function! s:HandleExit(job_id, exit_code) abort
|
||||
call s:HandleLoclist(l:linter.name, l:buffer, l:loclist)
|
||||
endfunction
|
||||
|
||||
function! s:HandleLSPResponse(response) abort
|
||||
let l:is_diag_response = get(a:response, 'type', '') ==# 'event'
|
||||
\ && get(a:response, 'event', '') ==# 'semanticDiag'
|
||||
function! s:HandleLSPDiagnostics(response) abort
|
||||
let l:filename = ale#path#FromURI(a:response.params.uri)
|
||||
let l:buffer = bufnr(l:filename)
|
||||
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response)
|
||||
|
||||
if !l:is_diag_response
|
||||
return
|
||||
endif
|
||||
call s:HandleLoclist('langserver', l:buffer, l:loclist)
|
||||
endfunction
|
||||
|
||||
function! s:HandleTSServerDiagnostics(response) abort
|
||||
let l:buffer = bufnr(a:response.body.file)
|
||||
|
||||
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
||||
|
||||
if empty(l:info)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:info.waiting_for_tsserver = 0
|
||||
|
||||
let l:loclist = ale#lsp#response#ReadTSServerDiagnostics(a:response)
|
||||
|
||||
call s:HandleLoclist('tsserver', l:buffer, l:loclist)
|
||||
endfunction
|
||||
|
||||
function! s:HandleLSPResponse(response) abort
|
||||
let l:method = get(a:response, 'method', '')
|
||||
|
||||
if l:method ==# 'textDocument/publishDiagnostics'
|
||||
call s:HandleLSPDiagnostics(a:response)
|
||||
elseif get(a:response, 'type', '') ==# 'event'
|
||||
\&& get(a:response, 'event', '') ==# 'semanticDiag'
|
||||
call s:HandleTSServerDiagnostics(a:response)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#engine#SetResults(buffer, loclist) abort
|
||||
let l:linting_is_done = !ale#engine#IsCheckingBuffer(a:buffer)
|
||||
|
||||
@@ -430,6 +446,7 @@ function! s:RunJob(options) abort
|
||||
if l:job_id
|
||||
" Add the job to the list of jobs, so we can track them.
|
||||
call add(g:ale_buffer_info[l:buffer].job_list, l:job_id)
|
||||
call add(g:ale_buffer_info[l:buffer].active_linter_list, l:linter.name)
|
||||
|
||||
let l:status = 'started'
|
||||
" Store the ID for the job in the map to read back again.
|
||||
@@ -555,41 +572,27 @@ function! s:StopCurrentJobs(buffer, include_lint_file_jobs) abort
|
||||
let l:info.job_list = l:new_job_list
|
||||
endfunction
|
||||
|
||||
function! s:CheckWithTSServer(buffer, linter, executable) abort
|
||||
let l:info = g:ale_buffer_info[a:buffer]
|
||||
|
||||
let l:command = ale#job#PrepareCommand(
|
||||
\ ale#linter#GetCommand(a:buffer, a:linter),
|
||||
\)
|
||||
let l:id = ale#lsp#StartProgram(
|
||||
\ a:executable,
|
||||
\ l:command,
|
||||
function! s:CheckWithLSP(buffer, linter) abort
|
||||
let l:lsp_details = ale#linter#StartLSP(
|
||||
\ a:buffer,
|
||||
\ a:linter,
|
||||
\ function('s:HandleLSPResponse'),
|
||||
\)
|
||||
|
||||
if !l:id
|
||||
if g:ale_history_enabled
|
||||
call ale#history#Add(a:buffer, 'failed', l:id, l:command)
|
||||
endif
|
||||
|
||||
if empty(l:lsp_details)
|
||||
return 0
|
||||
endif
|
||||
|
||||
if ale#lsp#OpenTSServerDocumentIfNeeded(l:id, a:buffer)
|
||||
if g:ale_history_enabled
|
||||
call ale#history#Add(a:buffer, 'started', l:id, l:command)
|
||||
endif
|
||||
endif
|
||||
let l:id = l:lsp_details.connection_id
|
||||
let l:root = l:lsp_details.project_root
|
||||
|
||||
call ale#lsp#Send(l:id, ale#lsp#tsserver_message#Change(a:buffer))
|
||||
|
||||
let l:request_id = ale#lsp#Send(
|
||||
\ l:id,
|
||||
\ ale#lsp#tsserver_message#Geterr(a:buffer),
|
||||
\)
|
||||
let l:change_message = a:linter.lsp ==# 'tsserver'
|
||||
\ ? ale#lsp#tsserver_message#Geterr(a:buffer)
|
||||
\ : ale#lsp#message#DidChange(a:buffer)
|
||||
let l:request_id = ale#lsp#Send(l:id, l:change_message, l:root)
|
||||
|
||||
if l:request_id != 0
|
||||
let l:info.waiting_for_tsserver = 1
|
||||
call add(g:ale_buffer_info[a:buffer].active_linter_list, a:linter.name)
|
||||
endif
|
||||
|
||||
return l:request_id != 0
|
||||
@@ -614,15 +617,12 @@ endfunction
|
||||
"
|
||||
" Returns 1 if the linter was successfully run.
|
||||
function! s:RunLinter(buffer, linter) abort
|
||||
if empty(a:linter.lsp) || a:linter.lsp ==# 'tsserver'
|
||||
if !empty(a:linter.lsp) || a:linter.lsp ==# 'tsserver'
|
||||
return s:CheckWithLSP(a:buffer, a:linter)
|
||||
else
|
||||
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
||||
|
||||
" Run this program if it can be executed.
|
||||
if s:IsExecutable(l:executable)
|
||||
if a:linter.lsp ==# 'tsserver'
|
||||
return s:CheckWithTSServer(a:buffer, a:linter, l:executable)
|
||||
endif
|
||||
|
||||
return s:InvokeChain(a:buffer, a:linter, 0, [])
|
||||
endif
|
||||
endif
|
||||
|
||||
Reference in New Issue
Block a user