diff --git a/autoload/ale/balloon.vim b/autoload/ale/balloon.vim index 552ced8..d36dd4f 100644 --- a/autoload/ale/balloon.vim +++ b/autoload/ale/balloon.vim @@ -12,7 +12,13 @@ function! ale#balloon#MessageForPos(bufnr, lnum, col) abort let l:loclist = get(g:ale_buffer_info, a:bufnr, {'loclist': []}).loclist let l:index = ale#util#BinarySearch(l:loclist, a:bufnr, a:lnum, a:col) - return l:index >= 0 ? l:loclist[l:index].text : '' + " Show the diagnostics message if found, 'Hover' output otherwise + if l:index >= 0 + return l:loclist[l:index].text + else + call ale#hover#Show(a:bufnr, a:lnum, a:col, {'called_from_balloonexpr': 1}) + return '' + endif endfunction function! ale#balloon#Expr() abort @@ -20,9 +26,22 @@ function! ale#balloon#Expr() abort endfunction function! ale#balloon#Disable() abort - set noballooneval balloonexpr= + set noballooneval noballoonevalterm + set balloonexpr= endfunction function! ale#balloon#Enable() abort - set ballooneval balloonexpr=ale#balloon#Expr() + if !has('balloon_eval') && !has('balloon_eval_term') + return + endif + + if has('balloon_eval') + set ballooneval + endif + + if has('balloon_eval_term') + set balloonevalterm + endif + + set balloonexpr=ale#balloon#Expr() endfunction diff --git a/autoload/ale/hover.vim b/autoload/ale/hover.vim index 12af877..3bf9248 100644 --- a/autoload/ale/hover.vim +++ b/autoload/ale/hover.vim @@ -24,7 +24,13 @@ 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 - call ale#util#ShowMessage(a:response.body.displayString) + if get(l:options, 'hover_from_balloonexpr', 0) + \&& exists('*balloon_show') + \&& ale#Var(l:options.buffer, 'set_balloons') + call balloon_show(a:response.body.displayString) + else + call ale#util#ShowMessage(a:response.body.displayString) + endif endif endif endfunction @@ -34,15 +40,18 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort \&& has_key(s:hover_map, a:response.id) let l:options = remove(s:hover_map, a:response.id) - let l:buffer = bufnr('') - let [l:line, l:column] = getcurpos()[1:2] - let l:end = len(getline(l:line)) + " If the call did __not__ come from balloonexpr... + if !get(l:options, 'hover_from_balloonexpr', 0) + let l:buffer = bufnr('') + let [l:line, l:column] = getcurpos()[1:2] + let l:end = len(getline(l:line)) - if l:buffer isnot l:options.buffer - \|| l:line isnot l:options.line - \|| min([l:column, l:end]) isnot min([l:options.column, l:end]) - " Cancel display the message if the cursor has moved. - return + if l:buffer isnot l:options.buffer + \|| l:line isnot l:options.line + \|| min([l:column, l:end]) isnot min([l:options.column, l:end]) + " ... Cancel display the message if the cursor has moved. + return + endif endif " The result can be a Dictionary item, a List of the same, or null. @@ -71,21 +80,24 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort let l:str = substitute(l:str, '^\s*\(.\{-}\)\s*$', '\1', '') if !empty(l:str) - call ale#util#ShowMessage(l:str) + if get(l:options, 'hover_from_balloonexpr', 0) + \&& exists('*balloon_show') + \&& ale#Var(l:options.buffer, 'set_balloons') + call balloon_show(l:str) + else + call ale#util#ShowMessage(l:str) + endif endif endif endif endfunction -function! s:ShowDetails(linter) abort - let l:buffer = bufnr('') - let [l:line, l:column] = getcurpos()[1:2] - +function! s:ShowDetails(linter, buffer, line, column, opt) abort let l:Callback = a:linter.lsp is# 'tsserver' \ ? function('ale#hover#HandleTSServerResponse') \ : function('ale#hover#HandleLSPResponse') - let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback) + let l:lsp_details = ale#linter#StartLSP(a:buffer, a:linter, l:Callback) if empty(l:lsp_details) return 0 @@ -95,34 +107,46 @@ function! s:ShowDetails(linter) abort let l:root = l:lsp_details.project_root if a:linter.lsp is# 'tsserver' + let l:column = a:column + let l:message = ale#lsp#tsserver_message#Quickinfo( - \ l:buffer, - \ l:line, + \ 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#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root) + call ale#lsp#Send(l:id, ale#lsp#message#DidChange(a:buffer), l:root) - let l:column = min([l:column, len(getline(l:line))]) + let l:column = min([a:column, len(getbufline(a:buffer, a:line)[0])]) - let l:message = ale#lsp#message#Hover(l:buffer, l:line, l:column) + 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:root) let s:hover_map[l:request_id] = { - \ 'buffer': l:buffer, - \ 'line': l:line, + \ 'buffer': a:buffer, + \ 'line': a:line, \ 'column': l:column, + \ 'hover_from_balloonexpr': get(a:opt, 'called_from_balloonexpr', 0), \} endfunction -function! ale#hover#Show() abort - for l:linter in ale#linter#Get(&filetype) +" Obtain Hover information for the specified position +" Pass optional arguments in the dictionary opt. +" Currently, only one key/value is useful: +" - called_from_balloonexpr, this flag marks if we want the result from this +" ale#hover#Show to display in a balloon if possible +" +" Currently, the callbacks displays the info from hover : +" - 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 + for l:linter in ale#linter#Get(getbufvar(a:buffer, '&filetype')) if !empty(l:linter.lsp) - call s:ShowDetails(l:linter) + call s:ShowDetails(l:linter, a:buffer, a:line, a:col, a:opt) endif endfor endfunction diff --git a/plugin/ale.vim b/plugin/ale.vim index a49bf68..48ff531 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -278,7 +278,8 @@ command! -bar ALEGoToDefinitionInTab :call ale#definition#GoTo({'open_in_tab': 1 command! -bar ALEFindReferences :call ale#references#Find() " Get information for the cursor. -command! -bar ALEHover :call ale#hover#Show() +command! -bar ALEHover :call ale#hover#Show(bufnr(''), getcurpos()[1], + \ getcurpos()[2], {}) " mappings for commands nnoremap (ale_previous) :ALEPrevious diff --git a/test/smoke_test.vader b/test/smoke_test.vader index f6d0be5..843bdda 100644 --- a/test/smoke_test.vader +++ b/test/smoke_test.vader @@ -93,7 +93,7 @@ Execute(Linters should run in PowerShell too): \}) call ale#Lint() - call ale#engine#WaitForJobs(2000) + call ale#engine#WaitForJobs(4000) AssertEqual [ \ {