summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autoload/ale/engine.vim33
-rw-r--r--doc/ale.txt16
-rw-r--r--plugin/ale.vim4
-rw-r--r--test/smoke_test.vader68
4 files changed, 105 insertions, 16 deletions
diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim
index 59c6de77..cd4c7b93 100644
--- a/autoload/ale/engine.vim
+++ b/autoload/ale/engine.vim
@@ -266,21 +266,22 @@ function! s:RunJob(options) abort
let l:job_options.out_cb = function('s:GatherOutputVim')
endif
- if has('win32')
- " job_start commands on Windows have to be run with cmd /c,
- " othwerwise %PATHTEXT% will not be used to programs ending int
- " .cmd, .bat, .exe, etc.
- let l:command = 'cmd /c ' . l:command
- else
- " Execute the command with the shell, to fix escaping issues.
- let l:command = split(&shell) + split(&shellcmdflag) + [l:command]
-
- if l:read_buffer
- " On Unix machines, we can send the Vim buffer directly.
- " This is faster than reading the lines ourselves.
- let l:job_options.in_io = 'buffer'
- let l:job_options.in_buf = l:buffer
- 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]
+
+ if l:read_buffer && !g:ale_use_ch_sendraw
+ " Send the buffer via internal Vim 8 mechanisms, rather than
+ " by reading and sending it ourselves.
+ " On Unix machines, we can send the Vim buffer directly.
+ " This is faster than reading the lines ourselves.
+ let l:job_options.in_io = 'buffer'
+ let l:job_options.in_buf = l:buffer
endif
" Vim 8 will read the stdin from the file's buffer.
@@ -307,7 +308,7 @@ function! s:RunJob(options) abort
call jobsend(l:job, l:input)
call jobclose(l:job, 'stdin')
- elseif has('win32')
+ elseif g:ale_use_ch_sendraw
" On some Vim versions, we have to send the buffer data ourselves.
let l:input = join(getbufline(l:buffer, 1, '$'), "\n") . "\n"
let l:channel = job_getchannel(l:job)
diff --git a/doc/ale.txt b/doc/ale.txt
index a4d476c3..4a8f0ecb 100644
--- a/doc/ale.txt
+++ b/doc/ale.txt
@@ -395,6 +395,22 @@ g:ale_statusline_format *g:ale_statusline_format*
- The 3rd element is for when no errors are detected
+g:ale_use_ch_sendraw *g:ale_use_ch_sendraw*
+
+ Type: |Number|
+ Default: `has('win32')`
+
+ This option only applies to Vim, and is ignored when the plugin is run
+ in NeoVim.
+
+ When this option is set to `1`, ALE will use |ch_sendraw()| for sending text
+ buffers to jobs, instead of setting the `in_io` option to `'buffer'` for
+ |job_start()|. See |in_io-buffer| for more information on this Vim option.
+
+ Using |ch_sendraw()| instead may lead to better performance or stability in
+ some cases. Typically for Linux users, `in_io` seems to be a better option.
+
+
g:ale_warn_about_trailing_whitespace *g:ale_warn_about_trailing_whitespace*
Type: |Number|
diff --git a/plugin/ale.vim b/plugin/ale.vim
index d65a99cb..13c681a0 100644
--- a/plugin/ale.vim
+++ b/plugin/ale.vim
@@ -66,6 +66,10 @@ let g:ale_lint_on_save = get(g:, 'ale_lint_on_save', 0)
" should be used instead.
let g:ale_enabled = get(g:, 'ale_enabled', 1)
+" This flag can be used to force ALE to send buffer data using ch_sendraw
+" in Vim 8. This works better for some users.
+let g:ale_use_ch_sendraw = get(g:, 'ale_use_ch_sendraw', has('win32'))
+
" These flags dictates if ale uses the quickfix or the loclist (loclist is the
" default, quickfix overrides loclist).
let g:ale_set_loclist = get(g:, 'ale_set_loclist', 1)
diff --git a/test/smoke_test.vader b/test/smoke_test.vader
new file mode 100644
index 00000000..9d0ea3f4
--- /dev/null
+++ b/test/smoke_test.vader
@@ -0,0 +1,68 @@
+Before:
+ function! TestCallback(buffer, output)
+ return [{
+ \ 'bufnr': a:buffer,
+ \ 'lnum': 2,
+ \ 'vcol': 0,
+ \ 'col': 3,
+ \ 'text': a:output[0],
+ \ 'type': 'E',
+ \ 'nr': -1,
+ \}]
+ endfunction
+
+ call ale#linter#Define('foobar', {
+ \ 'name': 'testlinter',
+ \ 'callback': 'TestCallback',
+ \ 'executable': 'echo',
+ \ 'command': 'echo foo bar',
+ \})
+
+After:
+ let g:ale_use_ch_sendraw = 0
+ let g:ale_buffer_info = {}
+ delfunction TestCallback
+ call ale#linter#Reset()
+
+Given foobar (Some imaginary filetype):
+ foo
+ bar
+ baz
+
+Execute(Linters should run with the default options):
+ AssertEqual 'foobar', &filetype
+
+ call ale#Lint()
+ call ale#engine#WaitForJobs(2000)
+
+ AssertEqual [{
+ \ 'bufnr': bufnr('%'),
+ \ 'lnum': 2,
+ \ 'vcol': 0,
+ \ 'col': 3,
+ \ 'text': 'foo bar',
+ \ 'type': 'E',
+ \ 'nr': -1,
+ \ 'pattern': '',
+ \ 'valid': 1,
+ \ }], getloclist(0)
+
+Execute(Linters should run with `let g:ale_use_ch_sendraw = 1`):
+ AssertEqual 'foobar', &filetype
+
+ let g:ale_use_ch_sendraw = 1
+
+ call ale#Lint()
+ call ale#engine#WaitForJobs(2000)
+
+ AssertEqual [{
+ \ 'bufnr': bufnr('%'),
+ \ 'lnum': 2,
+ \ 'vcol': 0,
+ \ 'col': 3,
+ \ 'text': 'foo bar',
+ \ 'type': 'E',
+ \ 'nr': -1,
+ \ 'pattern': '',
+ \ 'valid': 1,
+ \ }], getloclist(0)