mirror of
https://github.com/dense-analysis/ale.git
synced 2026-02-05 01:17:46 +08:00
#2132 - Replace command_chain and chain_with with ale#command#Run
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
let s:chain_results = []
|
||||
let s:command_output = []
|
||||
|
||||
function! ale#assert#WithChainResults(...) abort
|
||||
let s:chain_results = a:000
|
||||
function! ale#assert#GivenCommandOutput(...) abort
|
||||
let s:command_output = a:000
|
||||
endfunction
|
||||
|
||||
function! s:GetLinter() abort
|
||||
@@ -19,6 +19,39 @@ function! s:GetLinter() abort
|
||||
return l:filetype_linters[0]
|
||||
endfunction
|
||||
|
||||
function! s:FormatExe(command, executable) abort
|
||||
return substitute(a:command, '%e', '\=ale#Escape(a:executable)', 'g')
|
||||
endfunction
|
||||
|
||||
function! s:ProcessDeferredCommands(initial_result) abort
|
||||
let l:result = a:initial_result
|
||||
let l:command_index = 0
|
||||
let l:command = []
|
||||
|
||||
while ale#command#IsDeferred(l:result)
|
||||
call add(l:command, s:FormatExe(l:result.command, l:result.executable))
|
||||
|
||||
if get(g:, 'ale_run_synchronously_emulate_commands')
|
||||
" Don't run commands, but simulate the results.
|
||||
let l:Callback = g:ale_run_synchronously_callbacks[0]
|
||||
let l:output = get(s:command_output, l:command_index, [])
|
||||
call l:Callback(0, l:output)
|
||||
unlet g:ale_run_synchronously_callbacks
|
||||
|
||||
let l:command_index += 1
|
||||
else
|
||||
" Run the commands in the shell, synchronously.
|
||||
call ale#test#FlushJobs()
|
||||
endif
|
||||
|
||||
let l:result = l:result.value
|
||||
endwhile
|
||||
|
||||
call add(l:command, l:result)
|
||||
|
||||
return l:command
|
||||
endfunction
|
||||
|
||||
" Load the currently loaded linter for a test case, and check that the command
|
||||
" matches the given string.
|
||||
function! ale#assert#Linter(expected_executable, expected_command) abort
|
||||
@@ -31,47 +64,20 @@ function! ale#assert#Linter(expected_executable, expected_command) abort
|
||||
let l:executable = l:executable.value
|
||||
endwhile
|
||||
|
||||
if has_key(l:linter, 'command_chain')
|
||||
let l:callbacks = map(copy(l:linter.command_chain), 'v:val.callback')
|
||||
let l:command = s:ProcessDeferredCommands(
|
||||
\ ale#linter#GetCommand(l:buffer, l:linter),
|
||||
\)
|
||||
|
||||
" If the expected command is a string, just check the last one.
|
||||
if type(a:expected_command) is v:t_string
|
||||
if len(l:callbacks) is 1
|
||||
let l:command = call(l:callbacks[0], [l:buffer])
|
||||
else
|
||||
let l:input = get(s:chain_results, len(l:callbacks) - 2, [])
|
||||
let l:command = call(l:callbacks[-1], [l:buffer, l:input])
|
||||
endif
|
||||
else
|
||||
let l:command = []
|
||||
let l:chain_index = 0
|
||||
|
||||
for l:Callback in l:callbacks
|
||||
if l:chain_index is 0
|
||||
call add(l:command, call(l:Callback, [l:buffer]))
|
||||
else
|
||||
let l:input = get(s:chain_results, l:chain_index - 1, [])
|
||||
call add(l:command, call(l:Callback, [l:buffer, l:input]))
|
||||
endif
|
||||
|
||||
let l:chain_index += 1
|
||||
endfor
|
||||
endif
|
||||
else
|
||||
let l:command = ale#linter#GetCommand(l:buffer, l:linter)
|
||||
|
||||
while ale#command#IsDeferred(l:command)
|
||||
call ale#test#FlushJobs()
|
||||
let l:command = l:command.value
|
||||
endwhile
|
||||
if type(a:expected_command) isnot v:t_list
|
||||
let l:command = l:command[-1]
|
||||
endif
|
||||
|
||||
if type(l:command) is v:t_string
|
||||
" Replace %e with the escaped executable, so tests keep passing after
|
||||
" linters are changed to use %e.
|
||||
let l:command = substitute(l:command, '%e', '\=ale#Escape(l:executable)', 'g')
|
||||
let l:command = s:FormatExe(l:command, l:executable)
|
||||
elseif type(l:command) is v:t_list
|
||||
call map(l:command, 'substitute(v:val, ''%e'', ''\=ale#Escape(l:executable)'', ''g'')')
|
||||
call map(l:command, 's:FormatExe(v:val, l:executable)')
|
||||
endif
|
||||
|
||||
AssertEqual
|
||||
@@ -79,6 +85,17 @@ function! ale#assert#Linter(expected_executable, expected_command) abort
|
||||
\ [l:executable, l:command]
|
||||
endfunction
|
||||
|
||||
function! ale#assert#Fixer(expected_result) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))
|
||||
|
||||
if type(a:expected_result) isnot v:t_list
|
||||
let l:result = l:result[-1]
|
||||
endif
|
||||
|
||||
AssertEqual a:expected_result, l:result
|
||||
endfunction
|
||||
|
||||
function! ale#assert#LinterNotExecuted() abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
@@ -128,7 +145,7 @@ function! ale#assert#LSPAddress(expected_address) abort
|
||||
endfunction
|
||||
|
||||
function! ale#assert#SetUpLinterTestCommands() abort
|
||||
command! -nargs=+ WithChainResults :call ale#assert#WithChainResults(<args>)
|
||||
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
|
||||
command! -nargs=+ AssertLinter :call ale#assert#Linter(<args>)
|
||||
command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted()
|
||||
command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions(<args>)
|
||||
@@ -138,6 +155,11 @@ function! ale#assert#SetUpLinterTestCommands() abort
|
||||
command! -nargs=+ AssertLSPAddress :call ale#assert#LSPAddress(<args>)
|
||||
endfunction
|
||||
|
||||
function! ale#assert#SetUpFixerTestCommands() abort
|
||||
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
|
||||
command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>)
|
||||
endfunction
|
||||
|
||||
" A dummy function for making sure this module is loaded.
|
||||
function! ale#assert#SetUpLinterTest(filetype, name) abort
|
||||
" Set up a marker so ALE doesn't create real random temporary filenames.
|
||||
@@ -179,14 +201,21 @@ function! ale#assert#SetUpLinterTest(filetype, name) abort
|
||||
endif
|
||||
|
||||
call ale#assert#SetUpLinterTestCommands()
|
||||
|
||||
let g:ale_run_synchronously = 1
|
||||
let g:ale_run_synchronously_emulate_commands = 1
|
||||
endfunction
|
||||
|
||||
function! ale#assert#TearDownLinterTest() abort
|
||||
unlet! g:ale_create_dummy_temporary_file
|
||||
let s:chain_results = []
|
||||
unlet! g:ale_run_synchronously
|
||||
unlet! g:ale_run_synchronously_callbacks
|
||||
unlet! g:ale_run_synchronously_emulate_commands
|
||||
unlet! g:ale_run_synchronously_command_results
|
||||
let s:command_output = []
|
||||
|
||||
if exists(':WithChainResults')
|
||||
delcommand WithChainResults
|
||||
if exists(':GivenCommandOutput')
|
||||
delcommand GivenCommandOutput
|
||||
endif
|
||||
|
||||
if exists(':AssertLinter')
|
||||
@@ -229,3 +258,62 @@ function! ale#assert#TearDownLinterTest() abort
|
||||
call ale#semver#ResetVersionCache()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#assert#SetUpFixerTest(filetype, name) abort
|
||||
" Set up a marker so ALE doesn't create real random temporary filenames.
|
||||
let g:ale_create_dummy_temporary_file = 1
|
||||
|
||||
let l:function_name = ale#fix#registry#GetFunc(a:name)
|
||||
let s:FixerFunction = function(l:function_name)
|
||||
|
||||
let l:prefix = 'ale_' . a:filetype . '_' . a:name
|
||||
let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix'
|
||||
|
||||
for l:key in filter(keys(g:), b:filter_expr)
|
||||
execute 'Save g:' . l:key
|
||||
unlet g:[l:key]
|
||||
endfor
|
||||
|
||||
for l:key in filter(keys(b:), b:filter_expr)
|
||||
unlet b:[l:key]
|
||||
endfor
|
||||
|
||||
execute 'runtime autoload/ale/fixers/' . a:name . '.vim'
|
||||
|
||||
if !exists('g:dir')
|
||||
call ale#test#SetDirectory('/testplugin/test/fixers')
|
||||
endif
|
||||
|
||||
call ale#assert#SetUpFixerTestCommands()
|
||||
|
||||
let g:ale_run_synchronously = 1
|
||||
let g:ale_run_synchronously_emulate_commands = 1
|
||||
endfunction
|
||||
|
||||
function! ale#assert#TearDownFixerTest() abort
|
||||
unlet! g:ale_create_dummy_temporary_file
|
||||
unlet! g:ale_run_synchronously
|
||||
unlet! g:ale_run_synchronously_callbacks
|
||||
unlet! g:ale_run_synchronously_emulate_commands
|
||||
unlet! g:ale_run_synchronously_command_results
|
||||
let s:command_output = []
|
||||
unlet! s:FixerFunction
|
||||
|
||||
if exists('g:dir')
|
||||
call ale#test#RestoreDirectory()
|
||||
endif
|
||||
|
||||
Restore
|
||||
|
||||
if exists('*ale#semver#ResetVersionCache')
|
||||
call ale#semver#ResetVersionCache()
|
||||
endif
|
||||
|
||||
if exists(':GivenCommandOutput')
|
||||
delcommand GivenCommandOutput
|
||||
endif
|
||||
|
||||
if exists(':AssertFixer')
|
||||
delcommand AssertFixer
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@@ -284,6 +284,20 @@ function! ale#c#GetMakeCommand(buffer) abort
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale#c#RunMakeCommand(buffer, Callback) abort
|
||||
let l:command = ale#c#GetMakeCommand(a:buffer)
|
||||
|
||||
if empty(l:command)
|
||||
return a:Callback(a:buffer, [])
|
||||
endif
|
||||
|
||||
return ale#command#Run(
|
||||
\ a:buffer,
|
||||
\ l:command,
|
||||
\ {b, output -> a:Callback(a:buffer, output)},
|
||||
\)
|
||||
endfunction
|
||||
|
||||
" Given a buffer number, search for a project root, and output a List
|
||||
" of directories to include based on some heuristics.
|
||||
"
|
||||
|
||||
@@ -329,30 +329,46 @@ function! ale#command#Run(buffer, command, Callback, ...) abort
|
||||
"
|
||||
" The `_deferred_job_id` is used for both checking the type of object, and
|
||||
" for checking the job ID and status.
|
||||
let l:result = {'_deferred_job_id': l:job_id}
|
||||
"
|
||||
" The original command here is used in tests.
|
||||
let l:result = {
|
||||
\ '_deferred_job_id': l:job_id,
|
||||
\ 'executable': get(l:options, 'executable', ''),
|
||||
\ 'command': a:command,
|
||||
\}
|
||||
|
||||
if get(g:, 'ale_run_synchronously') == 1 && l:job_id
|
||||
" Run a command synchronously if this test option is set.
|
||||
call extend(l:line_list, systemlist(
|
||||
\ type(l:command) is v:t_list
|
||||
\ ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2])
|
||||
\ : l:command
|
||||
\))
|
||||
|
||||
" Don't capture output when the callbacks aren't set.
|
||||
if !has_key(l:job_options, 'out_cb')
|
||||
\&& !has_key(l:job_options, 'err_cb')
|
||||
let l:line_list = []
|
||||
endif
|
||||
|
||||
if !exists('g:ale_run_synchronously_callbacks')
|
||||
let g:ale_run_synchronously_callbacks = []
|
||||
endif
|
||||
|
||||
call add(
|
||||
\ g:ale_run_synchronously_callbacks,
|
||||
\ {-> l:job_options.exit_cb(l:job_id, v:shell_error)}
|
||||
\)
|
||||
if get(g:, 'ale_run_synchronously_emulate_commands', 0)
|
||||
call add(
|
||||
\ g:ale_run_synchronously_callbacks,
|
||||
\ {exit_code, output -> [
|
||||
\ extend(l:line_list, output),
|
||||
\ l:job_options.exit_cb(l:job_id, exit_code),
|
||||
\ ]}
|
||||
\)
|
||||
else
|
||||
" Run a command synchronously if this test option is set.
|
||||
call extend(l:line_list, systemlist(
|
||||
\ type(l:command) is v:t_list
|
||||
\ ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2])
|
||||
\ : l:command
|
||||
\))
|
||||
|
||||
" Don't capture output when the callbacks aren't set.
|
||||
if !has_key(l:job_options, 'out_cb')
|
||||
\&& !has_key(l:job_options, 'err_cb')
|
||||
let l:line_list = []
|
||||
endif
|
||||
|
||||
call add(
|
||||
\ g:ale_run_synchronously_callbacks,
|
||||
\ {-> l:job_options.exit_cb(l:job_id, v:shell_error)}
|
||||
\)
|
||||
endif
|
||||
endif
|
||||
|
||||
return l:result
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
" Author: Auri <me@aurieh.me>
|
||||
" Description: Functions for integrating with D linters.
|
||||
|
||||
function! otherproject#util#Double(x) abort
|
||||
return a:x * 2
|
||||
endfunction
|
||||
|
||||
function! ale#d#FindDUBConfig(buffer) abort
|
||||
" Find a DUB configuration file in ancestor paths.
|
||||
" The most DUB-specific names will be tried first.
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
|
||||
function! ale#fixers#eslint#Fix(buffer) abort
|
||||
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
|
||||
let l:command = ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ' --version'
|
||||
|
||||
let l:command = ale#semver#HasVersion(l:executable)
|
||||
\ ? ''
|
||||
\ : ale#node#Executable(a:buffer, l:executable) . ' --version'
|
||||
|
||||
return {
|
||||
\ 'command': l:command,
|
||||
\ 'chain_with': 'ale#fixers#eslint#ApplyFixForVersion',
|
||||
\}
|
||||
return ale#semver#RunWithVersionCheck(
|
||||
\ a:buffer,
|
||||
\ l:executable,
|
||||
\ l:command,
|
||||
\ function('ale#fixers#eslint#ApplyFixForVersion'),
|
||||
\)
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#eslint#ProcessFixDryRunOutput(buffer, output) abort
|
||||
@@ -33,10 +33,8 @@ function! ale#fixers#eslint#ProcessEslintDOutput(buffer, output) abort
|
||||
return a:output
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#eslint#ApplyFixForVersion(buffer, version_output) abort
|
||||
function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
|
||||
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
|
||||
|
||||
let l:config = ale#handlers#eslint#FindConfig(a:buffer)
|
||||
|
||||
if empty(l:config)
|
||||
@@ -44,7 +42,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version_output) abort
|
||||
endif
|
||||
|
||||
" Use --fix-to-stdout with eslint_d
|
||||
if l:executable =~# 'eslint_d$' && ale#semver#GTE(l:version, [3, 19, 0])
|
||||
if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
|
||||
return {
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ' --stdin-filename %s --stdin --fix-to-stdout',
|
||||
@@ -53,7 +51,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version_output) abort
|
||||
endif
|
||||
|
||||
" 4.9.0 is the first version with --fix-dry-run
|
||||
if ale#semver#GTE(l:version, [4, 9, 0])
|
||||
if ale#semver#GTE(a:version, [4, 9, 0])
|
||||
return {
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
|
||||
|
||||
@@ -15,16 +15,12 @@ function! ale#fixers#prettier#GetExecutable(buffer) abort
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#prettier#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#prettier#GetExecutable(a:buffer)
|
||||
|
||||
let l:command = ale#semver#HasVersion(l:executable)
|
||||
\ ? ''
|
||||
\ : ale#Escape(l:executable) . ' --version'
|
||||
|
||||
return {
|
||||
\ 'command': l:command,
|
||||
\ 'chain_with': 'ale#fixers#prettier#ApplyFixForVersion',
|
||||
\}
|
||||
return ale#semver#RunWithVersionCheck(
|
||||
\ a:buffer,
|
||||
\ ale#fixers#prettier#GetExecutable(a:buffer),
|
||||
\ '%e --version',
|
||||
\ function('ale#fixers#prettier#ApplyFixForVersion'),
|
||||
\)
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort
|
||||
@@ -38,10 +34,9 @@ function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort
|
||||
return a:output
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort
|
||||
function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
|
||||
let l:executable = ale#fixers#prettier#GetExecutable(a:buffer)
|
||||
let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
|
||||
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
|
||||
let l:parser = ''
|
||||
|
||||
" Append the --parser flag depending on the current filetype (unless it's
|
||||
@@ -50,7 +45,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort
|
||||
" Mimic Prettier's defaults. In cases without a file extension or
|
||||
" filetype (scratch buffer), Prettier needs `parser` set to know how
|
||||
" to process the buffer.
|
||||
if ale#semver#GTE(l:version, [1, 16, 0])
|
||||
if ale#semver#GTE(a:version, [1, 16, 0])
|
||||
let l:parser = 'babel'
|
||||
else
|
||||
let l:parser = 'babylon'
|
||||
@@ -94,7 +89,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort
|
||||
endif
|
||||
|
||||
" 1.4.0 is the first version with --stdin-filepath
|
||||
if ale#semver#GTE(l:version, [1, 4, 0])
|
||||
if ale#semver#GTE(a:version, [1, 4, 0])
|
||||
return {
|
||||
\ 'command': ale#path#BufferCdString(a:buffer)
|
||||
\ . ale#Escape(l:executable)
|
||||
|
||||
@@ -2,13 +2,9 @@
|
||||
" w0rp <devw0rp@gmail.com>, morhetz (Pavel Pertsev) <morhetz@gmail.com>
|
||||
" Description: Integration between Prettier and ESLint.
|
||||
|
||||
function! ale#fixers#prettier_eslint#SetOptionDefaults() abort
|
||||
call ale#Set('javascript_prettier_eslint_executable', 'prettier-eslint')
|
||||
call ale#Set('javascript_prettier_eslint_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('javascript_prettier_eslint_options', '')
|
||||
endfunction
|
||||
|
||||
call ale#fixers#prettier_eslint#SetOptionDefaults()
|
||||
call ale#Set('javascript_prettier_eslint_executable', 'prettier-eslint')
|
||||
call ale#Set('javascript_prettier_eslint_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('javascript_prettier_eslint_options', '')
|
||||
|
||||
function! ale#fixers#prettier_eslint#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'javascript_prettier_eslint', [
|
||||
@@ -18,26 +14,20 @@ function! ale#fixers#prettier_eslint#GetExecutable(buffer) abort
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#prettier_eslint#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#prettier_eslint#GetExecutable(a:buffer)
|
||||
|
||||
let l:command = ale#semver#HasVersion(l:executable)
|
||||
\ ? ''
|
||||
\ : ale#Escape(l:executable) . ' --version'
|
||||
|
||||
return {
|
||||
\ 'command': l:command,
|
||||
\ 'chain_with': 'ale#fixers#prettier_eslint#ApplyFixForVersion',
|
||||
\}
|
||||
return ale#semver#RunWithVersionCheck(
|
||||
\ a:buffer,
|
||||
\ ale#fixers#prettier_eslint#GetExecutable(a:buffer),
|
||||
\ '%e --version',
|
||||
\ function('ale#fixers#prettier_eslint#ApplyFixForVersion'),
|
||||
\)
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version_output) abort
|
||||
function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version) abort
|
||||
let l:options = ale#Var(a:buffer, 'javascript_prettier_eslint_options')
|
||||
let l:executable = ale#fixers#prettier_eslint#GetExecutable(a:buffer)
|
||||
|
||||
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
|
||||
|
||||
" 4.2.0 is the first version with --eslint-config-path
|
||||
let l:config = ale#semver#GTE(l:version, [4, 2, 0])
|
||||
let l:config = ale#semver#GTE(a:version, [4, 2, 0])
|
||||
\ ? ale#handlers#eslint#FindConfig(a:buffer)
|
||||
\ : ''
|
||||
let l:eslint_config_option = !empty(l:config)
|
||||
@@ -45,7 +35,7 @@ function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version_output)
|
||||
\ : ''
|
||||
|
||||
" 4.4.0 is the first version with --stdin-filepath
|
||||
if ale#semver#GTE(l:version, [4, 4, 0])
|
||||
if ale#semver#GTE(a:version, [4, 4, 0])
|
||||
return {
|
||||
\ 'command': ale#path#BufferCdString(a:buffer)
|
||||
\ . ale#Escape(l:executable)
|
||||
|
||||
@@ -32,7 +32,7 @@ endfunction
|
||||
"
|
||||
" The executable is only prefixed for Windows machines
|
||||
function! ale#node#Executable(buffer, executable) abort
|
||||
if ale#Has('win32') && a:executable =~? '\.js$'
|
||||
if has('win32') && a:executable =~? '\.js$'
|
||||
let l:node = ale#Var(a:buffer, 'windows_node_executable_path')
|
||||
|
||||
return ale#Escape(l:node) . ' ' . ale#Escape(a:executable)
|
||||
|
||||
@@ -5,31 +5,52 @@ function! ale#semver#ResetVersionCache() abort
|
||||
let s:version_cache = {}
|
||||
endfunction
|
||||
|
||||
function! ale#semver#ParseVersion(version_lines) abort
|
||||
for l:line in a:version_lines
|
||||
let l:match = matchlist(l:line, '\v(\d+)\.(\d+)(\.(\d+))?')
|
||||
|
||||
if !empty(l:match)
|
||||
return [l:match[1] + 0, l:match[2] + 0, l:match[4] + 0]
|
||||
endif
|
||||
endfor
|
||||
|
||||
return []
|
||||
endfunction
|
||||
|
||||
" Given an executable name and some lines of output, which can be empty,
|
||||
" parse the version from the lines of output, or return the cached version
|
||||
" triple [major, minor, patch]
|
||||
"
|
||||
" If the version cannot be found, an empty List will be returned instead.
|
||||
function! ale#semver#GetVersion(executable, version_lines) abort
|
||||
function! s:GetVersion(executable, version_lines) abort
|
||||
let l:version = get(s:version_cache, a:executable, [])
|
||||
let l:parsed_version = ale#semver#ParseVersion(a:version_lines)
|
||||
|
||||
for l:line in a:version_lines
|
||||
let l:match = matchlist(l:line, '\v(\d+)\.(\d+)(\.(\d+))?')
|
||||
|
||||
if !empty(l:match)
|
||||
let l:version = [l:match[1] + 0, l:match[2] + 0, l:match[4] + 0]
|
||||
let s:version_cache[a:executable] = l:version
|
||||
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if !empty(l:parsed_version)
|
||||
let l:version = l:parsed_version
|
||||
let s:version_cache[a:executable] = l:version
|
||||
endif
|
||||
|
||||
return l:version
|
||||
endfunction
|
||||
|
||||
" Return 1 if the semver version has been cached for a given executable.
|
||||
function! ale#semver#HasVersion(executable) abort
|
||||
return has_key(s:version_cache, a:executable)
|
||||
function! ale#semver#RunWithVersionCheck(buffer, executable, command, Callback) abort
|
||||
if empty(a:executable)
|
||||
return ''
|
||||
endif
|
||||
|
||||
let l:cache = s:version_cache
|
||||
|
||||
if has_key(s:version_cache, a:executable)
|
||||
return a:Callback(a:buffer, s:version_cache[a:executable])
|
||||
endif
|
||||
|
||||
return ale#command#Run(
|
||||
\ a:buffer,
|
||||
\ a:command,
|
||||
\ {_, output -> a:Callback(a:buffer, s:GetVersion(a:executable, output))},
|
||||
\ {'output_stream': 'both', 'executable': a:executable}
|
||||
\)
|
||||
endfunction
|
||||
|
||||
" Given two triples of integers [major, minor, patch], compare the triples
|
||||
|
||||
Reference in New Issue
Block a user