Add nvim floating window support (replaces #3314) (#3470)

* Add nvim floating window hover support
* Add configuration for float to replace preview
* preview#ShowFloating: qualify local variables
* Configure floating preview usecases individually

Also:
  * Extract floating preview to its own file.
  * Ignore 'stay_here' option. Moving into the floating preview window
    seems confusing at best.
  * Re-use existing floating preview window if it's still up.
  * Flush out floating preview documentation.

* Watch cursor position changes per window

Floating previews open a new window, so when that window is written to,
it moves briefly there at a different position than the original window.
This makes repeated positions detected when positions are tracked at a
s: level. Instead, we change the variable to window scoped, which only
fires a message if the cursor has changed from the last position in
*that window*.

* g:ale_floating_preview cleanup
* floating_preview: add ALEDetail tests
* Fix fecs test missing runtime call
* Add ALEHover floating preview tests

Co-authored-by: Jan-Grimo Sobez <jan-grimo.sobez@phys.chem.ethz.ch>
This commit is contained in:
Kevin Clark
2021-01-14 10:06:20 -08:00
committed by GitHub
parent 97ce2423b0
commit 39f393ef07
8 changed files with 330 additions and 7 deletions

View File

@@ -1,5 +1,6 @@
Before:
call ale#assert#SetUpLinterTest('javascript', 'fecs')
runtime autoload/ale/handlers/fecs.vim
After:
call ale#assert#TearDownLinterTest()

View File

@@ -0,0 +1,92 @@
Before:
let g:ale_floating_preview = 0
let g:ale_hover_to_floating_preview = 0
let g:ale_detail_to_floating_preview = 0
runtime autoload/ale/floating_preview.vim
let g:floated_lines = []
let g:floating_preview_show_called = 0
" Stub out so we can track the call
function! ale#floating_preview#Show(lines, ...) abort
let g:floating_preview_show_called = 1
let g:floated_lines = a:lines
endfunction
let g:ale_buffer_info = {
\ bufnr('%'): {
\ 'loclist': [
\ {
\ 'lnum': 1,
\ 'col': 10,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
\ 'linter_name': 'notalinter',
\ 'nr': -1,
\ 'type': 'E',
\ 'code': 'semi',
\ 'text': "Missing semicolon.\r",
\ 'detail': "Every statement should end with a semicolon\nsecond line",
\ },
\ ],
\ }
\}
call ale#linter#Reset()
call ale#linter#PreventLoading('javascript')
After:
Restore
let g:ale_floating_preview = 0
let g:ale_hover_to_floating_preview = 0
let g:ale_detail_to_floating_preview = 0
call cursor(1, 1)
let g:ale_buffer_info = {}
" Close the preview window if it's open.
if &filetype is# 'ale-preview'
noautocmd :q!
endif
call ale#linter#Reset()
Given javascript(A file with warnings/errors):
var x = 3 + 12345678
var x = 5*2 + parseInt("10");
// comment
Execute(Floating preview is used with ALEDetail when g:ale_floating_preview set):
let g:ale_floating_preview = 1
call cursor(1, 10)
ALEDetail
let expected = ["Every statement should end with a semicolon", "second line"]
AssertEqual 1, g:floating_preview_show_called
AssertEqual expected, g:floated_lines
Execute(Floating preview is used with ALEDetail when g:ale_detail_to_floating_preview set):
let g:ale_detail_to_floating_preview = 1
call cursor(1, 10)
ALEDetail
let expected = ["Every statement should end with a semicolon", "second line"]
AssertEqual 1, g:floating_preview_show_called
AssertEqual expected, g:floated_lines
Execute(Floating preview is not used with ALEDetail by default):
call cursor(1, 10)
ALEDetail
AssertEqual 0, g:floating_preview_show_called

View File

@@ -7,9 +7,25 @@ Before:
let g:item_list = []
let g:show_message_arg_list = []
let g:ale_floating_preview = 0
let g:ale_hover_to_floating_preview = 0
let g:ale_detail_to_floating_preview = 0
runtime autoload/ale/linter.vim
runtime autoload/ale/lsp.vim
runtime autoload/ale/lsp_linter.vim
runtime autoload/ale/util.vim
runtime autoload/ale/floating_preview.vim
runtime autoload/ale/hover.vim
let g:floated_lines = []
let g:floating_preview_show_called = 0
" Stub out so we can track the call
function! ale#floating_preview#Show(lines, ...) abort
let g:floating_preview_show_called = 1
let g:floated_lines = a:lines
endfunction
function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort
let g:Callback = a:callback
@@ -50,6 +66,7 @@ Before:
\)
endfunction
After:
call ale#hover#SetMap({})
call ale#test#RestoreDirectory()
@@ -65,6 +82,7 @@ After:
runtime autoload/ale/lsp_linter.vim
runtime autoload/ale/lsp.vim
runtime autoload/ale/util.vim
runtime autoload/ale/floating_preview.vim
Given python(Some Python file):
foo
@@ -168,6 +186,28 @@ Execute(LSP hover response with lists of strings and marked strings should be ha
\], g:show_message_arg_list
AssertEqual {}, ale#hover#GetMap()
Execute(LSP hover with ale_floating_preview should float):
let g:ale_floating_preview = 1
call HandleValidLSPResult({'contents': "the message\ncontinuing"})
AssertEqual 1, g:floating_preview_show_called
AssertEqual ["the message", "continuing"], g:floated_lines
Execute(LSP hover ale_hover_to_floating_preview should float):
let g:ale_hover_to_floating_preview = 1
call HandleValidLSPResult({'contents': "the message\ncontinuing"})
AssertEqual 1, g:floating_preview_show_called
AssertEqual ["the message", "continuing"], g:floated_lines
Execute(LSP hover by default should not float):
call HandleValidLSPResult({'contents': "the message\ncontinuing"})
AssertEqual 0, g:floating_preview_show_called
Execute(tsserver responses for documentation requests should be handled):
call ale#hover#SetMap({3: {'show_documentation': 1, 'buffer': bufnr('')}})
@@ -187,3 +227,46 @@ Execute(tsserver responses for documentation requests should be handled):
" The preview window should show the text.
AssertEqual ['foo is a very good method'], ale#test#GetPreviewWindowText()
silent! pclose
Execute(hover with show_documentation should be in the preview window, not floating):
let g:ale_hover_to_floating_preview = 1
let g:ale_floating_preview = 1
call ale#hover#SetMap({3: {'show_documentation': 1, 'buffer': bufnr('')}})
call ale#hover#HandleTSServerResponse(
\ 1,
\ {
\ 'command': 'quickinfo',
\ 'request_seq': 3,
\ 'success': v:true,
\ 'body': {
\ 'documentation': 'foo is a very good method',
\ 'displayString': 'foo bar ',
\ },
\ }
\)
let expected = ["Every statement should end with a semicolon", "second line"]
AssertEqual 0, g:floating_preview_show_called
Execute(TSServer hover without show_documentation and ale_floating_preview should float):
let g:ale_floating_preview = 1
call ale#hover#SetMap({3: {'buffer': bufnr('')}})
call ale#hover#HandleTSServerResponse(
\ 1,
\ {
\ 'command': 'quickinfo',
\ 'request_seq': 3,
\ 'success': v:true,
\ 'body': {
\ 'displayString': "the message\ncontinuing",
\ },
\ }
\)
AssertEqual 1, g:floating_preview_show_called
AssertEqual ["the message", "continuing"], g:floated_lines