diff options
-rw-r--r-- | PULL_REQUEST_TEMPLATE.md | 3 | ||||
-rw-r--r-- | ale_linters/d/dmd.vim | 2 | ||||
-rw-r--r-- | ale_linters/po/msgfmt.vim | 22 | ||||
-rw-r--r-- | ale_linters/sass/sasslint.vim | 5 | ||||
-rw-r--r-- | ale_linters/scss/sasslint.vim | 14 | ||||
-rw-r--r-- | autoload/ale/balloon.vim | 33 | ||||
-rw-r--r-- | autoload/ale/handlers/sasslint.vim | 8 | ||||
-rw-r--r-- | autoload/ale/hover.vim | 76 | ||||
-rw-r--r-- | doc/ale.txt | 18 | ||||
-rw-r--r-- | plugin/ale.vim | 8 | ||||
-rw-r--r-- | test/command_callback/test_sasslint_command_callback.vader | 12 | ||||
-rw-r--r-- | test/handler/test_msgfmt_hander.vader | 24 | ||||
-rw-r--r-- | test/smoke_test.vader | 2 | ||||
-rw-r--r-- | test/test_ale_toggle.vader | 10 |
14 files changed, 194 insertions, 43 deletions
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 94116532..e1ca94f6 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -12,7 +12,8 @@ READ THIS: Before creating a pull request, please consider the following first. that ALE can work with, please add Vader tests for them. Look at existing tests in the test/handler directory, etc. * If you add or modify a function for computing a command line string for - running a command, please add Vader tests for that. + running a command, please add Vader tests for that. Look at existing + tests in the test/command_callback directory, etc. * Generally try and cover anything with Vader tests, although some things just can't be tested with Vader, or at least they can be hard to test. Consider breaking up your code so that some parts can be tested, and generally open up diff --git a/ale_linters/d/dmd.vim b/ale_linters/d/dmd.vim index b91238ae..d64b6c3d 100644 --- a/ale_linters/d/dmd.vim +++ b/ale_linters/d/dmd.vim @@ -46,7 +46,7 @@ function! ale_linters#d#dmd#DMDCommand(buffer, dub_output) abort endif endfor - return 'dmd '. join(l:import_list) . ' -o- -vcolumns -c %t' + return 'dmd '. join(l:import_list) . ' -o- -wi -vcolumns -c %t' endfunction function! ale_linters#d#dmd#Handle(buffer, lines) abort diff --git a/ale_linters/po/msgfmt.vim b/ale_linters/po/msgfmt.vim index 578792bf..8279ccdc 100644 --- a/ale_linters/po/msgfmt.vim +++ b/ale_linters/po/msgfmt.vim @@ -1,10 +1,30 @@ " Author: Cian Butler https://github.com/butlerx " Description: msgfmt for PO files +function! ale_linters#po#msgfmt#Handle(buffer, lines) abort + let l:results = ale#handlers#unix#HandleAsWarning(a:buffer, a:lines) + let l:index = 0 + + for l:item in l:results + if l:index > 0 && l:item.text =~? 'this is the location of the first definition' + let l:last_item = l:results[l:index - 1] + + if l:last_item.text =~? 'duplicate message definition' + let l:last_item.text = 'duplicate of message at line ' . l:item.lnum + let l:item.text = 'first location of duplicate of message at line ' . l:last_item.lnum + endif + endif + + let l:index += 1 + endfor + + return l:results +endfunction + call ale#linter#Define('po', { \ 'name': 'msgfmt', \ 'executable': 'msgfmt', \ 'output_stream': 'stderr', \ 'command': 'msgfmt --statistics --output-file=- %t', -\ 'callback': 'ale#handlers#unix#HandleAsWarning', +\ 'callback': 'ale_linters#po#msgfmt#Handle', \}) diff --git a/ale_linters/sass/sasslint.vim b/ale_linters/sass/sasslint.vim index bbe71255..4df56dfd 100644 --- a/ale_linters/sass/sasslint.vim +++ b/ale_linters/sass/sasslint.vim @@ -1,8 +1,9 @@ -" Author: KabbAmine - https://github.com/KabbAmine +" Author: KabbAmine - https://github.com/KabbAmine, +" Ben Falconer <ben@falconers.me.uk> call ale#linter#Define('sass', { \ 'name': 'sasslint', \ 'executable': 'sass-lint', -\ 'command': 'sass-lint -v -q -f compact %t', +\ 'command_callback': 'ale#handlers#sasslint#GetCommand', \ 'callback': 'ale#handlers#css#HandleCSSLintFormat', \}) diff --git a/ale_linters/scss/sasslint.vim b/ale_linters/scss/sasslint.vim index bd016465..f6075001 100644 --- a/ale_linters/scss/sasslint.vim +++ b/ale_linters/scss/sasslint.vim @@ -1,8 +1,18 @@ -" Author: KabbAmine - https://github.com/KabbAmine +" Author: KabbAmine - https://github.com/KabbAmine, Ben Falconer +" <ben@falconers.me.uk> + +function! ale_linters#scss#sasslint#GetCommand(buffer) abort + return ale#path#BufferCdString(a:buffer) + \ . ale#Escape('sass-lint') + \ . ' -v' + \ . ' -q' + \ . ' -f compact' + \ . ' %t' +endfunction call ale#linter#Define('scss', { \ 'name': 'sasslint', \ 'executable': 'sass-lint', -\ 'command': 'sass-lint -v -q -f compact %t', +\ 'command_callback': 'ale_linters#scss#sasslint#GetCommand', \ 'callback': 'ale#handlers#css#HandleCSSLintFormat', \}) diff --git a/autoload/ale/balloon.vim b/autoload/ale/balloon.vim index 552ced82..d49dcbf9 100644 --- a/autoload/ale/balloon.vim +++ b/autoload/ale/balloon.vim @@ -12,7 +12,21 @@ 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 + elseif exists('*balloon_show') || getbufvar( + \ a:bufnr, + \ 'ale_set_balloons_legacy_echo', + \ get(g:, 'ale_set_balloons_legacy_echo', 0) + \) + " Request LSP/tsserver hover information, but only if this version of + " Vim supports the balloon_show function, or if we turned a legacy + " setting on. + call ale#hover#Show(a:bufnr, a:lnum, a:col, {'called_from_balloonexpr': 1}) + endif + + return '' endfunction function! ale#balloon#Expr() abort @@ -20,9 +34,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/handlers/sasslint.vim b/autoload/ale/handlers/sasslint.vim new file mode 100644 index 00000000..399bf47c --- /dev/null +++ b/autoload/ale/handlers/sasslint.vim @@ -0,0 +1,8 @@ +" Author: KabbAmine - https://github.com/KabbAmine, +" Ben Falconer <ben@falconers.me.uk> + +function! ale#handlers#sasslint#GetCommand(buffer) abort + return ale#path#BufferCdString(a:buffer) + \ . ale#Escape('sass-lint') + \ . ' -v -q -f compact %t' +endfunction diff --git a/autoload/ale/hover.vim b/autoload/ale/hover.vim index 12af877d..3bf92488 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 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 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 + 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/doc/ale.txt b/doc/ale.txt index 90686444..636ef12a 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1350,7 +1350,8 @@ g:ale_set_balloons *g:ale_set_balloons* *b:ale_set_balloons* Type: |Number| - Default: `has('balloon_eval')` + Default: `has('balloon_eval') && has('gui_running') ||` + `has('balloon_eval_term') && !has('gui_running')` When this option is set to `1`, balloon messages will be displayed for problems. Problems nearest to the cursor on the line the cursor is over will @@ -1362,6 +1363,21 @@ g:ale_set_balloons *g:ale_set_balloons* globally. +g:ale_set_balloons_legacy_echo *g:ale_set_balloons_legacy_echo* + *b:ale_set_balloons_legacy_echo* + Type: |Number| + Default: undefined + + If set to `1`, moving your mouse over documents in Vim will make ALE ask + `tsserver` or `LSP` servers for information about the symbol where the mouse + cursor is, and print that information into Vim's echo line. This is an + option for supporting older versions of Vim which do not properly support + balloons in an asynchronous manner. + + If your version of Vim supports the |balloon_show| function, then this + option does nothing meaningful. + + g:ale_set_highlights *g:ale_set_highlights* Type: |Number| diff --git a/plugin/ale.vim b/plugin/ale.vim index d59ffd6b..48ff531c 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -174,7 +174,10 @@ let g:ale_echo_cursor = get(g:, 'ale_echo_cursor', 1) let g:ale_echo_delay = get(g:, 'ale_echo_delay', 10) " This flag can be set to 0 to disable balloon support. -call ale#Set('set_balloons', has('balloon_eval')) +call ale#Set('set_balloons', +\ has('balloon_eval') && has('gui_running') || +\ has('balloon_eval_term') && !has('gui_running') +\) " A deprecated setting for ale#statusline#Status() " See :help ale#statusline#Count() for getting status reports. @@ -275,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], {}) " <Plug> mappings for commands nnoremap <silent> <Plug>(ale_previous) :ALEPrevious<Return> diff --git a/test/command_callback/test_sasslint_command_callback.vader b/test/command_callback/test_sasslint_command_callback.vader new file mode 100644 index 00000000..1db7e5fb --- /dev/null +++ b/test/command_callback/test_sasslint_command_callback.vader @@ -0,0 +1,12 @@ +Before: + call ale#test#SetDirectory('/testplugin/test/command_callback') + call ale#test#SetFilename('test.sass') + +After: + call ale#test#RestoreDirectory() + +Execute(The default sasslint command should be correct): + AssertEqual + \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && ' + \ . ale#Escape('sass-lint') . ' -v -q -f compact %t', + \ ale#handlers#sasslint#GetCommand(bufnr('')) diff --git a/test/handler/test_msgfmt_hander.vader b/test/handler/test_msgfmt_hander.vader new file mode 100644 index 00000000..1a67dbc6 --- /dev/null +++ b/test/handler/test_msgfmt_hander.vader @@ -0,0 +1,24 @@ +Before: + runtime ale_linters/po/msgfmt.vim + +After: + call ale#linter#Reset() + +Execute(Duplicate messages should be made easier to navigate): + AssertEqual + \ [ + \ {'lnum': 14, 'col': 0, 'type': 'W', 'text': 'some other thing'}, + \ {'lnum': 1746, 'col': 0, 'type': 'W', 'text': 'duplicate of message at line 262'}, + \ {'lnum': 262, 'col': 0, 'type': 'W', 'text': 'first location of duplicate of message at line 1746'}, + \ {'lnum': 666, 'col': 0, 'type': 'W', 'text': 'duplicate message definition...'}, + \ {'lnum': 888, 'col': 0, 'type': 'W', 'text': 'some other thing'}, + \ {'lnum': 999, 'col': 0, 'type': 'W', 'text': '...this is the location of the first definition'}, + \ ], + \ ale_linters#po#msgfmt#Handle(bufnr(''), [ + \ '/tmp/v6GMUFf/16/foo.po:14: some other thing', + \ '/tmp/v6GMUFf/16/foo.po:1746: duplicate message definition...', + \ '/tmp/v6GMUFf/16/foo.po:262: ...this is the location of the first definition', + \ '/tmp/v6GMUFf/16/foo.po:666: duplicate message definition...', + \ '/tmp/v6GMUFf/16/foo.po:888: some other thing', + \ '/tmp/v6GMUFf/16/foo.po:999: ...this is the location of the first definition', + \ ]) diff --git a/test/smoke_test.vader b/test/smoke_test.vader index f6d0be56..843bddab 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 [ \ { diff --git a/test/test_ale_toggle.vader b/test/test_ale_toggle.vader index ca8b25d5..427000b6 100644 --- a/test/test_ale_toggle.vader +++ b/test/test_ale_toggle.vader @@ -12,7 +12,9 @@ Before: let g:ale_run_synchronously = 1 let g:ale_pattern_options = {} let g:ale_pattern_options_enabled = 1 - let g:ale_set_balloons = has('balloon_eval') + let g:ale_set_balloons = + \ has('balloon_eval') && has('gui_running') || + \ has('balloon_eval_term') && !has('gui_running') unlet! b:ale_enabled @@ -349,7 +351,8 @@ Execute(ALEResetBuffer should reset everything for a buffer): Execute(Disabling ALE should disable balloons): " These tests won't run in the console, but we can run them manually in GVim. - if has('balloon_eval') + if has('balloon_eval') && has('gui_running') || + \ has('balloon_eval_term') && !has('gui_running') call ale#linter#Reset() " Enable balloons, so we can check the expr value. @@ -367,7 +370,8 @@ Execute(Disabling ALE should disable balloons): endif Execute(Enabling ALE should enable balloons if the setting is on): - if has('balloon_eval') + if has('balloon_eval') && has('gui_running') || + \ has('balloon_eval_term') && !has('gui_running') call ale#linter#Reset() call ale#balloon#Disable() ALEDisable |