From 39c892eff4f167333e2a05472e0922cba5471a0d Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 10 Dec 2018 20:08:28 +0000 Subject: #1520 - Add an :ALEDocumentation for tsserver --- autoload/ale/hover.vim | 38 +++++++++++++++++++++++++++++++++++++- autoload/ale/test.vim | 10 ++++++++++ doc/ale.txt | 14 ++++++++++++++ plugin/ale.vim | 9 ++++++--- test/test_hover.vader | 20 ++++++++++++++++++++ 5 files changed, 87 insertions(+), 4 deletions(-) diff --git a/autoload/ale/hover.vim b/autoload/ale/hover.vim index 69db276e..490cc406 100644 --- a/autoload/ale/hover.vim +++ b/autoload/ale/hover.vim @@ -24,7 +24,21 @@ function! ale#hover#HandleTSServerResponse(conn_id, response) abort if get(a:response, 'success', v:false) is v:true \&& get(a:response, 'body', v:null) isnot v:null - if get(l:options, 'hover_from_balloonexpr', 0) + " If we pass the show_documentation flag, we should show the full + " documentation, and always in the preview window. + if get(l:options, 'show_documentation', 0) + let l:documentation = get(a:response.body, 'documentation', '') + + " displayString is not included here, because it can be very + " noisy and run on for many lines for complex types. A less + " verbose alternative may be nice in future. + if !empty(l:documentation) + call ale#preview#Show(split(l:documentation, "\n"), { + \ 'filetype': 'ale-preview.message', + \ 'stay_here': 1, + \}) + endif + elseif get(l:options, 'hover_from_balloonexpr', 0) \&& exists('*balloon_show') \&& ale#Var(l:options.buffer, 'set_balloons') call balloon_show(a:response.body.displayString) @@ -126,6 +140,7 @@ function! s:OnReady(linter, lsp_details, line, column, opt, ...) abort \ 'line': a:line, \ 'column': l:column, \ 'hover_from_balloonexpr': get(a:opt, 'called_from_balloonexpr', 0), + \ 'show_documentation': get(a:opt, 'show_documentation', 0), \} endfunction @@ -153,9 +168,30 @@ endfunction " - in the balloon if opt.called_from_balloonexpr and balloon_show is detected " - as status message otherwise function! ale#hover#Show(buffer, line, col, opt) abort + let l:show_documentation = get(a:opt, 'show_documentation', 0) + 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) endif endfor endfunction + +" This function implements the :ALEHover command. +function! ale#hover#ShowAtCursor() abort + let l:buffer = bufnr('') + let l:pos = getcurpos() + + call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], {}) +endfunction + +" This function implements the :ALEDocumentation command. +function! ale#hover#ShowDocumentationAtCursor() abort + let l:buffer = bufnr('') + let l:pos = getcurpos() + let l:options = {'show_documentation': 1} + + call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], l:options) +endfunction diff --git a/autoload/ale/test.vim b/autoload/ale/test.vim index 083b546f..e6ec70dc 100644 --- a/autoload/ale/test.vim +++ b/autoload/ale/test.vim @@ -75,3 +75,13 @@ function! ale#test#GetQflistWithoutModule() abort return l:results endfunction + +function! ale#test#GetPreviewWindowText() abort + for l:window in range(1, winnr('$')) + if getwinvar(l:window, '&previewwindow', 0) + let l:buffer = winbufnr(l:window) + + return getbufline(l:buffer, 1, '$') + endif + endfor +endfunction diff --git a/doc/ale.txt b/doc/ale.txt index 68d685d9..87d4e017 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -876,6 +876,9 @@ settings. For example: > set ttymouse=xterm < +Documentation for symbols at the cursor can be retrieved using the +|ALEDocumentation| command. This command is only available for `tsserver`. + ------------------------------------------------------------------------------- 5.5 Symbol Search *ale-symbol-search* @@ -2198,6 +2201,17 @@ ALE will use to search for Python executables. =============================================================================== 8. Commands/Keybinds *ale-commands* +ALEDocumentation *ALEDocumentation* + + Similar to the |ALEHover| command, retrieve documentation information for + the symbol at the cursor. Documentation data will always be shown in a + preview window, no matter how small the documentation content is. + + NOTE: This command is only available for `tsserver`. + + A plug mapping `(ale_documentation)` is defined for this command. + + ALEFindReferences *ALEFindReferences* Find references in the codebase for the symbol under the cursor using the diff --git a/plugin/ale.vim b/plugin/ale.vim index 7231d1bd..610ff142 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -193,9 +193,11 @@ command! -bar ALEGoToDefinitionInTab :call ale#definition#GoTo({'open_in_tab': 1 " Find references for tsserver and LSP command! -bar ALEFindReferences :call ale#references#Find() -" Get information for the cursor. -command! -bar ALEHover :call ale#hover#Show(bufnr(''), getcurpos()[1], - \ getcurpos()[2], {}) +" Show summary information for the cursor. +command! -bar ALEHover :call ale#hover#ShowAtCursor() + +" Show documentation for the cursor. +command! -bar ALEDocumentation :call ale#hover#ShowDocumentationAtCursor() " Search for appearances of a symbol, such as a type name or function name. command! -nargs=1 ALESymbolSearch :call ale#symbol#Search() @@ -222,6 +224,7 @@ nnoremap (ale_go_to_definition) :ALEGoToDefinition nnoremap (ale_go_to_definition_in_tab) :ALEGoToDefinitionInTab nnoremap (ale_find_references) :ALEFindReferences nnoremap (ale_hover) :ALEHover +nnoremap (ale_documentation) :ALEDocumentation " Set up autocmd groups now. call ale#events#Init() diff --git a/test/test_hover.vader b/test/test_hover.vader index a18fc651..13cfdbab 100644 --- a/test/test_hover.vader +++ b/test/test_hover.vader @@ -149,3 +149,23 @@ Execute(LSP hover response with lists of strings and marked strings should be ha AssertEqual ["foo\nbar\n"], g:echo_list AssertEqual {}, ale#hover#GetMap() + +Execute(tsserver responses for documentation requests should be handled): + call ale#hover#SetMap({3: {'show_documentation': 1}}) + + call ale#hover#HandleTSServerResponse( + \ 1, + \ { + \ 'command': 'quickinfo', + \ 'request_seq': 3, + \ 'success': v:true, + \ 'body': { + \ 'documentation': 'foo is a very good method', + \ 'displayString': 'foo bar', + \ }, + \ } + \) + + " The preview window should show the text. + AssertEqual ['foo is a very good method'], ale#test#GetPreviewWindowText() + silent! pclose -- cgit v1.2.3