Add tsserver support
This commit is contained in:
parent
64ad51048d
commit
5146332206
23
ale_linters/typescript/tsserver.vim
Normal file
23
ale_linters/typescript/tsserver.vim
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" Description: tsserver integration for ALE
|
||||||
|
|
||||||
|
call ale#Set('typescript_tsserver_executable', 'tsserver')
|
||||||
|
call ale#Set('typescript_tsserver_config_path', '')
|
||||||
|
call ale#Set('typescript_tsserver_use_global', 0)
|
||||||
|
|
||||||
|
function! ale_linters#typescript#tsserver#GetExecutable(buffer) abort
|
||||||
|
return ale#node#FindExecutable(a:buffer, 'typescript_tsserver', [
|
||||||
|
\ 'node_modules/.bin/tsserver',
|
||||||
|
\])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#typescript#tsserver#Handle(buffer, lines) abort
|
||||||
|
return a:lines
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('typescript', {
|
||||||
|
\ 'name': 'tsserver',
|
||||||
|
\ 'lsp': 'tsserver',
|
||||||
|
\ 'executable_callback': 'ale_linters#typescript#tsserver#GetExecutable',
|
||||||
|
\ 'callback': 'ale_linters#typescript#tsserver#Handle',
|
||||||
|
\})
|
@ -11,6 +11,15 @@ if !has_key(s:, 'job_info_map')
|
|||||||
let s:job_info_map = {}
|
let s:job_info_map = {}
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" Stores information for each LSP command including:
|
||||||
|
"
|
||||||
|
" linter: The linter dictionary for the command.
|
||||||
|
" buffer: The buffer number for the command.
|
||||||
|
" message: The message we sent, [is_notification, command, params?]
|
||||||
|
if !has_key(s:, 'lsp_command_info_map')
|
||||||
|
let s:lsp_command_info_map = {}
|
||||||
|
endif
|
||||||
|
|
||||||
let s:executable_cache_map = {}
|
let s:executable_cache_map = {}
|
||||||
|
|
||||||
" Check if files are executable, and if they are, remember that they are
|
" Check if files are executable, and if they are, remember that they are
|
||||||
@ -42,6 +51,8 @@ function! ale#engine#InitBufferInfo(buffer) abort
|
|||||||
\ 'temporary_file_list': [],
|
\ 'temporary_file_list': [],
|
||||||
\ 'temporary_directory_list': [],
|
\ 'temporary_directory_list': [],
|
||||||
\ 'history': [],
|
\ 'history': [],
|
||||||
|
\ 'open_lsp_documents': [],
|
||||||
|
\ 'lsp_command_list': [],
|
||||||
\}
|
\}
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
@ -103,6 +114,51 @@ function! s:GatherOutput(job_id, line) abort
|
|||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:HandleLoclist(linter, buffer, loclist) abort
|
||||||
|
" 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, a:loclist)
|
||||||
|
|
||||||
|
" Remove previous items for this linter.
|
||||||
|
call filter(g:ale_buffer_info[a:buffer].loclist, 'v:val.linter_name !=# a:linter.name')
|
||||||
|
" Add the new items.
|
||||||
|
call extend(g:ale_buffer_info[a:buffer].loclist, l:linter_loclist)
|
||||||
|
|
||||||
|
" Sort the loclist again.
|
||||||
|
" We need a sorted list so we can run a binary search against it
|
||||||
|
" for efficient lookup of the messages in the cursor handler.
|
||||||
|
call sort(g:ale_buffer_info[a:buffer].loclist, 'ale#util#LocItemCompare')
|
||||||
|
|
||||||
|
let l:linting_is_done = empty(g:ale_buffer_info[a:buffer].job_list)
|
||||||
|
\ && empty(g:ale_buffer_info[a:buffer].lsp_command_list)
|
||||||
|
|
||||||
|
if l:linting_is_done
|
||||||
|
" Automatically remove all managed temporary files and directories
|
||||||
|
" now that all jobs have completed.
|
||||||
|
call ale#engine#RemoveManagedFiles(a:buffer)
|
||||||
|
|
||||||
|
" Figure out which linters are still enabled, and remove
|
||||||
|
" problems for linters which are no longer enabled.
|
||||||
|
let l:name_map = {}
|
||||||
|
|
||||||
|
for l:linter in ale#linter#Get(getbufvar(a:buffer, '&filetype'))
|
||||||
|
let l:name_map[l:linter.name] = 1
|
||||||
|
endfor
|
||||||
|
|
||||||
|
call filter(
|
||||||
|
\ g:ale_buffer_info[a:buffer].loclist,
|
||||||
|
\ 'get(l:name_map, v:val.linter_name)',
|
||||||
|
\)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call ale#engine#SetResults(a:buffer, g:ale_buffer_info[a:buffer].loclist)
|
||||||
|
|
||||||
|
if l:linting_is_done
|
||||||
|
" Call user autocommands. This allows users to hook into ALE's lint cycle.
|
||||||
|
silent doautocmd User ALELint
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:HandleExit(job_id, exit_code) abort
|
function! s:HandleExit(job_id, exit_code) abort
|
||||||
if !has_key(s:job_info_map, a:job_id)
|
if !has_key(s:job_info_map, a:job_id)
|
||||||
return
|
return
|
||||||
@ -143,55 +199,33 @@ function! s:HandleExit(job_id, exit_code) abort
|
|||||||
call ale#history#RememberOutput(l:buffer, a:job_id, l:output[:])
|
call ale#history#RememberOutput(l:buffer, a:job_id, l:output[:])
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:linter_loclist = ale#util#GetFunction(l:linter.callback)(l:buffer, l:output)
|
let l:loclist = ale#util#GetFunction(l:linter.callback)(l:buffer, l:output)
|
||||||
|
|
||||||
" Make some adjustments to the loclists to fix common problems, and also
|
call s:HandleLoclist(l:linter, l:buffer, l:loclist)
|
||||||
" to set default values for loclist items.
|
endfunction
|
||||||
let l:linter_loclist = ale#engine#FixLocList(l:buffer, l:linter, l:linter_loclist)
|
|
||||||
|
|
||||||
" Remove previous items for this linter.
|
function! s:HandleLSPResponse(request_id, response) abort
|
||||||
call filter(g:ale_buffer_info[l:buffer].loclist, 'v:val.linter_name !=# l:linter.name')
|
let l:info = get(s:lsp_command_info_map, a:request_id, {})
|
||||||
" Add the new items.
|
|
||||||
call extend(g:ale_buffer_info[l:buffer].loclist, l:linter_loclist)
|
|
||||||
|
|
||||||
" Sort the loclist again.
|
if empty(l:info)
|
||||||
" We need a sorted list so we can run a binary search against it
|
return
|
||||||
" for efficient lookup of the messages in the cursor handler.
|
|
||||||
call sort(g:ale_buffer_info[l:buffer].loclist, 'ale#util#LocItemCompare')
|
|
||||||
|
|
||||||
let l:linting_is_done = empty(g:ale_buffer_info[l:buffer].job_list)
|
|
||||||
|
|
||||||
if l:linting_is_done
|
|
||||||
" Automatically remove all managed temporary files and directories
|
|
||||||
" now that all jobs have completed.
|
|
||||||
call ale#engine#RemoveManagedFiles(l:buffer)
|
|
||||||
|
|
||||||
" Figure out which linters are still enabled, and remove
|
|
||||||
" problems for linters which are no longer enabled.
|
|
||||||
let l:name_map = {}
|
|
||||||
|
|
||||||
for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype'))
|
|
||||||
let l:name_map[l:linter.name] = 1
|
|
||||||
endfor
|
|
||||||
|
|
||||||
call filter(
|
|
||||||
\ g:ale_buffer_info[l:buffer].loclist,
|
|
||||||
\ 'get(l:name_map, v:val.linter_name)',
|
|
||||||
\)
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call ale#engine#SetResults(l:buffer, g:ale_buffer_info[l:buffer].loclist)
|
call remove(s:lsp_command_info_map, a:request_id)
|
||||||
|
|
||||||
if l:linting_is_done
|
let l:command_list = g:ale_buffer_info[l:info.buffer].lsp_command_list
|
||||||
" Call user autocommands. This allows users to hook into ALE's lint cycle.
|
call filter(l:command_list, 'v:val != a:request_id')
|
||||||
silent doautocmd User ALELint
|
|
||||||
endif
|
let l:loclist = ale#lsp#response#ReadTSServerDiagnostics(a:response)
|
||||||
|
|
||||||
|
call s:HandleLoclist(l:info.linter, l:info.buffer, l:loclist)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#engine#SetResults(buffer, loclist) abort
|
function! ale#engine#SetResults(buffer, loclist) abort
|
||||||
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
||||||
let l:job_list = get(l:info, 'job_list', [])
|
let l:job_list = get(l:info, 'job_list', [])
|
||||||
let l:linting_is_done = empty(l:job_list)
|
let l:lsp_command_list = get(l:info, 'lsp_command_list', [])
|
||||||
|
let l:linting_is_done = empty(l:job_list) && empty(l:lsp_command_list)
|
||||||
|
|
||||||
" Set signs first. This could potentially fix some line numbers.
|
" Set signs first. This could potentially fix some line numbers.
|
||||||
" The List could be sorted again here by SetSigns.
|
" The List could be sorted again here by SetSigns.
|
||||||
@ -498,17 +532,64 @@ function! ale#engine#StopCurrentJobs(buffer, include_lint_file_jobs) abort
|
|||||||
|
|
||||||
" Update the List, so it includes only the jobs we still need.
|
" Update the List, so it includes only the jobs we still need.
|
||||||
let l:info.job_list = l:new_job_list
|
let l:info.job_list = l:new_job_list
|
||||||
|
" Ignore current LSP commands.
|
||||||
|
" We should consider cancelling them in future.
|
||||||
|
let l:info.lsp_command_list = []
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:CheckWithTSServer(buffer, linter, executable) abort
|
||||||
|
let l:info = g:ale_buffer_info[a:buffer]
|
||||||
|
let l:open_documents = l:info.open_lsp_documents
|
||||||
|
let l:is_open = index(l:open_documents, a:linter.name) >= 0
|
||||||
|
|
||||||
|
if !l:is_open
|
||||||
|
call add(l:open_documents, a:linter.name)
|
||||||
|
call ale#lsp#SendMessageToProgram(
|
||||||
|
\ a:executable,
|
||||||
|
\ a:executable,
|
||||||
|
\ ale#lsp#tsserver_message#Open(a:buffer),
|
||||||
|
\)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call ale#lsp#SendMessageToProgram(
|
||||||
|
\ a:executable,
|
||||||
|
\ a:executable,
|
||||||
|
\ ale#lsp#tsserver_message#Change(a:buffer),
|
||||||
|
\)
|
||||||
|
|
||||||
|
let l:message = ale#lsp#tsserver_message#Geterr(a:buffer)
|
||||||
|
let l:request_id = ale#lsp#SendMessageToProgram(
|
||||||
|
\ a:executable,
|
||||||
|
\ a:executable,
|
||||||
|
\ l:message,
|
||||||
|
\ function('s:HandleLSPResponse'),
|
||||||
|
\)
|
||||||
|
|
||||||
|
if l:request_id > 0
|
||||||
|
let s:lsp_command_info_map[l:request_id] = {
|
||||||
|
\ 'buffer': a:buffer,
|
||||||
|
\ 'linter': a:linter,
|
||||||
|
\ 'message': l:message,
|
||||||
|
\}
|
||||||
|
call add(l:info.lsp_command_list, l:request_id)
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#engine#Invoke(buffer, linter) abort
|
function! ale#engine#Invoke(buffer, linter) abort
|
||||||
|
if empty(a:linter.lsp) || a:linter.lsp ==# 'tsserver'
|
||||||
let l:executable = has_key(a:linter, 'executable_callback')
|
let l:executable = has_key(a:linter, 'executable_callback')
|
||||||
\ ? ale#util#GetFunction(a:linter.executable_callback)(a:buffer)
|
\ ? ale#util#GetFunction(a:linter.executable_callback)(a:buffer)
|
||||||
\ : a:linter.executable
|
\ : a:linter.executable
|
||||||
|
|
||||||
" Run this program if it can be executed.
|
" Run this program if it can be executed.
|
||||||
if s:IsExecutable(l:executable)
|
if s:IsExecutable(l:executable)
|
||||||
|
if a:linter.lsp ==# 'tsserver'
|
||||||
|
call s:CheckWithTSServer(a:buffer, a:linter, l:executable)
|
||||||
|
else
|
||||||
call s:InvokeChain(a:buffer, a:linter, 0, [])
|
call s:InvokeChain(a:buffer, a:linter, 0, [])
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Given a buffer number, return the warnings and errors for a given buffer.
|
" Given a buffer number, return the warnings and errors for a given buffer.
|
||||||
|
@ -60,7 +60,7 @@ function! s:CreateTSServerMessageData(message) abort
|
|||||||
let l:obj.arguments = a:message[2]
|
let l:obj.arguments = a:message[2]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:data = json_encode(l:obj)
|
let l:data = json_encode(l:obj) . "\n"
|
||||||
return [l:is_notification ? 0 : l:obj.seq, l:data]
|
return [l:is_notification ? 0 : l:obj.seq, l:data]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@ -135,6 +135,16 @@ function! ale#lsp#ReadMessageData(data) abort
|
|||||||
return [l:remainder, l:response_list]
|
return [l:remainder, l:response_list]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:FindCallbackIDForType(callback_map, type) abort
|
||||||
|
for l:key in reverse(keys(a:callback_map))
|
||||||
|
if a:callback_map[l:key][1][1] ==# a:type
|
||||||
|
return str2nr(l:key)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ale#lsp#HandleMessage(conn, message) abort
|
function! ale#lsp#HandleMessage(conn, message) abort
|
||||||
let a:conn.data .= a:message
|
let a:conn.data .= a:message
|
||||||
|
|
||||||
@ -147,8 +157,15 @@ function! ale#lsp#HandleMessage(conn, message) abort
|
|||||||
\ ? l:response.seq
|
\ ? l:response.seq
|
||||||
\ : l:response.id
|
\ : l:response.id
|
||||||
|
|
||||||
let l:callback = a:conn.callback_map.pop(l:id)
|
if get(l:response, 'type', '') ==# 'event'
|
||||||
call ale#util#GetFunction(l:callback)(l:response)
|
\&& get(l:response, 'event', '') ==# 'semanticDiag'
|
||||||
|
let l:id = s:FindCallbackIDForType(a:conn.callback_map, 'ts@geterr')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(a:conn.callback_map, l:id)
|
||||||
|
let [l:Callback, l:message] = remove(a:conn.callback_map, l:id)
|
||||||
|
call ale#util#GetFunction(l:Callback)(l:id, l:response)
|
||||||
|
endif
|
||||||
endfor
|
endfor
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@ -190,8 +207,10 @@ function! ale#lsp#SendMessageToProgram(executable, command, message, ...) abort
|
|||||||
let [l:id, l:data] = ale#lsp#CreateMessageData(a:message)
|
let [l:id, l:data] = ale#lsp#CreateMessageData(a:message)
|
||||||
|
|
||||||
let l:matches = filter(s:connections[:], 'v:val.executable ==# a:executable')
|
let l:matches = filter(s:connections[:], 'v:val.executable ==# a:executable')
|
||||||
|
|
||||||
" Get the current connection or a new one.
|
" Get the current connection or a new one.
|
||||||
let l:conn = !empty(l:matches) ? l:matches[0] : s:NewConnection()
|
let l:conn = !empty(l:matches) ? l:matches[0] : s:NewConnection()
|
||||||
|
let l:conn.executable = a:executable
|
||||||
|
|
||||||
if !ale#job#IsRunning(l:conn.job_id)
|
if !ale#job#IsRunning(l:conn.job_id)
|
||||||
let l:options = {
|
let l:options = {
|
||||||
@ -199,6 +218,8 @@ function! ale#lsp#SendMessageToProgram(executable, command, message, ...) abort
|
|||||||
\ 'out_cb': function('s:HandleCommandMessage'),
|
\ 'out_cb': function('s:HandleCommandMessage'),
|
||||||
\}
|
\}
|
||||||
let l:job_id = ale#job#Start(ale#job#PrepareCommand(a:command), l:options)
|
let l:job_id = ale#job#Start(ale#job#PrepareCommand(a:command), l:options)
|
||||||
|
else
|
||||||
|
let l:job_id = l:conn.job_id
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if l:job_id <= 0
|
if l:job_id <= 0
|
||||||
@ -209,14 +230,14 @@ function! ale#lsp#SendMessageToProgram(executable, command, message, ...) abort
|
|||||||
" request for which the server must not return a response.
|
" request for which the server must not return a response.
|
||||||
if l:id != 0
|
if l:id != 0
|
||||||
" Add the callback, which the server will respond to later.
|
" Add the callback, which the server will respond to later.
|
||||||
let l:conn.callback_map[l:id] = a:1
|
let l:conn.callback_map[l:id] = [a:1, a:message]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call ale#job#SendRaw(l:job_id, l:data)
|
call ale#job#SendRaw(l:job_id, l:data)
|
||||||
|
|
||||||
let l:conn.job_id = l:job_id
|
let l:conn.job_id = l:job_id
|
||||||
|
|
||||||
return 1
|
return l:id
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Send a message to a server at a given address.
|
" Send a message to a server at a given address.
|
||||||
@ -252,7 +273,7 @@ function! ale#lsp#SendMessageToAddress(address, message, ...) abort
|
|||||||
" request for which the server must not return a response.
|
" request for which the server must not return a response.
|
||||||
if l:id != 0
|
if l:id != 0
|
||||||
" Add the callback, which the server will respond to later.
|
" Add the callback, which the server will respond to later.
|
||||||
let l:conn.callback_map[l:id] = a:1
|
let l:conn.callback_map[l:id] = [a:1, a:message]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ch_status(l:conn.channnel) ==# 'fail'
|
if ch_status(l:conn.channnel) ==# 'fail'
|
||||||
@ -261,4 +282,6 @@ function! ale#lsp#SendMessageToAddress(address, message, ...) abort
|
|||||||
|
|
||||||
" Send the message to the server
|
" Send the message to the server
|
||||||
call ch_sendraw(l:conn.channel, l:data)
|
call ch_sendraw(l:conn.channel, l:data)
|
||||||
|
|
||||||
|
return l:id
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -15,7 +15,7 @@ function! ale#lsp#response#ReadDiagnostics(params) abort
|
|||||||
for l:diagnostic in a:params.diagnostics
|
for l:diagnostic in a:params.diagnostics
|
||||||
let l:severity = get(l:diagnostic, 'severity', 0)
|
let l:severity = get(l:diagnostic, 'severity', 0)
|
||||||
let l:loclist_item = {
|
let l:loclist_item = {
|
||||||
\ 'message': l:diagnostic.message,
|
\ 'text': l:diagnostic.message,
|
||||||
\ 'type': 'E',
|
\ 'type': 'E',
|
||||||
\ 'lnum': l:diagnostic.range.start.line + 1,
|
\ 'lnum': l:diagnostic.range.start.line + 1,
|
||||||
\ 'col': l:diagnostic.range.start.character + 1,
|
\ 'col': l:diagnostic.range.start.character + 1,
|
||||||
@ -42,3 +42,26 @@ function! ale#lsp#response#ReadDiagnostics(params) abort
|
|||||||
|
|
||||||
return [l:filename, l:loclist]
|
return [l:filename, l:loclist]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale#lsp#response#ReadTSServerDiagnostics(response) abort
|
||||||
|
let l:loclist = []
|
||||||
|
|
||||||
|
for l:diagnostic in a:response.body.diagnostics
|
||||||
|
let l:loclist_item = {
|
||||||
|
\ 'text': l:diagnostic.text,
|
||||||
|
\ 'type': 'E',
|
||||||
|
\ 'lnum': l:diagnostic.start.line,
|
||||||
|
\ 'col': l:diagnostic.start.offset,
|
||||||
|
\ 'end_lnum': l:diagnostic.end.line,
|
||||||
|
\ 'end_col': l:diagnostic.end.offset,
|
||||||
|
\}
|
||||||
|
|
||||||
|
if has_key(l:diagnostic, 'code')
|
||||||
|
let l:loclist_item.nr = l:diagnostic.code
|
||||||
|
endif
|
||||||
|
|
||||||
|
call add(l:loclist, l:loclist_item)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:loclist
|
||||||
|
endfunction
|
||||||
|
@ -19,16 +19,19 @@ endfunction
|
|||||||
function! ale#lsp#tsserver_message#Change(buffer) abort
|
function! ale#lsp#tsserver_message#Change(buffer) abort
|
||||||
let l:lines = getbufline(a:buffer, 1, '$')
|
let l:lines = getbufline(a:buffer, 1, '$')
|
||||||
|
|
||||||
|
" We will always use a very high endLine number, so we can delete
|
||||||
|
" lines from files. tsserver will gladly accept line numbers beyond the
|
||||||
|
" end.
|
||||||
return [1, 'ts@change', {
|
return [1, 'ts@change', {
|
||||||
\ 'file': expand('#' . a:buffer . ':p'),
|
\ 'file': expand('#' . a:buffer . ':p'),
|
||||||
\ 'line': 1,
|
\ 'line': 1,
|
||||||
\ 'offset': 1,
|
\ 'offset': 1,
|
||||||
\ 'endLine': len(l:lines),
|
\ 'endLine': 1073741824 ,
|
||||||
\ 'endOffset': len(l:lines[-1]),
|
\ 'endOffset': 1,
|
||||||
\ 'insertString': join(l:lines, "\n"),
|
\ 'insertString': join(l:lines, "\n"),
|
||||||
\}]
|
\}]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#lsp#tsserver_message#Geterr(buffer) abort
|
function! ale#lsp#tsserver_message#Geterr(buffer) abort
|
||||||
return [1, 'ts@geterr', {'files': [expand('#' . a:buffer . ':p')]}]
|
return [0, 'ts@geterr', {'files': [expand('#' . a:buffer . ':p')]}]
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -127,8 +127,8 @@ Execute(ale#lsp#tsserver_message#Change() should return correct messages):
|
|||||||
\ 'file': b:dir . '/foo.ts',
|
\ 'file': b:dir . '/foo.ts',
|
||||||
\ 'line': 1,
|
\ 'line': 1,
|
||||||
\ 'offset': 1,
|
\ 'offset': 1,
|
||||||
\ 'endLine': 3,
|
\ 'endLine': 1073741824,
|
||||||
\ 'endOffset': 5,
|
\ 'endOffset': 1,
|
||||||
\ 'insertString': "foo()\nbar()\nbaz()",
|
\ 'insertString': "foo()\nbar()\nbaz()",
|
||||||
\ }
|
\ }
|
||||||
\ ],
|
\ ],
|
||||||
@ -139,7 +139,7 @@ Execute(ale#lsp#tsserver_message#Geterr() should return correct messages):
|
|||||||
|
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ [
|
\ [
|
||||||
\ 1,
|
\ 0,
|
||||||
\ 'ts@geterr',
|
\ 'ts@geterr',
|
||||||
\ {
|
\ {
|
||||||
\ 'files': [b:dir . '/foo.ts'],
|
\ 'files': [b:dir . '/foo.ts'],
|
||||||
|
@ -110,55 +110,63 @@ Execute(ale#lsp#CreateMessageData() should create tsserver notification messages
|
|||||||
AssertEqual
|
AssertEqual
|
||||||
\ [
|
\ [
|
||||||
\ 0,
|
\ 0,
|
||||||
\ '{"seq": null, "type": "request", "command": "someNotification"}',
|
\ '{"seq": null, "type": "request", "command": "someNotification"}'
|
||||||
|
\ . "\n",
|
||||||
\ ],
|
\ ],
|
||||||
\ ale#lsp#CreateMessageData([1, 'ts@someNotification'])
|
\ ale#lsp#CreateMessageData([1, 'ts@someNotification'])
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ [
|
\ [
|
||||||
\ 0,
|
\ 0,
|
||||||
\ '{"seq": null, "arguments": {"foo": "bar"}, "type": "request", "command": "someNotification"}',
|
\ '{"seq": null, "arguments": {"foo": "bar"}, "type": "request", "command": "someNotification"}'
|
||||||
|
\ . "\n",
|
||||||
\ ],
|
\ ],
|
||||||
\ ale#lsp#CreateMessageData([1, 'ts@someNotification', {'foo': 'bar'}])
|
\ ale#lsp#CreateMessageData([1, 'ts@someNotification', {'foo': 'bar'}])
|
||||||
else
|
else
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ [
|
\ [
|
||||||
\ 0,
|
\ 0,
|
||||||
\ '{"seq":null,"type":"request","command":"someNotification"}',
|
\ '{"seq":null,"type":"request","command":"someNotification"}'
|
||||||
|
\ . "\n",
|
||||||
\ ],
|
\ ],
|
||||||
\ ale#lsp#CreateMessageData([1, 'ts@someNotification'])
|
\ ale#lsp#CreateMessageData([1, 'ts@someNotification'])
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ [
|
\ [
|
||||||
\ 0,
|
\ 0,
|
||||||
\ '{"seq":null,"arguments":{"foo":"bar"},"type":"request","command":"someNotification"}',
|
\ '{"seq":null,"arguments":{"foo":"bar"},"type":"request","command":"someNotification"}'
|
||||||
|
\ . "\n",
|
||||||
\ ],
|
\ ],
|
||||||
\ ale#lsp#CreateMessageData([1, 'ts@someNotification', {'foo': 'bar'}])
|
\ ale#lsp#CreateMessageData([1, 'ts@someNotification', {'foo': 'bar'}])
|
||||||
endif
|
endif
|
||||||
|
|
||||||
Execute(ale#lsp#CreateMessageData() should create tsserver messages excepting responses):
|
Execute(ale#lsp#CreateMessageData() should create tsserver messages expecting responses):
|
||||||
if has('nvim')
|
if has('nvim')
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ [
|
\ [
|
||||||
\ 1,
|
\ 1,
|
||||||
\ '{"seq": 1, "type": "request", "command": "someMessage"}',
|
\ '{"seq": 1, "type": "request", "command": "someMessage"}'
|
||||||
|
\ . "\n",
|
||||||
\ ],
|
\ ],
|
||||||
\ ale#lsp#CreateMessageData([0, 'ts@someMessage'])
|
\ ale#lsp#CreateMessageData([0, 'ts@someMessage'])
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ [
|
\ [
|
||||||
\ 2,
|
\ 2,
|
||||||
\ '{"seq": 2, "arguments": {"foo": "bar"}, "type": "request", "command": "someMessage"}',
|
\ '{"seq": 2, "arguments": {"foo": "bar"}, "type": "request", "command": "someMessage"}'
|
||||||
|
\ . "\n",
|
||||||
\ ],
|
\ ],
|
||||||
\ ale#lsp#CreateMessageData([0, 'ts@someMessage', {'foo': 'bar'}])
|
\ ale#lsp#CreateMessageData([0, 'ts@someMessage', {'foo': 'bar'}])
|
||||||
else
|
else
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ [
|
\ [
|
||||||
\ 1,
|
\ 1,
|
||||||
\ '{"seq":1,"type":"request","command":"someMessage"}',
|
\ '{"seq":1,"type":"request","command":"someMessage"}'
|
||||||
|
\ . "\n",
|
||||||
\ ],
|
\ ],
|
||||||
\ ale#lsp#CreateMessageData([0, 'ts@someMessage'])
|
\ ale#lsp#CreateMessageData([0, 'ts@someMessage'])
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ [
|
\ [
|
||||||
\ 2,
|
\ 2,
|
||||||
\ '{"seq":2,"arguments":{"foo":"bar"},"type":"request","command":"someMessage"}',
|
\ '{"seq":2,"arguments":{"foo":"bar"},"type":"request","command":"someMessage"}'
|
||||||
|
\ . "\n",
|
||||||
\ ],
|
\ ],
|
||||||
\ ale#lsp#CreateMessageData([0, 'ts@someMessage', {'foo': 'bar'}])
|
\ ale#lsp#CreateMessageData([0, 'ts@someMessage', {'foo': 'bar'}])
|
||||||
endif
|
endif
|
||||||
|
@ -13,7 +13,7 @@ Execute(ale#lsp#response#ReadDiagnostics() should handle errors):
|
|||||||
AssertEqual ['filename.ts', [
|
AssertEqual ['filename.ts', [
|
||||||
\ {
|
\ {
|
||||||
\ 'type': 'E',
|
\ 'type': 'E',
|
||||||
\ 'message': 'Something went wrong!',
|
\ 'text': 'Something went wrong!',
|
||||||
\ 'lnum': 3,
|
\ 'lnum': 3,
|
||||||
\ 'col': 11,
|
\ 'col': 11,
|
||||||
\ 'end_lnum': 5,
|
\ 'end_lnum': 5,
|
||||||
@ -34,7 +34,7 @@ Execute(ale#lsp#response#ReadDiagnostics() should handle warnings):
|
|||||||
AssertEqual ['filename.ts', [
|
AssertEqual ['filename.ts', [
|
||||||
\ {
|
\ {
|
||||||
\ 'type': 'W',
|
\ 'type': 'W',
|
||||||
\ 'message': 'Something went wrong!',
|
\ 'text': 'Something went wrong!',
|
||||||
\ 'lnum': 2,
|
\ 'lnum': 2,
|
||||||
\ 'col': 4,
|
\ 'col': 4,
|
||||||
\ 'end_lnum': 2,
|
\ 'end_lnum': 2,
|
||||||
@ -55,7 +55,7 @@ Execute(ale#lsp#response#ReadDiagnostics() should treat messages with missing se
|
|||||||
AssertEqual ['filename.ts', [
|
AssertEqual ['filename.ts', [
|
||||||
\ {
|
\ {
|
||||||
\ 'type': 'E',
|
\ 'type': 'E',
|
||||||
\ 'message': 'Something went wrong!',
|
\ 'text': 'Something went wrong!',
|
||||||
\ 'lnum': 3,
|
\ 'lnum': 3,
|
||||||
\ 'col': 11,
|
\ 'col': 11,
|
||||||
\ 'end_lnum': 5,
|
\ 'end_lnum': 5,
|
||||||
@ -75,7 +75,7 @@ Execute(ale#lsp#response#ReadDiagnostics() should handle messages without codes)
|
|||||||
AssertEqual ['filename.ts', [
|
AssertEqual ['filename.ts', [
|
||||||
\ {
|
\ {
|
||||||
\ 'type': 'E',
|
\ 'type': 'E',
|
||||||
\ 'message': 'Something went wrong!',
|
\ 'text': 'Something went wrong!',
|
||||||
\ 'lnum': 3,
|
\ 'lnum': 3,
|
||||||
\ 'col': 11,
|
\ 'col': 11,
|
||||||
\ 'end_lnum': 5,
|
\ 'end_lnum': 5,
|
||||||
@ -93,7 +93,7 @@ Execute(ale#lsp#response#ReadDiagnostics() should handle multiple messages):
|
|||||||
AssertEqual ['filename.ts', [
|
AssertEqual ['filename.ts', [
|
||||||
\ {
|
\ {
|
||||||
\ 'type': 'E',
|
\ 'type': 'E',
|
||||||
\ 'message': 'Something went wrong!',
|
\ 'text': 'Something went wrong!',
|
||||||
\ 'lnum': 1,
|
\ 'lnum': 1,
|
||||||
\ 'col': 3,
|
\ 'col': 3,
|
||||||
\ 'end_lnum': 1,
|
\ 'end_lnum': 1,
|
||||||
@ -101,7 +101,7 @@ Execute(ale#lsp#response#ReadDiagnostics() should handle multiple messages):
|
|||||||
\ },
|
\ },
|
||||||
\ {
|
\ {
|
||||||
\ 'type': 'W',
|
\ 'type': 'W',
|
||||||
\ 'message': 'A warning',
|
\ 'text': 'A warning',
|
||||||
\ 'lnum': 2,
|
\ 'lnum': 2,
|
||||||
\ 'col': 5,
|
\ 'col': 5,
|
||||||
\ 'end_lnum': 2,
|
\ 'end_lnum': 2,
|
||||||
@ -119,3 +119,17 @@ Execute(ale#lsp#response#ReadDiagnostics() should handle multiple messages):
|
|||||||
\ 'message': 'A warning',
|
\ 'message': 'A warning',
|
||||||
\ },
|
\ },
|
||||||
\ ]})
|
\ ]})
|
||||||
|
|
||||||
|
Execute(ale#lsp#response#ReadTSServerDiagnostics() should handle tsserver responses):
|
||||||
|
AssertEqual [
|
||||||
|
\ {
|
||||||
|
\ 'type': 'E',
|
||||||
|
\ 'nr': 2365,
|
||||||
|
\ 'text': 'Operator ''''+'''' cannot be applied to types ''''3'''' and ''''{}''''.',
|
||||||
|
\ 'lnum': 1,
|
||||||
|
\ 'col': 11,
|
||||||
|
\ 'end_lnum': 1,
|
||||||
|
\ 'end_col': 17,
|
||||||
|
\ },
|
||||||
|
\],
|
||||||
|
\ ale#lsp#response#ReadTSServerDiagnostics({"seq":0,"type":"event","event":"semanticDiag","body":{"file":"/bar/foo.ts","diagnostics":[{"start":{"line":1,"offset":11},"end":{"line":1,"offset":17},"text":"Operator ''+'' cannot be applied to types ''3'' and ''{}''.","code":2365}]}})
|
||||||
|
Loading…
Reference in New Issue
Block a user