Updated plugins
This commit is contained in:
parent
6711ae6453
commit
3aefdbd21a
244 changed files with 9486 additions and 3395 deletions
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2016-2018, w0rp <devw0rp@gmail.com>
|
Copyright (c) 2016-2019, w0rp <devw0rp@gmail.com>
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -5,7 +5,10 @@ call ale#Set('asm_gcc_executable', 'gcc')
|
||||||
call ale#Set('asm_gcc_options', '-Wall')
|
call ale#Set('asm_gcc_options', '-Wall')
|
||||||
|
|
||||||
function! ale_linters#asm#gcc#GetCommand(buffer) abort
|
function! ale_linters#asm#gcc#GetCommand(buffer) abort
|
||||||
return '%e -x assembler -fsyntax-only '
|
" `-o /dev/null` or `-o null` is needed to catch all errors,
|
||||||
|
" -fsyntax-only doesn't catch everything.
|
||||||
|
return '%e -x assembler'
|
||||||
|
\ . ' -o ' . g:ale#util#nul_file
|
||||||
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||||
\ . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -'
|
\ . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
@ -4,12 +4,6 @@
|
||||||
call ale#Set('c_clangd_executable', 'clangd')
|
call ale#Set('c_clangd_executable', 'clangd')
|
||||||
call ale#Set('c_clangd_options', '')
|
call ale#Set('c_clangd_options', '')
|
||||||
|
|
||||||
function! ale_linters#c#clangd#GetProjectRoot(buffer) abort
|
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
|
||||||
|
|
||||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ale_linters#c#clangd#GetCommand(buffer) abort
|
function! ale_linters#c#clangd#GetCommand(buffer) abort
|
||||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options'))
|
return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options'))
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -19,5 +13,5 @@ call ale#linter#Define('c', {
|
||||||
\ 'lsp': 'stdio',
|
\ 'lsp': 'stdio',
|
||||||
\ 'executable': {b -> ale#Var(b, 'c_clangd_executable')},
|
\ 'executable': {b -> ale#Var(b, 'c_clangd_executable')},
|
||||||
\ 'command': function('ale_linters#c#clangd#GetCommand'),
|
\ 'command': function('ale_linters#c#clangd#GetCommand'),
|
||||||
\ 'project_root': function('ale_linters#c#clangd#GetProjectRoot'),
|
\ 'project_root': function('ale#c#FindProjectRoot'),
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -11,9 +11,12 @@ call ale#Set('c_clangtidy_executable', 'clang-tidy')
|
||||||
" http://clang.llvm.org/extra/clang-tidy/checks/list.html
|
" http://clang.llvm.org/extra/clang-tidy/checks/list.html
|
||||||
|
|
||||||
call ale#Set('c_clangtidy_checks', [])
|
call ale#Set('c_clangtidy_checks', [])
|
||||||
" Set this option to manually set some options for clang-tidy.
|
" Set this option to manually set some options for clang-tidy to use as compile
|
||||||
|
" flags.
|
||||||
" This will disable compile_commands.json detection.
|
" This will disable compile_commands.json detection.
|
||||||
call ale#Set('c_clangtidy_options', '')
|
call ale#Set('c_clangtidy_options', '')
|
||||||
|
" Set this option to manually set options for clang-tidy directly.
|
||||||
|
call ale#Set('c_clangtidy_extra_options', '')
|
||||||
call ale#Set('c_build_dir', '')
|
call ale#Set('c_build_dir', '')
|
||||||
|
|
||||||
function! ale_linters#c#clangtidy#GetCommand(buffer) abort
|
function! ale_linters#c#clangtidy#GetCommand(buffer) abort
|
||||||
|
@ -25,8 +28,12 @@ function! ale_linters#c#clangtidy#GetCommand(buffer) abort
|
||||||
\ ? ale#Var(a:buffer, 'c_clangtidy_options')
|
\ ? ale#Var(a:buffer, 'c_clangtidy_options')
|
||||||
\ : ''
|
\ : ''
|
||||||
|
|
||||||
|
" Get the options to pass directly to clang-tidy
|
||||||
|
let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options')
|
||||||
|
|
||||||
return '%e'
|
return '%e'
|
||||||
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
|
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
|
||||||
|
\ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '')
|
||||||
\ . ' %s'
|
\ . ' %s'
|
||||||
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
|
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
|
||||||
\ . (!empty(l:options) ? ' -- ' . l:options : '')
|
\ . (!empty(l:options) ? ' -- ' . l:options : '')
|
||||||
|
|
|
@ -5,23 +5,17 @@ call ale#Set('c_cppcheck_executable', 'cppcheck')
|
||||||
call ale#Set('c_cppcheck_options', '--enable=style')
|
call ale#Set('c_cppcheck_options', '--enable=style')
|
||||||
|
|
||||||
function! ale_linters#c#cppcheck#GetCommand(buffer) abort
|
function! ale_linters#c#cppcheck#GetCommand(buffer) abort
|
||||||
" Search upwards from the file for compile_commands.json.
|
let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer)
|
||||||
"
|
let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer)
|
||||||
" If we find it, we'll `cd` to where the compile_commands.json file is,
|
let l:buffer_path_include = empty(l:compile_commands_option)
|
||||||
" then use the file to set up import paths, etc.
|
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
|
||||||
let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
|
||||||
|
|
||||||
let l:cd_command = !empty(l:compile_commmands_path)
|
|
||||||
\ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
|
|
||||||
\ : ''
|
|
||||||
let l:compile_commands_option = !empty(l:compile_commmands_path)
|
|
||||||
\ ? '--project=compile_commands.json '
|
|
||||||
\ : ''
|
\ : ''
|
||||||
|
|
||||||
return l:cd_command
|
return l:cd_command
|
||||||
\ . '%e -q --language=c'
|
\ . '%e -q --language=c'
|
||||||
\ . l:compile_commands_option
|
\ . ale#Pad(l:compile_commands_option)
|
||||||
\ . ale#Var(a:buffer, 'c_cppcheck_options')
|
\ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options'))
|
||||||
|
\ . l:buffer_path_include
|
||||||
\ . ' %t'
|
\ . ' %t'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,15 @@ call ale#Set('c_cquery_executable', 'cquery')
|
||||||
call ale#Set('c_cquery_cache_directory', expand('~/.cache/cquery'))
|
call ale#Set('c_cquery_cache_directory', expand('~/.cache/cquery'))
|
||||||
|
|
||||||
function! ale_linters#c#cquery#GetProjectRoot(buffer) abort
|
function! ale_linters#c#cquery#GetProjectRoot(buffer) abort
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
" Try to find cquery configuration files first.
|
||||||
|
let l:config = ale#path#FindNearestFile(a:buffer, '.cquery')
|
||||||
|
|
||||||
if empty(l:project_root)
|
if !empty(l:config)
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery')
|
return fnamemodify(l:config, ':h')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
" Fall back on default project root detection.
|
||||||
|
return ale#c#FindProjectRoot(a:buffer)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#c#cquery#GetInitializationOptions(buffer) abort
|
function! ale_linters#c#cquery#GetInitializationOptions(buffer) abort
|
||||||
|
|
|
@ -9,7 +9,11 @@ function! ale_linters#c#gcc#GetCommand(buffer, output) abort
|
||||||
|
|
||||||
" -iquote with the directory the file is in makes #include work for
|
" -iquote with the directory the file is in makes #include work for
|
||||||
" headers in the same directory.
|
" headers in the same directory.
|
||||||
return '%e -S -x c -fsyntax-only'
|
"
|
||||||
|
" `-o /dev/null` or `-o null` is needed to catch all errors,
|
||||||
|
" -fsyntax-only doesn't catch everything.
|
||||||
|
return '%e -S -x c'
|
||||||
|
\ . ' -o ' . g:ale#util#nul_file
|
||||||
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||||
\ . ale#Pad(l:cflags)
|
\ . ale#Pad(l:cflags)
|
||||||
\ . ale#Pad(ale#Var(a:buffer, 'c_gcc_options')) . ' -'
|
\ . ale#Pad(ale#Var(a:buffer, 'c_gcc_options')) . ' -'
|
||||||
|
|
|
@ -12,7 +12,8 @@ function! ale_linters#cpp#clangcheck#GetCommand(buffer) abort
|
||||||
let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
|
let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
|
||||||
|
|
||||||
if empty(l:build_dir)
|
if empty(l:build_dir)
|
||||||
let l:build_dir = ale#path#Dirname(ale#c#FindCompileCommands(a:buffer))
|
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||||
|
let l:build_dir = ale#path#Dirname(l:json_file)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" The extra arguments in the command are used to prevent .plist files from
|
" The extra arguments in the command are used to prevent .plist files from
|
||||||
|
|
|
@ -4,12 +4,6 @@
|
||||||
call ale#Set('cpp_clangd_executable', 'clangd')
|
call ale#Set('cpp_clangd_executable', 'clangd')
|
||||||
call ale#Set('cpp_clangd_options', '')
|
call ale#Set('cpp_clangd_options', '')
|
||||||
|
|
||||||
function! ale_linters#cpp#clangd#GetProjectRoot(buffer) abort
|
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
|
||||||
|
|
||||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ale_linters#cpp#clangd#GetCommand(buffer) abort
|
function! ale_linters#cpp#clangd#GetCommand(buffer) abort
|
||||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options'))
|
return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options'))
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -19,5 +13,5 @@ call ale#linter#Define('cpp', {
|
||||||
\ 'lsp': 'stdio',
|
\ 'lsp': 'stdio',
|
||||||
\ 'executable': {b -> ale#Var(b, 'cpp_clangd_executable')},
|
\ 'executable': {b -> ale#Var(b, 'cpp_clangd_executable')},
|
||||||
\ 'command': function('ale_linters#cpp#clangd#GetCommand'),
|
\ 'command': function('ale_linters#cpp#clangd#GetCommand'),
|
||||||
\ 'project_root': function('ale_linters#cpp#clangd#GetProjectRoot'),
|
\ 'project_root': function('ale#c#FindProjectRoot'),
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -5,9 +5,12 @@
|
||||||
call ale#Set('cpp_clangtidy_executable', 'clang-tidy')
|
call ale#Set('cpp_clangtidy_executable', 'clang-tidy')
|
||||||
" Set this option to check the checks clang-tidy will apply.
|
" Set this option to check the checks clang-tidy will apply.
|
||||||
call ale#Set('cpp_clangtidy_checks', [])
|
call ale#Set('cpp_clangtidy_checks', [])
|
||||||
" Set this option to manually set some options for clang-tidy.
|
" Set this option to manually set some options for clang-tidy to use as compile
|
||||||
|
" flags.
|
||||||
" This will disable compile_commands.json detection.
|
" This will disable compile_commands.json detection.
|
||||||
call ale#Set('cpp_clangtidy_options', '')
|
call ale#Set('cpp_clangtidy_options', '')
|
||||||
|
" Set this option to manually set options for clang-tidy directly.
|
||||||
|
call ale#Set('cpp_clangtidy_extra_options', '')
|
||||||
call ale#Set('c_build_dir', '')
|
call ale#Set('c_build_dir', '')
|
||||||
|
|
||||||
function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
|
function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
|
||||||
|
@ -19,8 +22,12 @@ function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
|
||||||
\ ? ale#Var(a:buffer, 'cpp_clangtidy_options')
|
\ ? ale#Var(a:buffer, 'cpp_clangtidy_options')
|
||||||
\ : ''
|
\ : ''
|
||||||
|
|
||||||
|
" Get the options to pass directly to clang-tidy
|
||||||
|
let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options')
|
||||||
|
|
||||||
return '%e'
|
return '%e'
|
||||||
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
|
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
|
||||||
|
\ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '')
|
||||||
\ . ' %s'
|
\ . ' %s'
|
||||||
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
|
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
|
||||||
\ . (!empty(l:options) ? ' -- ' . l:options : '')
|
\ . (!empty(l:options) ? ' -- ' . l:options : '')
|
||||||
|
|
|
@ -5,23 +5,17 @@ call ale#Set('cpp_cppcheck_executable', 'cppcheck')
|
||||||
call ale#Set('cpp_cppcheck_options', '--enable=style')
|
call ale#Set('cpp_cppcheck_options', '--enable=style')
|
||||||
|
|
||||||
function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort
|
function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort
|
||||||
" Search upwards from the file for compile_commands.json.
|
let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer)
|
||||||
"
|
let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer)
|
||||||
" If we find it, we'll `cd` to where the compile_commands.json file is,
|
let l:buffer_path_include = empty(l:compile_commands_option)
|
||||||
" then use the file to set up import paths, etc.
|
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
|
||||||
let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
|
||||||
|
|
||||||
let l:cd_command = !empty(l:compile_commmands_path)
|
|
||||||
\ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
|
|
||||||
\ : ''
|
|
||||||
let l:compile_commands_option = !empty(l:compile_commmands_path)
|
|
||||||
\ ? '--project=compile_commands.json '
|
|
||||||
\ : ''
|
\ : ''
|
||||||
|
|
||||||
return l:cd_command
|
return l:cd_command
|
||||||
\ . '%e -q --language=c++'
|
\ . '%e -q --language=c++'
|
||||||
\ . l:compile_commands_option
|
\ . ale#Pad(l:compile_commands_option)
|
||||||
\ . ale#Var(a:buffer, 'cpp_cppcheck_options')
|
\ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options'))
|
||||||
|
\ . l:buffer_path_include
|
||||||
\ . ' %t'
|
\ . ' %t'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,15 @@ call ale#Set('cpp_cquery_executable', 'cquery')
|
||||||
call ale#Set('cpp_cquery_cache_directory', expand('~/.cache/cquery'))
|
call ale#Set('cpp_cquery_cache_directory', expand('~/.cache/cquery'))
|
||||||
|
|
||||||
function! ale_linters#cpp#cquery#GetProjectRoot(buffer) abort
|
function! ale_linters#cpp#cquery#GetProjectRoot(buffer) abort
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
" Try to find cquery configuration files first.
|
||||||
|
let l:config = ale#path#FindNearestFile(a:buffer, '.cquery')
|
||||||
|
|
||||||
if empty(l:project_root)
|
if !empty(l:config)
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery')
|
return fnamemodify(l:config, ':h')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
" Fall back on default project root detection.
|
||||||
|
return ale#c#FindProjectRoot(a:buffer)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#cpp#cquery#GetInitializationOptions(buffer) abort
|
function! ale_linters#cpp#cquery#GetInitializationOptions(buffer) abort
|
||||||
|
|
|
@ -9,7 +9,11 @@ function! ale_linters#cpp#gcc#GetCommand(buffer, output) abort
|
||||||
|
|
||||||
" -iquote with the directory the file is in makes #include work for
|
" -iquote with the directory the file is in makes #include work for
|
||||||
" headers in the same directory.
|
" headers in the same directory.
|
||||||
return '%e -S -x c++ -fsyntax-only'
|
"
|
||||||
|
" `-o /dev/null` or `-o null` is needed to catch all errors,
|
||||||
|
" -fsyntax-only doesn't catch everything.
|
||||||
|
return '%e -S -x c++'
|
||||||
|
\ . ' -o ' . g:ale#util#nul_file
|
||||||
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||||
\ . ale#Pad(l:cflags)
|
\ . ale#Pad(l:cflags)
|
||||||
\ . ale#Pad(ale#Var(a:buffer, 'cpp_gcc_options')) . ' -'
|
\ . ale#Pad(ale#Var(a:buffer, 'cpp_gcc_options')) . ' -'
|
||||||
|
|
95
sources_non_forked/ale/ale_linters/cs/csc.vim
Normal file
95
sources_non_forked/ale/ale_linters/cs/csc.vim
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
call ale#Set('cs_csc_options', '')
|
||||||
|
call ale#Set('cs_csc_source', '')
|
||||||
|
call ale#Set('cs_csc_assembly_path', [])
|
||||||
|
call ale#Set('cs_csc_assemblies', [])
|
||||||
|
|
||||||
|
function! s:GetWorkingDirectory(buffer) abort
|
||||||
|
let l:working_directory = ale#Var(a:buffer, 'cs_csc_source')
|
||||||
|
|
||||||
|
if !empty(l:working_directory)
|
||||||
|
return l:working_directory
|
||||||
|
endif
|
||||||
|
|
||||||
|
return expand('#' . a:buffer . ':p:h')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#cs#csc#GetCommand(buffer) abort
|
||||||
|
" Pass assembly paths via the -lib: parameter.
|
||||||
|
let l:path_list = ale#Var(a:buffer, 'cs_csc_assembly_path')
|
||||||
|
|
||||||
|
let l:lib_option = !empty(l:path_list)
|
||||||
|
\ ? '/lib:' . join(map(copy(l:path_list), 'ale#Escape(v:val)'), ',')
|
||||||
|
\ : ''
|
||||||
|
|
||||||
|
" Pass paths to DLL files via the -r: parameter.
|
||||||
|
let l:assembly_list = ale#Var(a:buffer, 'cs_csc_assemblies')
|
||||||
|
|
||||||
|
let l:r_option = !empty(l:assembly_list)
|
||||||
|
\ ? '/r:' . join(map(copy(l:assembly_list), 'ale#Escape(v:val)'), ',')
|
||||||
|
\ : ''
|
||||||
|
|
||||||
|
" register temporary module target file with ale
|
||||||
|
" register temporary module target file with ALE.
|
||||||
|
let l:out = ale#command#CreateFile(a:buffer)
|
||||||
|
|
||||||
|
" The code is compiled as a module and the output is redirected to a
|
||||||
|
" temporary file.
|
||||||
|
return ale#path#CdString(s:GetWorkingDirectory(a:buffer))
|
||||||
|
\ . 'csc /unsafe'
|
||||||
|
\ . ale#Pad(ale#Var(a:buffer, 'cs_csc_options'))
|
||||||
|
\ . ale#Pad(l:lib_option)
|
||||||
|
\ . ale#Pad(l:r_option)
|
||||||
|
\ . ' /out:' . l:out
|
||||||
|
\ . ' /t:module'
|
||||||
|
\ . ' /recurse:' . ale#Escape('*.cs')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#cs#csc#Handle(buffer, lines) abort
|
||||||
|
" Look for lines like the following.
|
||||||
|
"
|
||||||
|
" Tests.cs(12,29): error CSXXXX: ; expected
|
||||||
|
"
|
||||||
|
" NOTE: pattern also captures file name as linter compiles all
|
||||||
|
" files within the source tree rooted at the specified source
|
||||||
|
" path and not just the file loaded in the buffer
|
||||||
|
let l:patterns = [
|
||||||
|
\ '^\v(.+\.cs)\((\d+),(\d+)\)\:\s+([^ ]+)\s+([cC][sS][^ ]+):\s(.+)$',
|
||||||
|
\ '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$',
|
||||||
|
\]
|
||||||
|
let l:output = []
|
||||||
|
|
||||||
|
let l:dir = s:GetWorkingDirectory(a:buffer)
|
||||||
|
|
||||||
|
for l:match in ale#util#GetMatches(a:lines, l:patterns)
|
||||||
|
if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS'
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
|
||||||
|
\ 'lnum': l:match[2] + 0,
|
||||||
|
\ 'col': l:match[3] + 0,
|
||||||
|
\ 'type': l:match[4] is# 'error' ? 'E' : 'W',
|
||||||
|
\ 'code': l:match[5],
|
||||||
|
\ 'text': l:match[6] ,
|
||||||
|
\})
|
||||||
|
elseif strlen(l:match[2]) > 2 && l:match[2][:1] is? 'CS'
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'filename':'<csc>',
|
||||||
|
\ 'lnum': -1,
|
||||||
|
\ 'col': -1,
|
||||||
|
\ 'type': l:match[1] is# 'error' ? 'E' : 'W',
|
||||||
|
\ 'code': l:match[2],
|
||||||
|
\ 'text': l:match[3],
|
||||||
|
\})
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('cs',{
|
||||||
|
\ 'name': 'csc',
|
||||||
|
\ 'output_stream': 'stdout',
|
||||||
|
\ 'executable': 'csc',
|
||||||
|
\ 'command': function('ale_linters#cs#csc#GetCommand'),
|
||||||
|
\ 'callback': 'ale_linters#cs#csc#Handle',
|
||||||
|
\ 'lint_file': 1
|
||||||
|
\})
|
|
@ -52,12 +52,16 @@ function! ale_linters#cs#mcsc#Handle(buffer, lines) abort
|
||||||
" NOTE: pattern also captures file name as linter compiles all
|
" NOTE: pattern also captures file name as linter compiles all
|
||||||
" files within the source tree rooted at the specified source
|
" files within the source tree rooted at the specified source
|
||||||
" path and not just the file loaded in the buffer
|
" path and not just the file loaded in the buffer
|
||||||
let l:pattern = '^\v(.+\.cs)\((\d+),(\d+)\)\: ([^ ]+) ([^ ]+): (.+)$'
|
let l:patterns = [
|
||||||
|
\ '^\v(.+\.cs)\((\d+),(\d+)\)\:\s+([^ ]+)\s+([cC][sS][^ ]+):\s(.+)$',
|
||||||
|
\ '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$',
|
||||||
|
\]
|
||||||
let l:output = []
|
let l:output = []
|
||||||
|
|
||||||
let l:dir = s:GetWorkingDirectory(a:buffer)
|
let l:dir = s:GetWorkingDirectory(a:buffer)
|
||||||
|
|
||||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
for l:match in ale#util#GetMatches(a:lines, l:patterns)
|
||||||
|
if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS'
|
||||||
call add(l:output, {
|
call add(l:output, {
|
||||||
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
|
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
|
||||||
\ 'lnum': l:match[2] + 0,
|
\ 'lnum': l:match[2] + 0,
|
||||||
|
@ -66,6 +70,16 @@ function! ale_linters#cs#mcsc#Handle(buffer, lines) abort
|
||||||
\ 'code': l:match[5],
|
\ 'code': l:match[5],
|
||||||
\ 'text': l:match[6] ,
|
\ 'text': l:match[6] ,
|
||||||
\})
|
\})
|
||||||
|
elseif strlen(l:match[2]) > 2 && l:match[2][:1] is? 'CS'
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'filename':'<mcs>',
|
||||||
|
\ 'lnum': -1,
|
||||||
|
\ 'col': -1,
|
||||||
|
\ 'type': l:match[1] is# 'error' ? 'E' : 'W',
|
||||||
|
\ 'code': l:match[2],
|
||||||
|
\ 'text': l:match[3],
|
||||||
|
\})
|
||||||
|
endif
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
return l:output
|
return l:output
|
||||||
|
|
37
sources_non_forked/ale/ale_linters/elm/elm_ls.vim
Normal file
37
sources_non_forked/ale/ale_linters/elm/elm_ls.vim
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
" Author: antew - https://github.com/antew
|
||||||
|
" Description: elm-language-server integration for elm (diagnostics, formatting, and more)
|
||||||
|
|
||||||
|
call ale#Set('elm_ls_executable', 'elm-language-server')
|
||||||
|
call ale#Set('elm_ls_use_global', get(g:, 'ale_use_global_executables', 1))
|
||||||
|
call ale#Set('elm_ls_elm_path', 'elm')
|
||||||
|
call ale#Set('elm_ls_elm_format_path', 'elm-format')
|
||||||
|
call ale#Set('elm_ls_elm_test_path', 'elm-test')
|
||||||
|
|
||||||
|
function! elm_ls#GetRootDir(buffer) abort
|
||||||
|
let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
|
||||||
|
|
||||||
|
return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! elm_ls#GetOptions(buffer) abort
|
||||||
|
return {
|
||||||
|
\ 'runtime': 'node',
|
||||||
|
\ 'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'),
|
||||||
|
\ 'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'),
|
||||||
|
\ 'elmTestPath': ale#Var(a:buffer, 'elm_ls_elm_test_path'),
|
||||||
|
\}
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('elm', {
|
||||||
|
\ 'name': 'elm_ls',
|
||||||
|
\ 'lsp': 'stdio',
|
||||||
|
\ 'executable': {b -> ale#node#FindExecutable(b, 'elm_ls', [
|
||||||
|
\ 'node_modules/.bin/elm-language-server',
|
||||||
|
\ 'node_modules/.bin/elm-lsp',
|
||||||
|
\ 'elm-lsp'
|
||||||
|
\ ])},
|
||||||
|
\ 'command': '%e --stdio',
|
||||||
|
\ 'project_root': function('elm_ls#GetRootDir'),
|
||||||
|
\ 'language': 'elm',
|
||||||
|
\ 'initialization_options': function('elm_ls#GetOptions')
|
||||||
|
\})
|
|
@ -1,22 +0,0 @@
|
||||||
" Author: antew - https://github.com/antew
|
|
||||||
" Description: LSP integration for elm, currently supports diagnostics (linting)
|
|
||||||
|
|
||||||
call ale#Set('elm_lsp_executable', 'elm-lsp')
|
|
||||||
call ale#Set('elm_lsp_use_global', get(g:, 'ale_use_global_executables', 0))
|
|
||||||
|
|
||||||
function! elm_lsp#GetRootDir(buffer) abort
|
|
||||||
let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
|
|
||||||
|
|
||||||
return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
call ale#linter#Define('elm', {
|
|
||||||
\ 'name': 'elm_lsp',
|
|
||||||
\ 'lsp': 'stdio',
|
|
||||||
\ 'executable': {b -> ale#node#FindExecutable(b, 'elm_lsp', [
|
|
||||||
\ 'node_modules/.bin/elm-lsp',
|
|
||||||
\ ])},
|
|
||||||
\ 'command': '%e --stdio',
|
|
||||||
\ 'project_root': function('elm_lsp#GetRootDir'),
|
|
||||||
\ 'language': 'elm'
|
|
||||||
\})
|
|
93
sources_non_forked/ale/ale_linters/erlang/dialyzer.vim
Normal file
93
sources_non_forked/ale/ale_linters/erlang/dialyzer.vim
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
" Author: Autoine Gagne - https://github.com/AntoineGagne
|
||||||
|
" Description: Define a checker that runs dialyzer on Erlang files.
|
||||||
|
|
||||||
|
let g:ale_erlang_dialyzer_executable =
|
||||||
|
\ get(g:, 'ale_erlang_dialyzer_executable', 'dialyzer')
|
||||||
|
let g:ale_erlang_dialyzer_plt_file =
|
||||||
|
\ get(g:, 'ale_erlang_dialyzer_plt_file', '')
|
||||||
|
let g:ale_erlang_dialyzer_rebar3_profile =
|
||||||
|
\ get(g:, 'ale_erlang_dialyzer_rebar3_profile', 'default')
|
||||||
|
|
||||||
|
function! ale_linters#erlang#dialyzer#GetRebar3Profile(buffer) abort
|
||||||
|
return ale#Var(a:buffer, 'erlang_dialyzer_rebar3_profile')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#erlang#dialyzer#FindPlt(buffer) abort
|
||||||
|
let l:plt_file = ''
|
||||||
|
let l:rebar3_profile = ale_linters#erlang#dialyzer#GetRebar3Profile(a:buffer)
|
||||||
|
let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build' . l:rebar3_profile)
|
||||||
|
|
||||||
|
if !empty(l:plt_file_directory)
|
||||||
|
let l:plt_file = split(globpath(l:plt_file_directory, '/*_plt'), '\n')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !empty(l:plt_file)
|
||||||
|
return l:plt_file[0]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !empty($REBAR_PLT_DIR)
|
||||||
|
return expand('$REBAR_PLT_DIR/dialyzer/plt')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return expand('$HOME/.dialyzer_plt')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#erlang#dialyzer#GetPlt(buffer) abort
|
||||||
|
let l:plt_file = ale#Var(a:buffer, 'erlang_dialyzer_plt_file')
|
||||||
|
|
||||||
|
if !empty(l:plt_file)
|
||||||
|
return l:plt_file
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ale_linters#erlang#dialyzer#FindPlt(a:buffer)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#erlang#dialyzer#GetExecutable(buffer) abort
|
||||||
|
return ale#Var(a:buffer, 'erlang_dialyzer_executable')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#erlang#dialyzer#GetCommand(buffer) abort
|
||||||
|
let l:command = ale#Escape(ale_linters#erlang#dialyzer#GetExecutable(a:buffer))
|
||||||
|
\ . ' -n'
|
||||||
|
\ . ' --plt ' . ale#Escape(ale_linters#erlang#dialyzer#GetPlt(a:buffer))
|
||||||
|
\ . ' -Wunmatched_returns'
|
||||||
|
\ . ' -Werror_handling'
|
||||||
|
\ . ' -Wrace_conditions'
|
||||||
|
\ . ' -Wunderspecs'
|
||||||
|
\ . ' %s'
|
||||||
|
|
||||||
|
return l:command
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#erlang#dialyzer#Handle(buffer, lines) abort
|
||||||
|
" Match patterns like the following:
|
||||||
|
"
|
||||||
|
" erl_tidy_prv_fmt.erl:3: Callback info about the provider behaviour is not available
|
||||||
|
let l:pattern = '^\S\+:\(\d\+\): \(.\+\)$'
|
||||||
|
let l:output = []
|
||||||
|
|
||||||
|
for l:line in a:lines
|
||||||
|
let l:match = matchlist(l:line, l:pattern)
|
||||||
|
|
||||||
|
if len(l:match) != 0
|
||||||
|
let l:code = l:match[2]
|
||||||
|
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'lnum': str2nr(l:match[1]),
|
||||||
|
\ 'lcol': 0,
|
||||||
|
\ 'text': l:code,
|
||||||
|
\ 'type': 'W'
|
||||||
|
\})
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('erlang', {
|
||||||
|
\ 'name': 'dialyzer',
|
||||||
|
\ 'executable': function('ale_linters#erlang#dialyzer#GetExecutable'),
|
||||||
|
\ 'command': function('ale_linters#erlang#dialyzer#GetCommand'),
|
||||||
|
\ 'callback': function('ale_linters#erlang#dialyzer#Handle'),
|
||||||
|
\ 'lint_file': 1
|
||||||
|
\})
|
|
@ -5,11 +5,13 @@ call ale#Set('go_bingo_executable', 'bingo')
|
||||||
call ale#Set('go_bingo_options', '--mode stdio')
|
call ale#Set('go_bingo_options', '--mode stdio')
|
||||||
|
|
||||||
function! ale_linters#go#bingo#GetCommand(buffer) abort
|
function! ale_linters#go#bingo#GetCommand(buffer) abort
|
||||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'go_bingo_options'))
|
return ale#go#EnvString(a:buffer) . '%e' . ale#Pad(ale#Var(a:buffer, 'go_bingo_options'))
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#go#bingo#FindProjectRoot(buffer) abort
|
function! ale_linters#go#bingo#FindProjectRoot(buffer) abort
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'go.mod')
|
let l:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off'
|
||||||
|
let l:project_root = l:go_modules_off ?
|
||||||
|
\ '' : ale#path#FindNearestFile(a:buffer, 'go.mod')
|
||||||
let l:mods = ':h'
|
let l:mods = ':h'
|
||||||
|
|
||||||
if empty(l:project_root)
|
if empty(l:project_root)
|
||||||
|
|
|
@ -11,6 +11,7 @@ function! ale_linters#go#gobuild#GetCommand(buffer) abort
|
||||||
|
|
||||||
" Run go test in local directory with relative path
|
" Run go test in local directory with relative path
|
||||||
return ale#path#BufferCdString(a:buffer)
|
return ale#path#BufferCdString(a:buffer)
|
||||||
|
\ . ale#go#EnvString(a:buffer)
|
||||||
\ . ale#Var(a:buffer, 'go_go_executable') . ' test'
|
\ . ale#Var(a:buffer, 'go_go_executable') . ' test'
|
||||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
\ . ' -c -o /dev/null ./'
|
\ . ' -c -o /dev/null ./'
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
" Author: neersighted <bjorn@neersighted.com>
|
" Author: neersighted <bjorn@neersighted.com>
|
||||||
" Description: gofmt for Go files
|
" Description: gofmt for Go files
|
||||||
|
|
||||||
|
function! ale_linters#go#gofmt#GetCommand(buffer) abort
|
||||||
|
return ale#go#EnvString(a:buffer)
|
||||||
|
\ . '%e -e %t'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
call ale#linter#Define('go', {
|
call ale#linter#Define('go', {
|
||||||
\ 'name': 'gofmt',
|
\ 'name': 'gofmt',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable': 'gofmt',
|
\ 'executable': 'gofmt',
|
||||||
\ 'command': 'gofmt -e %t',
|
\ 'command': function('ale_linters#go#gofmt#GetCommand'),
|
||||||
\ 'callback': 'ale#handlers#unix#HandleAsError',
|
\ 'callback': 'ale#handlers#unix#HandleAsError',
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -10,13 +10,16 @@ function! ale_linters#go#golangci_lint#GetCommand(buffer) abort
|
||||||
let l:options = ale#Var(a:buffer, 'go_golangci_lint_options')
|
let l:options = ale#Var(a:buffer, 'go_golangci_lint_options')
|
||||||
let l:lint_package = ale#Var(a:buffer, 'go_golangci_lint_package')
|
let l:lint_package = ale#Var(a:buffer, 'go_golangci_lint_package')
|
||||||
|
|
||||||
|
|
||||||
if l:lint_package
|
if l:lint_package
|
||||||
return ale#path#BufferCdString(a:buffer)
|
return ale#path#BufferCdString(a:buffer)
|
||||||
|
\ . ale#go#EnvString(a:buffer)
|
||||||
\ . '%e run '
|
\ . '%e run '
|
||||||
\ . l:options
|
\ . l:options
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return ale#path#BufferCdString(a:buffer)
|
return ale#path#BufferCdString(a:buffer)
|
||||||
|
\ . ale#go#EnvString(a:buffer)
|
||||||
\ . '%e run '
|
\ . '%e run '
|
||||||
\ . ale#Escape(l:filename)
|
\ . ale#Escape(l:filename)
|
||||||
\ . ' ' . l:options
|
\ . ' ' . l:options
|
||||||
|
|
|
@ -7,7 +7,7 @@ call ale#Set('go_golint_options', '')
|
||||||
function! ale_linters#go#golint#GetCommand(buffer) abort
|
function! ale_linters#go#golint#GetCommand(buffer) abort
|
||||||
let l:options = ale#Var(a:buffer, 'go_golint_options')
|
let l:options = ale#Var(a:buffer, 'go_golint_options')
|
||||||
|
|
||||||
return '%e'
|
return ale#go#EnvString(a:buffer) . '%e'
|
||||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
\ . ' %t'
|
\ . ' %t'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
@ -14,11 +14,13 @@ function! ale_linters#go#gometalinter#GetCommand(buffer) abort
|
||||||
" be calculated to absolute paths in the Handler
|
" be calculated to absolute paths in the Handler
|
||||||
if l:lint_package
|
if l:lint_package
|
||||||
return ale#path#BufferCdString(a:buffer)
|
return ale#path#BufferCdString(a:buffer)
|
||||||
|
\ . ale#go#EnvString(a:buffer)
|
||||||
\ . '%e'
|
\ . '%e'
|
||||||
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
|
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return ale#path#BufferCdString(a:buffer)
|
return ale#path#BufferCdString(a:buffer)
|
||||||
|
\ . ale#go#EnvString(a:buffer)
|
||||||
\ . '%e'
|
\ . '%e'
|
||||||
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename))
|
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename))
|
||||||
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
|
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
|
||||||
|
|
|
@ -6,11 +6,15 @@ call ale#Set('go_gopls_executable', 'gopls')
|
||||||
call ale#Set('go_gopls_options', '--mode stdio')
|
call ale#Set('go_gopls_options', '--mode stdio')
|
||||||
|
|
||||||
function! ale_linters#go#gopls#GetCommand(buffer) abort
|
function! ale_linters#go#gopls#GetCommand(buffer) abort
|
||||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'go_gopls_options'))
|
return ale#go#EnvString(a:buffer)
|
||||||
|
\ . '%e'
|
||||||
|
\ . ale#Pad(ale#Var(a:buffer, 'go_gopls_options'))
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#go#gopls#FindProjectRoot(buffer) abort
|
function! ale_linters#go#gopls#FindProjectRoot(buffer) abort
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'go.mod')
|
let l:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off'
|
||||||
|
let l:project_root = l:go_modules_off ?
|
||||||
|
\ '' : ale#path#FindNearestFile(a:buffer, 'go.mod')
|
||||||
let l:mods = ':h'
|
let l:mods = ':h'
|
||||||
|
|
||||||
if empty(l:project_root)
|
if empty(l:project_root)
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
" Description: gosimple for Go files
|
" Description: gosimple for Go files
|
||||||
|
|
||||||
function! ale_linters#go#gosimple#GetCommand(buffer) abort
|
function! ale_linters#go#gosimple#GetCommand(buffer) abort
|
||||||
return ale#path#BufferCdString(a:buffer) . ' gosimple .'
|
return ale#path#BufferCdString(a:buffer) . ' '
|
||||||
|
\ . ale#go#EnvString(a:buffer) . 'gosimple .'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('go', {
|
call ale#linter#Define('go', {
|
||||||
|
|
|
@ -6,7 +6,8 @@ function! ale_linters#go#gotype#GetCommand(buffer) abort
|
||||||
return ''
|
return ''
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return ale#path#BufferCdString(a:buffer) . ' gotype -e .'
|
return ale#path#BufferCdString(a:buffer) . ' '
|
||||||
|
\ . ale#go#EnvString(a:buffer) . 'gotype -e .'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('go', {
|
call ale#linter#Define('go', {
|
||||||
|
|
|
@ -11,6 +11,7 @@ function! ale_linters#go#govet#GetCommand(buffer) abort
|
||||||
let l:options = ale#Var(a:buffer, 'go_govet_options')
|
let l:options = ale#Var(a:buffer, 'go_govet_options')
|
||||||
|
|
||||||
return ale#path#BufferCdString(a:buffer) . ' '
|
return ale#path#BufferCdString(a:buffer) . ' '
|
||||||
|
\ . ale#go#EnvString(a:buffer)
|
||||||
\ . ale#Var(a:buffer, 'go_go_executable') . ' vet '
|
\ . ale#Var(a:buffer, 'go_go_executable') . ' vet '
|
||||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
\ . ' .'
|
\ . ' .'
|
||||||
|
|
|
@ -15,8 +15,9 @@ function! ale_linters#go#langserver#GetCommand(buffer) abort
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:options = uniq(sort(l:options))
|
let l:options = uniq(sort(l:options))
|
||||||
|
let l:env = ale#go#EnvString(a:buffer)
|
||||||
|
|
||||||
return join(extend(l:executable, l:options), ' ')
|
return l:env . join(extend(l:executable, l:options), ' ')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('go', {
|
call ale#linter#Define('go', {
|
||||||
|
|
|
@ -8,17 +8,18 @@ function! ale_linters#go#staticcheck#GetCommand(buffer) abort
|
||||||
let l:filename = expand('#' . a:buffer . ':t')
|
let l:filename = expand('#' . a:buffer . ':t')
|
||||||
let l:options = ale#Var(a:buffer, 'go_staticcheck_options')
|
let l:options = ale#Var(a:buffer, 'go_staticcheck_options')
|
||||||
let l:lint_package = ale#Var(a:buffer, 'go_staticcheck_lint_package')
|
let l:lint_package = ale#Var(a:buffer, 'go_staticcheck_lint_package')
|
||||||
|
let l:env = ale#go#EnvString(a:buffer)
|
||||||
|
|
||||||
" BufferCdString is used so that we can be sure the paths output from
|
" BufferCdString is used so that we can be sure the paths output from
|
||||||
" staticcheck can be calculated to absolute paths in the Handler
|
" staticcheck can be calculated to absolute paths in the Handler
|
||||||
if l:lint_package
|
if l:lint_package
|
||||||
return ale#path#BufferCdString(a:buffer)
|
return ale#path#BufferCdString(a:buffer)
|
||||||
\ . 'staticcheck'
|
\ . l:env . 'staticcheck'
|
||||||
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
|
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return ale#path#BufferCdString(a:buffer)
|
return ale#path#BufferCdString(a:buffer)
|
||||||
\ . 'staticcheck'
|
\ . l:env . 'staticcheck'
|
||||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
\ . ' ' . ale#Escape(l:filename)
|
\ . ' ' . ale#Escape(l:filename)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
" Author: Devon Meunier <devon.meunier@gmail.com>
|
" Author: Devon Meunier <devon.meunier@gmail.com>
|
||||||
" Description: checkstyle for Java files
|
" Description: checkstyle for Java files
|
||||||
|
|
||||||
|
call ale#Set('java_checkstyle_executable', 'checkstyle')
|
||||||
|
call ale#Set('java_checkstyle_config', '/google_checks.xml')
|
||||||
|
call ale#Set('java_checkstyle_options', '')
|
||||||
|
|
||||||
function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
|
function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
|
||||||
let l:output = []
|
let l:output = []
|
||||||
|
|
||||||
|
@ -17,6 +21,10 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
|
||||||
\})
|
\})
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
|
if !empty(l:output)
|
||||||
|
return l:output
|
||||||
|
endif
|
||||||
|
|
||||||
" old checkstyle versions
|
" old checkstyle versions
|
||||||
let l:pattern = '\v(.+):(\d+): ([^:]+): (.+)$'
|
let l:pattern = '\v(.+):(\d+): ([^:]+): (.+)$'
|
||||||
|
|
||||||
|
@ -31,19 +39,32 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
|
||||||
return l:output
|
return l:output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:GetConfig(buffer, config) abort
|
||||||
|
if ale#path#IsAbsolute(a:config)
|
||||||
|
return a:config
|
||||||
|
endif
|
||||||
|
|
||||||
|
let s:file = ale#path#FindNearestFile(a:buffer, a:config)
|
||||||
|
|
||||||
|
return !empty(s:file) ? s:file : a:config
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#java#checkstyle#GetCommand(buffer) abort
|
function! ale_linters#java#checkstyle#GetCommand(buffer) abort
|
||||||
return 'checkstyle '
|
let l:options = ale#Var(a:buffer, 'java_checkstyle_options')
|
||||||
\ . ale#Var(a:buffer, 'java_checkstyle_options')
|
let l:config_option = ale#Var(a:buffer, 'java_checkstyle_config')
|
||||||
|
let l:config = l:options !~# '\v(^| )-c' && !empty(l:config_option)
|
||||||
|
\ ? s:GetConfig(a:buffer, l:config_option)
|
||||||
|
\ : ''
|
||||||
|
|
||||||
|
return '%e'
|
||||||
|
\ . ale#Pad(l:options)
|
||||||
|
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
|
||||||
\ . ' %s'
|
\ . ' %s'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
if !exists('g:ale_java_checkstyle_options')
|
|
||||||
let g:ale_java_checkstyle_options = '-c /google_checks.xml'
|
|
||||||
endif
|
|
||||||
|
|
||||||
call ale#linter#Define('java', {
|
call ale#linter#Define('java', {
|
||||||
\ 'name': 'checkstyle',
|
\ 'name': 'checkstyle',
|
||||||
\ 'executable': 'checkstyle',
|
\ 'executable': {b -> ale#Var(b, 'java_checkstyle_executable')},
|
||||||
\ 'command': function('ale_linters#java#checkstyle#GetCommand'),
|
\ 'command': function('ale_linters#java#checkstyle#GetCommand'),
|
||||||
\ 'callback': 'ale_linters#java#checkstyle#Handle',
|
\ 'callback': 'ale_linters#java#checkstyle#Handle',
|
||||||
\ 'lint_file': 1,
|
\ 'lint_file': 1,
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
let s:version_cache = {}
|
let s:version_cache = {}
|
||||||
|
|
||||||
call ale#Set('java_eclipselsp_path', ale#path#Simplify($HOME . '/eclipse.jdt.ls'))
|
call ale#Set('java_eclipselsp_path', ale#path#Simplify($HOME . '/eclipse.jdt.ls'))
|
||||||
|
call ale#Set('java_eclipselsp_config_path', '')
|
||||||
|
call ale#Set('java_eclipselsp_workspace_path', '')
|
||||||
call ale#Set('java_eclipselsp_executable', 'java')
|
call ale#Set('java_eclipselsp_executable', 'java')
|
||||||
|
|
||||||
function! ale_linters#java#eclipselsp#Executable(buffer) abort
|
function! ale_linters#java#eclipselsp#Executable(buffer) abort
|
||||||
|
@ -32,11 +34,23 @@ function! ale_linters#java#eclipselsp#JarPath(buffer) abort
|
||||||
return l:files[0]
|
return l:files[0]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" Search jar file within system package path
|
||||||
|
let l:files = globpath('/usr/share/java/jdtls/plugins', 'org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
|
||||||
|
|
||||||
|
if len(l:files) == 1
|
||||||
|
return l:files[0]
|
||||||
|
endif
|
||||||
|
|
||||||
return ''
|
return ''
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#java#eclipselsp#ConfigurationPath(buffer) abort
|
function! ale_linters#java#eclipselsp#ConfigurationPath(buffer) abort
|
||||||
let l:path = fnamemodify(ale_linters#java#eclipselsp#JarPath(a:buffer), ':p:h:h')
|
let l:path = fnamemodify(ale_linters#java#eclipselsp#JarPath(a:buffer), ':p:h:h')
|
||||||
|
let l:config_path = ale#Var(a:buffer, 'java_eclipselsp_config_path')
|
||||||
|
|
||||||
|
if !empty(l:config_path)
|
||||||
|
return ale#path#Simplify(l:config_path)
|
||||||
|
endif
|
||||||
|
|
||||||
if has('win32')
|
if has('win32')
|
||||||
let l:path = l:path . '/config_win'
|
let l:path = l:path . '/config_win'
|
||||||
|
@ -76,6 +90,16 @@ function! ale_linters#java#eclipselsp#CommandWithVersion(buffer, version_lines,
|
||||||
return ale_linters#java#eclipselsp#Command(a:buffer, l:version)
|
return ale_linters#java#eclipselsp#Command(a:buffer, l:version)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#java#eclipselsp#WorkspacePath(buffer) abort
|
||||||
|
let l:wspath = ale#Var(a:buffer, 'java_eclipselsp_workspace_path')
|
||||||
|
|
||||||
|
if !empty(l:wspath)
|
||||||
|
return l:wspath
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ale#path#Dirname(ale#java#FindProjectRoot(a:buffer))
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#java#eclipselsp#Command(buffer, version) abort
|
function! ale_linters#java#eclipselsp#Command(buffer, version) abort
|
||||||
let l:path = ale#Var(a:buffer, 'java_eclipselsp_path')
|
let l:path = ale#Var(a:buffer, 'java_eclipselsp_path')
|
||||||
|
|
||||||
|
@ -89,11 +113,11 @@ function! ale_linters#java#eclipselsp#Command(buffer, version) abort
|
||||||
\ '-noverify',
|
\ '-noverify',
|
||||||
\ '-Xmx1G',
|
\ '-Xmx1G',
|
||||||
\ '-jar',
|
\ '-jar',
|
||||||
\ ale_linters#java#eclipselsp#JarPath(a:buffer),
|
\ ale#Escape(ale_linters#java#eclipselsp#JarPath(a:buffer)),
|
||||||
\ '-configuration',
|
\ '-configuration',
|
||||||
\ ale_linters#java#eclipselsp#ConfigurationPath(a:buffer),
|
\ ale#Escape(ale_linters#java#eclipselsp#ConfigurationPath(a:buffer)),
|
||||||
\ '-data',
|
\ '-data',
|
||||||
\ ale#java#FindProjectRoot(a:buffer)
|
\ ale#Escape(ale_linters#java#eclipselsp#WorkspacePath(a:buffer))
|
||||||
\ ]
|
\ ]
|
||||||
|
|
||||||
if ale#semver#GTE(a:version, [1, 9])
|
if ale#semver#GTE(a:version, [1, 9])
|
||||||
|
|
|
@ -21,6 +21,11 @@ function! ale_linters#java#javac#RunWithImportPaths(buffer) abort
|
||||||
let l:command = ale#gradle#BuildClasspathCommand(a:buffer)
|
let l:command = ale#gradle#BuildClasspathCommand(a:buffer)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" Try to use Ant if Gradle and Maven aren't available
|
||||||
|
if empty(l:command)
|
||||||
|
let l:command = ale#ant#BuildClasspathCommand(a:buffer)
|
||||||
|
endif
|
||||||
|
|
||||||
if empty(l:command)
|
if empty(l:command)
|
||||||
return ale_linters#java#javac#GetCommand(a:buffer, [], {})
|
return ale_linters#java#javac#GetCommand(a:buffer, [], {})
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -1,16 +1,47 @@
|
||||||
" Author: Horacio Sanson <https://github.com/hsanson>
|
" Author: Horacio Sanson <https://github.com/hsanson>
|
||||||
" Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac
|
" Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac
|
||||||
|
|
||||||
call ale#Set('java_javalsp_executable', 'java')
|
call ale#Set('java_javalsp_executable', '')
|
||||||
|
call ale#Set('java_javalsp_config', {})
|
||||||
|
|
||||||
function! ale_linters#java#javalsp#Executable(buffer) abort
|
function! ale_linters#java#javalsp#Executable(buffer) abort
|
||||||
return ale#Var(a:buffer, 'java_javalsp_executable')
|
return ale#Var(a:buffer, 'java_javalsp_executable')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#java#javalsp#Config(buffer) abort
|
||||||
|
let l:defaults = { 'java': { 'classPath': [], 'externalDependencies': [] } }
|
||||||
|
let l:config = ale#Var(a:buffer, 'java_javalsp_config')
|
||||||
|
|
||||||
|
" Ensure the config dictionary contains both classPath and
|
||||||
|
" externalDependencies keys to avoid a NPE crash on Java Language Server.
|
||||||
|
call extend(l:config, l:defaults, 'keep')
|
||||||
|
call extend(l:config['java'], l:defaults['java'], 'keep')
|
||||||
|
|
||||||
|
return l:config
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#java#javalsp#Command(buffer) abort
|
function! ale_linters#java#javalsp#Command(buffer) abort
|
||||||
let l:executable = ale_linters#java#javalsp#Executable(a:buffer)
|
let l:executable = ale_linters#java#javalsp#Executable(a:buffer)
|
||||||
|
|
||||||
return ale#Escape(l:executable) . ' -Xverify:none -m javacs/org.javacs.Main'
|
if fnamemodify(l:executable, ':t') is# 'java'
|
||||||
|
" For backward compatibility.
|
||||||
|
let l:cmd = [
|
||||||
|
\ ale#Escape(l:executable),
|
||||||
|
\ '--add-exports jdk.compiler/com.sun.tools.javac.api=javacs',
|
||||||
|
\ '--add-exports jdk.compiler/com.sun.tools.javac.code=javacs',
|
||||||
|
\ '--add-exports jdk.compiler/com.sun.tools.javac.comp=javacs',
|
||||||
|
\ '--add-exports jdk.compiler/com.sun.tools.javac.main=javacs',
|
||||||
|
\ '--add-exports jdk.compiler/com.sun.tools.javac.tree=javacs',
|
||||||
|
\ '--add-exports jdk.compiler/com.sun.tools.javac.model=javacs',
|
||||||
|
\ '--add-exports jdk.compiler/com.sun.tools.javac.util=javacs',
|
||||||
|
\ '--add-opens jdk.compiler/com.sun.tools.javac.api=javacs',
|
||||||
|
\ '-m javacs/org.javacs.Main',
|
||||||
|
\]
|
||||||
|
|
||||||
|
return join(l:cmd, ' ')
|
||||||
|
else
|
||||||
|
return ale#Escape(l:executable)
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('java', {
|
call ale#linter#Define('java', {
|
||||||
|
@ -20,4 +51,5 @@ call ale#linter#Define('java', {
|
||||||
\ 'command': function('ale_linters#java#javalsp#Command'),
|
\ 'command': function('ale_linters#java#javalsp#Command'),
|
||||||
\ 'language': 'java',
|
\ 'language': 'java',
|
||||||
\ 'project_root': function('ale#java#FindProjectRoot'),
|
\ 'project_root': function('ale#java#FindProjectRoot'),
|
||||||
|
\ 'lsp_config': function('ale_linters#java#javalsp#Config')
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -6,5 +6,5 @@ call ale#linter#Define('javascript', {
|
||||||
\ 'output_stream': 'both',
|
\ 'output_stream': 'both',
|
||||||
\ 'executable': function('ale#handlers#eslint#GetExecutable'),
|
\ 'executable': function('ale#handlers#eslint#GetExecutable'),
|
||||||
\ 'command': function('ale#handlers#eslint#GetCommand'),
|
\ 'command': function('ale#handlers#eslint#GetCommand'),
|
||||||
\ 'callback': 'ale#handlers#eslint#Handle',
|
\ 'callback': 'ale#handlers#eslint#HandleJSON',
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -14,7 +14,7 @@ endfunction
|
||||||
function! ale_linters#javascript#xo#GetCommand(buffer) abort
|
function! ale_linters#javascript#xo#GetCommand(buffer) abort
|
||||||
return ale#Escape(ale_linters#javascript#xo#GetExecutable(a:buffer))
|
return ale#Escape(ale_linters#javascript#xo#GetExecutable(a:buffer))
|
||||||
\ . ' ' . ale#Var(a:buffer, 'javascript_xo_options')
|
\ . ' ' . ale#Var(a:buffer, 'javascript_xo_options')
|
||||||
\ . ' --reporter unix --stdin --stdin-filename %s'
|
\ . ' --reporter json --stdin --stdin-filename %s'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" xo uses eslint and the output format is the same
|
" xo uses eslint and the output format is the same
|
||||||
|
@ -22,5 +22,5 @@ call ale#linter#Define('javascript', {
|
||||||
\ 'name': 'xo',
|
\ 'name': 'xo',
|
||||||
\ 'executable': function('ale_linters#javascript#xo#GetExecutable'),
|
\ 'executable': function('ale_linters#javascript#xo#GetExecutable'),
|
||||||
\ 'command': function('ale_linters#javascript#xo#GetCommand'),
|
\ 'command': function('ale_linters#javascript#xo#GetCommand'),
|
||||||
\ 'callback': 'ale#handlers#eslint#Handle',
|
\ 'callback': 'ale#handlers#eslint#HandleJSON',
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -4,12 +4,6 @@
|
||||||
call ale#Set('objc_clangd_executable', 'clangd')
|
call ale#Set('objc_clangd_executable', 'clangd')
|
||||||
call ale#Set('objc_clangd_options', '')
|
call ale#Set('objc_clangd_options', '')
|
||||||
|
|
||||||
function! ale_linters#objc#clangd#GetProjectRoot(buffer) abort
|
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
|
||||||
|
|
||||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ale_linters#objc#clangd#GetCommand(buffer) abort
|
function! ale_linters#objc#clangd#GetCommand(buffer) abort
|
||||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'objc_clangd_options'))
|
return '%e' . ale#Pad(ale#Var(a:buffer, 'objc_clangd_options'))
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -19,5 +13,5 @@ call ale#linter#Define('objc', {
|
||||||
\ 'lsp': 'stdio',
|
\ 'lsp': 'stdio',
|
||||||
\ 'executable': {b -> ale#Var(b, 'objc_clangd_executable')},
|
\ 'executable': {b -> ale#Var(b, 'objc_clangd_executable')},
|
||||||
\ 'command': function('ale_linters#objc#clangd#GetCommand'),
|
\ 'command': function('ale_linters#objc#clangd#GetCommand'),
|
||||||
\ 'project_root': function('ale_linters#objc#clangd#GetProjectRoot'),
|
\ 'project_root': function('ale#c#FindProjectRoot'),
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -4,12 +4,6 @@
|
||||||
call ale#Set('objcpp_clangd_executable', 'clangd')
|
call ale#Set('objcpp_clangd_executable', 'clangd')
|
||||||
call ale#Set('objcpp_clangd_options', '')
|
call ale#Set('objcpp_clangd_options', '')
|
||||||
|
|
||||||
function! ale_linters#objcpp#clangd#GetProjectRoot(buffer) abort
|
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
|
||||||
|
|
||||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ale_linters#objcpp#clangd#GetCommand(buffer) abort
|
function! ale_linters#objcpp#clangd#GetCommand(buffer) abort
|
||||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'objcpp_clangd_options'))
|
return '%e' . ale#Pad(ale#Var(a:buffer, 'objcpp_clangd_options'))
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -19,5 +13,5 @@ call ale#linter#Define('objcpp', {
|
||||||
\ 'lsp': 'stdio',
|
\ 'lsp': 'stdio',
|
||||||
\ 'executable': {b -> ale#Var(b, 'objcpp_clangd_executable')},
|
\ 'executable': {b -> ale#Var(b, 'objcpp_clangd_executable')},
|
||||||
\ 'command': function('ale_linters#objcpp#clangd#GetCommand'),
|
\ 'command': function('ale_linters#objcpp#clangd#GetCommand'),
|
||||||
\ 'project_root': function('ale_linters#objcpp#clangd#GetProjectRoot'),
|
\ 'project_root': function('ale#c#FindProjectRoot'),
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -10,13 +10,13 @@ call ale#Set('php_phpcs_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||||
function! ale_linters#php#phpcs#GetCommand(buffer) abort
|
function! ale_linters#php#phpcs#GetCommand(buffer) abort
|
||||||
let l:standard = ale#Var(a:buffer, 'php_phpcs_standard')
|
let l:standard = ale#Var(a:buffer, 'php_phpcs_standard')
|
||||||
let l:standard_option = !empty(l:standard)
|
let l:standard_option = !empty(l:standard)
|
||||||
\ ? '--standard=' . l:standard
|
\ ? '--standard=' . ale#Escape(l:standard)
|
||||||
\ : ''
|
\ : ''
|
||||||
let l:options = ale#Var(a:buffer, 'php_phpcs_options')
|
|
||||||
|
|
||||||
return '%e -s --report=emacs --stdin-path=%s'
|
return ale#path#BufferCdString(a:buffer)
|
||||||
|
\ . '%e -s --report=emacs --stdin-path=%s'
|
||||||
\ . ale#Pad(l:standard_option)
|
\ . ale#Pad(l:standard_option)
|
||||||
\ . ale#Pad(l:options)
|
\ . ale#Pad(ale#Var(a:buffer, 'php_phpcs_options'))
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#php#phpcs#Handle(buffer, lines) abort
|
function! ale_linters#php#phpcs#Handle(buffer, lines) abort
|
||||||
|
@ -36,6 +36,7 @@ function! ale_linters#php#phpcs#Handle(buffer, lines) abort
|
||||||
\ 'col': l:match[2] + 0,
|
\ 'col': l:match[2] + 0,
|
||||||
\ 'text': l:text,
|
\ 'text': l:text,
|
||||||
\ 'type': l:type is# 'error' ? 'E' : 'W',
|
\ 'type': l:type is# 'error' ? 'E' : 'W',
|
||||||
|
\ 'sub_type': 'style',
|
||||||
\})
|
\})
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
|
|
|
@ -49,11 +49,19 @@ function! ale_linters#powershell#powershell#Handle(buffer, lines) abort
|
||||||
let l:matchcount = 1
|
let l:matchcount = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" If the match is 0, it was a failed match
|
||||||
|
" probably due to an unexpected token which
|
||||||
|
" contained a newline. Reset matchcount. to
|
||||||
|
" continue to the next match
|
||||||
|
if !empty(l:match[1])
|
||||||
let l:item = {
|
let l:item = {
|
||||||
\ 'lnum': str2nr(l:match[1]),
|
\ 'lnum': str2nr(l:match[1]),
|
||||||
\ 'col': str2nr(l:match[2]),
|
\ 'col': str2nr(l:match[2]),
|
||||||
\ 'type': 'E',
|
\ 'type': 'E',
|
||||||
\}
|
\}
|
||||||
|
else
|
||||||
|
let l:matchcount = 0
|
||||||
|
endif
|
||||||
elseif l:matchcount == 2
|
elseif l:matchcount == 2
|
||||||
" Second match[0] grabs the full line in order
|
" Second match[0] grabs the full line in order
|
||||||
" to handles the text
|
" to handles the text
|
||||||
|
@ -84,8 +92,8 @@ endfunction
|
||||||
|
|
||||||
call ale#linter#Define('powershell', {
|
call ale#linter#Define('powershell', {
|
||||||
\ 'name': 'powershell',
|
\ 'name': 'powershell',
|
||||||
\ 'executable_callback': 'ale_linters#powershell#powershell#GetExecutable',
|
\ 'executable': function('ale_linters#powershell#powershell#GetExecutable'),
|
||||||
\ 'command_callback': 'ale_linters#powershell#powershell#GetCommand',
|
\ 'command': function('ale_linters#powershell#powershell#GetCommand'),
|
||||||
\ 'output_stream': 'stdout',
|
\ 'output_stream': 'stdout',
|
||||||
\ 'callback': 'ale_linters#powershell#powershell#Handle',
|
\ 'callback': 'ale_linters#powershell#powershell#Handle',
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -31,6 +31,20 @@ function! ale_linters#pug#puglint#GetCommand(buffer) abort
|
||||||
\ . ' -r inline %t'
|
\ . ' -r inline %t'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#pug#puglint#Handle(buffer, lines) abort
|
||||||
|
for l:line in a:lines[:10]
|
||||||
|
if l:line =~# '^SyntaxError: '
|
||||||
|
return [{
|
||||||
|
\ 'lnum': 1,
|
||||||
|
\ 'text': 'puglint configuration error (type :ALEDetail for more information)',
|
||||||
|
\ 'detail': join(a:lines, "\n"),
|
||||||
|
\}]
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return ale#handlers#unix#HandleAsError(a:buffer, a:lines)
|
||||||
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('pug', {
|
call ale#linter#Define('pug', {
|
||||||
\ 'name': 'puglint',
|
\ 'name': 'puglint',
|
||||||
\ 'executable': {b -> ale#node#FindExecutable(b, 'pug_puglint', [
|
\ 'executable': {b -> ale#node#FindExecutable(b, 'pug_puglint', [
|
||||||
|
@ -38,5 +52,5 @@ call ale#linter#Define('pug', {
|
||||||
\ ])},
|
\ ])},
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'command': function('ale_linters#pug#puglint#GetCommand'),
|
\ 'command': function('ale_linters#pug#puglint#GetCommand'),
|
||||||
\ 'callback': 'ale#handlers#unix#HandleAsError',
|
\ 'callback': 'ale_linters#pug#puglint#Handle',
|
||||||
\})
|
\})
|
||||||
|
|
49
sources_non_forked/ale/ale_linters/purescript/ls.vim
Normal file
49
sources_non_forked/ale/ale_linters/purescript/ls.vim
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
" Author: Drew Olson <drew@drewolson.org>
|
||||||
|
" Description: Integrate ALE with purescript-language-server.
|
||||||
|
|
||||||
|
call ale#Set('purescript_ls_executable', 'purescript-language-server')
|
||||||
|
call ale#Set('purescript_ls_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||||
|
call ale#Set('purescript_ls_config', {})
|
||||||
|
|
||||||
|
function! ale_linters#purescript#ls#GetExecutable(buffer) abort
|
||||||
|
return ale#node#FindExecutable(a:buffer, 'purescript_ls', [
|
||||||
|
\ 'node_modules/.bin/purescript-language-server',
|
||||||
|
\])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#purescript#ls#GetCommand(buffer) abort
|
||||||
|
let l:executable = ale_linters#purescript#ls#GetExecutable(a:buffer)
|
||||||
|
|
||||||
|
return ale#Escape(l:executable) . ' --stdio'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#purescript#ls#FindProjectRoot(buffer) abort
|
||||||
|
let l:config = ale#path#FindNearestFile(a:buffer, 'bower.json')
|
||||||
|
|
||||||
|
if !empty(l:config)
|
||||||
|
return fnamemodify(l:config, ':h')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:config = ale#path#FindNearestFile(a:buffer, 'psc-package.json')
|
||||||
|
|
||||||
|
if !empty(l:config)
|
||||||
|
return fnamemodify(l:config, ':h')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:config = ale#path#FindNearestFile(a:buffer, 'spago.dhall')
|
||||||
|
|
||||||
|
if !empty(l:config)
|
||||||
|
return fnamemodify(l:config, ':h')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('purescript', {
|
||||||
|
\ 'name': 'purescript-language-server',
|
||||||
|
\ 'lsp': 'stdio',
|
||||||
|
\ 'executable': function('ale_linters#purescript#ls#GetExecutable'),
|
||||||
|
\ 'command': function('ale_linters#purescript#ls#GetCommand'),
|
||||||
|
\ 'project_root': function('ale_linters#purescript#ls#FindProjectRoot'),
|
||||||
|
\ 'lsp_config': {b -> ale#Var(b, 'purescript_ls_config')},
|
||||||
|
\})
|
|
@ -78,4 +78,5 @@ call ale#linter#Define('python', {
|
||||||
\ 'executable': function('ale_linters#python#mypy#GetExecutable'),
|
\ 'executable': function('ale_linters#python#mypy#GetExecutable'),
|
||||||
\ 'command': function('ale_linters#python#mypy#GetCommand'),
|
\ 'command': function('ale_linters#python#mypy#GetCommand'),
|
||||||
\ 'callback': 'ale_linters#python#mypy#Handle',
|
\ 'callback': 'ale_linters#python#mypy#Handle',
|
||||||
|
\ 'output_stream': 'both'
|
||||||
\})
|
\})
|
||||||
|
|
23
sources_non_forked/ale/ale_linters/reason/ls.vim
Normal file
23
sources_non_forked/ale/ale_linters/reason/ls.vim
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
" Author: David Buchan-Swanson <github@deecewan.com>
|
||||||
|
" Description: Integrate ALE with reason-language-server.
|
||||||
|
|
||||||
|
call ale#Set('reason_ls_executable', '')
|
||||||
|
|
||||||
|
function! ale_linters#reason#ls#FindProjectRoot(buffer) abort
|
||||||
|
let l:reason_config = ale#path#FindNearestFile(a:buffer, 'bsconfig.json')
|
||||||
|
|
||||||
|
if !empty(l:reason_config)
|
||||||
|
return fnamemodify(l:reason_config, ':h')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('reason', {
|
||||||
|
\ 'name': 'reason-language-server',
|
||||||
|
\ 'lsp': 'stdio',
|
||||||
|
\ 'executable': {buffer -> ale#Var(buffer, 'reason_ls_executable')},
|
||||||
|
\ 'command': '%e',
|
||||||
|
\ 'project_root': function('ale_linters#reason#ls#FindProjectRoot'),
|
||||||
|
\ 'language': 'reason',
|
||||||
|
\})
|
23
sources_non_forked/ale/ale_linters/ruby/sorbet.vim
Normal file
23
sources_non_forked/ale/ale_linters/ruby/sorbet.vim
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
call ale#Set('ruby_sorbet_executable', 'srb')
|
||||||
|
call ale#Set('ruby_sorbet_options', '')
|
||||||
|
|
||||||
|
function! ale_linters#ruby#sorbet#GetCommand(buffer) abort
|
||||||
|
let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable')
|
||||||
|
let l:options = ale#Var(a:buffer, 'ruby_sorbet_options')
|
||||||
|
|
||||||
|
return ale#handlers#ruby#EscapeExecutable(l:executable, 'srb')
|
||||||
|
\ . ' tc'
|
||||||
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
|
\ . ' --lsp --disable-watchman'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('ruby', {
|
||||||
|
\ 'name': 'sorbet',
|
||||||
|
\ 'aliases': ['srb'],
|
||||||
|
\ 'lsp': 'stdio',
|
||||||
|
\ 'language': 'ruby',
|
||||||
|
\ 'executable': {b -> ale#Var(b, 'ruby_sorbet_executable')},
|
||||||
|
\ 'command': function('ale_linters#ruby#sorbet#GetCommand'),
|
||||||
|
\ 'project_root': function('ale#ruby#FindProjectRoot')
|
||||||
|
\})
|
||||||
|
|
|
@ -25,14 +25,11 @@ endfunction
|
||||||
function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
|
function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
|
||||||
let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check')
|
let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check')
|
||||||
\ && ale#semver#GTE(a:version, [0, 17, 0])
|
\ && ale#semver#GTE(a:version, [0, 17, 0])
|
||||||
let l:use_all_targets = l:use_check
|
let l:use_all_targets = ale#Var(a:buffer, 'rust_cargo_check_all_targets')
|
||||||
\ && ale#Var(a:buffer, 'rust_cargo_check_all_targets')
|
|
||||||
\ && ale#semver#GTE(a:version, [0, 22, 0])
|
\ && ale#semver#GTE(a:version, [0, 22, 0])
|
||||||
let l:use_examples = l:use_check
|
let l:use_examples = ale#Var(a:buffer, 'rust_cargo_check_examples')
|
||||||
\ && ale#Var(a:buffer, 'rust_cargo_check_examples')
|
|
||||||
\ && ale#semver#GTE(a:version, [0, 22, 0])
|
\ && ale#semver#GTE(a:version, [0, 22, 0])
|
||||||
let l:use_tests = l:use_check
|
let l:use_tests = ale#Var(a:buffer, 'rust_cargo_check_tests')
|
||||||
\ && ale#Var(a:buffer, 'rust_cargo_check_tests')
|
|
||||||
\ && ale#semver#GTE(a:version, [0, 22, 0])
|
\ && ale#semver#GTE(a:version, [0, 22, 0])
|
||||||
|
|
||||||
let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features')
|
let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features')
|
||||||
|
@ -69,7 +66,15 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
|
||||||
|
|
||||||
if ale#Var(a:buffer, 'rust_cargo_use_clippy')
|
if ale#Var(a:buffer, 'rust_cargo_use_clippy')
|
||||||
let l:subcommand = 'clippy'
|
let l:subcommand = 'clippy'
|
||||||
let l:clippy_options = ' ' . ale#Var(a:buffer, 'rust_cargo_clippy_options')
|
let l:clippy_options = ale#Var(a:buffer, 'rust_cargo_clippy_options')
|
||||||
|
|
||||||
|
if l:clippy_options =~# '^-- '
|
||||||
|
let l:clippy_options = join(split(l:clippy_options, '-- '))
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:clippy_options isnot# ''
|
||||||
|
let l:clippy_options = ' -- ' . l:clippy_options
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return l:nearest_cargo_prefix . 'cargo '
|
return l:nearest_cargo_prefix . 'cargo '
|
||||||
|
|
49
sources_non_forked/ale/ale_linters/terraform/terraform.vim
Normal file
49
sources_non_forked/ale/ale_linters/terraform/terraform.vim
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
" Author: Keith Maxwell <keith.maxwell@gmail.com>
|
||||||
|
" Description: terraform fmt to check for errors
|
||||||
|
|
||||||
|
call ale#Set('terraform_terraform_executable', 'terraform')
|
||||||
|
|
||||||
|
function! ale_linters#terraform#terraform#GetExecutable(buffer) abort
|
||||||
|
return ale#Var(a:buffer, 'terraform_terraform_executable')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#terraform#terraform#GetCommand(buffer) abort
|
||||||
|
return ale#Escape(ale_linters#terraform#terraform#GetExecutable(a:buffer))
|
||||||
|
\ . ' fmt -no-color --check=true -'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#terraform#terraform#Handle(buffer, lines) abort
|
||||||
|
let l:head = '^Error running fmt: In <standard input>: '
|
||||||
|
let l:output = []
|
||||||
|
let l:patterns = [
|
||||||
|
\ l:head.'At \(\d\+\):\(\d\+\): \(.*\)$',
|
||||||
|
\ l:head.'\(.*\)$'
|
||||||
|
\]
|
||||||
|
|
||||||
|
for l:match in ale#util#GetMatches(a:lines, l:patterns)
|
||||||
|
if len(l:match[2]) > 0
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'lnum': str2nr(l:match[1]),
|
||||||
|
\ 'col': str2nr(l:match[2]),
|
||||||
|
\ 'text': l:match[3],
|
||||||
|
\ 'type': 'E',
|
||||||
|
\})
|
||||||
|
else
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'lnum': line('$'),
|
||||||
|
\ 'text': l:match[1],
|
||||||
|
\ 'type': 'E',
|
||||||
|
\})
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('terraform', {
|
||||||
|
\ 'name': 'terraform',
|
||||||
|
\ 'output_stream': 'stderr',
|
||||||
|
\ 'executable': function('ale_linters#terraform#terraform#GetExecutable'),
|
||||||
|
\ 'command': function('ale_linters#terraform#terraform#GetCommand'),
|
||||||
|
\ 'callback': 'ale_linters#terraform#terraform#Handle',
|
||||||
|
\})
|
21
sources_non_forked/ale/ale_linters/tex/texlab.vim
Normal file
21
sources_non_forked/ale/ale_linters/tex/texlab.vim
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
" Author: Ricardo Liang <ricardoliang@gmail.com>
|
||||||
|
" Description: Texlab language server (Rust rewrite)
|
||||||
|
|
||||||
|
call ale#Set('tex_texlab_executable', 'texlab')
|
||||||
|
call ale#Set('tex_texlab_options', '')
|
||||||
|
|
||||||
|
function! ale_linters#tex#texlab#GetProjectRoot(buffer) abort
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#tex#texlab#GetCommand(buffer) abort
|
||||||
|
return '%e' . ale#Pad(ale#Var(a:buffer, 'tex_texlab_options'))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('tex', {
|
||||||
|
\ 'name': 'texlab',
|
||||||
|
\ 'lsp': 'stdio',
|
||||||
|
\ 'executable': {b -> ale#Var(b, 'tex_texlab_executable')},
|
||||||
|
\ 'command': function('ale_linters#tex#texlab#GetCommand'),
|
||||||
|
\ 'project_root': function('ale_linters#tex#texlab#GetProjectRoot'),
|
||||||
|
\})
|
|
@ -5,5 +5,5 @@ call ale#linter#Define('typescript', {
|
||||||
\ 'name': 'eslint',
|
\ 'name': 'eslint',
|
||||||
\ 'executable': function('ale#handlers#eslint#GetExecutable'),
|
\ 'executable': function('ale#handlers#eslint#GetExecutable'),
|
||||||
\ 'command': function('ale#handlers#eslint#GetCommand'),
|
\ 'command': function('ale#handlers#eslint#GetCommand'),
|
||||||
\ 'callback': 'ale#handlers#eslint#Handle',
|
\ 'callback': 'ale#handlers#eslint#HandleJSON',
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -11,7 +11,7 @@ endfunction
|
||||||
function! ale_linters#typescript#xo#GetCommand(buffer) abort
|
function! ale_linters#typescript#xo#GetCommand(buffer) abort
|
||||||
return ale#Escape(ale_linters#typescript#xo#GetExecutable(a:buffer))
|
return ale#Escape(ale_linters#typescript#xo#GetExecutable(a:buffer))
|
||||||
\ . ale#Pad(ale#Var(a:buffer, 'typescript_xo_options'))
|
\ . ale#Pad(ale#Var(a:buffer, 'typescript_xo_options'))
|
||||||
\ . ' --reporter unix --stdin --stdin-filename %s'
|
\ . ' --reporter json --stdin --stdin-filename %s'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" xo uses eslint and the output format is the same
|
" xo uses eslint and the output format is the same
|
||||||
|
@ -19,5 +19,5 @@ call ale#linter#Define('typescript', {
|
||||||
\ 'name': 'xo',
|
\ 'name': 'xo',
|
||||||
\ 'executable': function('ale_linters#typescript#xo#GetExecutable'),
|
\ 'executable': function('ale_linters#typescript#xo#GetExecutable'),
|
||||||
\ 'command': function('ale_linters#typescript#xo#GetCommand'),
|
\ 'command': function('ale_linters#typescript#xo#GetCommand'),
|
||||||
\ 'callback': 'ale#handlers#eslint#Handle',
|
\ 'callback': 'ale#handlers#eslint#HandleJSON',
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -156,7 +156,7 @@ function! ale#Queue(delay, ...) abort
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
let s:current_ale_version = [2, 4, 0]
|
let s:current_ale_version = [2, 5, 0]
|
||||||
|
|
||||||
" A function used to check for ALE features in files outside of the project.
|
" A function used to check for ALE features in files outside of the project.
|
||||||
function! ale#Has(feature) abort
|
function! ale#Has(feature) abort
|
||||||
|
|
41
sources_non_forked/ale/autoload/ale/ant.vim
Normal file
41
sources_non_forked/ale/autoload/ale/ant.vim
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
" Author: Andrew Lee <andrewl@mbda.fun>.
|
||||||
|
" Inspired by ale/gradle.vim by Michael Pardo <michael@michaelpardo.com>
|
||||||
|
" Description: Functions for working with Ant projects.
|
||||||
|
|
||||||
|
" Given a buffer number, find an Ant project root
|
||||||
|
function! ale#ant#FindProjectRoot(buffer) abort
|
||||||
|
let l:build_xml_path = ale#path#FindNearestFile(a:buffer, 'build.xml')
|
||||||
|
|
||||||
|
if !empty(l:build_xml_path)
|
||||||
|
return fnamemodify(l:build_xml_path, ':h')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Given a buffer number, find the path to the `ant` executable. Returns an empty
|
||||||
|
" string if cannot find the executable.
|
||||||
|
function! ale#ant#FindExecutable(buffer) abort
|
||||||
|
if executable('ant')
|
||||||
|
return 'ant'
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Given a buffer number, build a command to print the classpath of the root
|
||||||
|
" project. Returns an empty string if cannot build the command.
|
||||||
|
function! ale#ant#BuildClasspathCommand(buffer) abort
|
||||||
|
let l:executable = ale#ant#FindExecutable(a:buffer)
|
||||||
|
let l:project_root = ale#ant#FindProjectRoot(a:buffer)
|
||||||
|
|
||||||
|
if !empty(l:executable) && !empty(l:project_root)
|
||||||
|
return ale#path#CdString(l:project_root)
|
||||||
|
\ . ale#Escape(l:executable)
|
||||||
|
\ . ' classpath'
|
||||||
|
\ . ' -S'
|
||||||
|
\ . ' -q'
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ''
|
||||||
|
endfunction
|
|
@ -96,6 +96,13 @@ function! ale#assert#Fixer(expected_result) abort
|
||||||
AssertEqual a:expected_result, l:result
|
AssertEqual a:expected_result, l:result
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale#assert#FixerNotExecuted() abort
|
||||||
|
let l:buffer = bufnr('')
|
||||||
|
let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))[-1]
|
||||||
|
|
||||||
|
Assert empty(l:result), "The fixer will be executed when it shouldn't be"
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ale#assert#LinterNotExecuted() abort
|
function! ale#assert#LinterNotExecuted() abort
|
||||||
let l:buffer = bufnr('')
|
let l:buffer = bufnr('')
|
||||||
let l:linter = s:GetLinter()
|
let l:linter = s:GetLinter()
|
||||||
|
@ -158,6 +165,7 @@ endfunction
|
||||||
function! ale#assert#SetUpFixerTestCommands() abort
|
function! ale#assert#SetUpFixerTestCommands() abort
|
||||||
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
|
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
|
||||||
command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>)
|
command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>)
|
||||||
|
command! -nargs=0 AssertFixerNotExecuted :call ale#assert#FixerNotExecuted()
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" A dummy function for making sure this module is loaded.
|
" A dummy function for making sure this module is loaded.
|
||||||
|
@ -316,4 +324,8 @@ function! ale#assert#TearDownFixerTest() abort
|
||||||
if exists(':AssertFixer')
|
if exists(':AssertFixer')
|
||||||
delcommand AssertFixer
|
delcommand AssertFixer
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if exists(':AssertFixerNotExecuted')
|
||||||
|
delcommand AssertFixerNotExecuted
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
@ -23,104 +23,117 @@ function! ale#c#GetBuildDirectory(buffer) abort
|
||||||
return l:build_dir
|
return l:build_dir
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return ale#path#Dirname(ale#c#FindCompileCommands(a:buffer))
|
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||||
|
|
||||||
|
return ale#path#Dirname(l:json_file)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale#c#ShellSplit(line) abort
|
||||||
function! ale#c#FindProjectRoot(buffer) abort
|
|
||||||
for l:project_filename in g:__ale_c_project_filenames
|
|
||||||
let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
|
|
||||||
|
|
||||||
if !empty(l:full_path)
|
|
||||||
let l:path = fnamemodify(l:full_path, ':h')
|
|
||||||
|
|
||||||
" Correct .git path detection.
|
|
||||||
if fnamemodify(l:path, ':t') is# '.git'
|
|
||||||
let l:path = fnamemodify(l:path, ':h')
|
|
||||||
endif
|
|
||||||
|
|
||||||
return l:path
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ale#c#AreSpecialCharsBalanced(option) abort
|
|
||||||
" Escape \"
|
|
||||||
let l:option_escaped = substitute(a:option, '\\"', '', 'g')
|
|
||||||
|
|
||||||
" Retain special chars only
|
|
||||||
let l:special_chars = substitute(l:option_escaped, '[^"''()`]', '', 'g')
|
|
||||||
let l:special_chars = split(l:special_chars, '\zs')
|
|
||||||
|
|
||||||
" Check if they are balanced
|
|
||||||
let l:stack = []
|
let l:stack = []
|
||||||
|
let l:args = ['']
|
||||||
|
let l:prev = ''
|
||||||
|
|
||||||
for l:char in l:special_chars
|
for l:char in split(a:line, '\zs')
|
||||||
if l:char is# ')'
|
if l:char is# ''''
|
||||||
if len(l:stack) == 0 || get(l:stack, -1) isnot# '('
|
if len(l:stack) > 0 && get(l:stack, -1) is# ''''
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
call remove(l:stack, -1)
|
call remove(l:stack, -1)
|
||||||
elseif l:char is# '('
|
elseif (len(l:stack) == 0 || get(l:stack, -1) isnot# '"') && l:prev isnot# '\'
|
||||||
call add(l:stack, l:char)
|
call add(l:stack, l:char)
|
||||||
else
|
endif
|
||||||
|
elseif (l:char is# '"' || l:char is# '`') && l:prev isnot# '\'
|
||||||
if len(l:stack) > 0 && get(l:stack, -1) is# l:char
|
if len(l:stack) > 0 && get(l:stack, -1) is# l:char
|
||||||
call remove(l:stack, -1)
|
call remove(l:stack, -1)
|
||||||
else
|
elseif len(l:stack) == 0 || get(l:stack, -1) isnot# ''''
|
||||||
call add(l:stack, l:char)
|
call add(l:stack, l:char)
|
||||||
endif
|
endif
|
||||||
|
elseif (l:char is# '(' || l:char is# '[' || l:char is# '{') && l:prev isnot# '\'
|
||||||
|
if len(l:stack) == 0 || get(l:stack, -1) isnot# ''''
|
||||||
|
call add(l:stack, l:char)
|
||||||
endif
|
endif
|
||||||
|
elseif (l:char is# ')' || l:char is# ']' || l:char is# '}') && l:prev isnot# '\'
|
||||||
|
if len(l:stack) > 0 && get(l:stack, -1) is# {')': '(', ']': '[', '}': '{'}[l:char]
|
||||||
|
call remove(l:stack, -1)
|
||||||
|
endif
|
||||||
|
elseif l:char is# ' ' && len(l:stack) == 0
|
||||||
|
if len(get(l:args, -1)) > 0
|
||||||
|
call add(l:args, '')
|
||||||
|
endif
|
||||||
|
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:args[-1] = get(l:args, -1) . l:char
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
return len(l:stack) == 0
|
return l:args
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#c#ParseCFlags(path_prefix, cflag_line) abort
|
function! ale#c#ParseCFlags(path_prefix, cflag_line) abort
|
||||||
let l:split_lines = split(a:cflag_line)
|
let l:cflags_list = []
|
||||||
|
|
||||||
|
let l:split_lines = ale#c#ShellSplit(a:cflag_line)
|
||||||
let l:option_index = 0
|
let l:option_index = 0
|
||||||
|
|
||||||
while l:option_index < len(l:split_lines)
|
while l:option_index < len(l:split_lines)
|
||||||
let l:next_option_index = l:option_index + 1
|
let l:option = l:split_lines[l:option_index]
|
||||||
|
|
||||||
" Join space-separated option
|
|
||||||
while l:next_option_index < len(l:split_lines)
|
|
||||||
\&& stridx(l:split_lines[l:next_option_index], '-') != 0
|
|
||||||
let l:next_option_index += 1
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
let l:option = join(l:split_lines[l:option_index : l:next_option_index-1], ' ')
|
|
||||||
call remove(l:split_lines, l:option_index, l:next_option_index-1)
|
|
||||||
call insert(l:split_lines, l:option, l:option_index)
|
|
||||||
|
|
||||||
" Ignore invalid or conflicting options
|
|
||||||
if stridx(l:option, '-') != 0
|
|
||||||
\|| stridx(l:option, '-o') == 0
|
|
||||||
\|| stridx(l:option, '-c') == 0
|
|
||||||
call remove(l:split_lines, l:option_index)
|
|
||||||
let l:option_index = l:option_index - 1
|
|
||||||
" Fix relative path
|
|
||||||
elseif stridx(l:option, '-I') == 0
|
|
||||||
if !(stridx(l:option, ':') == 2+1 || stridx(l:option, '/') == 2+0)
|
|
||||||
let l:option = '-I' . a:path_prefix . s:sep . l:option[2:]
|
|
||||||
call remove(l:split_lines, l:option_index)
|
|
||||||
call insert(l:split_lines, l:option, l:option_index)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:option_index = l:option_index + 1
|
let l:option_index = l:option_index + 1
|
||||||
|
|
||||||
|
" Include options, that may need relative path fix
|
||||||
|
if stridx(l:option, '-I') == 0
|
||||||
|
\ || stridx(l:option, '-iquote') == 0
|
||||||
|
\ || stridx(l:option, '-isystem') == 0
|
||||||
|
\ || stridx(l:option, '-idirafter') == 0
|
||||||
|
if stridx(l:option, '-I') == 0 && l:option isnot# '-I'
|
||||||
|
let l:arg = join(split(l:option, '\zs')[2:], '')
|
||||||
|
let l:option = '-I'
|
||||||
|
else
|
||||||
|
let l:arg = l:split_lines[l:option_index]
|
||||||
|
let l:option_index = l:option_index + 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Fix relative paths if needed
|
||||||
|
if stridx(l:arg, s:sep) != 0 && stridx(l:arg, '/') != 0
|
||||||
|
let l:rel_path = substitute(l:arg, '"', '', 'g')
|
||||||
|
let l:rel_path = substitute(l:rel_path, '''', '', 'g')
|
||||||
|
let l:arg = ale#Escape(a:path_prefix . s:sep . l:rel_path)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call add(l:cflags_list, l:option)
|
||||||
|
call add(l:cflags_list, l:arg)
|
||||||
|
" Options with arg that can be grouped with the option or separate
|
||||||
|
elseif stridx(l:option, '-D') == 0 || stridx(l:option, '-B') == 0
|
||||||
|
call add(l:cflags_list, l:option)
|
||||||
|
|
||||||
|
if l:option is# '-D' || l:option is# '-B'
|
||||||
|
call add(l:cflags_list, l:split_lines[l:option_index])
|
||||||
|
let l:option_index = l:option_index + 1
|
||||||
|
endif
|
||||||
|
" Options that have an argument (always separate)
|
||||||
|
elseif l:option is# '-iprefix' || stridx(l:option, '-iwithprefix') == 0
|
||||||
|
\ || l:option is# '-isysroot' || l:option is# '-imultilib'
|
||||||
|
call add(l:cflags_list, l:option)
|
||||||
|
call add(l:cflags_list, l:split_lines[l:option_index])
|
||||||
|
let l:option_index = l:option_index + 1
|
||||||
|
" Options without argument
|
||||||
|
elseif (stridx(l:option, '-W') == 0 && stridx(l:option, '-Wa,') != 0 && stridx(l:option, '-Wl,') != 0 && stridx(l:option, '-Wp,') != 0)
|
||||||
|
\ || l:option is# '-w' || stridx(l:option, '-pedantic') == 0
|
||||||
|
\ || l:option is# '-ansi' || stridx(l:option, '-std=') == 0
|
||||||
|
\ || (stridx(l:option, '-f') == 0 && stridx(l:option, '-fdump') != 0 && stridx(l:option, '-fdiagnostics') != 0 && stridx(l:option, '-fno-show-column') != 0)
|
||||||
|
\ || stridx(l:option, '-O') == 0
|
||||||
|
\ || l:option is# '-C' || l:option is# '-CC' || l:option is# '-trigraphs'
|
||||||
|
\ || stridx(l:option, '-nostdinc') == 0 || stridx(l:option, '-iplugindir=') == 0
|
||||||
|
\ || stridx(l:option, '--sysroot=') == 0 || l:option is# '--no-sysroot-suffix'
|
||||||
|
\ || stridx(l:option, '-m') == 0
|
||||||
|
call add(l:cflags_list, l:option)
|
||||||
|
endif
|
||||||
endwhile
|
endwhile
|
||||||
|
|
||||||
call uniq(l:split_lines)
|
return join(l:cflags_list, ' ')
|
||||||
|
|
||||||
return join(l:split_lines, ' ')
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
|
function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
|
||||||
if !g:ale_c_parse_makefile
|
if !g:ale_c_parse_makefile
|
||||||
return ''
|
return v:null
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:buffer_filename = expand('#' . a:buffer . ':t')
|
let l:buffer_filename = expand('#' . a:buffer . ':t')
|
||||||
|
@ -140,14 +153,17 @@ function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
|
||||||
return ale#c#ParseCFlags(l:makefile_dir, l:cflag_line)
|
return ale#c#ParseCFlags(l:makefile_dir, l:cflag_line)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Given a buffer number, find the build subdirectory with compile commands
|
" Given a buffer number, find the project directory containing
|
||||||
" The subdirectory is returned without the trailing /
|
" compile_commands.json, and the path to the compile_commands.json file.
|
||||||
|
"
|
||||||
|
" If compile_commands.json cannot be found, two empty strings will be
|
||||||
|
" returned.
|
||||||
function! ale#c#FindCompileCommands(buffer) abort
|
function! ale#c#FindCompileCommands(buffer) abort
|
||||||
" Look above the current source file to find compile_commands.json
|
" Look above the current source file to find compile_commands.json
|
||||||
let l:json_file = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
let l:json_file = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||||
|
|
||||||
if !empty(l:json_file)
|
if !empty(l:json_file)
|
||||||
return l:json_file
|
return [fnamemodify(l:json_file, ':h'), l:json_file]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Search in build directories if we can't find it in the project.
|
" Search in build directories if we can't find it in the project.
|
||||||
|
@ -157,12 +173,42 @@ function! ale#c#FindCompileCommands(buffer) abort
|
||||||
let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json'
|
let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json'
|
||||||
|
|
||||||
if filereadable(l:json_file)
|
if filereadable(l:json_file)
|
||||||
return l:json_file
|
return [l:path, l:json_file]
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
return ''
|
return ['', '']
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Find the project root for C/C++ projects.
|
||||||
|
"
|
||||||
|
" The location of compile_commands.json will be used to find project roots.
|
||||||
|
"
|
||||||
|
" If compile_commands.json cannot be found, other common configuration files
|
||||||
|
" will be used to detect the project root.
|
||||||
|
function! ale#c#FindProjectRoot(buffer) abort
|
||||||
|
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||||
|
|
||||||
|
" Fall back on detecting the project root based on other filenames.
|
||||||
|
if empty(l:root)
|
||||||
|
for l:project_filename in g:__ale_c_project_filenames
|
||||||
|
let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
|
||||||
|
|
||||||
|
if !empty(l:full_path)
|
||||||
|
let l:path = fnamemodify(l:full_path, ':h')
|
||||||
|
|
||||||
|
" Correct .git path detection.
|
||||||
|
if fnamemodify(l:path, ':t') is# '.git'
|
||||||
|
let l:path = fnamemodify(l:path, ':h')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:path
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:root
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Cache compile_commands.json data in a Dictionary, so we don't need to read
|
" Cache compile_commands.json data in a Dictionary, so we don't need to read
|
||||||
|
@ -194,10 +240,14 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
|
||||||
let l:raw_data = []
|
let l:raw_data = []
|
||||||
silent! let l:raw_data = json_decode(join(readfile(a:compile_commands_file), ''))
|
silent! let l:raw_data = json_decode(join(readfile(a:compile_commands_file), ''))
|
||||||
|
|
||||||
|
if type(l:raw_data) isnot v:t_list
|
||||||
|
let l:raw_data = []
|
||||||
|
endif
|
||||||
|
|
||||||
let l:file_lookup = {}
|
let l:file_lookup = {}
|
||||||
let l:dir_lookup = {}
|
let l:dir_lookup = {}
|
||||||
|
|
||||||
for l:entry in l:raw_data
|
for l:entry in (type(l:raw_data) is v:t_list ? l:raw_data : [])
|
||||||
let l:basename = tolower(fnamemodify(l:entry.file, ':t'))
|
let l:basename = tolower(fnamemodify(l:entry.file, ':t'))
|
||||||
let l:file_lookup[l:basename] = get(l:file_lookup, l:basename, []) + [l:entry]
|
let l:file_lookup[l:basename] = get(l:file_lookup, l:basename, []) + [l:entry]
|
||||||
|
|
||||||
|
@ -274,25 +324,25 @@ function! ale#c#FlagsFromCompileCommands(buffer, compile_commands_file) abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#c#GetCFlags(buffer, output) abort
|
function! ale#c#GetCFlags(buffer, output) abort
|
||||||
let l:cflags = ' '
|
let l:cflags = v:null
|
||||||
|
|
||||||
if ale#Var(a:buffer, 'c_parse_makefile') && !empty(a:output)
|
if ale#Var(a:buffer, 'c_parse_makefile') && !empty(a:output)
|
||||||
let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output)
|
let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ale#Var(a:buffer, 'c_parse_compile_commands')
|
if ale#Var(a:buffer, 'c_parse_compile_commands')
|
||||||
let l:json_file = ale#c#FindCompileCommands(a:buffer)
|
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||||
|
|
||||||
if !empty(l:json_file)
|
if !empty(l:json_file)
|
||||||
let l:cflags = ale#c#FlagsFromCompileCommands(a:buffer, l:json_file)
|
let l:cflags = ale#c#FlagsFromCompileCommands(a:buffer, l:json_file)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if l:cflags is# ' '
|
if l:cflags is v:null
|
||||||
let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))
|
let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return l:cflags
|
return l:cflags isnot v:null ? l:cflags : ''
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#c#GetMakeCommand(buffer) abort
|
function! ale#c#GetMakeCommand(buffer) abort
|
||||||
|
|
|
@ -52,6 +52,7 @@ let s:should_complete_map = {
|
||||||
\ 'lisp': s:lisp_regex,
|
\ 'lisp': s:lisp_regex,
|
||||||
\ 'typescript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|''$|"$',
|
\ 'typescript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|''$|"$',
|
||||||
\ 'rust': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$',
|
\ 'rust': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$',
|
||||||
|
\ 'cpp': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$|-\>$',
|
||||||
\}
|
\}
|
||||||
|
|
||||||
" Regular expressions for finding the start column to replace with completion.
|
" Regular expressions for finding the start column to replace with completion.
|
||||||
|
@ -59,11 +60,13 @@ let s:omni_start_map = {
|
||||||
\ '<default>': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$',
|
\ '<default>': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$',
|
||||||
\}
|
\}
|
||||||
|
|
||||||
" A map of exact characters for triggering LSP completions.
|
" A map of exact characters for triggering LSP completions. Do not forget to
|
||||||
|
" update self.input_patterns in ale.py in updating entries in this map.
|
||||||
let s:trigger_character_map = {
|
let s:trigger_character_map = {
|
||||||
\ '<default>': ['.'],
|
\ '<default>': ['.'],
|
||||||
\ 'typescript': ['.', '''', '"'],
|
\ 'typescript': ['.', '''', '"'],
|
||||||
\ 'rust': ['.', '::'],
|
\ 'rust': ['.', '::'],
|
||||||
|
\ 'cpp': ['.', '::', '->'],
|
||||||
\}
|
\}
|
||||||
|
|
||||||
function! s:GetFiletypeValue(map, filetype) abort
|
function! s:GetFiletypeValue(map, filetype) abort
|
||||||
|
@ -169,7 +172,7 @@ function! s:ReplaceCompletionOptions() abort
|
||||||
let b:ale_old_omnifunc = &l:omnifunc
|
let b:ale_old_omnifunc = &l:omnifunc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let &l:omnifunc = 'ale#completion#OmniFunc'
|
let &l:omnifunc = 'ale#completion#AutomaticOmniFunc'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if l:source is# 'ale-automatic'
|
if l:source is# 'ale-automatic'
|
||||||
|
@ -215,19 +218,11 @@ function! ale#completion#GetCompletionPosition() abort
|
||||||
return l:column - len(l:match) - 1
|
return l:column - len(l:match) - 1
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale#completion#GetCompletionPositionForDeoplete(input) abort
|
||||||
|
return match(a:input, '\k*$')
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ale#completion#GetCompletionResult() abort
|
function! ale#completion#GetCompletionResult() abort
|
||||||
" Parse a new response if there is one.
|
|
||||||
if exists('b:ale_completion_response')
|
|
||||||
\&& exists('b:ale_completion_parser')
|
|
||||||
let l:response = b:ale_completion_response
|
|
||||||
let l:parser = b:ale_completion_parser
|
|
||||||
|
|
||||||
unlet b:ale_completion_response
|
|
||||||
unlet b:ale_completion_parser
|
|
||||||
|
|
||||||
let b:ale_completion_result = function(l:parser)(l:response)
|
|
||||||
endif
|
|
||||||
|
|
||||||
if exists('b:ale_completion_result')
|
if exists('b:ale_completion_result')
|
||||||
return b:ale_completion_result
|
return b:ale_completion_result
|
||||||
endif
|
endif
|
||||||
|
@ -235,7 +230,7 @@ function! ale#completion#GetCompletionResult() abort
|
||||||
return v:null
|
return v:null
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#completion#OmniFunc(findstart, base) abort
|
function! ale#completion#AutomaticOmniFunc(findstart, base) abort
|
||||||
if a:findstart
|
if a:findstart
|
||||||
return ale#completion#GetCompletionPosition()
|
return ale#completion#GetCompletionPosition()
|
||||||
else
|
else
|
||||||
|
@ -247,15 +242,20 @@ function! ale#completion#OmniFunc(findstart, base) abort
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#completion#Show(response, completion_parser) abort
|
function! ale#completion#Show(result) abort
|
||||||
if ale#util#Mode() isnot# 'i'
|
if ale#util#Mode() isnot# 'i'
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Set the list in the buffer, temporarily replace omnifunc with our
|
" Set the list in the buffer, temporarily replace omnifunc with our
|
||||||
" function, and then start omni-completion.
|
" function, and then start omni-completion.
|
||||||
let b:ale_completion_response = a:response
|
let b:ale_completion_result = a:result
|
||||||
let b:ale_completion_parser = a:completion_parser
|
|
||||||
|
" Don't try to open the completion menu if there's nothing to show.
|
||||||
|
if empty(b:ale_completion_result)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
" Replace completion options shortly before opening the menu.
|
" Replace completion options shortly before opening the menu.
|
||||||
call s:ReplaceCompletionOptions()
|
call s:ReplaceCompletionOptions()
|
||||||
|
|
||||||
|
@ -267,6 +267,14 @@ function! ale#completion#Show(response, completion_parser) abort
|
||||||
\ {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")}
|
\ {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")}
|
||||||
\)
|
\)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if l:source is# 'ale-callback'
|
||||||
|
call b:CompleteCallback(b:ale_completion_result)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#completion#GetAllTriggers() abort
|
||||||
|
return deepcopy(s:trigger_character_map)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:CompletionStillValid(request_id) abort
|
function! s:CompletionStillValid(request_id) abort
|
||||||
|
@ -279,6 +287,8 @@ function! s:CompletionStillValid(request_id) abort
|
||||||
\&& (
|
\&& (
|
||||||
\ b:ale_completion_info.column == l:column
|
\ b:ale_completion_info.column == l:column
|
||||||
\ || b:ale_completion_info.source is# 'deoplete'
|
\ || b:ale_completion_info.source is# 'deoplete'
|
||||||
|
\ || b:ale_completion_info.source is# 'ale-omnifunc'
|
||||||
|
\ || b:ale_completion_info.source is# 'ale-callback'
|
||||||
\)
|
\)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -474,8 +484,7 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
|
||||||
endif
|
endif
|
||||||
elseif l:command is# 'completionEntryDetails'
|
elseif l:command is# 'completionEntryDetails'
|
||||||
call ale#completion#Show(
|
call ale#completion#Show(
|
||||||
\ a:response,
|
\ ale#completion#ParseTSServerCompletionEntryDetails(a:response),
|
||||||
\ 'ale#completion#ParseTSServerCompletionEntryDetails',
|
|
||||||
\)
|
\)
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -487,8 +496,7 @@ function! ale#completion#HandleLSPResponse(conn_id, response) abort
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call ale#completion#Show(
|
call ale#completion#Show(
|
||||||
\ a:response,
|
\ ale#completion#ParseLSPCompletions(a:response),
|
||||||
\ 'ale#completion#ParseLSPCompletions',
|
|
||||||
\)
|
\)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -529,10 +537,7 @@ function! s:OnReady(linter, lsp_details) abort
|
||||||
let l:message = ale#lsp#message#Completion(
|
let l:message = ale#lsp#message#Completion(
|
||||||
\ l:buffer,
|
\ l:buffer,
|
||||||
\ b:ale_completion_info.line,
|
\ b:ale_completion_info.line,
|
||||||
\ min([
|
|
||||||
\ b:ale_completion_info.line_length,
|
|
||||||
\ b:ale_completion_info.column,
|
\ b:ale_completion_info.column,
|
||||||
\ ]) + 1,
|
|
||||||
\ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix),
|
\ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix),
|
||||||
\)
|
\)
|
||||||
endif
|
endif
|
||||||
|
@ -564,13 +569,26 @@ endfunction
|
||||||
|
|
||||||
" This function can be used to manually trigger autocomplete, even when
|
" This function can be used to manually trigger autocomplete, even when
|
||||||
" g:ale_completion_enabled is set to false
|
" g:ale_completion_enabled is set to false
|
||||||
function! ale#completion#GetCompletions(source) abort
|
function! ale#completion#GetCompletions(...) abort
|
||||||
|
let l:source = get(a:000, 0, '')
|
||||||
|
let l:options = get(a:000, 1, {})
|
||||||
|
|
||||||
|
if len(a:000) > 2
|
||||||
|
throw 'Too many arguments!'
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:CompleteCallback = get(l:options, 'callback', v:null)
|
||||||
|
|
||||||
|
if l:CompleteCallback isnot v:null
|
||||||
|
let b:CompleteCallback = l:CompleteCallback
|
||||||
|
endif
|
||||||
|
|
||||||
let [l:line, l:column] = getpos('.')[1:2]
|
let [l:line, l:column] = getpos('.')[1:2]
|
||||||
|
|
||||||
let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
|
let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
|
||||||
|
|
||||||
if a:source is# 'ale-automatic' && empty(l:prefix)
|
if l:source is# 'ale-automatic' && empty(l:prefix)
|
||||||
return
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:line_length = len(getline('.'))
|
let l:line_length = len(getline('.'))
|
||||||
|
@ -582,18 +600,47 @@ function! ale#completion#GetCompletions(source) abort
|
||||||
\ 'prefix': l:prefix,
|
\ 'prefix': l:prefix,
|
||||||
\ 'conn_id': 0,
|
\ 'conn_id': 0,
|
||||||
\ 'request_id': 0,
|
\ 'request_id': 0,
|
||||||
\ 'source': a:source,
|
\ 'source': l:source,
|
||||||
\}
|
\}
|
||||||
unlet! b:ale_completion_result
|
unlet! b:ale_completion_result
|
||||||
|
|
||||||
let l:buffer = bufnr('')
|
let l:buffer = bufnr('')
|
||||||
let l:Callback = function('s:OnReady')
|
let l:Callback = function('s:OnReady')
|
||||||
|
|
||||||
|
let l:started = 0
|
||||||
|
|
||||||
for l:linter in ale#linter#Get(&filetype)
|
for l:linter in ale#linter#Get(&filetype)
|
||||||
if !empty(l:linter.lsp)
|
if !empty(l:linter.lsp)
|
||||||
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||||
|
let l:started = 1
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
|
return l:started
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#completion#OmniFunc(findstart, base) abort
|
||||||
|
if a:findstart
|
||||||
|
let l:started = ale#completion#GetCompletions('ale-omnifunc')
|
||||||
|
|
||||||
|
if !l:started
|
||||||
|
" This is the special value for cancelling completions silently.
|
||||||
|
" See :help complete-functions
|
||||||
|
return -3
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ale#completion#GetCompletionPosition()
|
||||||
|
else
|
||||||
|
let l:result = ale#completion#GetCompletionResult()
|
||||||
|
|
||||||
|
while l:result is v:null && !complete_check()
|
||||||
|
sleep 2ms
|
||||||
|
let l:result = ale#completion#GetCompletionResult()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return l:result isnot v:null ? l:result : []
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:TimerHandler(...) abort
|
function! s:TimerHandler(...) abort
|
||||||
|
|
|
@ -62,7 +62,7 @@ function! s:Echo(message) abort
|
||||||
execute 'echo a:message'
|
execute 'echo a:message'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:GetLinterVariables(filetype, linter_names) abort
|
function! s:GetLinterVariables(filetype, exclude_linter_names) abort
|
||||||
let l:variable_list = []
|
let l:variable_list = []
|
||||||
let l:filetype_parts = split(a:filetype, '\.')
|
let l:filetype_parts = split(a:filetype, '\.')
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ function! s:GetLinterVariables(filetype, linter_names) abort
|
||||||
" Include matching variables.
|
" Include matching variables.
|
||||||
if !empty(l:match)
|
if !empty(l:match)
|
||||||
\&& index(l:filetype_parts, l:match[1]) >= 0
|
\&& index(l:filetype_parts, l:match[1]) >= 0
|
||||||
\&& index(a:linter_names, l:match[2]) >= 0
|
\&& index(a:exclude_linter_names, l:match[2]) == -1
|
||||||
call add(l:variable_list, l:key)
|
call add(l:variable_list, l:key)
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
|
@ -211,10 +211,11 @@ function! ale#debugging#Info() abort
|
||||||
|
|
||||||
let l:all_names = map(copy(l:all_linters), 'v:val[''name'']')
|
let l:all_names = map(copy(l:all_linters), 'v:val[''name'']')
|
||||||
let l:enabled_names = map(copy(l:enabled_linters), 'v:val[''name'']')
|
let l:enabled_names = map(copy(l:enabled_linters), 'v:val[''name'']')
|
||||||
|
let l:exclude_names = filter(copy(l:all_names), 'index(l:enabled_names, v:val) == -1')
|
||||||
|
|
||||||
" Load linter variables to display
|
" Load linter variables to display
|
||||||
" This must be done after linters are loaded.
|
" This must be done after linters are loaded.
|
||||||
let l:variable_list = s:GetLinterVariables(l:filetype, l:enabled_names)
|
let l:variable_list = s:GetLinterVariables(l:filetype, l:exclude_names)
|
||||||
|
|
||||||
let l:fixers = ale#fix#registry#SuggestedFixers(l:filetype)
|
let l:fixers = ale#fix#registry#SuggestedFixers(l:filetype)
|
||||||
let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1]))
|
let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1]))
|
||||||
|
@ -238,6 +239,12 @@ function! ale#debugging#Info() abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#debugging#InfoToClipboard() abort
|
function! ale#debugging#InfoToClipboard() abort
|
||||||
|
if !has('clipboard')
|
||||||
|
call s:Echo('clipboard not available. Try :ALEInfoToFile instead.')
|
||||||
|
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
redir => l:output
|
redir => l:output
|
||||||
silent call ale#debugging#Info()
|
silent call ale#debugging#Info()
|
||||||
redir END
|
redir END
|
||||||
|
|
|
@ -710,6 +710,10 @@ function! ale#engine#Cleanup(buffer) abort
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if exists('*ale#lsp#CloseDocument')
|
||||||
|
call ale#lsp#CloseDocument(a:buffer)
|
||||||
|
endif
|
||||||
|
|
||||||
if !has_key(g:ale_buffer_info, a:buffer)
|
if !has_key(g:ale_buffer_info, a:buffer)
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -128,7 +128,7 @@ function! ale#events#Init() abort
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if g:ale_lint_on_insert_leave
|
if g:ale_lint_on_insert_leave
|
||||||
autocmd InsertLeave * call ale#Queue(0)
|
autocmd InsertLeave * if ale#Var(str2nr(expand('<abuf>')), 'lint_on_insert_leave') | call ale#Queue(0) | endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if g:ale_echo_cursor || g:ale_cursor_detail
|
if g:ale_echo_cursor || g:ale_cursor_detail
|
||||||
|
|
|
@ -2,46 +2,60 @@ call ale#Set('fix_on_save_ignore', {})
|
||||||
|
|
||||||
" Apply fixes queued up for buffers which may be hidden.
|
" Apply fixes queued up for buffers which may be hidden.
|
||||||
" Vim doesn't let you modify hidden buffers.
|
" Vim doesn't let you modify hidden buffers.
|
||||||
function! ale#fix#ApplyQueuedFixes() abort
|
function! ale#fix#ApplyQueuedFixes(buffer) abort
|
||||||
let l:buffer = bufnr('')
|
let l:data = get(g:ale_fix_buffer_data, a:buffer, {'done': 0})
|
||||||
let l:data = get(g:ale_fix_buffer_data, l:buffer, {'done': 0})
|
let l:has_bufline_api = exists('*deletebufline') && exists('*setbufline')
|
||||||
|
|
||||||
if !l:data.done
|
if !l:data.done || (!l:has_bufline_api && a:buffer isnot bufnr(''))
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call remove(g:ale_fix_buffer_data, l:buffer)
|
call remove(g:ale_fix_buffer_data, a:buffer)
|
||||||
|
|
||||||
if l:data.changes_made
|
if l:data.changes_made
|
||||||
let l:start_line = len(l:data.output) + 1
|
|
||||||
let l:end_line = len(l:data.lines_before)
|
|
||||||
|
|
||||||
if l:end_line >= l:start_line
|
|
||||||
let l:save = winsaveview()
|
|
||||||
silent execute l:start_line . ',' . l:end_line . 'd_'
|
|
||||||
call winrestview(l:save)
|
|
||||||
endif
|
|
||||||
|
|
||||||
" If the file is in DOS mode, we have to remove carriage returns from
|
" If the file is in DOS mode, we have to remove carriage returns from
|
||||||
" the ends of lines before calling setline(), or we will see them
|
" the ends of lines before calling setline(), or we will see them
|
||||||
" twice.
|
" twice.
|
||||||
let l:lines_to_set = getbufvar(l:buffer, '&fileformat') is# 'dos'
|
let l:new_lines = getbufvar(a:buffer, '&fileformat') is# 'dos'
|
||||||
\ ? map(copy(l:data.output), 'substitute(v:val, ''\r\+$'', '''', '''')')
|
\ ? map(copy(l:data.output), 'substitute(v:val, ''\r\+$'', '''', '''')')
|
||||||
\ : l:data.output
|
\ : l:data.output
|
||||||
|
let l:first_line_to_remove = len(l:new_lines) + 1
|
||||||
|
|
||||||
call setline(1, l:lines_to_set)
|
" Use a Vim API for setting lines in other buffers, if available.
|
||||||
|
if l:has_bufline_api
|
||||||
|
call setbufline(a:buffer, 1, l:new_lines)
|
||||||
|
call deletebufline(a:buffer, l:first_line_to_remove, '$')
|
||||||
|
" Fall back on setting lines the old way, for the current buffer.
|
||||||
|
else
|
||||||
|
let l:old_line_length = len(l:data.lines_before)
|
||||||
|
|
||||||
|
if l:old_line_length >= l:first_line_to_remove
|
||||||
|
let l:save = winsaveview()
|
||||||
|
silent execute
|
||||||
|
\ l:first_line_to_remove . ',' . l:old_line_length . 'd_'
|
||||||
|
call winrestview(l:save)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call setline(1, l:new_lines)
|
||||||
|
endif
|
||||||
|
|
||||||
if l:data.should_save
|
if l:data.should_save
|
||||||
|
if a:buffer is bufnr('')
|
||||||
if empty(&buftype)
|
if empty(&buftype)
|
||||||
noautocmd :w!
|
noautocmd :w!
|
||||||
else
|
else
|
||||||
set nomodified
|
set nomodified
|
||||||
endif
|
endif
|
||||||
|
else
|
||||||
|
call writefile(l:new_lines, expand(a:buffer . ':p')) " no-custom-checks
|
||||||
|
call setbufvar(a:buffer, '&modified', 0)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if l:data.should_save
|
if l:data.should_save
|
||||||
let l:should_lint = g:ale_fix_on_save
|
let l:should_lint = ale#Var(a:buffer, 'fix_on_save')
|
||||||
|
\ && ale#Var(a:buffer, 'lint_on_save')
|
||||||
else
|
else
|
||||||
let l:should_lint = l:data.changes_made
|
let l:should_lint = l:data.changes_made
|
||||||
endif
|
endif
|
||||||
|
@ -52,7 +66,7 @@ function! ale#fix#ApplyQueuedFixes() abort
|
||||||
" fixing problems.
|
" fixing problems.
|
||||||
if g:ale_enabled
|
if g:ale_enabled
|
||||||
\&& l:should_lint
|
\&& l:should_lint
|
||||||
\&& !ale#events#QuitRecently(l:buffer)
|
\&& !ale#events#QuitRecently(a:buffer)
|
||||||
call ale#Queue(0, l:data.should_save ? 'lint_file' : '')
|
call ale#Queue(0, l:data.should_save ? 'lint_file' : '')
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -83,7 +97,7 @@ function! ale#fix#ApplyFixes(buffer, output) abort
|
||||||
|
|
||||||
" We can only change the lines of a buffer which is currently open,
|
" We can only change the lines of a buffer which is currently open,
|
||||||
" so try and apply the fixes to the current buffer.
|
" so try and apply the fixes to the current buffer.
|
||||||
call ale#fix#ApplyQueuedFixes()
|
call ale#fix#ApplyQueuedFixes(a:buffer)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:HandleExit(job_info, buffer, job_output, data) abort
|
function! s:HandleExit(job_info, buffer, job_output, data) abort
|
||||||
|
@ -399,5 +413,4 @@ endfunction
|
||||||
" Set up an autocmd command to try and apply buffer fixes when available.
|
" Set up an autocmd command to try and apply buffer fixes when available.
|
||||||
augroup ALEBufferFixGroup
|
augroup ALEBufferFixGroup
|
||||||
autocmd!
|
autocmd!
|
||||||
autocmd BufEnter * call ale#fix#ApplyQueuedFixes()
|
autocmd BufEnter * call ale#fix#ApplyQueuedFixes(str2nr(expand('<abuf>')))
|
||||||
augroup END
|
|
||||||
|
|
|
@ -115,6 +115,11 @@ let s:default_registry = {
|
||||||
\ 'suggested_filetypes': ['scala'],
|
\ 'suggested_filetypes': ['scala'],
|
||||||
\ 'description': 'Fix Scala files using scalafmt',
|
\ 'description': 'Fix Scala files using scalafmt',
|
||||||
\ },
|
\ },
|
||||||
|
\ 'sorbet': {
|
||||||
|
\ 'function': 'ale#fixers#sorbet#Fix',
|
||||||
|
\ 'suggested_filetypes': ['ruby'],
|
||||||
|
\ 'description': 'Fix ruby files with srb tc --autocorrect.',
|
||||||
|
\ },
|
||||||
\ 'standard': {
|
\ 'standard': {
|
||||||
\ 'function': 'ale#fixers#standard#Fix',
|
\ 'function': 'ale#fixers#standard#Fix',
|
||||||
\ 'suggested_filetypes': ['javascript'],
|
\ 'suggested_filetypes': ['javascript'],
|
||||||
|
@ -145,6 +150,11 @@ let s:default_registry = {
|
||||||
\ 'suggested_filetypes': ['php'],
|
\ 'suggested_filetypes': ['php'],
|
||||||
\ 'description': 'Fix PHP files with php-cs-fixer.',
|
\ 'description': 'Fix PHP files with php-cs-fixer.',
|
||||||
\ },
|
\ },
|
||||||
|
\ 'clangtidy': {
|
||||||
|
\ 'function': 'ale#fixers#clangtidy#Fix',
|
||||||
|
\ 'suggested_filetypes': ['c', 'cpp', 'objc'],
|
||||||
|
\ 'description': 'Fix C/C++ and ObjectiveC files with clang-tidy.',
|
||||||
|
\ },
|
||||||
\ 'clang-format': {
|
\ 'clang-format': {
|
||||||
\ 'function': 'ale#fixers#clangformat#Fix',
|
\ 'function': 'ale#fixers#clangformat#Fix',
|
||||||
\ 'suggested_filetypes': ['c', 'cpp', 'cuda'],
|
\ 'suggested_filetypes': ['c', 'cpp', 'cuda'],
|
||||||
|
@ -205,6 +215,11 @@ let s:default_registry = {
|
||||||
\ 'suggested_filetypes': ['haskell'],
|
\ 'suggested_filetypes': ['haskell'],
|
||||||
\ 'description': 'Fix Haskell files with brittany.',
|
\ 'description': 'Fix Haskell files with brittany.',
|
||||||
\ },
|
\ },
|
||||||
|
\ 'hindent': {
|
||||||
|
\ 'function': 'ale#fixers#hindent#Fix',
|
||||||
|
\ 'suggested_filetypes': ['haskell'],
|
||||||
|
\ 'description': 'Fix Haskell files with hindent.',
|
||||||
|
\ },
|
||||||
\ 'hlint': {
|
\ 'hlint': {
|
||||||
\ 'function': 'ale#fixers#hlint#Fix',
|
\ 'function': 'ale#fixers#hlint#Fix',
|
||||||
\ 'suggested_filetypes': ['haskell'],
|
\ 'suggested_filetypes': ['haskell'],
|
||||||
|
@ -297,7 +312,7 @@ let s:default_registry = {
|
||||||
\ },
|
\ },
|
||||||
\ 'styler': {
|
\ 'styler': {
|
||||||
\ 'function': 'ale#fixers#styler#Fix',
|
\ 'function': 'ale#fixers#styler#Fix',
|
||||||
\ 'suggested_filetypes': ['r'],
|
\ 'suggested_filetypes': ['r', 'rmarkdown'],
|
||||||
\ 'description': 'Fix R files with styler.',
|
\ 'description': 'Fix R files with styler.',
|
||||||
\ },
|
\ },
|
||||||
\ 'latexindent': {
|
\ 'latexindent': {
|
||||||
|
@ -305,6 +320,21 @@ let s:default_registry = {
|
||||||
\ 'suggested_filetypes': ['tex'],
|
\ 'suggested_filetypes': ['tex'],
|
||||||
\ 'description' : 'Indent code within environments, commands, after headings and within special code blocks.',
|
\ 'description' : 'Indent code within environments, commands, after headings and within special code blocks.',
|
||||||
\ },
|
\ },
|
||||||
|
\ 'pgformatter': {
|
||||||
|
\ 'function': 'ale#fixers#pgformatter#Fix',
|
||||||
|
\ 'suggested_filetypes': ['sql'],
|
||||||
|
\ 'description': 'A PostgreSQL SQL syntax beautifier',
|
||||||
|
\ },
|
||||||
|
\ 'reorder-python-imports': {
|
||||||
|
\ 'function': 'ale#fixers#reorder_python_imports#Fix',
|
||||||
|
\ 'suggested_filetypes': ['python'],
|
||||||
|
\ 'description': 'Sort Python imports with reorder-python-imports.',
|
||||||
|
\ },
|
||||||
|
\ 'gnatpp': {
|
||||||
|
\ 'function': 'ale#fixers#gnatpp#Fix',
|
||||||
|
\ 'suggested_filetypes': ['ada'],
|
||||||
|
\ 'description': 'Format Ada files with gnatpp.',
|
||||||
|
\ },
|
||||||
\}
|
\}
|
||||||
|
|
||||||
" Reset the function registry to the default entries.
|
" Reset the function registry to the default entries.
|
||||||
|
|
|
@ -29,6 +29,10 @@ function! ale#fixers#black#Fix(buffer) abort
|
||||||
|
|
||||||
let l:options = ale#Var(a:buffer, 'python_black_options')
|
let l:options = ale#Var(a:buffer, 'python_black_options')
|
||||||
|
|
||||||
|
if expand('#' . a:buffer . ':e') is? 'pyi'
|
||||||
|
let l:options .= '--pyi'
|
||||||
|
endif
|
||||||
|
|
||||||
return {
|
return {
|
||||||
\ 'command': l:cd_string . ale#Escape(l:executable) . l:exec_args
|
\ 'command': l:cd_string . ale#Escape(l:executable) . l:exec_args
|
||||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
|
|
|
@ -13,10 +13,15 @@ function! ale#fixers#clangformat#GetExecutable(buffer) abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#fixers#clangformat#Fix(buffer) abort
|
function! ale#fixers#clangformat#Fix(buffer) abort
|
||||||
|
let l:executable = ale#Escape(ale#fixers#clangformat#GetExecutable(a:buffer))
|
||||||
|
let l:filename = ale#Escape(bufname(a:buffer))
|
||||||
let l:options = ale#Var(a:buffer, 'c_clangformat_options')
|
let l:options = ale#Var(a:buffer, 'c_clangformat_options')
|
||||||
|
|
||||||
return {
|
let l:command = l:executable . ' --assume-filename=' . l:filename
|
||||||
\ 'command': ale#Escape(ale#fixers#clangformat#GetExecutable(a:buffer))
|
|
||||||
\ . ' ' . l:options,
|
if l:options isnot# ''
|
||||||
\}
|
let l:command .= ' ' . l:options
|
||||||
|
endif
|
||||||
|
|
||||||
|
return {'command': l:command}
|
||||||
endfunction
|
endfunction
|
||||||
|
|
52
sources_non_forked/ale/autoload/ale/fixers/clangtidy.vim
Normal file
52
sources_non_forked/ale/autoload/ale/fixers/clangtidy.vim
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
scriptencoding utf-8
|
||||||
|
" Author: ObserverOfTime <chronobserver@disroot.org>
|
||||||
|
" Description: Fixing C/C++ files with clang-tidy.
|
||||||
|
|
||||||
|
function! s:set_variables() abort
|
||||||
|
let l:use_global = get(g:, 'ale_use_global_executables', 0)
|
||||||
|
|
||||||
|
for l:ft in ['c', 'cpp']
|
||||||
|
call ale#Set(l:ft . '_clangtidy_executable', 'clang-tidy')
|
||||||
|
call ale#Set(l:ft . '_clangtidy_use_global', l:use_global)
|
||||||
|
call ale#Set(l:ft . '_clangtidy_checks', [])
|
||||||
|
call ale#Set(l:ft . '_clangtidy_options', '')
|
||||||
|
call ale#Set(l:ft . '_clangtidy_extra_options', '')
|
||||||
|
call ale#Set(l:ft . '_clangtidy_fix_errors', 1)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
call ale#Set('c_build_dir', '')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call s:set_variables()
|
||||||
|
|
||||||
|
function! ale#fixers#clangtidy#Var(buffer, name) abort
|
||||||
|
let l:ft = getbufvar(str2nr(a:buffer), '&filetype')
|
||||||
|
let l:ft = l:ft =~# 'cpp' ? 'cpp' : 'c'
|
||||||
|
|
||||||
|
return ale#Var(a:buffer, l:ft . '_clangtidy_' . a:name)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#fixers#clangtidy#GetCommand(buffer) abort
|
||||||
|
let l:checks = join(ale#fixers#clangtidy#Var(a:buffer, 'checks'), ',')
|
||||||
|
let l:extra_options = ale#fixers#clangtidy#Var(a:buffer, 'extra_options')
|
||||||
|
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
|
||||||
|
let l:options = empty(l:build_dir)
|
||||||
|
\ ? ale#fixers#clangtidy#Var(a:buffer, 'options') : ''
|
||||||
|
let l:fix_errors = ale#fixers#clangtidy#Var(a:buffer, 'fix_errors')
|
||||||
|
|
||||||
|
return ' -fix' . (l:fix_errors ? ' -fix-errors' : '')
|
||||||
|
\ . (empty(l:checks) ? '' : ' -checks=' . ale#Escape(l:checks))
|
||||||
|
\ . (empty(l:extra_options) ? '' : ' ' . l:extra_options)
|
||||||
|
\ . (empty(l:build_dir) ? '' : ' -p ' . ale#Escape(l:build_dir))
|
||||||
|
\ . ' %t' . (empty(l:options) ? '' : ' -- ' . l:options)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#fixers#clangtidy#Fix(buffer) abort
|
||||||
|
let l:executable = ale#fixers#clangtidy#Var(a:buffer, 'executable')
|
||||||
|
let l:command = ale#fixers#clangtidy#GetCommand(a:buffer)
|
||||||
|
|
||||||
|
return {
|
||||||
|
\ 'command': ale#Escape(l:executable) . l:command,
|
||||||
|
\ 'read_temporary_file': 1,
|
||||||
|
\}
|
||||||
|
endfunction
|
|
@ -35,9 +35,18 @@ endfunction
|
||||||
|
|
||||||
function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||||
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
|
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
|
||||||
let l:config = ale#handlers#eslint#FindConfig(a:buffer)
|
let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
|
||||||
|
|
||||||
if empty(l:config)
|
" Use the configuration file from the options, if configured.
|
||||||
|
if l:options =~# '\v(^| )-c|(^| )--config'
|
||||||
|
let l:config = ''
|
||||||
|
let l:has_config = 1
|
||||||
|
else
|
||||||
|
let l:config = ale#handlers#eslint#FindConfig(a:buffer)
|
||||||
|
let l:has_config = !empty(l:config)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !l:has_config
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -45,6 +54,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||||
if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
|
if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
|
||||||
return {
|
return {
|
||||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||||
|
\ . ale#Pad(l:options)
|
||||||
\ . ' --stdin-filename %s --stdin --fix-to-stdout',
|
\ . ' --stdin-filename %s --stdin --fix-to-stdout',
|
||||||
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
|
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
|
||||||
\}
|
\}
|
||||||
|
@ -54,6 +64,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||||
if ale#semver#GTE(a:version, [4, 9, 0])
|
if ale#semver#GTE(a:version, [4, 9, 0])
|
||||||
return {
|
return {
|
||||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||||
|
\ . ale#Pad(l:options)
|
||||||
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
|
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
|
||||||
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
|
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
|
||||||
\}
|
\}
|
||||||
|
@ -61,7 +72,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||||
|
|
||||||
return {
|
return {
|
||||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||||
\ . ' -c ' . ale#Escape(l:config)
|
\ . ale#Pad(l:options)
|
||||||
|
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
|
||||||
\ . ' --fix %t',
|
\ . ' --fix %t',
|
||||||
\ 'read_temporary_file': 1,
|
\ 'read_temporary_file': 1,
|
||||||
\}
|
\}
|
||||||
|
|
17
sources_non_forked/ale/autoload/ale/fixers/gnatpp.vim
Normal file
17
sources_non_forked/ale/autoload/ale/fixers/gnatpp.vim
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
" Author: tim <tim@inept.tech>
|
||||||
|
" Description: Fix files with gnatpp.
|
||||||
|
|
||||||
|
call ale#Set('ada_gnatpp_executable', 'gnatpp')
|
||||||
|
call ale#Set('ada_gnatpp_options', '')
|
||||||
|
|
||||||
|
function! ale#fixers#gnatpp#Fix(buffer) abort
|
||||||
|
let l:executable = ale#Var(a:buffer, 'ada_gnatpp_executable')
|
||||||
|
let l:options = ale#Var(a:buffer, 'ada_gnatpp_options')
|
||||||
|
|
||||||
|
return {
|
||||||
|
\ 'command': ale#Escape(l:executable)
|
||||||
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
|
\ . ' %t',
|
||||||
|
\ 'read_temporary_file': 1,
|
||||||
|
\}
|
||||||
|
endfunction
|
|
@ -7,9 +7,10 @@ call ale#Set('go_gofmt_options', '')
|
||||||
function! ale#fixers#gofmt#Fix(buffer) abort
|
function! ale#fixers#gofmt#Fix(buffer) abort
|
||||||
let l:executable = ale#Var(a:buffer, 'go_gofmt_executable')
|
let l:executable = ale#Var(a:buffer, 'go_gofmt_executable')
|
||||||
let l:options = ale#Var(a:buffer, 'go_gofmt_options')
|
let l:options = ale#Var(a:buffer, 'go_gofmt_options')
|
||||||
|
let l:env = ale#go#EnvString(a:buffer)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
\ 'command': ale#Escape(l:executable)
|
\ 'command': l:env . ale#Escape(l:executable)
|
||||||
\ . ' -l -w'
|
\ . ' -l -w'
|
||||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||||
\ . ' %t',
|
\ . ' %t',
|
||||||
|
|
|
@ -7,13 +7,14 @@ call ale#Set('go_goimports_options', '')
|
||||||
function! ale#fixers#goimports#Fix(buffer) abort
|
function! ale#fixers#goimports#Fix(buffer) abort
|
||||||
let l:executable = ale#Var(a:buffer, 'go_goimports_executable')
|
let l:executable = ale#Var(a:buffer, 'go_goimports_executable')
|
||||||
let l:options = ale#Var(a:buffer, 'go_goimports_options')
|
let l:options = ale#Var(a:buffer, 'go_goimports_options')
|
||||||
|
let l:env = ale#go#EnvString(a:buffer)
|
||||||
|
|
||||||
if !executable(l:executable)
|
if !executable(l:executable)
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return {
|
return {
|
||||||
\ 'command': ale#Escape(l:executable)
|
\ 'command': l:env . ale#Escape(l:executable)
|
||||||
\ . ' -l -w -srcdir %s'
|
\ . ' -l -w -srcdir %s'
|
||||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||||
\ . ' %t',
|
\ . ' %t',
|
||||||
|
|
|
@ -2,9 +2,10 @@ call ale#Set('go_go_executable', 'go')
|
||||||
|
|
||||||
function! ale#fixers#gomod#Fix(buffer) abort
|
function! ale#fixers#gomod#Fix(buffer) abort
|
||||||
let l:executable = ale#Var(a:buffer, 'go_go_executable')
|
let l:executable = ale#Var(a:buffer, 'go_go_executable')
|
||||||
|
let l:env = ale#go#EnvString(a:buffer)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
\ 'command': ale#Escape(l:executable) . ' mod edit -fmt %t',
|
\ 'command': l:env . ale#Escape(l:executable) . ' mod edit -fmt %t',
|
||||||
\ 'read_temporary_file': 1,
|
\ 'read_temporary_file': 1,
|
||||||
\}
|
\}
|
||||||
endfunction
|
endfunction
|
||||||
|
|
20
sources_non_forked/ale/autoload/ale/fixers/hindent.vim
Normal file
20
sources_non_forked/ale/autoload/ale/fixers/hindent.vim
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
" Author: AlexeiDrake <drake.alexei@gmail.com>
|
||||||
|
" Description: Integration of hindent formatting with ALE.
|
||||||
|
"
|
||||||
|
call ale#Set('haskell_hindent_executable', 'hindent')
|
||||||
|
|
||||||
|
function! ale#fixers#hindent#GetExecutable(buffer) abort
|
||||||
|
let l:executable = ale#Var(a:buffer, 'haskell_hindent_executable')
|
||||||
|
|
||||||
|
return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'hindent')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#fixers#hindent#Fix(buffer) abort
|
||||||
|
let l:executable = ale#fixers#hindent#GetExecutable(a:buffer)
|
||||||
|
|
||||||
|
return {
|
||||||
|
\ 'command': l:executable
|
||||||
|
\ . ' %t',
|
||||||
|
\ 'read_temporary_file': 1,
|
||||||
|
\}
|
||||||
|
endfunction
|
12
sources_non_forked/ale/autoload/ale/fixers/pgformatter.vim
Normal file
12
sources_non_forked/ale/autoload/ale/fixers/pgformatter.vim
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
call ale#Set('sql_pgformatter_executable', 'pg_format')
|
||||||
|
call ale#Set('sql_pgformatter_options', '')
|
||||||
|
|
||||||
|
function! ale#fixers#pgformatter#Fix(buffer) abort
|
||||||
|
let l:executable = ale#Var(a:buffer, 'sql_pgformatter_executable')
|
||||||
|
let l:options = ale#Var(a:buffer, 'sql_pgformatter_options')
|
||||||
|
|
||||||
|
return {
|
||||||
|
\ 'command': ale#Escape(l:executable)
|
||||||
|
\ . (empty(l:options) ? '' : ' ' . l:options),
|
||||||
|
\}
|
||||||
|
endfunction
|
|
@ -39,9 +39,15 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
|
||||||
let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
|
let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
|
||||||
let l:parser = ''
|
let l:parser = ''
|
||||||
|
|
||||||
|
let l:filetypes = split(getbufvar(a:buffer, '&filetype'), '\.')
|
||||||
|
|
||||||
|
if index(l:filetypes, 'handlebars') > -1
|
||||||
|
let l:parser = 'glimmer'
|
||||||
|
endif
|
||||||
|
|
||||||
" Append the --parser flag depending on the current filetype (unless it's
|
" Append the --parser flag depending on the current filetype (unless it's
|
||||||
" already set in g:javascript_prettier_options).
|
" already set in g:javascript_prettier_options).
|
||||||
if empty(expand('#' . a:buffer . ':e')) && match(l:options, '--parser') == -1
|
if empty(expand('#' . a:buffer . ':e')) && l:parser is# '' && match(l:options, '--parser') == -1
|
||||||
" Mimic Prettier's defaults. In cases without a file extension or
|
" Mimic Prettier's defaults. In cases without a file extension or
|
||||||
" filetype (scratch buffer), Prettier needs `parser` set to know how
|
" filetype (scratch buffer), Prettier needs `parser` set to know how
|
||||||
" to process the buffer.
|
" to process the buffer.
|
||||||
|
@ -65,7 +71,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
|
||||||
\ 'html': 'html',
|
\ 'html': 'html',
|
||||||
\}
|
\}
|
||||||
|
|
||||||
for l:filetype in split(getbufvar(a:buffer, '&filetype'), '\.')
|
for l:filetype in l:filetypes
|
||||||
if has_key(l:prettier_parsers, l:filetype)
|
if has_key(l:prettier_parsers, l:filetype)
|
||||||
let l:parser = l:prettier_parsers[l:filetype]
|
let l:parser = l:prettier_parsers[l:filetype]
|
||||||
break
|
break
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
" Author: jake <me@jake.computer>
|
||||||
|
" Description: Fixing Python imports with reorder-python-imports.
|
||||||
|
|
||||||
|
call ale#Set('python_reorder_python_imports_executable', 'reorder-python-imports')
|
||||||
|
call ale#Set('python_reorder_python_imports_options', '')
|
||||||
|
call ale#Set('python_reorder_python_imports_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||||
|
|
||||||
|
function! ale#fixers#reorder_python_imports#Fix(buffer) abort
|
||||||
|
let l:executable = ale#python#FindExecutable(
|
||||||
|
\ a:buffer,
|
||||||
|
\ 'python_reorder_python_imports',
|
||||||
|
\ ['reorder-python-imports'],
|
||||||
|
\)
|
||||||
|
|
||||||
|
if !executable(l:executable)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:options = ale#Var(a:buffer, 'python_reorder_python_imports_options')
|
||||||
|
|
||||||
|
return {
|
||||||
|
\ 'command': ale#Escape(l:executable)
|
||||||
|
\ . (!empty(l:options) ? ' ' . l:options : '') . ' -',
|
||||||
|
\}
|
||||||
|
endfunction
|
19
sources_non_forked/ale/autoload/ale/fixers/sorbet.vim
Normal file
19
sources_non_forked/ale/autoload/ale/fixers/sorbet.vim
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
call ale#Set('ruby_sorbet_executable', 'srb')
|
||||||
|
call ale#Set('ruby_sorbet_options', '')
|
||||||
|
|
||||||
|
function! ale#fixers#sorbet#GetCommand(buffer) abort
|
||||||
|
let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable')
|
||||||
|
let l:options = ale#Var(a:buffer, 'ruby_sorbet_options')
|
||||||
|
|
||||||
|
return ale#handlers#ruby#EscapeExecutable(l:executable, 'srb')
|
||||||
|
\ . ' tc'
|
||||||
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
|
\ . ' --autocorrect --file %t'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#fixers#sorbet#Fix(buffer) abort
|
||||||
|
return {
|
||||||
|
\ 'command': ale#fixers#sorbet#GetCommand(a:buffer),
|
||||||
|
\ 'read_temporary_file': 1,
|
||||||
|
\}
|
||||||
|
endfunction
|
|
@ -25,3 +25,20 @@ function! ale#go#FindProjectRoot(buffer) abort
|
||||||
|
|
||||||
return ''
|
return ''
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
call ale#Set('go_go111module', '')
|
||||||
|
|
||||||
|
" Return a string setting Go-specific environment variables
|
||||||
|
function! ale#go#EnvString(buffer) abort
|
||||||
|
let l:env = ''
|
||||||
|
|
||||||
|
" GO111MODULE - turn go modules behavior on/off
|
||||||
|
let l:go111module = ale#Var(a:buffer, 'go_go111module')
|
||||||
|
|
||||||
|
if !empty(l:go111module)
|
||||||
|
let l:env = ale#Env('GO111MODULE', l:go111module) . l:env
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:env
|
||||||
|
endfunction
|
||||||
|
|
|
@ -3,15 +3,17 @@ scriptencoding utf-8
|
||||||
" Description: Utilities for ccls
|
" Description: Utilities for ccls
|
||||||
|
|
||||||
function! ale#handlers#ccls#GetProjectRoot(buffer) abort
|
function! ale#handlers#ccls#GetProjectRoot(buffer) abort
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls-root')
|
" Try to find ccls configuration files first.
|
||||||
|
let l:config = ale#path#FindNearestFile(a:buffer, '.ccls-root')
|
||||||
|
|
||||||
if empty(l:project_root)
|
if empty(l:config)
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
let l:config = ale#path#FindNearestFile(a:buffer, '.ccls')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if empty(l:project_root)
|
if !empty(l:config)
|
||||||
let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls')
|
return fnamemodify(l:config, ':h')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
" Fall back on default project root detection.
|
||||||
|
return ale#c#FindProjectRoot(a:buffer)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
@ -1,5 +1,46 @@
|
||||||
" Description: Handle errors for cppcheck.
|
" Description: Handle errors for cppcheck.
|
||||||
|
|
||||||
|
function! ale#handlers#cppcheck#GetCdCommand(buffer) abort
|
||||||
|
let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer)
|
||||||
|
let l:cd_command = !empty(l:dir) ? ale#path#CdString(l:dir) : ''
|
||||||
|
|
||||||
|
return l:cd_command
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#handlers#cppcheck#GetBufferPathIncludeOptions(buffer) abort
|
||||||
|
let l:buffer_path_include = ''
|
||||||
|
|
||||||
|
" Get path to this buffer so we can include it into cppcheck with -I
|
||||||
|
" This could be expanded to get more -I directives from the compile
|
||||||
|
" command in compile_commands.json, if it's found.
|
||||||
|
let l:buffer_path = fnamemodify(bufname(a:buffer), ':p:h')
|
||||||
|
let l:buffer_path_include = ' -I' . ale#Escape(l:buffer_path)
|
||||||
|
|
||||||
|
return l:buffer_path_include
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#handlers#cppcheck#GetCompileCommandsOptions(buffer) abort
|
||||||
|
" If the current buffer is modified, using compile_commands.json does no
|
||||||
|
" good, so include the file's directory instead. It's not quite as good as
|
||||||
|
" using --project, but is at least equivalent to running cppcheck on this
|
||||||
|
" file manually from the file's directory.
|
||||||
|
let l:modified = getbufvar(a:buffer, '&modified')
|
||||||
|
|
||||||
|
if l:modified
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Search upwards from the file for compile_commands.json.
|
||||||
|
"
|
||||||
|
" If we find it, we'll `cd` to where the compile_commands.json file is,
|
||||||
|
" then use the file to set up import paths, etc.
|
||||||
|
let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer)
|
||||||
|
|
||||||
|
return !empty(l:json_path)
|
||||||
|
\ ? '--project=' . ale#Escape(l:json_path[len(l:dir) + 1: ])
|
||||||
|
\ : ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ale#handlers#cppcheck#HandleCppCheckFormat(buffer, lines) abort
|
function! ale#handlers#cppcheck#HandleCppCheckFormat(buffer, lines) abort
|
||||||
" Look for lines like the following.
|
" Look for lines like the following.
|
||||||
"
|
"
|
||||||
|
|
|
@ -44,16 +44,9 @@ function! ale#handlers#eslint#GetCommand(buffer) abort
|
||||||
|
|
||||||
return ale#node#Executable(a:buffer, l:executable)
|
return ale#node#Executable(a:buffer, l:executable)
|
||||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||||
\ . ' -f unix --stdin --stdin-filename %s'
|
\ . ' -f json --stdin --stdin-filename %s'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
let s:col_end_patterns = [
|
|
||||||
\ '\vParsing error: Unexpected token (.+) ?',
|
|
||||||
\ '\v''(.+)'' is not defined.',
|
|
||||||
\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]',
|
|
||||||
\ '\vUnexpected (console) statement',
|
|
||||||
\]
|
|
||||||
|
|
||||||
function! s:AddHintsForTypeScriptParsingErrors(output) abort
|
function! s:AddHintsForTypeScriptParsingErrors(output) abort
|
||||||
for l:item in a:output
|
for l:item in a:output
|
||||||
let l:item.text = substitute(
|
let l:item.text = substitute(
|
||||||
|
@ -90,22 +83,71 @@ function! s:CheckForBadConfig(buffer, lines) abort
|
||||||
return 0
|
return 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#handlers#eslint#Handle(buffer, lines) abort
|
function! s:parseJSON(buffer, lines) abort
|
||||||
if s:CheckForBadConfig(a:buffer, a:lines)
|
try
|
||||||
return [{
|
let l:parsed = json_decode(a:lines[-1])
|
||||||
\ 'lnum': 1,
|
catch
|
||||||
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
|
return []
|
||||||
\ 'detail': join(a:lines, "\n"),
|
endtry
|
||||||
\}]
|
|
||||||
|
if type(l:parsed) != v:t_list || empty(l:parsed)
|
||||||
|
return []
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if a:lines == ['Could not connect']
|
let l:errors = l:parsed[0]['messages']
|
||||||
return [{
|
|
||||||
\ 'lnum': 1,
|
if empty(l:errors)
|
||||||
\ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.',
|
return []
|
||||||
\}]
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
let l:output = []
|
||||||
|
|
||||||
|
for l:error in l:errors
|
||||||
|
let l:obj = ({
|
||||||
|
\ 'lnum': get(l:error, 'line', 0),
|
||||||
|
\ 'text': get(l:error, 'message', ''),
|
||||||
|
\ 'type': 'E',
|
||||||
|
\})
|
||||||
|
|
||||||
|
if get(l:error, 'severity', 0) is# 1
|
||||||
|
let l:obj.type = 'W'
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(l:error, 'ruleId')
|
||||||
|
let l:code = l:error['ruleId']
|
||||||
|
|
||||||
|
" Sometimes ESLint returns null here
|
||||||
|
if !empty(l:code)
|
||||||
|
let l:obj.code = l:code
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(l:error, 'column')
|
||||||
|
let l:obj.col = l:error['column']
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(l:error, 'endColumn')
|
||||||
|
let l:obj.end_col = l:error['endColumn'] - 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(l:error, 'endLine')
|
||||||
|
let l:obj.end_lnum = l:error['endLine']
|
||||||
|
endif
|
||||||
|
|
||||||
|
call add(l:output, l:obj)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
let s:col_end_patterns = [
|
||||||
|
\ '\vParsing error: Unexpected token (.+) ?',
|
||||||
|
\ '\v''(.+)'' is not defined.',
|
||||||
|
\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]',
|
||||||
|
\ '\vUnexpected (console) statement',
|
||||||
|
\]
|
||||||
|
|
||||||
|
function! s:parseLines(buffer, lines) abort
|
||||||
" Matches patterns line the following:
|
" Matches patterns line the following:
|
||||||
"
|
"
|
||||||
" /path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]
|
" /path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]
|
||||||
|
@ -120,12 +162,6 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort
|
||||||
for l:match in ale#util#GetMatches(a:lines, [l:pattern, l:parsing_pattern])
|
for l:match in ale#util#GetMatches(a:lines, [l:pattern, l:parsing_pattern])
|
||||||
let l:text = l:match[3]
|
let l:text = l:match[3]
|
||||||
|
|
||||||
if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore')
|
|
||||||
if l:text =~# '^File ignored'
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:obj = {
|
let l:obj = {
|
||||||
\ 'lnum': l:match[1] + 0,
|
\ 'lnum': l:match[1] + 0,
|
||||||
\ 'col': l:match[2] + 0,
|
\ 'col': l:match[2] + 0,
|
||||||
|
@ -143,11 +179,6 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort
|
||||||
" The code can be something like 'Error/foo/bar', or just 'Error'
|
" The code can be something like 'Error/foo/bar', or just 'Error'
|
||||||
if !empty(get(l:split_code, 1))
|
if !empty(get(l:split_code, 1))
|
||||||
let l:obj.code = join(l:split_code[1:], '/')
|
let l:obj.code = join(l:split_code[1:], '/')
|
||||||
|
|
||||||
if l:obj.code is# 'no-trailing-spaces'
|
|
||||||
\&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
for l:col_match in ale#util#GetMatches(l:text, s:col_end_patterns)
|
for l:col_match in ale#util#GetMatches(l:text, s:col_end_patterns)
|
||||||
|
@ -157,9 +188,59 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort
|
||||||
call add(l:output, l:obj)
|
call add(l:output, l:obj)
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:FilterResult(buffer, obj) abort
|
||||||
|
if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore')
|
||||||
|
if a:obj.text =~# '^File ignored'
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(a:obj, 'code') && a:obj.code is# 'no-trailing-spaces'
|
||||||
|
\&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:HandleESLintOutput(buffer, lines, type) abort
|
||||||
|
if s:CheckForBadConfig(a:buffer, a:lines)
|
||||||
|
return [{
|
||||||
|
\ 'lnum': 1,
|
||||||
|
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
|
||||||
|
\ 'detail': join(a:lines, "\n"),
|
||||||
|
\}]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:lines == ['Could not connect']
|
||||||
|
return [{
|
||||||
|
\ 'lnum': 1,
|
||||||
|
\ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.',
|
||||||
|
\}]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:type is# 'json'
|
||||||
|
let l:output = s:parseJSON(a:buffer, a:lines)
|
||||||
|
else
|
||||||
|
let l:output = s:parseLines(a:buffer, a:lines)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call filter(l:output, {idx, obj -> s:FilterResult(a:buffer, obj)})
|
||||||
|
|
||||||
if expand('#' . a:buffer . ':t') =~? '\.tsx\?$'
|
if expand('#' . a:buffer . ':t') =~? '\.tsx\?$'
|
||||||
call s:AddHintsForTypeScriptParsingErrors(l:output)
|
call s:AddHintsForTypeScriptParsingErrors(l:output)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return l:output
|
return l:output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale#handlers#eslint#HandleJSON(buffer, lines) abort
|
||||||
|
return s:HandleESLintOutput(a:buffer, a:lines, 'json')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#handlers#eslint#Handle(buffer, lines) abort
|
||||||
|
return s:HandleESLintOutput(a:buffer, a:lines, 'lines')
|
||||||
|
endfunction
|
||||||
|
|
|
@ -11,6 +11,7 @@ let s:pragma_error = '#pragma once in main file'
|
||||||
" <stdin>:10:27: error: invalid operands to binary - (have ‘int’ and ‘char *’)
|
" <stdin>:10:27: error: invalid operands to binary - (have ‘int’ and ‘char *’)
|
||||||
" -:189:7: note: $/${} is unnecessary on arithmetic variables. [SC2004]
|
" -:189:7: note: $/${} is unnecessary on arithmetic variables. [SC2004]
|
||||||
let s:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+)$'
|
let s:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+)$'
|
||||||
|
let s:inline_pattern = '\v inlined from .* at \<stdin\>:(\d+):(\d+):$'
|
||||||
|
|
||||||
function! s:IsHeaderFile(filename) abort
|
function! s:IsHeaderFile(filename) abort
|
||||||
return a:filename =~? '\v\.(h|hpp)$'
|
return a:filename =~? '\v\.(h|hpp)$'
|
||||||
|
@ -25,6 +26,28 @@ function! s:RemoveUnicodeQuotes(text) abort
|
||||||
return l:text
|
return l:text
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:ParseInlinedFunctionProblems(buffer, lines) abort
|
||||||
|
let l:output = []
|
||||||
|
let l:pos_match = []
|
||||||
|
|
||||||
|
for l:line in a:lines
|
||||||
|
let l:match = matchlist(l:line, s:pattern)
|
||||||
|
|
||||||
|
if !empty(l:match) && !empty(l:pos_match)
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'lnum': str2nr(l:pos_match[1]),
|
||||||
|
\ 'col': str2nr(l:pos_match[2]),
|
||||||
|
\ 'type': (l:match[4] is# 'error' || l:match[4] is# 'fatal error') ? 'E' : 'W',
|
||||||
|
\ 'text': s:RemoveUnicodeQuotes(l:match[5]),
|
||||||
|
\})
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:pos_match = matchlist(l:line, s:inline_pattern)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
" Report problems inside of header files just for gcc and clang
|
" Report problems inside of header files just for gcc and clang
|
||||||
function! s:ParseProblemsInHeaders(buffer, lines) abort
|
function! s:ParseProblemsInHeaders(buffer, lines) abort
|
||||||
let l:output = []
|
let l:output = []
|
||||||
|
@ -129,6 +152,7 @@ endfunction
|
||||||
function! ale#handlers#gcc#HandleGCCFormatWithIncludes(buffer, lines) abort
|
function! ale#handlers#gcc#HandleGCCFormatWithIncludes(buffer, lines) abort
|
||||||
let l:output = ale#handlers#gcc#HandleGCCFormat(a:buffer, a:lines)
|
let l:output = ale#handlers#gcc#HandleGCCFormat(a:buffer, a:lines)
|
||||||
|
|
||||||
|
call extend(l:output, s:ParseInlinedFunctionProblems(a:buffer, a:lines))
|
||||||
call extend(l:output, s:ParseProblemsInHeaders(a:buffer, a:lines))
|
call extend(l:output, s:ParseProblemsInHeaders(a:buffer, a:lines))
|
||||||
|
|
||||||
return l:output
|
return l:output
|
||||||
|
|
|
@ -56,14 +56,20 @@ function! ale#handlers#rust#HandleRustErrors(buffer, lines) abort
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if !empty(l:span)
|
if !empty(l:span)
|
||||||
call add(l:output, {
|
let l:output_line = {
|
||||||
\ 'lnum': l:span.line_start,
|
\ 'lnum': l:span.line_start,
|
||||||
\ 'end_lnum': l:span.line_end,
|
\ 'end_lnum': l:span.line_end,
|
||||||
\ 'col': l:span.column_start,
|
\ 'col': l:span.column_start,
|
||||||
\ 'end_col': l:span.column_end-1,
|
\ 'end_col': l:span.column_end-1,
|
||||||
\ 'text': empty(l:span.label) ? l:error.message : printf('%s: %s', l:error.message, l:span.label),
|
\ 'text': empty(l:span.label) ? l:error.message : printf('%s: %s', l:error.message, l:span.label),
|
||||||
\ 'type': toupper(l:error.level[0]),
|
\ 'type': toupper(l:error.level[0]),
|
||||||
\})
|
\}
|
||||||
|
|
||||||
|
if has_key(l:error, 'rendered') && !empty(l:error.rendered)
|
||||||
|
let l:output_line.detail = l:error.rendered
|
||||||
|
endif
|
||||||
|
|
||||||
|
call add(l:output, l:output_line)
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
endfor
|
endfor
|
||||||
|
|
|
@ -26,41 +26,6 @@ endif
|
||||||
let s:MAX_POS_VALUES = 8
|
let s:MAX_POS_VALUES = 8
|
||||||
let s:MAX_COL_SIZE = 1073741824 " pow(2, 30)
|
let s:MAX_COL_SIZE = 1073741824 " pow(2, 30)
|
||||||
|
|
||||||
" Check if we have neovim's buffer highlight API
|
|
||||||
"
|
|
||||||
" Below we define some functions' implementation conditionally if this API
|
|
||||||
" exists or not.
|
|
||||||
"
|
|
||||||
" The API itself is more ergonomic and neovim performs highlights positions
|
|
||||||
" rebases during edits so we see less stalled highlights.
|
|
||||||
let s:nvim_api = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
|
|
||||||
|
|
||||||
function! ale#highlight#HasNeovimApi() abort
|
|
||||||
return s:nvim_api
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ale#highlight#nvim_buf_clear_namespace(...) abort
|
|
||||||
return call('nvim_buf_clear_namespace', a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ale#highlight#nvim_buf_add_highlight(...) abort
|
|
||||||
return call('nvim_buf_add_highlight', a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:ale_nvim_highlight_id(bufnr) abort
|
|
||||||
let l:id = getbufvar(a:bufnr, 'ale_nvim_highlight_id', -1)
|
|
||||||
|
|
||||||
if l:id is -1
|
|
||||||
" NOTE: This will highlight nothing but will allocate new id
|
|
||||||
let l:id = ale#highlight#nvim_buf_add_highlight(
|
|
||||||
\ a:bufnr, 0, '', 0, 0, -1
|
|
||||||
\)
|
|
||||||
call setbufvar(a:bufnr, 'ale_nvim_highlight_id', l:id)
|
|
||||||
endif
|
|
||||||
|
|
||||||
return l:id
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort
|
function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort
|
||||||
if a:line >= a:end_line
|
if a:line >= a:end_line
|
||||||
" For single lines, just return the one position.
|
" For single lines, just return the one position.
|
||||||
|
@ -86,76 +51,18 @@ endfunction
|
||||||
" except these which have matching loclist item entries.
|
" except these which have matching loclist item entries.
|
||||||
|
|
||||||
function! ale#highlight#RemoveHighlights() abort
|
function! ale#highlight#RemoveHighlights() abort
|
||||||
if ale#highlight#HasNeovimApi()
|
|
||||||
if get(b:, 'ale_nvim_highlight_id', 0)
|
|
||||||
let l:bufnr = bufnr('%')
|
|
||||||
" NOTE: 0, -1 means from 0 line till the end of buffer
|
|
||||||
call ale#highlight#nvim_buf_clear_namespace(
|
|
||||||
\ l:bufnr,
|
|
||||||
\ b:ale_nvim_highlight_id,
|
|
||||||
\ 0, -1
|
|
||||||
\)
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
for l:match in getmatches()
|
for l:match in getmatches()
|
||||||
if l:match.group =~# '^ALE'
|
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
|
||||||
call matchdelete(l:match.id)
|
call matchdelete(l:match.id)
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
endif
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:highlight_line(bufnr, lnum, group) abort
|
function! s:highlight_line(bufnr, lnum, group) abort
|
||||||
if ale#highlight#HasNeovimApi()
|
|
||||||
let l:highlight_id = s:ale_nvim_highlight_id(a:bufnr)
|
|
||||||
call ale#highlight#nvim_buf_add_highlight(
|
|
||||||
\ a:bufnr, l:highlight_id, a:group,
|
|
||||||
\ a:lnum - 1, 0, -1
|
|
||||||
\)
|
|
||||||
else
|
|
||||||
call matchaddpos(a:group, [a:lnum])
|
call matchaddpos(a:group, [a:lnum])
|
||||||
endif
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:highlight_range(bufnr, range, group) abort
|
function! s:highlight_range(bufnr, range, group) abort
|
||||||
if ale#highlight#HasNeovimApi()
|
|
||||||
let l:highlight_id = s:ale_nvim_highlight_id(a:bufnr)
|
|
||||||
" NOTE: lines and columns indicies are 0-based in nvim_buf_* API.
|
|
||||||
let l:lnum = a:range.lnum - 1
|
|
||||||
let l:end_lnum = a:range.end_lnum - 1
|
|
||||||
let l:col = a:range.col - 1
|
|
||||||
let l:end_col = a:range.end_col
|
|
||||||
|
|
||||||
if l:lnum >= l:end_lnum
|
|
||||||
" For single lines, just return the one position.
|
|
||||||
call ale#highlight#nvim_buf_add_highlight(
|
|
||||||
\ a:bufnr, l:highlight_id, a:group,
|
|
||||||
\ l:lnum, l:col, l:end_col
|
|
||||||
\)
|
|
||||||
else
|
|
||||||
" highlight first line from start till the line end
|
|
||||||
call ale#highlight#nvim_buf_add_highlight(
|
|
||||||
\ a:bufnr, l:highlight_id, a:group,
|
|
||||||
\ l:lnum, l:col, -1
|
|
||||||
\)
|
|
||||||
|
|
||||||
" highlight all lines between the first and last entirely
|
|
||||||
let l:cur = l:lnum + 1
|
|
||||||
|
|
||||||
while l:cur < l:end_lnum
|
|
||||||
call ale#highlight#nvim_buf_add_highlight(
|
|
||||||
\ a:bufnr, l:highlight_id, a:group,
|
|
||||||
\ l:cur, 0, -1
|
|
||||||
\ )
|
|
||||||
let l:cur += 1
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
call ale#highlight#nvim_buf_add_highlight(
|
|
||||||
\ a:bufnr, l:highlight_id, a:group,
|
|
||||||
\ l:end_lnum, 0, l:end_col
|
|
||||||
\)
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
" Set all of the positions, which are chunked into Lists which
|
" Set all of the positions, which are chunked into Lists which
|
||||||
" are as large as will be accepted by matchaddpos.
|
" are as large as will be accepted by matchaddpos.
|
||||||
call map(
|
call map(
|
||||||
|
@ -167,7 +74,6 @@ function! s:highlight_range(bufnr, range, group) abort
|
||||||
\ ),
|
\ ),
|
||||||
\ 'matchaddpos(a:group, v:val)'
|
\ 'matchaddpos(a:group, v:val)'
|
||||||
\)
|
\)
|
||||||
endif
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#highlight#UpdateHighlights() abort
|
function! ale#highlight#UpdateHighlights() abort
|
||||||
|
|
|
@ -16,5 +16,11 @@ function! ale#java#FindProjectRoot(buffer) abort
|
||||||
return fnamemodify(l:maven_pom_file, ':h')
|
return fnamemodify(l:maven_pom_file, ':h')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
let l:ant_root = ale#ant#FindProjectRoot(a:buffer)
|
||||||
|
|
||||||
|
if !empty(l:ant_root)
|
||||||
|
return l:ant_root
|
||||||
|
endif
|
||||||
|
|
||||||
return ''
|
return ''
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
@ -13,10 +13,13 @@ let s:default_ale_linter_aliases = {
|
||||||
\ 'Dockerfile': 'dockerfile',
|
\ 'Dockerfile': 'dockerfile',
|
||||||
\ 'csh': 'sh',
|
\ 'csh': 'sh',
|
||||||
\ 'plaintex': 'tex',
|
\ 'plaintex': 'tex',
|
||||||
|
\ 'rmarkdown': 'r',
|
||||||
\ 'systemverilog': 'verilog',
|
\ 'systemverilog': 'verilog',
|
||||||
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
|
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
|
||||||
\ 'vimwiki': 'markdown',
|
\ 'vimwiki': 'markdown',
|
||||||
\ 'vue': ['vue', 'javascript'],
|
\ 'vue': ['vue', 'javascript'],
|
||||||
|
\ 'xsd': ['xsd', 'xml'],
|
||||||
|
\ 'xslt': ['xslt', 'xml'],
|
||||||
\ 'zsh': 'sh',
|
\ 'zsh': 'sh',
|
||||||
\}
|
\}
|
||||||
|
|
||||||
|
@ -355,12 +358,14 @@ function! ale#linter#Define(filetype, linter) abort
|
||||||
" This command will throw from the sandbox.
|
" This command will throw from the sandbox.
|
||||||
let &l:equalprg=&l:equalprg
|
let &l:equalprg=&l:equalprg
|
||||||
|
|
||||||
|
let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter)
|
||||||
|
|
||||||
if !has_key(s:linters, a:filetype)
|
if !has_key(s:linters, a:filetype)
|
||||||
let s:linters[a:filetype] = []
|
let s:linters[a:filetype] = []
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter)
|
" Remove previously defined linters with the same name.
|
||||||
|
call filter(s:linters[a:filetype], 'v:val.name isnot# a:linter.name')
|
||||||
call add(s:linters[a:filetype], l:new_linter)
|
call add(s:linters[a:filetype], l:new_linter)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,8 @@ function! s:FixList(buffer, list) abort
|
||||||
return l:new_list
|
return l:new_list
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:BufWinId(buffer) abort
|
function! s:WinFindBuf(buffer) abort
|
||||||
return exists('*bufwinid') ? bufwinid(str2nr(a:buffer)) : 0
|
return exists('*win_findbuf') ? win_findbuf(str2nr(a:buffer)) : [0]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||||
|
@ -88,19 +88,24 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||||
call setqflist([], 'r', {'title': l:title})
|
call setqflist([], 'r', {'title': l:title})
|
||||||
endif
|
endif
|
||||||
elseif g:ale_set_loclist
|
elseif g:ale_set_loclist
|
||||||
" If windows support is off, bufwinid() may not exist.
|
" If windows support is off, win_findbuf() may not exist.
|
||||||
" We'll set result in the current window, which might not be correct,
|
" We'll set result in the current window, which might not be correct,
|
||||||
" but it's better than nothing.
|
" but it's better than nothing.
|
||||||
let l:id = s:BufWinId(a:buffer)
|
let l:ids = s:WinFindBuf(a:buffer)
|
||||||
|
|
||||||
|
for l:id in l:ids
|
||||||
if has('nvim')
|
if has('nvim')
|
||||||
call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title)
|
call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title)
|
||||||
else
|
else
|
||||||
call setloclist(l:id, s:FixList(a:buffer, a:loclist))
|
call setloclist(l:id, s:FixList(a:buffer, a:loclist))
|
||||||
call setloclist(l:id, [], 'r', {'title': l:title})
|
call setloclist(l:id, [], 'r', {'title': l:title})
|
||||||
endif
|
endif
|
||||||
|
endfor
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" Save the current view before opening/closing any window
|
||||||
|
call setbufvar(a:buffer, 'ale_winview', winsaveview())
|
||||||
|
|
||||||
" Open a window to show the problems if we need to.
|
" Open a window to show the problems if we need to.
|
||||||
"
|
"
|
||||||
" We'll check if the current buffer's List is not empty here, so the
|
" We'll check if the current buffer's List is not empty here, so the
|
||||||
|
@ -108,8 +113,6 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||||
if s:ShouldOpen(a:buffer) && !empty(a:loclist)
|
if s:ShouldOpen(a:buffer) && !empty(a:loclist)
|
||||||
let l:winnr = winnr()
|
let l:winnr = winnr()
|
||||||
let l:mode = mode()
|
let l:mode = mode()
|
||||||
let l:reset_visual_selection = l:mode is? 'v' || l:mode is# "\<c-v>"
|
|
||||||
let l:reset_character_selection = l:mode is? 's' || l:mode is# "\<c-s>"
|
|
||||||
|
|
||||||
" open windows vertically instead of default horizontally
|
" open windows vertically instead of default horizontally
|
||||||
let l:open_type = ''
|
let l:open_type = ''
|
||||||
|
@ -131,15 +134,18 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||||
wincmd p
|
wincmd p
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if l:reset_visual_selection || l:reset_character_selection
|
" Return to original mode when applicable
|
||||||
" If we were in a selection mode before, select the last selection.
|
if mode() != l:mode
|
||||||
|
if l:mode is? 'v' || l:mode is# "\<c-v>"
|
||||||
|
" Reset our last visual selection
|
||||||
normal! gv
|
normal! gv
|
||||||
|
elseif l:mode is? 's' || l:mode is# "\<c-s>"
|
||||||
if l:reset_character_selection
|
" Reset our last character selection
|
||||||
" Switch back to Select mode, if we were in that.
|
|
||||||
normal! "\<c-g>"
|
normal! "\<c-g>"
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
call s:RestoreViewIfNeeded(a:buffer)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" If ALE isn't currently checking for more problems, close the window if
|
" If ALE isn't currently checking for more problems, close the window if
|
||||||
|
@ -150,6 +156,30 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Try to restore the window view after closing any of the lists to avoid making
|
||||||
|
" the it moving around, especially useful when on insert mode
|
||||||
|
function! s:RestoreViewIfNeeded(buffer) abort
|
||||||
|
let l:saved_view = getbufvar(a:buffer, 'ale_winview', {})
|
||||||
|
|
||||||
|
" Saved view is empty, can't do anything
|
||||||
|
if empty(l:saved_view)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Check wether the cursor has moved since linting was actually requested. If
|
||||||
|
" the user has indeed moved lines, do nothing
|
||||||
|
let l:current_view = winsaveview()
|
||||||
|
|
||||||
|
if l:current_view['lnum'] != l:saved_view['lnum']
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Anchor view by topline if the list is set to open horizontally
|
||||||
|
if ale#Var(a:buffer, 'list_vertical') == 0
|
||||||
|
call winrestview({'topline': l:saved_view['topline']})
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ale#list#SetLists(buffer, loclist) abort
|
function! ale#list#SetLists(buffer, loclist) abort
|
||||||
if get(g:, 'ale_set_lists_synchronously') == 1
|
if get(g:, 'ale_set_lists_synchronously') == 1
|
||||||
\|| getbufvar(a:buffer, 'ale_save_event_fired', 0)
|
\|| getbufvar(a:buffer, 'ale_save_event_fired', 0)
|
||||||
|
@ -173,21 +203,31 @@ function! s:CloseWindowIfNeeded(buffer) abort
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
let l:did_close_any_list = 0
|
||||||
|
|
||||||
try
|
try
|
||||||
" Only close windows if the quickfix list or loclist is completely empty,
|
" Only close windows if the quickfix list or loclist is completely empty,
|
||||||
" including errors set through other means.
|
" including errors set through other means.
|
||||||
if g:ale_set_quickfix
|
if g:ale_set_quickfix
|
||||||
if empty(getqflist())
|
if empty(getqflist())
|
||||||
cclose
|
cclose
|
||||||
|
let l:did_close_any_list = 1
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
let l:win_id = s:BufWinId(a:buffer)
|
let l:win_ids = s:WinFindBuf(a:buffer)
|
||||||
|
|
||||||
|
for l:win_id in l:win_ids
|
||||||
if g:ale_set_loclist && empty(getloclist(l:win_id))
|
if g:ale_set_loclist && empty(getloclist(l:win_id))
|
||||||
lclose
|
lclose
|
||||||
|
let l:did_close_any_list = 1
|
||||||
endif
|
endif
|
||||||
|
endfor
|
||||||
endif
|
endif
|
||||||
" Ignore 'Cannot close last window' errors.
|
" Ignore 'Cannot close last window' errors.
|
||||||
catch /E444/
|
catch /E444/
|
||||||
endtry
|
endtry
|
||||||
|
|
||||||
|
if l:did_close_any_list
|
||||||
|
call s:RestoreViewIfNeeded(a:buffer)
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
@ -111,7 +111,7 @@ function! ale#loclist_jumping#Jump(direction, ...) abort
|
||||||
|
|
||||||
if !empty(l:nearest)
|
if !empty(l:nearest)
|
||||||
normal! m`
|
normal! m`
|
||||||
call cursor(l:nearest)
|
call cursor([l:nearest[0], max([l:nearest[1], 1])])
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
|
@ -321,7 +321,69 @@ endfunction
|
||||||
|
|
||||||
function! s:SendInitMessage(conn) abort
|
function! s:SendInitMessage(conn) abort
|
||||||
let [l:init_id, l:init_data] = ale#lsp#CreateMessageData(
|
let [l:init_id, l:init_data] = ale#lsp#CreateMessageData(
|
||||||
\ ale#lsp#message#Initialize(a:conn.root, a:conn.init_options),
|
\ ale#lsp#message#Initialize(
|
||||||
|
\ a:conn.root,
|
||||||
|
\ a:conn.init_options,
|
||||||
|
\ {
|
||||||
|
\ 'workspace': {
|
||||||
|
\ 'applyEdit': v:false,
|
||||||
|
\ 'didChangeConfiguration': {
|
||||||
|
\ 'dynamicRegistration': v:false,
|
||||||
|
\ },
|
||||||
|
\ 'symbol': {
|
||||||
|
\ 'dynamicRegistration': v:false,
|
||||||
|
\ },
|
||||||
|
\ 'workspaceFolders': v:false,
|
||||||
|
\ 'configuration': v:false,
|
||||||
|
\ },
|
||||||
|
\ 'textDocument': {
|
||||||
|
\ 'synchronization': {
|
||||||
|
\ 'dynamicRegistration': v:false,
|
||||||
|
\ 'willSave': v:false,
|
||||||
|
\ 'willSaveWaitUntil': v:false,
|
||||||
|
\ 'didSave': v:true,
|
||||||
|
\ },
|
||||||
|
\ 'completion': {
|
||||||
|
\ 'dynamicRegistration': v:false,
|
||||||
|
\ 'completionItem': {
|
||||||
|
\ 'snippetSupport': v:false,
|
||||||
|
\ 'commitCharactersSupport': v:false,
|
||||||
|
\ 'documentationFormat': ['plaintext'],
|
||||||
|
\ 'deprecatedSupport': v:false,
|
||||||
|
\ 'preselectSupport': v:false,
|
||||||
|
\ },
|
||||||
|
\ 'contextSupport': v:false,
|
||||||
|
\ },
|
||||||
|
\ 'hover': {
|
||||||
|
\ 'dynamicRegistration': v:false,
|
||||||
|
\ 'contentFormat': ['plaintext'],
|
||||||
|
\ },
|
||||||
|
\ 'references': {
|
||||||
|
\ 'dynamicRegistration': v:false,
|
||||||
|
\ },
|
||||||
|
\ 'documentSymbol': {
|
||||||
|
\ 'dynamicRegistration': v:false,
|
||||||
|
\ 'hierarchicalDocumentSymbolSupport': v:false,
|
||||||
|
\ },
|
||||||
|
\ 'definition': {
|
||||||
|
\ 'dynamicRegistration': v:false,
|
||||||
|
\ 'linkSupport': v:false,
|
||||||
|
\ },
|
||||||
|
\ 'typeDefinition': {
|
||||||
|
\ 'dynamicRegistration': v:false,
|
||||||
|
\ },
|
||||||
|
\ 'publishDiagnostics': {
|
||||||
|
\ 'relatedInformation': v:true,
|
||||||
|
\ },
|
||||||
|
\ 'codeAction': {
|
||||||
|
\ 'dynamicRegistration': v:false,
|
||||||
|
\ },
|
||||||
|
\ 'rename': {
|
||||||
|
\ 'dynamicRegistration': v:false,
|
||||||
|
\ },
|
||||||
|
\ },
|
||||||
|
\ },
|
||||||
|
\ ),
|
||||||
\)
|
\)
|
||||||
let a:conn.init_request_id = l:init_id
|
let a:conn.init_request_id = l:init_id
|
||||||
call s:SendMessageData(a:conn, l:init_data)
|
call s:SendMessageData(a:conn, l:init_data)
|
||||||
|
@ -484,6 +546,35 @@ function! ale#lsp#OpenDocument(conn_id, buffer, language_id) abort
|
||||||
return l:opened
|
return l:opened
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Notify LSP servers or tsserver that a document is closed, if opened before.
|
||||||
|
" If a document is closed, 1 will be returned, otherwise 0 will be returned.
|
||||||
|
"
|
||||||
|
" Only the buffer number is required here. A message will be sent to every
|
||||||
|
" language server that was notified previously of the document being opened.
|
||||||
|
function! ale#lsp#CloseDocument(buffer) abort
|
||||||
|
let l:closed = 0
|
||||||
|
|
||||||
|
" The connection keys are sorted so the messages are easier to test, and
|
||||||
|
" so messages are sent in a consistent order.
|
||||||
|
for l:conn_id in sort(keys(s:connections))
|
||||||
|
let l:conn = s:connections[l:conn_id]
|
||||||
|
|
||||||
|
if l:conn.initialized && has_key(l:conn.open_documents, a:buffer)
|
||||||
|
if l:conn.is_tsserver
|
||||||
|
let l:message = ale#lsp#tsserver_message#Close(a:buffer)
|
||||||
|
else
|
||||||
|
let l:message = ale#lsp#message#DidClose(a:buffer)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call ale#lsp#Send(l:conn_id, l:message)
|
||||||
|
call remove(l:conn.open_documents, a:buffer)
|
||||||
|
let l:closed = 1
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:closed
|
||||||
|
endfunction
|
||||||
|
|
||||||
" Notify LSP servers or tsserver that a document has changed, if needed.
|
" Notify LSP servers or tsserver that a document has changed, if needed.
|
||||||
" If a notification is sent, 1 will be returned, otherwise 0 will be returned.
|
" If a notification is sent, 1 will be returned, otherwise 0 will be returned.
|
||||||
function! ale#lsp#NotifyForChanges(conn_id, buffer) abort
|
function! ale#lsp#NotifyForChanges(conn_id, buffer) abort
|
||||||
|
|
|
@ -28,14 +28,13 @@ function! ale#lsp#message#GetNextVersionID() abort
|
||||||
return l:id
|
return l:id
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#lsp#message#Initialize(root_path, initialization_options) abort
|
function! ale#lsp#message#Initialize(root_path, options, capabilities) abort
|
||||||
" TODO: Define needed capabilities.
|
|
||||||
" NOTE: rootPath is deprecated in favour of rootUri
|
" NOTE: rootPath is deprecated in favour of rootUri
|
||||||
return [0, 'initialize', {
|
return [0, 'initialize', {
|
||||||
\ 'processId': getpid(),
|
\ 'processId': getpid(),
|
||||||
\ 'rootPath': a:root_path,
|
\ 'rootPath': a:root_path,
|
||||||
\ 'capabilities': {},
|
\ 'capabilities': a:capabilities,
|
||||||
\ 'initializationOptions': a:initialization_options,
|
\ 'initializationOptions': a:options,
|
||||||
\ 'rootUri': ale#path#ToURI(a:root_path),
|
\ 'rootUri': ale#path#ToURI(a:root_path),
|
||||||
\}]
|
\}]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
@ -90,7 +90,7 @@ function! ale#lsp#response#ReadTSServerDiagnostics(response) abort
|
||||||
\ 'lnum': l:diagnostic.start.line,
|
\ 'lnum': l:diagnostic.start.line,
|
||||||
\ 'col': l:diagnostic.start.offset,
|
\ 'col': l:diagnostic.start.offset,
|
||||||
\ 'end_lnum': l:diagnostic.end.line,
|
\ 'end_lnum': l:diagnostic.end.line,
|
||||||
\ 'end_col': l:diagnostic.end.offset,
|
\ 'end_col': l:diagnostic.end.offset - 1,
|
||||||
\}
|
\}
|
||||||
|
|
||||||
if has_key(l:diagnostic, 'code')
|
if has_key(l:diagnostic, 'code')
|
||||||
|
|
|
@ -8,6 +8,9 @@ if !has_key(s:, 'lsp_linter_map')
|
||||||
let s:lsp_linter_map = {}
|
let s:lsp_linter_map = {}
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" A Dictionary to track one-shot handlers for custom LSP requests
|
||||||
|
let s:custom_handlers_map = get(s:, 'custom_handlers_map', {})
|
||||||
|
|
||||||
" Check if diagnostics for a particular linter should be ignored.
|
" Check if diagnostics for a particular linter should be ignored.
|
||||||
function! s:ShouldIgnore(buffer, linter_name) abort
|
function! s:ShouldIgnore(buffer, linter_name) abort
|
||||||
" Ignore all diagnostics if LSP integration is disabled.
|
" Ignore all diagnostics if LSP integration is disabled.
|
||||||
|
@ -31,7 +34,7 @@ endfunction
|
||||||
function! s:HandleLSPDiagnostics(conn_id, response) abort
|
function! s:HandleLSPDiagnostics(conn_id, response) abort
|
||||||
let l:linter_name = s:lsp_linter_map[a:conn_id]
|
let l:linter_name = s:lsp_linter_map[a:conn_id]
|
||||||
let l:filename = ale#path#FromURI(a:response.params.uri)
|
let l:filename = ale#path#FromURI(a:response.params.uri)
|
||||||
let l:buffer = bufnr(l:filename)
|
let l:buffer = bufnr('^' . l:filename . '$')
|
||||||
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
||||||
|
|
||||||
if empty(l:info)
|
if empty(l:info)
|
||||||
|
@ -49,7 +52,7 @@ endfunction
|
||||||
|
|
||||||
function! s:HandleTSServerDiagnostics(response, error_type) abort
|
function! s:HandleTSServerDiagnostics(response, error_type) abort
|
||||||
let l:linter_name = 'tsserver'
|
let l:linter_name = 'tsserver'
|
||||||
let l:buffer = bufnr(a:response.body.file)
|
let l:buffer = bufnr('^' . a:response.body.file . '$')
|
||||||
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
||||||
|
|
||||||
if empty(l:info)
|
if empty(l:info)
|
||||||
|
@ -407,9 +410,57 @@ endfunction
|
||||||
" Clear LSP linter data for the linting engine.
|
" Clear LSP linter data for the linting engine.
|
||||||
function! ale#lsp_linter#ClearLSPData() abort
|
function! ale#lsp_linter#ClearLSPData() abort
|
||||||
let s:lsp_linter_map = {}
|
let s:lsp_linter_map = {}
|
||||||
|
let s:custom_handlers_map = {}
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Just for tests.
|
" Just for tests.
|
||||||
function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
|
function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
|
||||||
let s:lsp_linter_map = a:replacement_map
|
let s:lsp_linter_map = a:replacement_map
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:HandleLSPResponseToCustomRequests(conn_id, response) abort
|
||||||
|
if has_key(a:response, 'id')
|
||||||
|
\&& has_key(s:custom_handlers_map, a:response.id)
|
||||||
|
let l:Handler = remove(s:custom_handlers_map, a:response.id)
|
||||||
|
call l:Handler(a:response)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:OnReadyForCustomRequests(args, linter, lsp_details) abort
|
||||||
|
let l:id = a:lsp_details.connection_id
|
||||||
|
let l:request_id = ale#lsp#Send(l:id, a:args.message)
|
||||||
|
|
||||||
|
if l:request_id > 0 && has_key(a:args, 'handler')
|
||||||
|
let l:Callback = function('s:HandleLSPResponseToCustomRequests')
|
||||||
|
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||||
|
let s:custom_handlers_map[l:request_id] = a:args.handler
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Send a custom request to an LSP linter.
|
||||||
|
function! ale#lsp_linter#SendRequest(buffer, linter_name, message, ...) abort
|
||||||
|
let l:filetype = ale#linter#ResolveFiletype(getbufvar(a:buffer, '&filetype'))
|
||||||
|
let l:linter_list = ale#linter#GetAll(l:filetype)
|
||||||
|
let l:linter_list = filter(l:linter_list, {_, v -> v.name is# a:linter_name})
|
||||||
|
|
||||||
|
if len(l:linter_list) < 1
|
||||||
|
throw 'Linter "' . a:linter_name . '" not found!'
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:linter = l:linter_list[0]
|
||||||
|
|
||||||
|
if empty(l:linter.lsp)
|
||||||
|
throw 'Linter "' . a:linter_name . '" does not support LSP!'
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:is_notification = a:message[0]
|
||||||
|
let l:callback_args = {'message': a:message}
|
||||||
|
|
||||||
|
if !l:is_notification && a:0
|
||||||
|
let l:callback_args.handler = a:1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:Callback = function('s:OnReadyForCustomRequests', [l:callback_args])
|
||||||
|
|
||||||
|
return ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback)
|
||||||
|
endfunction
|
||||||
|
|
|
@ -3,13 +3,20 @@
|
||||||
|
|
||||||
" simplify a path, and fix annoying issues with paths on Windows.
|
" simplify a path, and fix annoying issues with paths on Windows.
|
||||||
"
|
"
|
||||||
" Forward slashes are changed to back slashes so path equality works better.
|
" Forward slashes are changed to back slashes so path equality works better
|
||||||
|
" on Windows. Back slashes are changed to forward slashes on Unix.
|
||||||
|
"
|
||||||
|
" Unix paths can technically contain back slashes, but in practice no path
|
||||||
|
" should, and replacing back slashes with forward slashes makes linters work
|
||||||
|
" in environments like MSYS.
|
||||||
"
|
"
|
||||||
" Paths starting with more than one forward slash are changed to only one
|
" Paths starting with more than one forward slash are changed to only one
|
||||||
" forward slash, to prevent the paths being treated as special MSYS paths.
|
" forward slash, to prevent the paths being treated as special MSYS paths.
|
||||||
function! ale#path#Simplify(path) abort
|
function! ale#path#Simplify(path) abort
|
||||||
if has('unix')
|
if has('unix')
|
||||||
return substitute(simplify(a:path), '^//\+', '/', 'g') " no-custom-checks
|
let l:unix_path = substitute(a:path, '\\', '/', 'g')
|
||||||
|
|
||||||
|
return substitute(simplify(l:unix_path), '^//\+', '/', 'g') " no-custom-checks
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:win_path = substitute(a:path, '/', '\\', 'g')
|
let l:win_path = substitute(a:path, '/', '\\', 'g')
|
||||||
|
|
|
@ -25,7 +25,7 @@ function! ale#python#FindProjectRootIni(buffer) abort
|
||||||
\|| filereadable(l:path . '/tox.ini')
|
\|| filereadable(l:path . '/tox.ini')
|
||||||
\|| filereadable(l:path . '/mypy.ini')
|
\|| filereadable(l:path . '/mypy.ini')
|
||||||
\|| filereadable(l:path . '/pycodestyle.cfg')
|
\|| filereadable(l:path . '/pycodestyle.cfg')
|
||||||
\|| filereadable(l:path . '/flake8.cfg')
|
\|| filereadable(l:path . '/.flake8')
|
||||||
\|| filereadable(l:path . '/.flake8rc')
|
\|| filereadable(l:path . '/.flake8rc')
|
||||||
\|| filereadable(l:path . '/pylama.ini')
|
\|| filereadable(l:path . '/pylama.ini')
|
||||||
\|| filereadable(l:path . '/pylintrc')
|
\|| filereadable(l:path . '/pylintrc')
|
||||||
|
|
|
@ -82,6 +82,34 @@ execute 'sign define ALEInfoSign text=' . s:EscapeSignText(g:ale_sign_info)
|
||||||
\ . ' texthl=ALEInfoSign linehl=ALEInfoLine'
|
\ . ' texthl=ALEInfoSign linehl=ALEInfoLine'
|
||||||
sign define ALEDummySign
|
sign define ALEDummySign
|
||||||
|
|
||||||
|
if has('nvim-0.3.2')
|
||||||
|
if !hlexists('ALEErrorSignLineNr')
|
||||||
|
highlight link ALEErrorSignLineNr CursorLineNr
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !hlexists('ALEStyleErrorSignLineNr')
|
||||||
|
highlight link ALEStyleErrorSignLineNr CursorLineNr
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !hlexists('ALEWarningSignLineNr')
|
||||||
|
highlight link ALEWarningSignLineNr CursorLineNr
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !hlexists('ALEStyleWarningSignLineNr')
|
||||||
|
highlight link ALEStyleWarningSignLineNr CursorLineNr
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !hlexists('ALEInfoSignLineNr')
|
||||||
|
highlight link ALEInfoSignLineNr CursorLineNr
|
||||||
|
endif
|
||||||
|
|
||||||
|
sign define ALEErrorSign numhl=ALEErrorSignLineNr
|
||||||
|
sign define ALEStyleErrorSign numhl=ALEStyleErrorSignLineNr
|
||||||
|
sign define ALEWarningSign numhl=ALEWarningSignLineNr
|
||||||
|
sign define ALEStyleWarningSign numhl=ALEStyleWarningSignLineNr
|
||||||
|
sign define ALEInfoSign numhl=ALEInfoSignLineNr
|
||||||
|
endif
|
||||||
|
|
||||||
function! ale#sign#GetSignName(sublist) abort
|
function! ale#sign#GetSignName(sublist) abort
|
||||||
let l:priority = g:ale#util#style_warning_priority
|
let l:priority = g:ale#util#style_warning_priority
|
||||||
|
|
||||||
|
|
26
sources_non_forked/ale/autoload/asyncomplete/sources/ale.vim
Normal file
26
sources_non_forked/ale/autoload/asyncomplete/sources/ale.vim
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
function! asyncomplete#sources#ale#get_source_options(...) abort
|
||||||
|
let l:default = extend({
|
||||||
|
\ 'name': 'ale',
|
||||||
|
\ 'completor': function('asyncomplete#sources#ale#completor'),
|
||||||
|
\ 'whitelist': ['*'],
|
||||||
|
\ 'triggers': asyncomplete#sources#ale#get_triggers(),
|
||||||
|
\ }, a:0 >= 1 ? a:1 : {})
|
||||||
|
|
||||||
|
return extend(l:default, {'refresh_pattern': '\k\+$'})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! asyncomplete#sources#ale#get_triggers() abort
|
||||||
|
let l:triggers = ale#completion#GetAllTriggers()
|
||||||
|
let l:triggers['*'] = l:triggers['<default>']
|
||||||
|
|
||||||
|
return l:triggers
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! asyncomplete#sources#ale#completor(options, context) abort
|
||||||
|
let l:keyword = matchstr(a:context.typed, '\w\+$')
|
||||||
|
let l:startcol = a:context.col - len(l:keyword)
|
||||||
|
|
||||||
|
call ale#completion#GetCompletions('ale-callback', { 'callback': {completions ->
|
||||||
|
\ asyncomplete#complete(a:options.name, a:context, l:startcol, completions)
|
||||||
|
\ }})
|
||||||
|
endfunction
|
|
@ -21,5 +21,16 @@ g:ale_ada_gcc_options *g:ale_ada_gcc_options*
|
||||||
This variable can be set to pass additional options to gcc.
|
This variable can be set to pass additional options to gcc.
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
gnatpp *ale-ada-gnatpp*
|
||||||
|
|
||||||
|
g:ale_ada_gnatpp_options *g:ale_ada_gnatpp_options*
|
||||||
|
*b:ale_ada_gnatpp_options*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
This variable can be set to pass extra options to the gnatpp fixer.
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||||
|
|
|
@ -156,7 +156,7 @@ g:ale_c_clangtidy_options *g:ale_c_clangtidy_options*
|
||||||
Type: |String|
|
Type: |String|
|
||||||
Default: `''`
|
Default: `''`
|
||||||
|
|
||||||
This variable can be changed to modify flags given to clang-tidy.
|
This variable can be changed to modify compiler flags given to clang-tidy.
|
||||||
|
|
||||||
- Setting this variable to a non-empty string,
|
- Setting this variable to a non-empty string,
|
||||||
- and working in a buffer where no compilation database is found using
|
- and working in a buffer where no compilation database is found using
|
||||||
|
@ -169,6 +169,23 @@ g:ale_c_clangtidy_options *g:ale_c_clangtidy_options*
|
||||||
of the |g:ale_c_build_dir_names| directories of the project tree.
|
of the |g:ale_c_build_dir_names| directories of the project tree.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_c_clangtidy_extra_options *g:ale_c_clangtidy_extra_options*
|
||||||
|
*b:ale_c_clangtidy_extra_options*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
This variable can be changed to modify flags given to clang-tidy.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_c_clangtidy_fix_errors *g:ale_c_clangtidy_fix_errors*
|
||||||
|
*b:ale_c_clangtidy_fix_errors*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `1`
|
||||||
|
|
||||||
|
This variable can be changed to disable the `-fix-errors` option for the
|
||||||
|
|clangtidy| fixer.
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
cppcheck *ale-c-cppcheck*
|
cppcheck *ale-c-cppcheck*
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options*
|
||||||
Type: |String|
|
Type: |String|
|
||||||
Default: `''`
|
Default: `''`
|
||||||
|
|
||||||
This variable can be changed to modify flags given to clang-tidy.
|
This variable can be changed to modify compiler flags given to clang-tidy.
|
||||||
|
|
||||||
- Setting this variable to a non-empty string,
|
- Setting this variable to a non-empty string,
|
||||||
- and working in a buffer where no compilation database is found using
|
- and working in a buffer where no compilation database is found using
|
||||||
|
@ -138,6 +138,23 @@ g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options*
|
||||||
of the |g:ale_c_build_dir_names| directories of the project tree.
|
of the |g:ale_c_build_dir_names| directories of the project tree.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_cpp_clangtidy_extra_options *g:ale_cpp_clangtidy_extra_options*
|
||||||
|
*b:ale_cpp_clangtidy_extra_options*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
This variable can be changed to modify flags given to clang-tidy.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_cpp_clangtidy_fix_errors *g:ale_cpp_clangtidy_fix_errors*
|
||||||
|
*b:ale_cpp_clangtidy_fix_errors*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `1`
|
||||||
|
|
||||||
|
This variable can be changed to disable the `-fix-errors` option for the
|
||||||
|
|clangtidy| fixer.
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
clazy *ale-cpp-clazy*
|
clazy *ale-cpp-clazy*
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,97 @@ In addition to the linters that are provided with ALE, C# code can be checked
|
||||||
with the OmniSharp plugin. See here: https://github.com/OmniSharp/omnisharp-vim
|
with the OmniSharp plugin. See here: https://github.com/OmniSharp/omnisharp-vim
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
csc *ale-cs-csc*
|
||||||
|
|
||||||
|
The |ale-cs-csc| linter checks for semantic errors when files are opened or
|
||||||
|
saved.
|
||||||
|
|
||||||
|
See |ale-lint-file-linters| for more information on linters which do not
|
||||||
|
check for problems while you type.
|
||||||
|
|
||||||
|
The csc linter uses the mono csc compiler providing full c# 7 and newer
|
||||||
|
support to generate a temporary module target file (/t:module). The module
|
||||||
|
includes including all '*.cs' files contained in the directory tree rooted
|
||||||
|
at the path defined by the |g:ale_cs_csc_source| or |b:ale_cs_csc_source|
|
||||||
|
variabl and all sub directories.
|
||||||
|
|
||||||
|
It will in future replace the |ale-cs-mcs| and |ale-cs-mcsc| linters as both
|
||||||
|
utilizer the mcsc compiler which according to mono porject ist further
|
||||||
|
developed and as of writint these lines only receives maintenance updates.
|
||||||
|
The down is that the csc compiler does not support the -sytax option any more
|
||||||
|
and therefore |ale-cs-csc| linter doese not offer any as you type syntax
|
||||||
|
checking like the |ale-cs-mcsc| linter doesn't.
|
||||||
|
|
||||||
|
The paths to search for additional assembly files can be specified using the
|
||||||
|
|g:ale_cs_csc_assembly_path| or |b:ale_cs_csc_assembly_path| variables.
|
||||||
|
|
||||||
|
NOTE: ALE will not find any errors in files apart from syntax errors if any
|
||||||
|
one of the source files contains a syntax error. Syntax errors must be fixed
|
||||||
|
first before other errors will be shown.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_cs_csc_options *g:ale_cs_csc_options*
|
||||||
|
*b:ale_cs_csc_options*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
This option can be set to pass additional arguments to the `csc` compiler.
|
||||||
|
|
||||||
|
For example, to add the dotnet package which is not added per default: >
|
||||||
|
|
||||||
|
let g:ale_cs_mcs_options = ' /warn:4 /langversion:7.2'
|
||||||
|
<
|
||||||
|
NOTE: the `/unsafe` option is always passed to `csc`.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_cs_csc_source *g:ale_cs_csc_source*
|
||||||
|
*b:ale_cs_csc_source*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
This variable defines the root path of the directory tree searched for the
|
||||||
|
'*.cs' files to be linted. If this option is empty, the source file's
|
||||||
|
directory will be used.
|
||||||
|
|
||||||
|
NOTE: Currently it is not possible to specify sub directories and
|
||||||
|
directory sub trees which shall not be searched for *.cs files.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_cs_csc_assembly_path *g:ale_cs_csc_assembly_path*
|
||||||
|
*b:ale_cs_csc_assembly_path*
|
||||||
|
Type: |List|
|
||||||
|
Default: `[]`
|
||||||
|
|
||||||
|
This variable defines a list of path strings to be searched for external
|
||||||
|
assembly files. The list is passed to the csc compiler using the `/lib:`
|
||||||
|
flag.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_cs_csc_assemblies *g:ale_cs_csc_assemblies*
|
||||||
|
*b:ale_cs_csc_assemblies*
|
||||||
|
Type: |List|
|
||||||
|
Default: `[]`
|
||||||
|
|
||||||
|
This variable defines a list of external assembly (*.dll) files required
|
||||||
|
by the mono mcs compiler to generate a valid module target. The list is
|
||||||
|
passed the csc compiler using the `/r:` flag.
|
||||||
|
|
||||||
|
For example: >
|
||||||
|
|
||||||
|
" Compile C# programs with the Unity engine DLL file on Mac.
|
||||||
|
let g:ale_cs_mcsc_assemblies = [
|
||||||
|
\ '/Applications/Unity/Unity.app/Contents/Frameworks/Managed/UnityEngine.dll',
|
||||||
|
\ 'path-to-unityproject/obj/Debug',
|
||||||
|
\]
|
||||||
|
<
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
mcs *ale-cs-mcs*
|
mcs *ale-cs-mcs*
|
||||||
|
|
||||||
The `mcs` linter looks only for syntax errors while you type. See |ale-cs-mcsc|
|
The `mcs` linter looks only for syntax errors while you type. See
|
||||||
for the separately configured linter for checking for semantic errors.
|
|ale-cs-mcsc| for the separately configured linter for checking for semantic
|
||||||
|
errors.
|
||||||
|
|
||||||
|
|
||||||
g:ale_cs_mcs_options *g:ale_cs_mcs_options*
|
g:ale_cs_mcs_options *g:ale_cs_mcs_options*
|
||||||
|
|
|
@ -151,9 +151,9 @@ ALE is tested with a suite of tests executed in Travis CI and AppVeyor. ALE
|
||||||
runs tests with the following versions of Vim in the following environments.
|
runs tests with the following versions of Vim in the following environments.
|
||||||
|
|
||||||
1. Vim 8.0.0027 on Linux via Travis CI.
|
1. Vim 8.0.0027 on Linux via Travis CI.
|
||||||
2. Vim 8.1.0204 on Linux via Travis CI.
|
2. Vim 8.1.0519 on Linux via Travis CI.
|
||||||
3. NeoVim 0.2.0 on Linux via Travis CI.
|
3. NeoVim 0.2.0 on Linux via Travis CI.
|
||||||
4. NeoVim 0.3.0 on Linux via Travis CI.
|
4. NeoVim 0.3.5 on Linux via Travis CI.
|
||||||
5. Vim 8 (stable builds) on Windows via AppVeyor.
|
5. Vim 8 (stable builds) on Windows via AppVeyor.
|
||||||
|
|
||||||
If you are developing ALE code on Linux, Mac OSX, or BSD, you can run ALEs
|
If you are developing ALE code on Linux, Mac OSX, or BSD, you can run ALEs
|
||||||
|
@ -351,6 +351,7 @@ given the above setup are as follows.
|
||||||
|
|
||||||
`GivenCommandOutput [...]` - Define output for ale#command#Run.
|
`GivenCommandOutput [...]` - Define output for ale#command#Run.
|
||||||
`AssertFixer results` - Check the fixer results
|
`AssertFixer results` - Check the fixer results
|
||||||
|
`AssertFixerNotExecuted` - Check that fixers will not be executed.
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
|
|
@ -29,20 +29,44 @@ g:ale_elm_format_options *g:ale_elm_format_options*
|
||||||
This variable can be set to pass additional options to elm-format.
|
This variable can be set to pass additional options to elm-format.
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
elm-lsp *ale-elm-elm-lsp*
|
elm-ls *ale-elm-elm-ls*
|
||||||
|
|
||||||
g:ale_elm_lsp_executable *g:ale_elm_lsp_executable*
|
g:ale_elm_ls_executable *g:ale_elm_ls_executable*
|
||||||
*b:ale_elm_lsp_executable*
|
*b:ale_elm_ls_executable*
|
||||||
Type: |String|
|
Type: |String|
|
||||||
Default: `'elm-lsp'`
|
Default: `'elm-language-server'`
|
||||||
|
|
||||||
See |ale-integrations-local-executables|
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
g:ale_elm_lsp_use_global *g:ale_elm_lsp_use_global*
|
g:ale_elm_ls_use_global *g:ale_elm_ls_use_global*
|
||||||
*b:ale_elm_lsp_use_global*
|
*b:ale_elm_ls_use_global*
|
||||||
Type: |Number|
|
Type: |Number|
|
||||||
Default: `get(g:, 'ale_use_global_executables', 0)`
|
Default: `get(g:, 'ale_use_global_executables', 1)`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_elm_ls_elm_path *g:ale_elm_ls_elm_path*
|
||||||
|
*b:ale_elm_ls_elm_path*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'elm'`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_elm_ls_elm_format_path *g:ale_elm_ls_elm_format_path*
|
||||||
|
*b:ale_elm_ls_elm_format_path*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'elm-format'`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_elm_ls_elm_test_path *g:ale_elm_ls_elm_test_path*
|
||||||
|
*b:ale_elm_ls_elm_test_path*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'elm-test'`
|
||||||
|
|
||||||
See |ale-integrations-local-executables|
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,35 @@ ALE Erlang Integration *ale-erlang-options*
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
dialyzer *ale-erlang-dialyzer*
|
||||||
|
|
||||||
|
g:ale_erlang_dialyzer_executable *g:ale_erlang_dialyzer_executable*
|
||||||
|
*b:ale_erlang_dialyzer_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'dialyzer'`
|
||||||
|
|
||||||
|
This variable can be changed to specify the dialyzer executable.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_erlang_dialyzer_plt_file *g:ale_erlang_dialyzer_plt_file*
|
||||||
|
*b:ale_erlang_dialyzer_plt_file*
|
||||||
|
Type: |String|
|
||||||
|
|
||||||
|
This variable can be changed to specify the path to the PLT file. By
|
||||||
|
default, it will search for the PLT file inside the `_build` directory. If
|
||||||
|
there isn't one, it will fallback to the path `$REBAR_PLT_DIR/dialyzer/plt`.
|
||||||
|
Otherwise, it will default to `$HOME/.dialyzer_plt`.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_erlang_dialyzer_rebar3_profile *g:ale_erlang_dialyzer_rebar3_profile*
|
||||||
|
*b:ale_erlang_dialyzer_rebar3_profile*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'default'`
|
||||||
|
|
||||||
|
This variable can be changed to specify the profile that is used to
|
||||||
|
run dialyzer with rebar3.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
erlc *ale-erlang-erlc*
|
erlc *ale-erlang-erlc*
|
||||||
|
|
||||||
g:ale_erlang_erlc_options *g:ale_erlang_erlc_options*
|
g:ale_erlang_erlc_options *g:ale_erlang_erlc_options*
|
||||||
|
|
|
@ -30,6 +30,16 @@ g:ale_go_go_executable *g:ale_go_go_options*
|
||||||
the `gomod` fixer.
|
the `gomod` fixer.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_go_go111module *g:ale_go_go111module*
|
||||||
|
*b:ale_go_go111module*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
Override the value of the `$GO111MODULE` environment variable for
|
||||||
|
golang tools.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
bingo *ale-go-bingo*
|
bingo *ale-go-bingo*
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue