diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 3eaf6e4..b5ea156 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -95,6 +95,12 @@ function! s:KillHandler(timer) abort endfunction function! ale#engine#ClearJob(job) abort + if get(g:, 'ale_run_synchronously') == 1 + call remove(s:job_info_map, a:job) + + return + endif + let l:job_id = s:GetJobID(a:job) if has('nvim') @@ -515,7 +521,26 @@ function! s:RunJob(options) abort let l:read_buffer = 0 endif - if has('nvim') + if !has('nvim') + " The command will be executed in a subshell. This fixes a number of + " issues, including reading the PATH variables correctly, %PATHEXT% + " expansion on Windows, etc. + " + " NeoVim handles this issue automatically if the command is a String. + let l:command = has('win32') + \ ? 'cmd /c ' . l:command + \ : split(&shell) + split(&shellcmdflag) + [l:command] + endif + + if get(g:, 'ale_run_synchronously') == 1 + " Find a unique Job value to use, which will be the same as the ID for + " running commands synchronously. This is only for test code. + let l:job = len(s:job_info_map) + 1 + + while has_key(s:job_info_map, l:job) + let l:job += 1 + endwhile + elseif has('nvim') if l:output_stream ==# 'stderr' " Read from stderr instead of stdout. let l:job = jobstart(l:command, { @@ -559,15 +584,6 @@ function! s:RunJob(options) abort let l:job_options.out_cb = function('s:GatherOutputVim') endif - " The command will be executed in a subshell. This fixes a number of - " issues, including reading the PATH variables correctly, %PATHEXT% - " expansion on Windows, etc. - " - " NeoVim handles this issue automatically if the command is a String. - let l:command = has('win32') - \ ? 'cmd /c ' . l:command - \ : split(&shell) + split(&shellcmdflag) + [l:command] - " Vim 8 will read the stdin from the file's buffer. let l:job = job_start(l:command, l:job_options) endif @@ -576,7 +592,9 @@ function! s:RunJob(options) abort let l:job_id = 0 " Only proceed if the job is being run. - if has('nvim') || (l:job !=# 'no process' && job_status(l:job) ==# 'run') + if has('nvim') + \ || get(g:, 'ale_run_synchronously') == 1 + \ || (l:job !=# 'no process' && job_status(l:job) ==# 'run') " Add the job to the list of jobs, so we can track them. call add(g:ale_buffer_info[l:buffer].job_list, l:job) @@ -596,6 +614,16 @@ function! s:RunJob(options) abort else let g:ale_buffer_info[l:buffer].history = [] endif + + if get(g:, 'ale_run_synchronously') == 1 + " Run a command synchronously if this test option is set. + let s:job_info_map[l:job_id].output = systemlist( + \ type(l:command) == type([]) + \ ? join(l:command[0:1]) . ' ' . shellescape(l:command[2]) + \ : l:command + \) + call s:HandleExit(l:job) + endif endfunction " Determine which commands to run for a link in a command chain, or diff --git a/test/c_tests/test_gcc.vader b/test/c_tests/test_gcc.vader new file mode 100644 index 0000000..67e4e42 --- /dev/null +++ b/test/c_tests/test_gcc.vader @@ -0,0 +1,63 @@ +Before: + Save g:ale_run_synchronously + Save g:ale_linters + Save g:ale_history_log_output + Save g:ale_cpp_gcc_options + + silent! cd /testplugin/test/c_tests + + let g:ale_run_synchronously = 1 + let g:ale_linters = {'c': ['gcc'], 'cpp': ['g++']} + let g:ale_history_log_output = 1 + let g:ale_cpp_gcc_options = '-Wall' + + function! GetCommandOutput() + if empty(g:ale_buffer_info[bufnr('')].history) + return '' + endif + + return join(g:ale_buffer_info[bufnr('')].history[-1].output, "\n") + endfunction + +After: + Restore + delfunction GetCommandOutput + call ale#linter#Reset() + call ale#engine#SetResults(bufnr(''), []) + call ale#cleanup#Buffer(bufnr('')) + +Given c (A test C file): + int main() { + return 0 + } + +Execute(Basic errors should be returned for GCC for C files): + call ale#Lint() + + AssertEqual [{ + \ 'lnum': 3, + \ 'col': 1, + \ }], + \ map(getloclist(0), '{''lnum'': v:val.lnum, ''col'': v:val.col}'), + \ 'No errors returned! Got: ' . GetCommandOutput() + + Assert match(getloclist(0)[0].text, '\v^expected .*;.* before .*\}.* token$') >= 0, + \ 'Invalid error text: ' . getloclist(0)[0].text + +Given cpp (A test C++ file): + int main() { + return 0 + } + +Execute(Basic errors should be returned for GCC for C++ files): + call ale#Lint() + + AssertEqual [{ + \ 'lnum': 3, + \ 'col': 1, + \ }], + \ map(getloclist(0), '{''lnum'': v:val.lnum, ''col'': v:val.col}'), + \ 'No errors returned! Got: ' . GetCommandOutput() + + Assert match(getloclist(0)[0].text, '\v^expected .*;.* before .*\}.* token$') >= 0, + \ 'Invalid error text: ' . getloclist(0)[0].text diff --git a/test/vimrc b/test/vimrc index 197be97..57af7e1 100644 --- a/test/vimrc +++ b/test/vimrc @@ -8,6 +8,7 @@ set runtimepath=/home/vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,/testplu filetype plugin indent on syntax on set shell=/bin/sh +set shellcmdflag=-c set nocompatible set tabstop=4 set softtabstop=4