diff options
author | w0rp <devw0rp@gmail.com> | 2017-11-21 00:21:45 +0000 |
---|---|---|
committer | w0rp <devw0rp@gmail.com> | 2017-11-21 00:21:45 +0000 |
commit | 7ea3aba5e587f1993c0377ed270b5cbd823e3711 (patch) | |
tree | a21347b43e4c6fb24dfe350e06eb7db1e21f7b3e /autoload | |
parent | 5a3a6955863fde86ef318a1fc6c3ad5d23429c0a (diff) | |
download | ale-7ea3aba5e587f1993c0377ed270b5cbd823e3711.zip |
Quietly add go to definition support for tsserver
Diffstat (limited to 'autoload')
-rw-r--r-- | autoload/ale/definition.vim | 82 | ||||
-rw-r--r-- | autoload/ale/lsp/tsserver_message.vim | 8 |
2 files changed, 90 insertions, 0 deletions
diff --git a/autoload/ale/definition.vim b/autoload/ale/definition.vim new file mode 100644 index 00000000..4b062b3e --- /dev/null +++ b/autoload/ale/definition.vim @@ -0,0 +1,82 @@ +" Author: w0rp <devw0rp@gmail.com> +" Description: Go to definition support for LSP linters. + +let s:go_to_definition_map = {} + +" Used to get the definition map in tests. +function! ale#definition#GetMap() abort + return deepcopy(s:go_to_definition_map) +endfunction + +" Used to set the definition map in tests. +function! ale#definition#SetMap(map) abort + let s:go_to_definition_map = a:map +endfunction + +" This function is used so we can check the execution of commands without +" running them. +function! ale#definition#Execute(expr) abort + execute a:expr +endfunction + +function! ale#definition#Open(options, filename, line, column) abort + if a:options.open_in_tab + call ale#definition#Execute('tabedit ' . fnameescape(a:filename)) + else + call ale#definition#Execute('edit ' . fnameescape(a:filename)) + endif + + call cursor(a:line, a:column) +endfunction + +function! ale#definition#HandleTSServerResponse(conn_id, response) abort + if get(a:response, 'command', '') is# 'definition' + \&& has_key(s:go_to_definition_map, a:response.request_seq) + let l:options = remove(s:go_to_definition_map, a:response.request_seq) + + if get(a:response, 'success', v:false) is v:true + let l:filename = a:response.body[0].file + let l:line = a:response.body[0].start.line + let l:column = a:response.body[0].start.offset + + call ale#definition#Open(l:options, l:filename, l:line, l:column) + endif + endif +endfunction + +function! s:GoToLSPDefinition(linter, options) abort + let l:buffer = bufnr('') + let [l:line, l:column] = getcurpos()[1:2] + + let l:lsp_details = ale#linter#StartLSP( + \ l:buffer, + \ a:linter, + \ function('ale#definition#HandleTSServerResponse'), + \) + + if empty(l:lsp_details) + return 0 + endif + + let l:id = l:lsp_details.connection_id + let l:root = l:lsp_details.project_root + + let l:message = ale#lsp#tsserver_message#Definition( + \ l:buffer, + \ l:line, + \ l:column + \) + 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! ale#definition#GoTo(options) abort + for l:linter in ale#linter#Get(&filetype) + if l:linter.lsp is# 'tsserver' + call s:GoToLSPDefinition(l:linter, a:options) + endif + endfor +endfunction diff --git a/autoload/ale/lsp/tsserver_message.vim b/autoload/ale/lsp/tsserver_message.vim index e2706ed5..b9bd7a01 100644 --- a/autoload/ale/lsp/tsserver_message.vim +++ b/autoload/ale/lsp/tsserver_message.vim @@ -53,3 +53,11 @@ function! ale#lsp#tsserver_message#CompletionEntryDetails(buffer, line, column, \ 'entryNames': a:entry_names, \}] endfunction + +function! ale#lsp#tsserver_message#Definition(buffer, line, column) abort + return [0, 'ts@definition', { + \ 'line': a:line, + \ 'offset': a:column, + \ 'file': expand('#' . a:buffer . ':p'), + \}] +endfunction |