Fix #1115 - Add support for wrapping all commands with an option
This commit is contained in:
parent
2495744fc3
commit
e43e7065da
@ -512,7 +512,7 @@ function! s:RunJob(options) abort
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:command = ale#job#PrepareCommand(l:command)
|
let l:command = ale#job#PrepareCommand(l:buffer, l:command)
|
||||||
let l:job_options = {
|
let l:job_options = {
|
||||||
\ 'mode': 'nl',
|
\ 'mode': 'nl',
|
||||||
\ 'exit_cb': function('s:HandleExit'),
|
\ 'exit_cb': function('s:HandleExit'),
|
||||||
|
@ -222,7 +222,7 @@ function! s:RunJob(options) abort
|
|||||||
\)
|
\)
|
||||||
call s:CreateTemporaryFileForJob(l:buffer, l:temporary_file, l:input)
|
call s:CreateTemporaryFileForJob(l:buffer, l:temporary_file, l:input)
|
||||||
|
|
||||||
let l:command = ale#job#PrepareCommand(l:command)
|
let l:command = ale#job#PrepareCommand(l:buffer, l:command)
|
||||||
let l:job_options = {
|
let l:job_options = {
|
||||||
\ 'mode': 'nl',
|
\ 'mode': 'nl',
|
||||||
\ 'exit_cb': function('s:HandleExit'),
|
\ 'exit_cb': function('s:HandleExit'),
|
||||||
|
@ -165,23 +165,54 @@ function! ale#job#ValidateArguments(command, options) abort
|
|||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#job#PrepareCommand(command) abort
|
function! s:PrepareWrappedCommand(original_wrapper, command) abort
|
||||||
|
let l:match = matchlist(a:command, '\v^(.*(\&\&|;)) *(.*)$')
|
||||||
|
let l:prefix = ''
|
||||||
|
let l:command = a:command
|
||||||
|
|
||||||
|
if !empty(l:match)
|
||||||
|
let l:prefix = l:match[1] . ' '
|
||||||
|
let l:command = l:match[3]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:format = a:original_wrapper
|
||||||
|
|
||||||
|
if l:format =~# '%@'
|
||||||
|
let l:wrapped = substitute(l:format, '%@', ale#Escape(l:command), '')
|
||||||
|
else
|
||||||
|
if l:format !~# '%\*'
|
||||||
|
let l:format .= ' %*'
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:wrapped = substitute(l:format, '%\*', l:command, '')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:prefix . l:wrapped
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#job#PrepareCommand(buffer, command) abort
|
||||||
|
let l:wrapper = ale#Var(a:buffer, 'command_wrapper')
|
||||||
|
|
||||||
|
let l:command = !empty(l:wrapper)
|
||||||
|
\ ? s:PrepareWrappedCommand(l:wrapper, a:command)
|
||||||
|
\ : a:command
|
||||||
|
|
||||||
" The command will be executed in a subshell. This fixes a number of
|
" The command will be executed in a subshell. This fixes a number of
|
||||||
" issues, including reading the PATH variables correctly, %PATHEXT%
|
" issues, including reading the PATH variables correctly, %PATHEXT%
|
||||||
" expansion on Windows, etc.
|
" expansion on Windows, etc.
|
||||||
"
|
"
|
||||||
" NeoVim handles this issue automatically if the command is a String,
|
" NeoVim handles this issue automatically if the command is a String,
|
||||||
" but we'll do this explicitly, so we use thes same exact command for both
|
" but we'll do this explicitly, so we use the same exact command for both
|
||||||
" versions.
|
" versions.
|
||||||
if ale#Has('win32')
|
if has('win32')
|
||||||
return 'cmd /c ' . a:command
|
return 'cmd /c ' . l:command
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if &shell =~? 'fish$'
|
if &shell =~? 'fish$'
|
||||||
return ['/bin/sh', '-c', a:command]
|
return ['/bin/sh', '-c', l:command]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return split(&shell) + split(&shellcmdflag) + [a:command]
|
return split(&shell) + split(&shellcmdflag) + [l:command]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Start a job with options which are agnostic to Vim and NeoVim.
|
" Start a job with options which are agnostic to Vim and NeoVim.
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
call ale#Set('wrap_command_as_one_argument', 0)
|
||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
" Description: Linter registration and lazy-loading
|
" Description: Linter registration and lazy-loading
|
||||||
" Retrieves linters as requested by the engine, loading them if needed.
|
" Retrieves linters as requested by the engine, loading them if needed.
|
||||||
@ -432,6 +433,7 @@ function! ale#linter#StartLSP(buffer, linter, callback) abort
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
let l:command = ale#job#PrepareCommand(
|
let l:command = ale#job#PrepareCommand(
|
||||||
|
\ a:buffer,
|
||||||
\ ale#linter#GetCommand(a:buffer, a:linter),
|
\ ale#linter#GetCommand(a:buffer, a:linter),
|
||||||
\)
|
\)
|
||||||
let l:conn_id = ale#lsp#StartProgram(
|
let l:conn_id = ale#lsp#StartProgram(
|
||||||
|
33
doc/ale.txt
33
doc/ale.txt
@ -646,6 +646,39 @@ g:ale_change_sign_column_color *g:ale_change_sign_column_color*
|
|||||||
windows.
|
windows.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_command_wrapper *g:ale_command_wrapper*
|
||||||
|
*b:ale_command_wrapper*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
An option for wrapping all commands that ALE runs, for linters, fixers,
|
||||||
|
and LSP commands. This option can be set globally, or for specific buffers.
|
||||||
|
|
||||||
|
This option can be used to apply nice to all commands. For example: >
|
||||||
|
|
||||||
|
" Prefix all commands with nice.
|
||||||
|
let g:ale_command_wrapper = 'nice -n5'
|
||||||
|
<
|
||||||
|
Use the |ALEInfo| command to view the commands that are run. All of the
|
||||||
|
arguments for commands will be put on the end of the wrapped command by
|
||||||
|
default. A `%*` marker can be used to spread the arguments in the wrapped
|
||||||
|
command. >
|
||||||
|
|
||||||
|
" Has the same effect as the above.
|
||||||
|
let g:ale_command_wrapper = 'nice -n5 %*'
|
||||||
|
<
|
||||||
|
|
||||||
|
For passing all of the arguments for a command as one argument to a wrapper,
|
||||||
|
`%@` can be used instead. >
|
||||||
|
|
||||||
|
" Will result in say: /bin/bash -c 'other-wrapper -c "some command" -x'
|
||||||
|
let g:ale_command_wrapper = 'other-wrapper -c %@ -x'
|
||||||
|
<
|
||||||
|
For commands including `&&` or `;`, only the last command in the list will
|
||||||
|
be passed to the wrapper. `&&` is most commonly used in ALE to change the
|
||||||
|
working directory before running a command.
|
||||||
|
|
||||||
|
|
||||||
g:ale_completion_delay *g:ale_completion_delay*
|
g:ale_completion_delay *g:ale_completion_delay*
|
||||||
|
|
||||||
Type: |Number|
|
Type: |Number|
|
||||||
|
@ -209,6 +209,9 @@ call ale#Set('completion_enabled', 0)
|
|||||||
call ale#Set('completion_delay', 100)
|
call ale#Set('completion_delay', 100)
|
||||||
call ale#Set('completion_max_suggestions', 50)
|
call ale#Set('completion_max_suggestions', 50)
|
||||||
|
|
||||||
|
" A setting for wrapping commands.
|
||||||
|
call ale#Set('command_wrapper', '')
|
||||||
|
|
||||||
if g:ale_set_balloons
|
if g:ale_set_balloons
|
||||||
call ale#balloon#Enable()
|
call ale#balloon#Enable()
|
||||||
endif
|
endif
|
||||||
|
@ -581,8 +581,8 @@ Execute(Test fixing with chained callbacks):
|
|||||||
" The buffer shouldn't be piped in for earlier commands in the chain.
|
" The buffer shouldn't be piped in for earlier commands in the chain.
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ [
|
\ [
|
||||||
\ string(ale#job#PrepareCommand('echo echoline')),
|
\ string(ale#job#PrepareCommand(bufnr(''), 'echo echoline')),
|
||||||
\ string(ale#job#PrepareCommand('echo echoline')),
|
\ string(ale#job#PrepareCommand(bufnr(''), 'echo echoline')),
|
||||||
\ ],
|
\ ],
|
||||||
\ map(ale#history#Get(bufnr(''))[-2:-1], 'string(v:val.command)')
|
\ map(ale#history#Get(bufnr(''))[-2:-1], 'string(v:val.command)')
|
||||||
|
|
||||||
@ -635,7 +635,7 @@ Execute(A temporary file shouldn't be piped into the command when disabled):
|
|||||||
ALEFix
|
ALEFix
|
||||||
|
|
||||||
AssertEqual
|
AssertEqual
|
||||||
\ string(ale#job#PrepareCommand('echo new line')),
|
\ string(ale#job#PrepareCommand(bufnr(''), 'echo new line')),
|
||||||
\ string(ale#history#Get(bufnr(''))[-1].command)
|
\ string(ale#history#Get(bufnr(''))[-1].command)
|
||||||
|
|
||||||
" Remove trailing whitespace for Windows.
|
" Remove trailing whitespace for Windows.
|
||||||
|
@ -4,35 +4,36 @@ Before:
|
|||||||
|
|
||||||
After:
|
After:
|
||||||
Restore
|
Restore
|
||||||
let g:ale_has_override = {}
|
|
||||||
|
|
||||||
Execute(sh should be used when the shell is fish):
|
Execute(sh should be used when the shell is fish):
|
||||||
" Set something else, so we will replace that too.
|
if !has('win32')
|
||||||
let &shellcmdflag = '-f'
|
" Set something else, so we will replace that too.
|
||||||
let g:ale_has_override = {'win32': 0}
|
let &shellcmdflag = '-f'
|
||||||
|
let &shell = 'fish'
|
||||||
|
|
||||||
let &shell = 'fish'
|
AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand(bufnr(''), 'foobar')
|
||||||
|
|
||||||
AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand('foobar')
|
let &shell = '/usr/bin/fish'
|
||||||
|
|
||||||
let &shell = '/usr/bin/fish'
|
AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand(bufnr(''), 'foobar')
|
||||||
|
|
||||||
AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand('foobar')
|
let &shell = '/usr/local/bin/fish'
|
||||||
|
|
||||||
let &shell = '/usr/local/bin/fish'
|
AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand(bufnr(''), 'foobar')
|
||||||
|
endif
|
||||||
AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand('foobar')
|
|
||||||
|
|
||||||
Execute(Other shells should be used when set):
|
Execute(Other shells should be used when set):
|
||||||
let &shell = '/bin/bash'
|
if !has('win32')
|
||||||
let &shellcmdflag = '-c'
|
let &shell = '/bin/bash'
|
||||||
let g:ale_has_override = {'win32': 0}
|
let &shellcmdflag = '-c'
|
||||||
|
|
||||||
AssertEqual ['/bin/bash', '-c', 'foobar'], ale#job#PrepareCommand('foobar')
|
AssertEqual ['/bin/bash', '-c', 'foobar'], ale#job#PrepareCommand(bufnr(''), 'foobar')
|
||||||
|
endif
|
||||||
|
|
||||||
Execute(cmd /c as a string should be used on Windows):
|
Execute(cmd /c as a string should be used on Windows):
|
||||||
let &shell = 'who cares'
|
if has('win32')
|
||||||
let &shellcmdflag = 'whatever'
|
let &shell = 'who cares'
|
||||||
let g:ale_has_override = {'win32': 1}
|
let &shellcmdflag = 'whatever'
|
||||||
|
|
||||||
AssertEqual 'cmd /c foobar', ale#job#PrepareCommand('foobar')
|
AssertEqual 'cmd /c foobar', ale#job#PrepareCommand(bufnr(''), 'foobar')
|
||||||
|
endif
|
||||||
|
48
test/test_wrap_comand.vader
Normal file
48
test/test_wrap_comand.vader
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
Before:
|
||||||
|
Save g:ale_command_wrapper
|
||||||
|
|
||||||
|
let g:ale_command_wrapper = ''
|
||||||
|
|
||||||
|
function! TestCommand(expected_part, input) abort
|
||||||
|
let l:expected = has('win32')
|
||||||
|
\ ? 'cmd /c ' . a:expected_part
|
||||||
|
\ : split(&shell) + split(&shellcmdflag) + [a:expected_part]
|
||||||
|
|
||||||
|
AssertEqual l:expected, ale#job#PrepareCommand(bufnr(''), a:input)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
After:
|
||||||
|
Restore
|
||||||
|
|
||||||
|
unlet! b:ale_command_wrapper
|
||||||
|
|
||||||
|
delfunction TestCommand
|
||||||
|
|
||||||
|
Execute(The command wrapper should work with a nice command):
|
||||||
|
let b:ale_command_wrapper = 'nice -n 5'
|
||||||
|
|
||||||
|
call TestCommand('nice -n 5 foo bar', 'foo bar')
|
||||||
|
|
||||||
|
Execute(The command wrapper should work with a nice command with an explicit marker):
|
||||||
|
let b:ale_command_wrapper = 'nice -n 5 %*'
|
||||||
|
|
||||||
|
call TestCommand('nice -n 5 foo bar', 'foo bar')
|
||||||
|
|
||||||
|
Execute(Wrappers with spread arguments in the middle should be suppported):
|
||||||
|
let b:ale_command_wrapper = 'wrap %* --'
|
||||||
|
|
||||||
|
call TestCommand('wrap foo bar --', 'foo bar')
|
||||||
|
|
||||||
|
Execute(Wrappers with the command as one argument should be supported):
|
||||||
|
let b:ale_command_wrapper = 'wrap -c %@ -x'
|
||||||
|
|
||||||
|
call TestCommand('wrap -c ' . ale#Escape('foo bar') . ' -x', 'foo bar')
|
||||||
|
|
||||||
|
Execute(&& and ; should be moved to the front):
|
||||||
|
let b:ale_command_wrapper = 'wrap -c %@ -x'
|
||||||
|
|
||||||
|
call TestCommand('foo && bar; wrap -c ' . ale#Escape('baz') . ' -x', 'foo && bar;baz')
|
||||||
|
|
||||||
|
let b:ale_command_wrapper = 'nice -n 5'
|
||||||
|
|
||||||
|
call TestCommand('foo && bar; nice -n 5 baz -z', 'foo && bar;baz -z')
|
Loading…
Reference in New Issue
Block a user