summaryrefslogtreecommitdiff
path: root/autoload
diff options
context:
space:
mode:
Diffstat (limited to 'autoload')
-rw-r--r--autoload/ale.vim24
-rw-r--r--autoload/ale/assert.vim172
-rw-r--r--autoload/ale/c.vim14
-rw-r--r--autoload/ale/command.vim52
-rw-r--r--autoload/ale/cursor.vim2
-rw-r--r--autoload/ale/d.vim4
-rw-r--r--autoload/ale/engine.vim20
-rw-r--r--autoload/ale/engine/ignore.vim6
-rw-r--r--autoload/ale/fix.vim4
-rw-r--r--autoload/ale/fixers/eslint.vim24
-rw-r--r--autoload/ale/fixers/prettier.vim23
-rw-r--r--autoload/ale/fixers/prettier_eslint.vim34
-rw-r--r--autoload/ale/handlers/redpen.vim4
-rw-r--r--autoload/ale/linter.vim10
-rw-r--r--autoload/ale/list.vim2
-rw-r--r--autoload/ale/lsp/message.vim2
-rw-r--r--autoload/ale/node.vim2
-rw-r--r--autoload/ale/path.vim9
-rw-r--r--autoload/ale/references.vim16
-rw-r--r--autoload/ale/semver.vim49
-rw-r--r--autoload/ale/swift.vim13
21 files changed, 335 insertions, 151 deletions
diff --git a/autoload/ale.vim b/autoload/ale.vim
index 5aa5fbfc..a887834b 100644
--- a/autoload/ale.vim
+++ b/autoload/ale.vim
@@ -8,6 +8,7 @@ let g:ale_echo_msg_info_str = get(g:, 'ale_echo_msg_info_str', 'Info')
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
" Ignoring linters, for disabling some, or ignoring LSP diagnostics.
let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {})
+let g:ale_disable_lsp = get(g:, 'ale_disable_lsp', 0)
let s:lint_timer = -1
let s:getcmdwintype_exists = exists('*getcmdwintype')
@@ -42,6 +43,11 @@ function! ale#ShouldDoNothing(buffer) abort
return 1
endif
+ " Do nothing for diff buffers.
+ if getbufvar(a:buffer, '&diff')
+ return 1
+ endif
+
" Do nothing for blacklisted files.
if index(get(g:, 'ale_filetype_blacklist', []), l:filetype) >= 0
return 1
@@ -90,8 +96,9 @@ function! s:Lint(buffer, should_lint_file, timer_id) abort
" Apply ignore lists for linters only if needed.
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
+ let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
let l:linters = !empty(l:ignore_config)
- \ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config)
+ \ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config, l:disable_lsp)
\ : l:linters
" Tell other sources that they can start checking the buffer now.
@@ -149,12 +156,19 @@ function! ale#Queue(delay, ...) abort
endif
endfunction
-let g:ale_has_override = get(g:, 'ale_has_override', {})
+let s:current_ale_version = [2, 4, 0]
-" Call has(), but check a global Dictionary so we can force flags on or off
-" for testing purposes.
+" A function used to check for ALE features in files outside of the project.
function! ale#Has(feature) abort
- return get(g:ale_has_override, a:feature, has(a:feature))
+ let l:match = matchlist(a:feature, '\c\v^ale-(\d+)\.(\d+)(\.(\d+))?$')
+
+ if !empty(l:match)
+ let l:version = [l:match[1] + 0, l:match[2] + 0, l:match[4] + 0]
+
+ return ale#semver#GTE(s:current_ale_version, l:version)
+ endif
+
+ return 0
endfunction
" Given a buffer number and a variable name, look for that variable in the
diff --git a/autoload/ale/assert.vim b/autoload/ale/assert.vim
index 6c2586a6..ed90792d 100644
--- a/autoload/ale/assert.vim
+++ b/autoload/ale/assert.vim
@@ -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')
-
- " 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)
+ let l:command = s:ProcessDeferredCommands(
+ \ 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 = []
-
- if exists(':WithChainResults')
- delcommand WithChainResults
+ 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(':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
diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim
index d759b25a..eeb512ba 100644
--- a/autoload/ale/c.vim
+++ b/autoload/ale/c.vim
@@ -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.
"
diff --git a/autoload/ale/command.vim b/autoload/ale/command.vim
index 33ce577c..1bbc4f4c 100644
--- a/autoload/ale/command.vim
+++ b/autoload/ale/command.vim
@@ -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
diff --git a/autoload/ale/cursor.vim b/autoload/ale/cursor.vim
index eea8ffe6..8c331c5c 100644
--- a/autoload/ale/cursor.vim
+++ b/autoload/ale/cursor.vim
@@ -25,7 +25,7 @@ function! ale#cursor#TruncatedEcho(original_message) abort
let l:cursor_position = getpos('.')
" The message is truncated and saved to the history.
- setlocal shortmess+=T
+ silent! setlocal shortmess+=T
try
exec "norm! :echomsg l:message\n"
diff --git a/autoload/ale/d.vim b/autoload/ale/d.vim
index 0e232203..2cbfda0d 100644
--- a/autoload/ale/d.vim
+++ b/autoload/ale/d.vim
@@ -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.
diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim
index 340f6913..6b312b4f 100644
--- a/autoload/ale/engine.vim
+++ b/autoload/ale/engine.vim
@@ -107,24 +107,36 @@ endfunction
" Register a temporary file to be managed with the ALE engine for
" a current job run.
function! ale#engine#ManageFile(buffer, filename) abort
- " TODO: Emit deprecation warning here later.
+ if !get(g:, 'ale_ignore_2_4_warnings')
+ execute 'echom ''ale#engine#ManageFile is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
+ endif
+
call ale#command#ManageFile(a:buffer, a:filename)
endfunction
" Same as the above, but manage an entire directory.
function! ale#engine#ManageDirectory(buffer, directory) abort
- " TODO: Emit deprecation warning here later.
+ if !get(g:, 'ale_ignore_2_4_warnings')
+ execute 'echom ''ale#engine#ManageDirectory is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
+ endif
+
call ale#command#ManageDirectory(a:buffer, a:directory)
endfunction
function! ale#engine#CreateFile(buffer) abort
- " TODO: Emit deprecation warning here later.
+ if !get(g:, 'ale_ignore_2_4_warnings')
+ execute 'echom ''ale#engine#CreateFile is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
+ endif
+
return ale#command#CreateFile(a:buffer)
endfunction
" Create a new temporary directory and manage it in one go.
function! ale#engine#CreateDirectory(buffer) abort
- " TODO: Emit deprecation warning here later.
+ if !get(g:, 'ale_ignore_2_4_warnings')
+ execute 'echom ''ale#engine#CreateDirectory is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
+ endif
+
return ale#command#CreateDirectory(a:buffer)
endfunction
diff --git a/autoload/ale/engine/ignore.vim b/autoload/ale/engine/ignore.vim
index 2db2c6c1..80574656 100644
--- a/autoload/ale/engine/ignore.vim
+++ b/autoload/ale/engine/ignore.vim
@@ -22,7 +22,7 @@ function! ale#engine#ignore#GetList(filetype, config) abort
endfunction
" Given a List of linter descriptions, exclude the linters to be ignored.
-function! ale#engine#ignore#Exclude(filetype, all_linters, config) abort
+function! ale#engine#ignore#Exclude(filetype, all_linters, config, disable_lsp) abort
let l:names_to_remove = ale#engine#ignore#GetList(a:filetype, a:config)
let l:filtered_linters = []
@@ -37,6 +37,10 @@ function! ale#engine#ignore#Exclude(filetype, all_linters, config) abort
endif
endfor
+ if a:disable_lsp && has_key(l:linter, 'lsp') && l:linter.lsp isnot# ''
+ let l:should_include = 0
+ endif
+
if l:should_include
call add(l:filtered_linters, l:linter)
endif
diff --git a/autoload/ale/fix.vim b/autoload/ale/fix.vim
index b8674606..c0f05611 100644
--- a/autoload/ale/fix.vim
+++ b/autoload/ale/fix.vim
@@ -117,6 +117,10 @@ function! s:HandleExit(job_info, buffer, job_output, data) abort
let l:input = a:job_info.input
endif
+ if l:ChainCallback isnot v:null && !get(g:, 'ale_ignore_2_4_warnings')
+ execute 'echom ''chain_with is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
+ endif
+
let l:next_index = l:ChainCallback is v:null
\ ? a:job_info.callback_index + 1
\ : a:job_info.callback_index
diff --git a/autoload/ale/fixers/eslint.vim b/autoload/ale/fixers/eslint.vim
index ea5b2a63..0f57cba6 100644
--- a/autoload/ale/fixers/eslint.vim
+++ b/autoload/ale/fixers/eslint.vim
@@ -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',
diff --git a/autoload/ale/fixers/prettier.vim b/autoload/ale/fixers/prettier.vim
index 0f99ae97..b7f0ecd7 100644
--- a/autoload/ale/fixers/prettier.vim
+++ b/autoload/ale/fixers/prettier.vim
@@ -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)
diff --git a/autoload/ale/fixers/prettier_eslint.vim b/autoload/ale/fixers/prettier_eslint.vim
index bc0caadd..1e66f49e 100644
--- a/autoload/ale/fixers/prettier_eslint.vim
+++ b/autoload/ale/fixers/prettier_eslint.vim
@@ -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)
diff --git a/autoload/ale/handlers/redpen.vim b/autoload/ale/handlers/redpen.vim
index 84e331ed..195057ca 100644
--- a/autoload/ale/handlers/redpen.vim
+++ b/autoload/ale/handlers/redpen.vim
@@ -4,10 +4,10 @@
function! ale#handlers#redpen#HandleRedpenOutput(buffer, lines) abort
" Only one file was passed to redpen. So response array has only one
" element.
- let l:res = json_decode(join(a:lines))[0]
+ let l:res = get(ale#util#FuzzyJSONDecode(a:lines, []), 0, {})
let l:output = []
- for l:err in l:res.errors
+ for l:err in get(l:res, 'errors', [])
let l:item = {
\ 'text': l:err.message,
\ 'type': 'W',
diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim
index 4937a6d7..273778c7 100644
--- a/autoload/ale/linter.vim
+++ b/autoload/ale/linter.vim
@@ -32,7 +32,7 @@ let s:default_ale_linter_aliases = {
" NOTE: Update the g:ale_linters documentation when modifying this.
let s:default_ale_linters = {
\ 'csh': ['shell'],
-\ 'elixir': ['credo', 'dialyxir', 'dogma', 'elixir-ls'],
+\ 'elixir': ['credo', 'dialyxir', 'dogma'],
\ 'go': ['gofmt', 'golint', 'go vet'],
\ 'hack': ['hack'],
\ 'help': [],
@@ -340,7 +340,13 @@ function! ale#linter#PreProcess(filetype, linter) abort
throw '`aliases` must be a List of String values'
endif
- " TODO: Emit deprecation warnings for deprecated options later.
+ for l:key in filter(keys(l:obj), 'v:val[-9:] is# ''_callback'' || v:val is# ''command_chain''')
+ if !get(g:, 'ale_ignore_2_4_warnings')
+ execute 'echom l:key . '' is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
+ endif
+
+ break
+ endfor
return l:obj
endfunction
diff --git a/autoload/ale/list.vim b/autoload/ale/list.vim
index 3417575c..63d97f35 100644
--- a/autoload/ale/list.vim
+++ b/autoload/ale/list.vim
@@ -115,7 +115,7 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
let l:open_type = ''
if ale#Var(a:buffer, 'list_vertical') == 1
- let l:open_type = 'vert '
+ let l:open_type = 'vert rightbelow '
endif
if g:ale_set_quickfix
diff --git a/autoload/ale/lsp/message.vim b/autoload/ale/lsp/message.vim
index 646dbd20..4ad94c4b 100644
--- a/autoload/ale/lsp/message.vim
+++ b/autoload/ale/lsp/message.vim
@@ -159,7 +159,7 @@ function! ale#lsp#message#Hover(buffer, line, column) abort
endfunction
function! ale#lsp#message#DidChangeConfiguration(buffer, config) abort
- return [0, 'workspace/didChangeConfiguration', {
+ return [1, 'workspace/didChangeConfiguration', {
\ 'settings': a:config,
\}]
endfunction
diff --git a/autoload/ale/node.vim b/autoload/ale/node.vim
index f75280b7..69060122 100644
--- a/autoload/ale/node.vim
+++ b/autoload/ale/node.vim
@@ -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)
diff --git a/autoload/ale/path.vim b/autoload/ale/path.vim
index ca3afc52..60d42eb5 100644
--- a/autoload/ale/path.vim
+++ b/autoload/ale/path.vim
@@ -205,10 +205,13 @@ function! ale#path#FromURI(uri) abort
let l:encoded_path = a:uri
endif
+ let l:path = ale#uri#Decode(l:encoded_path)
+
" If the path is like /C:/foo/bar, it should be C:\foo\bar instead.
- if l:encoded_path =~# '^/[a-zA-Z]:'
- let l:encoded_path = substitute(l:encoded_path[1:], '/', '\\', 'g')
+ if has('win32') && l:path =~# '^/[a-zA-Z][:|]'
+ let l:path = substitute(l:path[1:], '/', '\\', 'g')
+ let l:path = l:path[0] . ':' . l:path[2:]
endif
- return ale#uri#Decode(l:encoded_path)
+ return l:path
endfunction
diff --git a/autoload/ale/references.vim b/autoload/ale/references.vim
index 0e88afe2..b9725e1e 100644
--- a/autoload/ale/references.vim
+++ b/autoload/ale/references.vim
@@ -49,13 +49,15 @@ function! ale#references#HandleLSPResponse(conn_id, response) abort
let l:result = get(a:response, 'result', [])
let l:item_list = []
- for l:response_item in l:result
- call add(l:item_list, {
- \ 'filename': ale#path#FromURI(l:response_item.uri),
- \ 'line': l:response_item.range.start.line + 1,
- \ 'column': l:response_item.range.start.character + 1,
- \})
- endfor
+ if type(l:result) is v:t_list
+ for l:response_item in l:result
+ call add(l:item_list, {
+ \ 'filename': ale#path#FromURI(l:response_item.uri),
+ \ 'line': l:response_item.range.start.line + 1,
+ \ 'column': l:response_item.range.start.character + 1,
+ \})
+ endfor
+ endif
if empty(l:item_list)
call ale#util#Execute('echom ''No references found.''')
diff --git a/autoload/ale/semver.vim b/autoload/ale/semver.vim
index 5f1b46fc..e3eb49c0 100644
--- a/autoload/ale/semver.vim
+++ b/autoload/ale/semver.vim
@@ -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
diff --git a/autoload/ale/swift.vim b/autoload/ale/swift.vim
new file mode 100644
index 00000000..b31b8dc5
--- /dev/null
+++ b/autoload/ale/swift.vim
@@ -0,0 +1,13 @@
+" Author: Dan Loman <https://github.com/namolnad>
+" Description: Functions for integrating with Swift tools
+
+" Find the nearest dir containing a Package.swift file and assume it is the root of the Swift project.
+function! ale#swift#FindProjectRoot(buffer) abort
+ let l:swift_config = ale#path#FindNearestFile(a:buffer, 'Package.swift')
+
+ if !empty(l:swift_config)
+ return fnamemodify(l:swift_config, ':h')
+ endif
+
+ return ''
+endfunction