Updated plugins
This commit is contained in:
parent
96e10ed101
commit
72bdaba47e
204 changed files with 5936 additions and 1666 deletions
|
@ -3,9 +3,14 @@
|
|||
|
||||
call ale#Set('c_clangd_executable', 'clangd')
|
||||
call ale#Set('c_clangd_options', '')
|
||||
call ale#Set('c_build_dir', '')
|
||||
|
||||
function! ale_linters#c#clangd#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options'))
|
||||
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
|
||||
|
||||
return '%e'
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'c_clangd_options'))
|
||||
\ . (!empty(l:build_dir) ? ' -compile-commands-dir=' . ale#Escape(l:build_dir) : '')
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('c', {
|
||||
|
|
|
@ -19,14 +19,17 @@ call ale#Set('c_clangtidy_options', '')
|
|||
call ale#Set('c_clangtidy_extra_options', '')
|
||||
call ale#Set('c_build_dir', '')
|
||||
|
||||
function! ale_linters#c#clangtidy#GetCommand(buffer) abort
|
||||
function! ale_linters#c#clangtidy#GetCommand(buffer, output) abort
|
||||
let l:checks = join(ale#Var(a:buffer, 'c_clangtidy_checks'), ',')
|
||||
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
|
||||
let l:options = ''
|
||||
|
||||
" Get the extra options if we couldn't find a build directory.
|
||||
let l:options = empty(l:build_dir)
|
||||
\ ? ale#Var(a:buffer, 'c_clangtidy_options')
|
||||
\ : ''
|
||||
if empty(l:build_dir)
|
||||
let l:options = ale#Var(a:buffer, 'c_clangtidy_options')
|
||||
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
|
||||
let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags
|
||||
endif
|
||||
|
||||
" Get the options to pass directly to clang-tidy
|
||||
let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options')
|
||||
|
@ -43,7 +46,7 @@ call ale#linter#Define('c', {
|
|||
\ 'name': 'clangtidy',
|
||||
\ 'output_stream': 'stdout',
|
||||
\ 'executable': {b -> ale#Var(b, 'c_clangtidy_executable')},
|
||||
\ 'command': function('ale_linters#c#clangtidy#GetCommand'),
|
||||
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clangtidy#GetCommand'))},
|
||||
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
|
||||
\ 'lint_file': 1,
|
||||
\})
|
||||
|
|
|
@ -20,7 +20,7 @@ function! ale_linters#cpp#clangcheck#GetCommand(buffer) abort
|
|||
" being generated. These are only added if no build directory can be
|
||||
" detected.
|
||||
return '%e -analyze %s'
|
||||
\ . (empty(l:build_dir) ? ' -extra-arg -Xclang -extra-arg -analyzer-output=text' : '')
|
||||
\ . (empty(l:build_dir) ? ' --extra-arg=-Xclang --extra-arg=-analyzer-output=text --extra-arg=-fno-color-diagnostics': '')
|
||||
\ . ale#Pad(l:user_options)
|
||||
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
|
||||
endfunction
|
||||
|
|
|
@ -3,9 +3,14 @@
|
|||
|
||||
call ale#Set('cpp_clangd_executable', 'clangd')
|
||||
call ale#Set('cpp_clangd_options', '')
|
||||
call ale#Set('c_build_dir', '')
|
||||
|
||||
function! ale_linters#cpp#clangd#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options'))
|
||||
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
|
||||
|
||||
return '%e'
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options'))
|
||||
\ . (!empty(l:build_dir) ? ' -compile-commands-dir=' . ale#Escape(l:build_dir) : '')
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('cpp', {
|
||||
|
|
|
@ -13,14 +13,17 @@ call ale#Set('cpp_clangtidy_options', '')
|
|||
call ale#Set('cpp_clangtidy_extra_options', '')
|
||||
call ale#Set('c_build_dir', '')
|
||||
|
||||
function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
|
||||
function! ale_linters#cpp#clangtidy#GetCommand(buffer, output) abort
|
||||
let l:checks = join(ale#Var(a:buffer, 'cpp_clangtidy_checks'), ',')
|
||||
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
|
||||
let l:options = ''
|
||||
|
||||
" Get the extra options if we couldn't find a build directory.
|
||||
let l:options = empty(l:build_dir)
|
||||
\ ? ale#Var(a:buffer, 'cpp_clangtidy_options')
|
||||
\ : ''
|
||||
if empty(l:build_dir)
|
||||
let l:options = ale#Var(a:buffer, 'cpp_clangtidy_options')
|
||||
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
|
||||
let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags
|
||||
endif
|
||||
|
||||
" Get the options to pass directly to clang-tidy
|
||||
let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options')
|
||||
|
@ -37,7 +40,7 @@ call ale#linter#Define('cpp', {
|
|||
\ 'name': 'clangtidy',
|
||||
\ 'output_stream': 'stdout',
|
||||
\ 'executable': {b -> ale#Var(b, 'cpp_clangtidy_executable')},
|
||||
\ 'command': function('ale_linters#cpp#clangtidy#GetCommand'),
|
||||
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clangtidy#GetCommand'))},
|
||||
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
|
||||
\ 'lint_file': 1,
|
||||
\})
|
||||
|
|
|
@ -5,6 +5,10 @@ function! ale_linters#crystal#crystal#Handle(buffer, lines) abort
|
|||
let l:output = []
|
||||
|
||||
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
|
||||
if !has_key(l:error, 'file')
|
||||
continue
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:error.line + 0,
|
||||
\ 'col': l:error.column + 0,
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
|
||||
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')
|
||||
|
||||
" elm-language-server will search for local and global binaries, if empty
|
||||
call ale#Set('elm_ls_elm_path', '')
|
||||
call ale#Set('elm_ls_elm_format_path', '')
|
||||
call ale#Set('elm_ls_elm_test_path', '')
|
||||
call ale#Set('elm_ls_elm_analyse_trigger', 'change')
|
||||
|
||||
function! elm_ls#GetRootDir(buffer) abort
|
||||
let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
|
||||
|
@ -15,10 +18,10 @@ 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'),
|
||||
\ 'elmAnalyseTrigger': ale#Var(a:buffer, 'elm_ls_elm_analyse_trigger'),
|
||||
\}
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -15,10 +15,10 @@ 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)
|
||||
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')
|
||||
let l:plt_file = globpath(l:plt_file_directory, '*_plt', 0, 1)
|
||||
endif
|
||||
|
||||
if !empty(l:plt_file)
|
||||
|
|
|
@ -8,7 +8,7 @@ call ale#Set('eruby_ruumba_options', '')
|
|||
function! ale_linters#eruby#ruumba#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'eruby_ruumba_executable')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'ruumba')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'ruumba')
|
||||
\ . ' --format json --force-exclusion '
|
||||
\ . ale#Var(a:buffer, 'eruby_ruumba_options')
|
||||
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))
|
||||
|
|
35
sources_non_forked/ale/ale_linters/ink/ls.vim
Normal file
35
sources_non_forked/ale/ale_linters/ink/ls.vim
Normal file
|
@ -0,0 +1,35 @@
|
|||
" Author: Andreww Hayworth <ahayworth@gmail.com>
|
||||
" Description: Integrate ALE with ink-language-server
|
||||
|
||||
call ale#Set('ink_ls_executable', 'ink-language-server')
|
||||
call ale#Set('ink_ls_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('ink_ls_initialization_options', {})
|
||||
|
||||
function! ale_linters#ink#ls#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'ink_ls', [
|
||||
\ 'ink-language-server',
|
||||
\ 'node_modules/.bin/ink-language-server',
|
||||
\])
|
||||
endfunction
|
||||
|
||||
function! ale_linters#ink#ls#GetCommand(buffer) abort
|
||||
let l:executable = ale_linters#ink#ls#GetExecutable(a:buffer)
|
||||
|
||||
return ale#Escape(l:executable) . ' --stdio'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#ink#ls#FindProjectRoot(buffer) abort
|
||||
let l:main_file = get(ale#Var(a:buffer, 'ink_ls_initialization_options'), 'mainStoryPath', 'main.ink')
|
||||
let l:config = ale#path#ResolveLocalPath(a:buffer, l:main_file, expand('#' . a:buffer . ':p'))
|
||||
|
||||
return ale#path#Dirname(l:config)
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('ink', {
|
||||
\ 'name': 'ink-language-server',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': function('ale_linters#ink#ls#GetExecutable'),
|
||||
\ 'command': function('ale_linters#ink#ls#GetCommand'),
|
||||
\ 'project_root': function('ale_linters#ink#ls#FindProjectRoot'),
|
||||
\ 'initialization_options': {b -> ale#Var(b, 'ink_ls_initialization_options')},
|
||||
\})
|
|
@ -7,7 +7,9 @@ call ale#Set('javascript_standard_options', '')
|
|||
|
||||
function! ale_linters#javascript#standard#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'javascript_standard', [
|
||||
\ 'node_modules/standardx/bin/cmd.js',
|
||||
\ 'node_modules/standard/bin/cmd.js',
|
||||
\ 'node_modules/semistandard/bin/cmd.js',
|
||||
\ 'node_modules/.bin/standard',
|
||||
\])
|
||||
endfunction
|
||||
|
|
|
@ -17,18 +17,17 @@ function! ale_linters#markdown#mdl#GetCommand(buffer) abort
|
|||
let l:options = ale#Var(a:buffer, 'markdown_mdl_options')
|
||||
|
||||
return ale#Escape(l:executable) . l:exec_args
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' -j' . (!empty(l:options) ? ' ' . l:options : '')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#markdown#mdl#Handle(buffer, lines) abort
|
||||
" matches: '(stdin):173: MD004 Unordered list style'
|
||||
let l:pattern = ':\(\d*\): \(.*\)$'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'text': l:match[2],
|
||||
\ 'lnum': l:error['line'],
|
||||
\ 'code': l:error['rule'] . '/' . join(l:error['aliases'], '/'),
|
||||
\ 'text': l:error['description'],
|
||||
\ 'type': 'W',
|
||||
\})
|
||||
endfor
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
" Author: Baabelfish
|
||||
" Description: Typechecking for nim files
|
||||
|
||||
let s:end_col_patterns = [
|
||||
\ '\v''([^'']+)'' is declared but not used.*',
|
||||
\ '\videntifier expected, but found ''([^'']+)''',
|
||||
\ '\vimported and not used: ''([^'']+)''.*',
|
||||
\ '\vundeclared identifier: ''([^'']+)''',
|
||||
\ '\v''([^'']+)'' cannot be assigned to',
|
||||
\ '\vredefinition of ''([^'']+)'';',
|
||||
\]
|
||||
|
||||
function! ale_linters#nim#nimcheck#Handle(buffer, lines) abort
|
||||
let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p:t')
|
||||
let l:pattern = '^\(.\+\.nim\)(\(\d\+\), \(\d\+\)) \(.\+\)'
|
||||
|
@ -43,6 +52,11 @@ function! ale_linters#nim#nimcheck#Handle(buffer, lines) abort
|
|||
let l:item.code = l:code_match[2]
|
||||
endif
|
||||
|
||||
" Find position end_col.
|
||||
for l:col_match in ale#util#GetMatches(l:item.text, s:end_col_patterns)
|
||||
let l:item.end_col = l:item.col + len(l:col_match[1]) - 1
|
||||
endfor
|
||||
|
||||
call add(l:output, l:item)
|
||||
endfor
|
||||
|
||||
|
|
33
sources_non_forked/ale/ale_linters/nim/nimlsp.vim
Normal file
33
sources_non_forked/ale/ale_linters/nim/nimlsp.vim
Normal file
|
@ -0,0 +1,33 @@
|
|||
" Author: jeremija <https://github.com/jeremija>
|
||||
" Description: Support for nimlsp (language server for nim)
|
||||
|
||||
call ale#Set('nim_nimlsp_nim_sources', '')
|
||||
|
||||
function! ale_linters#nim#nimlsp#GetProjectRoot(buffer) abort
|
||||
let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git')
|
||||
|
||||
if !empty(l:project_root)
|
||||
return fnamemodify(l:project_root, ':h:h')
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale_linters#nim#nimlsp#GetCommand(buffer) abort
|
||||
let l:nim_sources = ale#Var(a:buffer, 'nim_nimlsp_nim_sources')
|
||||
|
||||
if !empty(l:nim_sources)
|
||||
let l:nim_sources = ale#Escape(l:nim_sources)
|
||||
endif
|
||||
|
||||
return '%e' . ale#Pad(l:nim_sources)
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('nim', {
|
||||
\ 'name': 'nimlsp',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': 'nimlsp',
|
||||
\ 'command': function('ale_linters#nim#nimlsp#GetCommand'),
|
||||
\ 'language': 'nim',
|
||||
\ 'project_root': function('ale_linters#nim#nimlsp#GetProjectRoot'),
|
||||
\})
|
|
@ -1,7 +1,8 @@
|
|||
" Author: Matt Brown <https://github.com/muglug>
|
||||
" Description: plugin for Psalm, static analyzer for PHP
|
||||
|
||||
call ale#Set('psalm_langserver_executable', 'psalm-language-server')
|
||||
call ale#Set('psalm_langserver_executable', 'psalm')
|
||||
call ale#Set('psalm_langserver_options', '')
|
||||
call ale#Set('psalm_langserver_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! ale_linters#php#psalm#GetProjectRoot(buffer) abort
|
||||
|
@ -10,12 +11,16 @@ function! ale_linters#php#psalm#GetProjectRoot(buffer) abort
|
|||
return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : ''
|
||||
endfunction
|
||||
|
||||
function! ale_linters#php#psalm#GetCommand(buffer) abort
|
||||
return '%e --language-server' . ale#Pad(ale#Var(a:buffer, 'psalm_langserver_options'))
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('php', {
|
||||
\ 'name': 'psalm',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {b -> ale#node#FindExecutable(b, 'psalm_langserver', [
|
||||
\ 'vendor/bin/psalm-language-server',
|
||||
\ 'vendor/bin/psalm',
|
||||
\ ])},
|
||||
\ 'command': '%e',
|
||||
\ 'command': function('ale_linters#php#psalm#GetCommand'),
|
||||
\ 'project_root': function('ale_linters#php#psalm#GetProjectRoot'),
|
||||
\})
|
||||
|
|
|
@ -12,6 +12,7 @@ endfunction
|
|||
" https://rkeithhill.wordpress.com/2007/10/30/powershell-quicktip-preparsing-scripts-to-check-for-syntax-errors/
|
||||
function! ale_linters#powershell#powershell#GetCommand(buffer) abort
|
||||
let l:script = ['Param($Script);
|
||||
\ $ErrorView = "Normal";
|
||||
\ trap {$_;continue} & {
|
||||
\ $Contents = Get-Content -Path $Script;
|
||||
\ $Contents = [string]::Join([Environment]::NewLine, $Contents);
|
||||
|
|
|
@ -36,7 +36,7 @@ function! ale_linters#ruby#brakeman#GetCommand(buffer) abort
|
|||
|
||||
let l:executable = ale#Var(a:buffer, 'ruby_brakeman_executable')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'brakeman')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'brakeman')
|
||||
\ . ' -f json -q '
|
||||
\ . ale#Var(a:buffer, 'ruby_brakeman_options')
|
||||
\ . ' -p ' . ale#Escape(l:rails_root)
|
||||
|
|
42
sources_non_forked/ale/ale_linters/ruby/debride.vim
Normal file
42
sources_non_forked/ale/ale_linters/ruby/debride.vim
Normal file
|
@ -0,0 +1,42 @@
|
|||
" Author: Eddie Lebow https://github.com/elebow
|
||||
" Description: debride, a dead method detector for Ruby files
|
||||
|
||||
call ale#Set('ruby_debride_executable', 'debride')
|
||||
call ale#Set('ruby_debride_options', '')
|
||||
|
||||
function! ale_linters#ruby#debride#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ruby_debride_executable')
|
||||
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'debride')
|
||||
\ . ale#Var(a:buffer, 'ruby_debride_options')
|
||||
\ . ' %s'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#ruby#debride#HandleOutput(buffer, lines) abort
|
||||
let l:output = []
|
||||
|
||||
for l:line in a:lines
|
||||
if l:line !~# '^ '
|
||||
continue
|
||||
endif
|
||||
|
||||
let l:elements = split(l:line)
|
||||
let l:method_name = l:elements[0]
|
||||
let l:lnum = split(l:elements[1], ':')[1]
|
||||
|
||||
call add(l:output, {
|
||||
\ 'lnum': 0 + l:lnum,
|
||||
\ 'text': 'Possible unused method: ' . l:method_name,
|
||||
\ 'type': 'W',
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('ruby', {
|
||||
\ 'name': 'debride',
|
||||
\ 'executable': {b -> ale#Var(b, 'ruby_debride_executable')},
|
||||
\ 'command': function('ale_linters#ruby#debride#GetCommand'),
|
||||
\ 'callback': 'ale_linters#ruby#debride#HandleOutput',
|
||||
\})
|
|
@ -33,7 +33,7 @@ function! ale_linters#ruby#rails_best_practices#GetCommand(buffer) abort
|
|||
let l:output_file = has('win32') ? '%t ' : '/dev/stdout '
|
||||
let l:cat_file = has('win32') ? '; type %t' : ''
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rails_best_practices')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'rails_best_practices')
|
||||
\ . ' --silent -f json --output-file ' . l:output_file
|
||||
\ . ale#Var(a:buffer, 'ruby_rails_best_practices_options')
|
||||
\ . ale#Escape(l:rails_root)
|
||||
|
|
|
@ -14,7 +14,7 @@ function! ale_linters#ruby#reek#GetCommand(buffer, version) abort
|
|||
\ ? ' --stdin-filename %s'
|
||||
\ : ''
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'reek')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'reek')
|
||||
\ . ' -f json --no-progress --no-color --force-exclusion'
|
||||
\ . l:display_name_args
|
||||
endfunction
|
||||
|
|
|
@ -7,7 +7,7 @@ call ale#Set('ruby_rubocop_options', '')
|
|||
function! ale_linters#ruby#rubocop#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ruby_rubocop_executable')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'rubocop')
|
||||
\ . ' --format json --force-exclusion '
|
||||
\ . ale#Var(a:buffer, 'ruby_rubocop_options')
|
||||
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))
|
||||
|
|
|
@ -5,7 +5,7 @@ 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')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'srb')
|
||||
\ . ' tc'
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --lsp --disable-watchman'
|
||||
|
|
|
@ -8,7 +8,7 @@ call ale#Set('ruby_standardrb_options', '')
|
|||
function! ale_linters#ruby#standardrb#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ruby_standardrb_executable')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'standardrb')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'standardrb')
|
||||
\ . ' --format json --force-exclusion '
|
||||
\ . ale#Var(a:buffer, 'ruby_standardrb_options')
|
||||
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))
|
||||
|
|
48
sources_non_forked/ale/ale_linters/scala/metals.vim
Normal file
48
sources_non_forked/ale/ale_linters/scala/metals.vim
Normal file
|
@ -0,0 +1,48 @@
|
|||
" Author: Jeffrey Lau - https://github.com/zoonfafer
|
||||
" Description: Metals Language Server for Scala https://scalameta.org/metals/
|
||||
|
||||
call ale#Set('scala_metals_executable', 'metals-vim')
|
||||
call ale#Set('scala_metals_project_root', '')
|
||||
|
||||
function! ale_linters#scala#metals#GetProjectRoot(buffer) abort
|
||||
let l:project_root = ale#Var(a:buffer, 'scala_metals_project_root')
|
||||
|
||||
if !empty(l:project_root)
|
||||
return l:project_root
|
||||
endif
|
||||
|
||||
let l:potential_roots = [
|
||||
\ 'build.sc',
|
||||
\ 'build.sbt',
|
||||
\ '.bloop',
|
||||
\ '.metals',
|
||||
\]
|
||||
|
||||
for l:root in l:potential_roots
|
||||
let l:project_root = ale#path#ResolveLocalPath(
|
||||
\ a:buffer,
|
||||
\ l:root,
|
||||
\ ''
|
||||
\)
|
||||
|
||||
if !empty(l:project_root)
|
||||
return fnamemodify(
|
||||
\ l:project_root,
|
||||
\ ':h',
|
||||
\)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale_linters#scala#metals#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad('stdio')
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('scala', {
|
||||
\ 'name': 'metals',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'language': 'scala',
|
||||
\ 'executable': {b -> ale#Var(b, 'scala_metals_executable')},
|
||||
\ 'command': function('ale_linters#scala#metals#GetCommand'),
|
||||
\ 'project_root': function('ale_linters#scala#metals#GetProjectRoot'),
|
||||
\})
|
|
@ -34,8 +34,10 @@ function! ale_linters#sh#shell#Handle(buffer, lines) abort
|
|||
" Matches patterns line the following:
|
||||
"
|
||||
" bash: line 13: syntax error near unexpected token `d'
|
||||
" bash:行0: 未预期的符号“done”附近有语法错误
|
||||
" bash: 列 90: 尋找匹配的「"」時遇到了未預期的檔案結束符
|
||||
" sh: 11: Syntax error: "(" unexpected
|
||||
let l:pattern = '\v(line |: ?)(\d+): (.+)$'
|
||||
let l:pattern = '\v([^:]+:\D*)(\d+): (.+)$'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
|
|
35
sources_non_forked/ale/ale_linters/solidity/solc.vim
Normal file
35
sources_non_forked/ale/ale_linters/solidity/solc.vim
Normal file
|
@ -0,0 +1,35 @@
|
|||
" Author: Karl Bartel <karl42@gmail.com> - http://karl.berlin/
|
||||
" Description: Report solc compiler errors in Solidity code
|
||||
|
||||
call ale#Set('solidity_solc_options', '')
|
||||
|
||||
function! ale_linters#solidity#solc#Handle(buffer, lines) abort
|
||||
" Matches patterns like the following:
|
||||
" /path/to/file/file.sol:1:10: Error: Identifier not found or not unique.
|
||||
let l:pattern = '\v^[^:]+:(\d+):(\d+): (Error|Warning): (.*)$'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
let l:isError = l:match[3] is? 'error'
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'col': l:match[2] + 0,
|
||||
\ 'text': l:match[4],
|
||||
\ 'type': l:isError ? 'E' : 'W',
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
function! ale_linters#solidity#solc#GetCommand(buffer) abort
|
||||
return 'solc' . ale#Pad(ale#Var(a:buffer, 'solidity_solc_options')) . ' %s'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('solidity', {
|
||||
\ 'name': 'solc',
|
||||
\ 'executable': 'solc',
|
||||
\ 'command': function('ale_linters#solidity#solc#GetCommand'),
|
||||
\ 'callback': 'ale_linters#solidity#solc#Handle',
|
||||
\ 'output_stream': 'stderr',
|
||||
\})
|
|
@ -9,23 +9,69 @@ call ale#Set('terraform_tflint_executable', 'tflint')
|
|||
|
||||
function! ale_linters#terraform#tflint#Handle(buffer, lines) abort
|
||||
let l:output = []
|
||||
let l:pattern = '\v^(.*):(\d+),(\d+)-(\d+)?,?(\d+): (.{-1,}); (.+)$'
|
||||
let l:json = ale#util#FuzzyJSONDecode(a:lines, {})
|
||||
|
||||
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
|
||||
if l:error.type is# 'ERROR'
|
||||
let l:type = 'E'
|
||||
elseif l:error.type is# 'NOTICE'
|
||||
let l:type = 'I'
|
||||
else
|
||||
let l:type = 'W'
|
||||
endif
|
||||
" This is a rough test for tflint's output format
|
||||
" On versions prior to 0.11 it outputs all errors as a single level list
|
||||
if type(l:json) is v:t_list
|
||||
for l:error in l:json
|
||||
if l:error.type is# 'ERROR'
|
||||
let l:type = 'E'
|
||||
elseif l:error.type is# 'NOTICE'
|
||||
let l:type = 'I'
|
||||
else
|
||||
let l:type = 'W'
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:error.line,
|
||||
\ 'text': l:error.message,
|
||||
\ 'type': l:type,
|
||||
\ 'code': l:error.detector,
|
||||
\})
|
||||
endfor
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:error.line,
|
||||
\ 'text': l:error.message,
|
||||
\ 'type': l:type,
|
||||
\ 'code': l:error.detector,
|
||||
\})
|
||||
endfor
|
||||
else
|
||||
for l:error in get(l:json, 'errors', [])
|
||||
for l:match in ale#util#GetMatches(l:error.message, [l:pattern])
|
||||
if l:match[4] is# ''
|
||||
let l:match[4] = l:match[2]
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'filename': l:match[1],
|
||||
\ 'lnum': str2nr(l:match[2]),
|
||||
\ 'col': str2nr(l:match[3]),
|
||||
\ 'end_lnum': str2nr(l:match[4]),
|
||||
\ 'end_col': str2nr(l:match[5]),
|
||||
\ 'text': l:match[7],
|
||||
\ 'code': l:match[6],
|
||||
\ 'type': 'E',
|
||||
\})
|
||||
endfor
|
||||
endfor
|
||||
|
||||
for l:error in get(l:json, 'issues', [])
|
||||
if l:error.rule.severity is# 'ERROR'
|
||||
let l:type = 'E'
|
||||
elseif l:error.rule.severity is# 'NOTICE'
|
||||
let l:type = 'I'
|
||||
else
|
||||
let l:type = 'W'
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'filename': l:error.range.filename,
|
||||
\ 'lnum': l:error.range.start.line,
|
||||
\ 'col': l:error.range.start.column,
|
||||
\ 'end_lnum': l:error.range.end.line,
|
||||
\ 'end_col': l:error.range.end.column,
|
||||
\ 'text': l:error.message,
|
||||
\ 'code': l:error.rule.name,
|
||||
\ 'type': l:type,
|
||||
\})
|
||||
endfor
|
||||
endif
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
|
31
sources_non_forked/ale/ale_linters/typescript/standard.vim
Normal file
31
sources_non_forked/ale/ale_linters/typescript/standard.vim
Normal file
|
@ -0,0 +1,31 @@
|
|||
" Author: Ahmed El Gabri <@ahmedelgabri>
|
||||
" Description: standardjs for typescript files
|
||||
|
||||
call ale#Set('typescript_standard_executable', 'standard')
|
||||
call ale#Set('typescript_standard_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('typescript_standard_options', '')
|
||||
|
||||
function! ale_linters#typescript#standard#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'typescript_standard', [
|
||||
\ 'node_modules/standardx/bin/cmd.js',
|
||||
\ 'node_modules/standard/bin/cmd.js',
|
||||
\ 'node_modules/.bin/standard',
|
||||
\])
|
||||
endfunction
|
||||
|
||||
function! ale_linters#typescript#standard#GetCommand(buffer) abort
|
||||
let l:executable = ale_linters#typescript#standard#GetExecutable(a:buffer)
|
||||
let l:options = ale#Var(a:buffer, 'typescript_standard_options')
|
||||
|
||||
return ale#node#Executable(a:buffer, l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --stdin %s'
|
||||
endfunction
|
||||
|
||||
" standard uses eslint and the output format is the same
|
||||
call ale#linter#Define('typescript', {
|
||||
\ 'name': 'standard',
|
||||
\ 'executable': function('ale_linters#typescript#standard#GetExecutable'),
|
||||
\ 'command': function('ale_linters#typescript#standard#GetCommand'),
|
||||
\ 'callback': 'ale#handlers#eslint#Handle',
|
||||
\})
|
|
@ -24,6 +24,20 @@ function! ale_linters#verilog#vlog#Handle(buffer, lines) abort
|
|||
\})
|
||||
endfor
|
||||
|
||||
"Matches patterns like the following:
|
||||
"** Warning: (vlog-2623) add.v(7): Undefined variable: C.
|
||||
"** Error: (vlog-13294) file.v(1): Identifier must be declared with a port mode: C.
|
||||
" let l:pattern = '^**\s\(\w*\):[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)'
|
||||
let l:pattern = '^**\s\(\w*\):\s\([^)]*)\)[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)'
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[3] + 0,
|
||||
\ 'type': l:match[1] is? 'Error' ? 'E' : 'W',
|
||||
\ 'text': l:match[2] . ' ' . l:match[4],
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -5,11 +5,18 @@
|
|||
" Strings used for severity in the echoed message
|
||||
let g:ale_echo_msg_error_str = get(g:, 'ale_echo_msg_error_str', 'Error')
|
||||
let g:ale_echo_msg_info_str = get(g:, 'ale_echo_msg_info_str', 'Info')
|
||||
let g:ale_echo_msg_log_str = get(g:, 'ale_echo_msg_log_str', 'Log')
|
||||
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
|
||||
" Ignoring linters, for disabling some, or ignoring LSP diagnostics.
|
||||
let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {})
|
||||
let g:ale_disable_lsp = get(g:, 'ale_disable_lsp', 0)
|
||||
|
||||
" LSP window/showMessage format
|
||||
let g:ale_lsp_show_message_format = get(g:, 'ale_lsp_show_message_format', '%severity%:%linter%: %s')
|
||||
" Valid values mimic LSP definitions (error, warning and information; log is
|
||||
" never shown)
|
||||
let g:ale_lsp_show_message_severity = get(g:, 'ale_lsp_show_message_severity', 'error')
|
||||
|
||||
let s:lint_timer = -1
|
||||
let s:getcmdwintype_exists = exists('*getcmdwintype')
|
||||
|
||||
|
@ -156,7 +163,7 @@ function! ale#Queue(delay, ...) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
let s:current_ale_version = [2, 5, 0]
|
||||
let s:current_ale_version = [2, 6, 0]
|
||||
|
||||
" A function used to check for ALE features in files outside of the project.
|
||||
function! ale#Has(feature) abort
|
||||
|
|
|
@ -267,14 +267,22 @@ function! ale#assert#TearDownLinterTest() abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#assert#SetUpFixerTest(filetype, name) abort
|
||||
function! ale#assert#SetUpFixerTest(filetype, name, ...) abort
|
||||
" If the suffix of the option names format is different, an additional
|
||||
" argument can be used for that instead.
|
||||
if a:0 > 1
|
||||
throw 'Too many arguments'
|
||||
endif
|
||||
|
||||
" Set up a marker so ALE doesn't create real random temporary filenames.
|
||||
let g:ale_create_dummy_temporary_file = 1
|
||||
|
||||
let l:function_name = ale#fix#registry#GetFunc(a:name)
|
||||
let s:FixerFunction = function(l:function_name)
|
||||
|
||||
let l:prefix = 'ale_' . a:filetype . '_' . a:name
|
||||
let l:option_suffix = get(a:000, 0, a:name)
|
||||
let l:prefix = 'ale_' . a:filetype . '_'
|
||||
\ . substitute(l:option_suffix, '-', '_', 'g')
|
||||
let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix'
|
||||
|
||||
for l:key in filter(keys(g:), b:filter_expr)
|
||||
|
@ -286,7 +294,7 @@ function! ale#assert#SetUpFixerTest(filetype, name) abort
|
|||
unlet b:[l:key]
|
||||
endfor
|
||||
|
||||
execute 'runtime autoload/ale/fixers/' . a:name . '.vim'
|
||||
execute 'runtime autoload/ale/fixers/' . substitute(a:name, '-', '_', 'g') . '.vim'
|
||||
|
||||
if !exists('g:dir')
|
||||
call ale#test#SetDirectory('/testplugin/test/fixers')
|
||||
|
|
|
@ -265,6 +265,16 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
|
|||
return l:empty
|
||||
endfunction
|
||||
|
||||
function! ale#c#GetCompileCommand(json_item) abort
|
||||
if has_key(a:json_item, 'command')
|
||||
return a:json_item.command
|
||||
elseif has_key(a:json_item, 'arguments')
|
||||
return join(a:json_item.arguments, ' ')
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
||||
" Search for an exact file match first.
|
||||
let l:basename = tolower(expand('#' . a:buffer . ':t'))
|
||||
|
@ -287,15 +297,14 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
|||
for l:item in l:file_list
|
||||
" Load the flags for this file, or for a source file matching the
|
||||
" header file.
|
||||
if has_key(l:item, 'command')
|
||||
\&& (
|
||||
if (
|
||||
\ bufnr(l:item.file) is a:buffer
|
||||
\ || (
|
||||
\ !empty(l:source_file)
|
||||
\ && l:item.file[-len(l:source_file):] is? l:source_file
|
||||
\ )
|
||||
\)
|
||||
return ale#c#ParseCFlags(l:item.directory, l:item.command)
|
||||
return ale#c#ParseCFlags(l:item.directory, ale#c#GetCompileCommand(l:item))
|
||||
endif
|
||||
endfor
|
||||
|
||||
|
@ -307,8 +316,7 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
|||
|
||||
for l:item in l:dir_list
|
||||
if ale#path#Simplify(fnamemodify(l:item.file, ':h')) is? l:dir
|
||||
\&& has_key(l:item, 'command')
|
||||
return ale#c#ParseCFlags(l:item.directory, l:item.command)
|
||||
return ale#c#ParseCFlags(l:item.directory, ale#c#GetCompileCommand(l:item))
|
||||
endif
|
||||
endfor
|
||||
|
||||
|
|
163
sources_non_forked/ale/autoload/ale/code_action.vim
Normal file
163
sources_non_forked/ale/autoload/ale/code_action.vim
Normal file
|
@ -0,0 +1,163 @@
|
|||
" Author: Jerko Steiner <jerko.steiner@gmail.com>
|
||||
" Description: Code action support for LSP / tsserver
|
||||
|
||||
function! ale#code_action#HandleCodeAction(code_action) abort
|
||||
let l:current_buffer = bufnr('')
|
||||
let l:changes = a:code_action.changes
|
||||
|
||||
for l:file_code_edit in l:changes
|
||||
let l:buf = bufnr(l:file_code_edit.fileName)
|
||||
|
||||
if l:buf != -1 && l:buf != l:current_buffer && getbufvar(l:buf, '&mod')
|
||||
call ale#util#Execute('echom ''Aborting action, file is unsaved''')
|
||||
|
||||
return
|
||||
endif
|
||||
endfor
|
||||
|
||||
for l:file_code_edit in l:changes
|
||||
call ale#code_action#ApplyChanges(
|
||||
\ l:file_code_edit.fileName, l:file_code_edit.textChanges)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#code_action#ApplyChanges(filename, changes) abort
|
||||
let l:current_buffer = bufnr('')
|
||||
" The buffer is used to determine the fileformat, if available.
|
||||
let l:buffer = bufnr(a:filename)
|
||||
let l:is_current_buffer = l:buffer > 0 && l:buffer == l:current_buffer
|
||||
|
||||
if l:buffer > 0
|
||||
let l:lines = getbufline(l:buffer, 1, '$')
|
||||
else
|
||||
let l:lines = readfile(a:filename, 'b')
|
||||
endif
|
||||
|
||||
if l:is_current_buffer
|
||||
let l:pos = getpos('.')[1:2]
|
||||
else
|
||||
let l:pos = [1, 1]
|
||||
endif
|
||||
|
||||
" We have to keep track of how many lines we have added, and offset
|
||||
" changes accordingly.
|
||||
let l:line_offset = 0
|
||||
let l:column_offset = 0
|
||||
let l:last_end_line = 0
|
||||
|
||||
for l:code_edit in a:changes
|
||||
if l:code_edit.start.line isnot l:last_end_line
|
||||
let l:column_offset = 0
|
||||
endif
|
||||
|
||||
let l:line = l:code_edit.start.line + l:line_offset
|
||||
let l:column = l:code_edit.start.offset + l:column_offset
|
||||
let l:end_line = l:code_edit.end.line + l:line_offset
|
||||
let l:end_column = l:code_edit.end.offset + l:column_offset
|
||||
let l:text = l:code_edit.newText
|
||||
|
||||
let l:cur_line = l:pos[0]
|
||||
let l:cur_column = l:pos[1]
|
||||
|
||||
let l:last_end_line = l:end_line
|
||||
|
||||
" Adjust the ends according to previous edits.
|
||||
if l:end_line > len(l:lines)
|
||||
let l:end_line_len = 0
|
||||
else
|
||||
let l:end_line_len = len(l:lines[l:end_line - 1])
|
||||
endif
|
||||
|
||||
let l:insertions = split(l:text, '\n', 1)
|
||||
|
||||
if l:line is 1
|
||||
" Same logic as for column below. Vimscript's slice [:-1] will not
|
||||
" be an empty list.
|
||||
let l:start = []
|
||||
else
|
||||
let l:start = l:lines[: l:line - 2]
|
||||
endif
|
||||
|
||||
if l:column is 1
|
||||
" We need to handle column 1 specially, because we can't slice an
|
||||
" empty string ending on index 0.
|
||||
let l:middle = [l:insertions[0]]
|
||||
else
|
||||
let l:middle = [l:lines[l:line - 1][: l:column - 2] . l:insertions[0]]
|
||||
endif
|
||||
|
||||
call extend(l:middle, l:insertions[1:])
|
||||
let l:middle[-1] .= l:lines[l:end_line - 1][l:end_column - 1 :]
|
||||
|
||||
let l:lines_before_change = len(l:lines)
|
||||
let l:lines = l:start + l:middle + l:lines[l:end_line :]
|
||||
|
||||
let l:current_line_offset = len(l:lines) - l:lines_before_change
|
||||
let l:line_offset += l:current_line_offset
|
||||
let l:column_offset = len(l:middle[-1]) - l:end_line_len
|
||||
|
||||
let l:pos = s:UpdateCursor(l:pos,
|
||||
\ [l:line, l:column],
|
||||
\ [l:end_line, l:end_column],
|
||||
\ [l:current_line_offset, l:column_offset])
|
||||
endfor
|
||||
|
||||
if l:lines[-1] is# ''
|
||||
call remove(l:lines, -1)
|
||||
endif
|
||||
|
||||
call ale#util#Writefile(l:buffer, l:lines, a:filename)
|
||||
|
||||
if l:is_current_buffer
|
||||
call ale#util#Execute(':e!')
|
||||
call setpos('.', [0, l:pos[0], l:pos[1], 0])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:UpdateCursor(cursor, start, end, offset) abort
|
||||
let l:cur_line = a:cursor[0]
|
||||
let l:cur_column = a:cursor[1]
|
||||
let l:line = a:start[0]
|
||||
let l:column = a:start[1]
|
||||
let l:end_line = a:end[0]
|
||||
let l:end_column = a:end[1]
|
||||
let l:line_offset = a:offset[0]
|
||||
let l:column_offset = a:offset[1]
|
||||
|
||||
if l:end_line < l:cur_line
|
||||
" both start and end lines are before the cursor. only line offset
|
||||
" needs to be updated
|
||||
let l:cur_line += l:line_offset
|
||||
elseif l:end_line == l:cur_line
|
||||
" end line is at the same location as cursor, which means
|
||||
" l:line <= l:cur_line
|
||||
if l:line < l:cur_line || l:column <= l:cur_column
|
||||
" updates are happening either before or around the cursor
|
||||
if l:end_column < l:cur_column
|
||||
" updates are happening before the cursor, update the
|
||||
" column offset for cursor
|
||||
let l:cur_line += l:line_offset
|
||||
let l:cur_column += l:column_offset
|
||||
else
|
||||
" updates are happening around the cursor, move the cursor
|
||||
" to the end of the changes
|
||||
let l:cur_line += l:line_offset
|
||||
let l:cur_column = l:end_column + l:column_offset
|
||||
endif
|
||||
" else is not necessary, it means modifications are happening
|
||||
" after the cursor so no cursor updates need to be done
|
||||
endif
|
||||
else
|
||||
" end line is after the cursor
|
||||
if l:line < l:cur_line || l:line == l:cur_line && l:column <= l:cur_column
|
||||
" changes are happening around the cursor, move the cursor
|
||||
" to the end of the changes
|
||||
let l:cur_line = l:end_line + l:line_offset
|
||||
let l:cur_column = l:end_column + l:column_offset
|
||||
" else is not necesary, it means modifications are happening
|
||||
" after the cursor so no cursor updates need to be done
|
||||
endif
|
||||
endif
|
||||
|
||||
return [l:cur_line, l:cur_column]
|
||||
endfunction
|
|
@ -1,5 +1,6 @@
|
|||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Completion support for LSP linters
|
||||
scriptencoding utf-8
|
||||
|
||||
" The omnicompletion menu is shown through a special Plug mapping which is
|
||||
" only valid in Insert mode. This way, feedkeys() won't send these keys if you
|
||||
|
@ -15,29 +16,107 @@ onoremap <silent> <Plug>(ale_show_completion_menu) <Nop>
|
|||
let g:ale_completion_delay = get(g:, 'ale_completion_delay', 100)
|
||||
let g:ale_completion_excluded_words = get(g:, 'ale_completion_excluded_words', [])
|
||||
let g:ale_completion_max_suggestions = get(g:, 'ale_completion_max_suggestions', 50)
|
||||
let g:ale_completion_tsserver_autoimport = get(g:, 'ale_completion_tsserver_autoimport', 0)
|
||||
|
||||
let s:timer_id = -1
|
||||
let s:last_done_pos = []
|
||||
|
||||
" CompletionItemKind values from the LSP protocol.
|
||||
let s:LSP_COMPLETION_TEXT_KIND = 1
|
||||
let s:LSP_COMPLETION_METHOD_KIND = 2
|
||||
let s:LSP_COMPLETION_FUNCTION_KIND = 3
|
||||
let s:LSP_COMPLETION_CONSTRUCTOR_KIND = 4
|
||||
let s:LSP_COMPLETION_FIELD_KIND = 5
|
||||
let s:LSP_COMPLETION_VARIABLE_KIND = 6
|
||||
let s:LSP_COMPLETION_CLASS_KIND = 7
|
||||
let s:LSP_COMPLETION_INTERFACE_KIND = 8
|
||||
let s:LSP_COMPLETION_MODULE_KIND = 9
|
||||
let s:LSP_COMPLETION_PROPERTY_KIND = 10
|
||||
let s:LSP_COMPLETION_UNIT_KIND = 11
|
||||
let s:LSP_COMPLETION_VALUE_KIND = 12
|
||||
let s:LSP_COMPLETION_ENUM_KIND = 13
|
||||
let s:LSP_COMPLETION_KEYWORD_KIND = 14
|
||||
let s:LSP_COMPLETION_SNIPPET_KIND = 15
|
||||
let s:LSP_COMPLETION_COLOR_KIND = 16
|
||||
let s:LSP_COMPLETION_FILE_KIND = 17
|
||||
let s:LSP_COMPLETION_REFERENCE_KIND = 18
|
||||
let g:ale_lsp_types = {
|
||||
\ 1: 'text',
|
||||
\ 2: 'method',
|
||||
\ 3: 'function',
|
||||
\ 4: 'constructor',
|
||||
\ 5: 'field',
|
||||
\ 6: 'variable',
|
||||
\ 7: 'class',
|
||||
\ 8: 'interface',
|
||||
\ 9: 'module',
|
||||
\ 10: 'property',
|
||||
\ 11: 'unit',
|
||||
\ 12: 'value',
|
||||
\ 13: 'enum',
|
||||
\ 14: 'keyword',
|
||||
\ 15: 'snippet',
|
||||
\ 16: 'color',
|
||||
\ 17: 'file',
|
||||
\ 18: 'reference',
|
||||
\ 19: 'folder',
|
||||
\ 20: 'enum_member',
|
||||
\ 21: 'constant',
|
||||
\ 22: 'struct',
|
||||
\ 23: 'event',
|
||||
\ 24: 'operator',
|
||||
\ 25: 'type_parameter',
|
||||
\ }
|
||||
|
||||
" from https://github.com/microsoft/TypeScript/blob/29becf05012bfa7ba20d50b0d16813971e46b8a6/lib/protocol.d.ts#L2472
|
||||
let g:ale_tsserver_types = {
|
||||
\ 'warning': 'text',
|
||||
\ 'keyword': 'keyword',
|
||||
\ 'script': 'file',
|
||||
\ 'module': 'module',
|
||||
\ 'class': 'class',
|
||||
\ 'local class': 'class',
|
||||
\ 'interface': 'interface',
|
||||
\ 'type': 'class',
|
||||
\ 'enum': 'enum',
|
||||
\ 'enum member': 'enum_member',
|
||||
\ 'var': 'variable',
|
||||
\ 'local var': 'variable',
|
||||
\ 'function': 'function',
|
||||
\ 'local function': 'function',
|
||||
\ 'method': 'method',
|
||||
\ 'getter': 'property',
|
||||
\ 'setter': 'method',
|
||||
\ 'property': 'property',
|
||||
\ 'constructor': 'constructor',
|
||||
\ 'call': 'method',
|
||||
\ 'index': 'index',
|
||||
\ 'construct': 'constructor',
|
||||
\ 'parameter': 'parameter',
|
||||
\ 'type parameter': 'type_parameter',
|
||||
\ 'primitive type': 'unit',
|
||||
\ 'label': 'text',
|
||||
\ 'alias': 'class',
|
||||
\ 'const': 'constant',
|
||||
\ 'let': 'variable',
|
||||
\ 'directory': 'folder',
|
||||
\ 'external module name': 'text',
|
||||
\ 'JSX attribute': 'parameter',
|
||||
\ 'string': 'text'
|
||||
\ }
|
||||
|
||||
" For compatibility reasons, we only use built in VIM completion kinds
|
||||
" See :help complete-items for Vim completion kinds
|
||||
let g:ale_completion_symbols = get(g:, 'ale_completion_symbols', {
|
||||
\ 'text': 'v',
|
||||
\ 'method': 'f',
|
||||
\ 'function': 'f',
|
||||
\ 'constructor': 'f',
|
||||
\ 'field': 'm',
|
||||
\ 'variable': 'v',
|
||||
\ 'class': 't',
|
||||
\ 'interface': 't',
|
||||
\ 'module': 'd',
|
||||
\ 'property': 'm',
|
||||
\ 'unit': 'v',
|
||||
\ 'value': 'v',
|
||||
\ 'enum': 't',
|
||||
\ 'keyword': 'v',
|
||||
\ 'snippet': 'v',
|
||||
\ 'color': 'v',
|
||||
\ 'file': 'v',
|
||||
\ 'reference': 'v',
|
||||
\ 'folder': 'v',
|
||||
\ 'enum_member': 'm',
|
||||
\ 'constant': 'm',
|
||||
\ 'struct': 't',
|
||||
\ 'event': 'v',
|
||||
\ 'operator': 'f',
|
||||
\ 'type_parameter': 'p',
|
||||
\ '<default>': 'v'
|
||||
\ })
|
||||
|
||||
let s:LSP_INSERT_TEXT_FORMAT_PLAIN = 1
|
||||
let s:LSP_INSERT_TEXT_FORMAT_SNIPPET = 2
|
||||
|
@ -277,6 +356,27 @@ function! ale#completion#GetAllTriggers() abort
|
|||
return deepcopy(s:trigger_character_map)
|
||||
endfunction
|
||||
|
||||
function! ale#completion#GetCompletionKind(kind) abort
|
||||
let l:lsp_symbol = get(g:ale_lsp_types, a:kind, '')
|
||||
|
||||
if !empty(l:lsp_symbol)
|
||||
return l:lsp_symbol
|
||||
endif
|
||||
|
||||
return get(g:ale_tsserver_types, a:kind, '')
|
||||
endfunction
|
||||
|
||||
function! ale#completion#GetCompletionSymbols(kind) abort
|
||||
let l:kind = ale#completion#GetCompletionKind(a:kind)
|
||||
let l:symbol = get(g:ale_completion_symbols, l:kind, '')
|
||||
|
||||
if !empty(l:symbol)
|
||||
return l:symbol
|
||||
endif
|
||||
|
||||
return get(g:ale_completion_symbols, '<default>', 'v')
|
||||
endfunction
|
||||
|
||||
function! s:CompletionStillValid(request_id) abort
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
|
||||
|
@ -296,7 +396,10 @@ function! ale#completion#ParseTSServerCompletions(response) abort
|
|||
let l:names = []
|
||||
|
||||
for l:suggestion in a:response.body
|
||||
call add(l:names, l:suggestion.name)
|
||||
call add(l:names, {
|
||||
\ 'word': l:suggestion.name,
|
||||
\ 'source': get(l:suggestion, 'source', ''),
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:names
|
||||
|
@ -310,6 +413,10 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
|||
for l:suggestion in a:response.body
|
||||
let l:displayParts = []
|
||||
|
||||
for l:action in get(l:suggestion, 'codeActions', [])
|
||||
call add(l:displayParts, l:action.description . ' ')
|
||||
endfor
|
||||
|
||||
for l:part in l:suggestion.displayParts
|
||||
call add(l:displayParts, l:part.text)
|
||||
endfor
|
||||
|
@ -321,22 +428,23 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
|||
call add(l:documentationParts, l:part.text)
|
||||
endfor
|
||||
|
||||
if l:suggestion.kind is# 'className'
|
||||
let l:kind = 'f'
|
||||
elseif l:suggestion.kind is# 'parameterName'
|
||||
let l:kind = 'f'
|
||||
else
|
||||
let l:kind = 'v'
|
||||
endif
|
||||
|
||||
" See :help complete-items
|
||||
call add(l:results, {
|
||||
let l:result = {
|
||||
\ 'word': l:suggestion.name,
|
||||
\ 'kind': l:kind,
|
||||
\ 'kind': ale#completion#GetCompletionSymbols(l:suggestion.kind),
|
||||
\ 'icase': 1,
|
||||
\ 'menu': join(l:displayParts, ''),
|
||||
\ 'dup': g:ale_completion_tsserver_autoimport,
|
||||
\ 'info': join(l:documentationParts, ''),
|
||||
\})
|
||||
\}
|
||||
|
||||
if has_key(l:suggestion, 'codeActions')
|
||||
let l:result.user_data = json_encode({
|
||||
\ 'codeActions': l:suggestion.codeActions,
|
||||
\ })
|
||||
endif
|
||||
|
||||
call add(l:results, l:result)
|
||||
endfor
|
||||
|
||||
let l:names = getbufvar(l:buffer, 'ale_tsserver_completion_names', [])
|
||||
|
@ -345,12 +453,12 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
|||
let l:names_with_details = map(copy(l:results), 'v:val.word')
|
||||
let l:missing_names = filter(
|
||||
\ copy(l:names),
|
||||
\ 'index(l:names_with_details, v:val) < 0',
|
||||
\ 'index(l:names_with_details, v:val.word) < 0',
|
||||
\)
|
||||
|
||||
for l:name in l:missing_names
|
||||
call add(l:results, {
|
||||
\ 'word': l:name,
|
||||
\ 'word': l:name.word,
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'menu': '',
|
||||
|
@ -408,23 +516,6 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
|||
continue
|
||||
endif
|
||||
|
||||
" See :help complete-items for Vim completion kinds
|
||||
if !has_key(l:item, 'kind')
|
||||
let l:kind = 'v'
|
||||
elseif l:item.kind is s:LSP_COMPLETION_METHOD_KIND
|
||||
let l:kind = 'm'
|
||||
elseif l:item.kind is s:LSP_COMPLETION_CONSTRUCTOR_KIND
|
||||
let l:kind = 'm'
|
||||
elseif l:item.kind is s:LSP_COMPLETION_FUNCTION_KIND
|
||||
let l:kind = 'f'
|
||||
elseif l:item.kind is s:LSP_COMPLETION_CLASS_KIND
|
||||
let l:kind = 'f'
|
||||
elseif l:item.kind is s:LSP_COMPLETION_INTERFACE_KIND
|
||||
let l:kind = 'f'
|
||||
else
|
||||
let l:kind = 'v'
|
||||
endif
|
||||
|
||||
let l:doc = get(l:item, 'documentation', '')
|
||||
|
||||
if type(l:doc) is v:t_dict && has_key(l:doc, 'value')
|
||||
|
@ -433,7 +524,7 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
|||
|
||||
call add(l:results, {
|
||||
\ 'word': l:word,
|
||||
\ 'kind': l:kind,
|
||||
\ 'kind': ale#completion#GetCompletionSymbols(get(l:item, 'kind', '')),
|
||||
\ 'icase': 1,
|
||||
\ 'menu': get(l:item, 'detail', ''),
|
||||
\ 'info': (type(l:doc) is v:t_string ? l:doc : ''),
|
||||
|
@ -472,13 +563,29 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
|
|||