First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload First off, the structure/function names should be revised a bit, but I will wait for @w0rp's input before unifying the naming style. Second off, the docs probably need some more work, I just did some simple find-and-replace work. With that said, this pull brings major performance gains for ale. On my slowest system, fully loading ale and all its code takes around 150ms. I have moved all of ale's autoload-able code to autoload/, and in addition, implemented lazy-loading of linters. This brings load time on that same system down to 5ms. The only downside of lazy loading is that `g:ale_linters` cannot be changed at runtime; however, it also speeds up performance at runtime by simplfying the logic greatly. Please let me know what you think! Closes #59 * Address Travis/Vint errors For some reason, ale isn't running vint for me... * Incorporate feedback, make fixes Lazy-loading logic is much improved. * Add header comments; remove incorrect workaround * Remove unneeded plugin guards * Fix lazy-loading linter logic Set the wrong variable.... * Fix capitialization
This commit is contained in:
parent
0680f875fe
commit
7f0ce89d2b
@ -12,7 +12,7 @@ if !exists('g:ale_c_gcc_options')
|
|||||||
let g:ale_c_gcc_options = '-Wall'
|
let g:ale_c_gcc_options = '-Wall'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call ALEAddLinter('c', {
|
call ale#linter#Define('c', {
|
||||||
\ 'name': 'gcc',
|
\ 'name': 'gcc',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable': 'gcc',
|
\ 'executable': 'gcc',
|
||||||
|
@ -7,7 +7,7 @@ endif
|
|||||||
|
|
||||||
let g:loaded_ale_linters_coffee_coffee = 1
|
let g:loaded_ale_linters_coffee_coffee = 1
|
||||||
|
|
||||||
call ALEAddLinter('coffee', {
|
call ale#linter#Define('coffee', {
|
||||||
\ 'name': 'coffee',
|
\ 'name': 'coffee',
|
||||||
\ 'executable': 'coffee',
|
\ 'executable': 'coffee',
|
||||||
\ 'command': 'coffee -cp -s',
|
\ 'command': 'coffee -cp -s',
|
||||||
|
@ -44,7 +44,7 @@ function! ale_linters#coffee#coffeelint#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('coffee', {
|
call ale#linter#Define('coffee', {
|
||||||
\ 'name': 'coffeelint',
|
\ 'name': 'coffeelint',
|
||||||
\ 'executable': 'coffeelint',
|
\ 'executable': 'coffeelint',
|
||||||
\ 'command': 'coffeelint --stdin --reporter csv',
|
\ 'command': 'coffeelint --stdin --reporter csv',
|
||||||
|
@ -12,7 +12,7 @@ if !exists('g:ale_cpp_gcc_options')
|
|||||||
let g:ale_cpp_gcc_options = '-Wall'
|
let g:ale_cpp_gcc_options = '-Wall'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call ALEAddLinter('cpp', {
|
call ale#linter#Define('cpp', {
|
||||||
\ 'name': 'gcc',
|
\ 'name': 'gcc',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable': 'gcc',
|
\ 'executable': 'gcc',
|
||||||
|
@ -7,7 +7,7 @@ endif
|
|||||||
|
|
||||||
let g:loaded_ale_linters_css_csslint = 1
|
let g:loaded_ale_linters_css_csslint = 1
|
||||||
|
|
||||||
call ALEAddLinter('css', {
|
call ale#linter#Define('css', {
|
||||||
\ 'name': 'csslint',
|
\ 'name': 'csslint',
|
||||||
\ 'executable': 'csslint',
|
\ 'executable': 'csslint',
|
||||||
\ 'command': g:ale#util#stdin_wrapper . ' .css csslint --format=compact',
|
\ 'command': g:ale#util#stdin_wrapper . ' .css csslint --format=compact',
|
||||||
|
@ -61,7 +61,7 @@ function! ale_linters#d#dmd#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('d', {
|
call ale#linter#Define('d', {
|
||||||
\ 'name': 'dmd',
|
\ 'name': 'dmd',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable': 'dmd',
|
\ 'executable': 'dmd',
|
||||||
|
@ -60,7 +60,7 @@ function! ale_linters#fortran#gcc#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('fortran', {
|
call ale#linter#Define('fortran', {
|
||||||
\ 'name': 'gcc',
|
\ 'name': 'gcc',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable': 'gcc',
|
\ 'executable': 'gcc',
|
||||||
|
@ -58,7 +58,7 @@ function! ale_linters#haskell#ghc#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('haskell', {
|
call ale#linter#Define('haskell', {
|
||||||
\ 'name': 'ghc',
|
\ 'name': 'ghc',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable': 'ghc',
|
\ 'executable': 'ghc',
|
||||||
@ -66,7 +66,7 @@ call ALEAddLinter('haskell', {
|
|||||||
\ 'callback': 'ale_linters#haskell#ghc#Handle',
|
\ 'callback': 'ale_linters#haskell#ghc#Handle',
|
||||||
\})
|
\})
|
||||||
|
|
||||||
call ALEAddLinter('haskell', {
|
call ale#linter#Define('haskell', {
|
||||||
\ 'name': 'stack-ghc',
|
\ 'name': 'stack-ghc',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable': 'stack',
|
\ 'executable': 'stack',
|
||||||
|
@ -40,7 +40,7 @@ function! ale_linters#html#htmlhint#Handle(buffer, lines) abort
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('html', {
|
call ale#linter#Define('html', {
|
||||||
\ 'name': 'htmlhint',
|
\ 'name': 'htmlhint',
|
||||||
\ 'executable': 'htmlhint',
|
\ 'executable': 'htmlhint',
|
||||||
\ 'command': 'htmlhint --format=unix stdin',
|
\ 'command': 'htmlhint --format=unix stdin',
|
||||||
|
@ -71,7 +71,7 @@ function! ale_linters#html#tidy#Handle(buffer, lines) abort
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('html', {
|
call ale#linter#Define('html', {
|
||||||
\ 'name': 'tidy',
|
\ 'name': 'tidy',
|
||||||
\ 'executable': g:ale_html_tidy_executable,
|
\ 'executable': g:ale_html_tidy_executable,
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
|
@ -49,14 +49,14 @@ function! ale_linters#javascript#eslint#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('javascript', {
|
call ale#linter#Define('javascript', {
|
||||||
\ 'name': 'eslint',
|
\ 'name': 'eslint',
|
||||||
\ 'executable': g:ale_javascript_eslint_executable,
|
\ 'executable': g:ale_javascript_eslint_executable,
|
||||||
\ 'command': g:ale_javascript_eslint_executable . ' -f unix --stdin --stdin-filename %s',
|
\ 'command': g:ale_javascript_eslint_executable . ' -f unix --stdin --stdin-filename %s',
|
||||||
\ 'callback': 'ale_linters#javascript#eslint#Handle',
|
\ 'callback': 'ale_linters#javascript#eslint#Handle',
|
||||||
\})
|
\})
|
||||||
|
|
||||||
call ALEAddLinter('javascript.jsx', {
|
call ale#linter#Define('javascript.jsx', {
|
||||||
\ 'name': 'eslint',
|
\ 'name': 'eslint',
|
||||||
\ 'executable': g:ale_javascript_eslint_executable,
|
\ 'executable': g:ale_javascript_eslint_executable,
|
||||||
\ 'command': g:ale_javascript_eslint_executable . ' -f unix --stdin --stdin-filename %s',
|
\ 'command': g:ale_javascript_eslint_executable . ' -f unix --stdin --stdin-filename %s',
|
||||||
|
@ -43,14 +43,14 @@ function! ale_linters#javascript#jscs#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('javascript', {
|
call ale#linter#Define('javascript', {
|
||||||
\ 'name': 'jscs',
|
\ 'name': 'jscs',
|
||||||
\ 'executable': 'jscs',
|
\ 'executable': 'jscs',
|
||||||
\ 'command': 'jscs -r unix -n -',
|
\ 'command': 'jscs -r unix -n -',
|
||||||
\ 'callback': 'ale_linters#javascript#jscs#Handle',
|
\ 'callback': 'ale_linters#javascript#jscs#Handle',
|
||||||
\})
|
\})
|
||||||
|
|
||||||
call ALEAddLinter('javascript.jsx', {
|
call ale#linter#Define('javascript.jsx', {
|
||||||
\ 'name': 'jscs',
|
\ 'name': 'jscs',
|
||||||
\ 'executable': 'jscs',
|
\ 'executable': 'jscs',
|
||||||
\ 'command': 'jscs -r unix -n -',
|
\ 'command': 'jscs -r unix -n -',
|
||||||
|
@ -70,14 +70,14 @@ function! ale_linters#javascript#jshint#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('javascript', {
|
call ale#linter#Define('javascript', {
|
||||||
\ 'name': 'jshint',
|
\ 'name': 'jshint',
|
||||||
\ 'executable': g:ale_javascript_jshint_executable,
|
\ 'executable': g:ale_javascript_jshint_executable,
|
||||||
\ 'command_callback': 'ale_linters#javascript#jshint#GetCommand',
|
\ 'command_callback': 'ale_linters#javascript#jshint#GetCommand',
|
||||||
\ 'callback': 'ale_linters#javascript#jshint#Handle',
|
\ 'callback': 'ale_linters#javascript#jshint#Handle',
|
||||||
\})
|
\})
|
||||||
|
|
||||||
call ALEAddLinter('javascript.jsx', {
|
call ale#linter#Define('javascript.jsx', {
|
||||||
\ 'name': 'jshint',
|
\ 'name': 'jshint',
|
||||||
\ 'executable': g:ale_javascript_jshint_executable,
|
\ 'executable': g:ale_javascript_jshint_executable,
|
||||||
\ 'command_callback': 'ale_linters#javascript#jshint#GetCommand',
|
\ 'command_callback': 'ale_linters#javascript#jshint#GetCommand',
|
||||||
|
@ -35,7 +35,7 @@ function! ale_linters#json#jsonlint#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('json', {
|
call ale#linter#Define('json', {
|
||||||
\ 'name': 'jsonlint',
|
\ 'name': 'jsonlint',
|
||||||
\ 'executable': 'jsonlint',
|
\ 'executable': 'jsonlint',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
|
@ -37,7 +37,7 @@ function! ale_linters#perl#perl#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('perl', {
|
call ale#linter#Define('perl', {
|
||||||
\ 'name': 'perl',
|
\ 'name': 'perl',
|
||||||
\ 'executable': 'perl',
|
\ 'executable': 'perl',
|
||||||
\ 'output_stream': 'both',
|
\ 'output_stream': 'both',
|
||||||
|
@ -37,7 +37,7 @@ function! ale_linters#perl#perlcritic#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('perl', {
|
call ale#linter#Define('perl', {
|
||||||
\ 'name': 'perlcritic',
|
\ 'name': 'perlcritic',
|
||||||
\ 'executable': 'perlcritic',
|
\ 'executable': 'perlcritic',
|
||||||
\ 'output_stream': 'sdtout',
|
\ 'output_stream': 'sdtout',
|
||||||
|
@ -36,7 +36,7 @@ function! ale_linters#php#php#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('php', {
|
call ale#linter#Define('php', {
|
||||||
\ 'name': 'php',
|
\ 'name': 'php',
|
||||||
\ 'executable': 'php',
|
\ 'executable': 'php',
|
||||||
\ 'output_stream': 'both',
|
\ 'output_stream': 'both',
|
||||||
|
@ -50,7 +50,7 @@ function! ale_linters#php#phpcs#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('php', {
|
call ale#linter#Define('php', {
|
||||||
\ 'name': 'phpcs',
|
\ 'name': 'phpcs',
|
||||||
\ 'executable': 'phpcs',
|
\ 'executable': 'phpcs',
|
||||||
\ 'command_callback': 'ale_linters#php#phpcs#GetCommand',
|
\ 'command_callback': 'ale_linters#php#phpcs#GetCommand',
|
||||||
|
@ -35,7 +35,7 @@ function! ale_linters#pug#puglint#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('pug', {
|
call ale#linter#Define('pug', {
|
||||||
\ 'name': 'puglint',
|
\ 'name': 'puglint',
|
||||||
\ 'executable': 'pug-lint',
|
\ 'executable': 'pug-lint',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
|
@ -34,7 +34,7 @@ function! ale_linters#pyrex#cython#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('pyrex', {
|
call ale#linter#Define('pyrex', {
|
||||||
\ 'name': 'cython',
|
\ 'name': 'cython',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable': 'cython',
|
\ 'executable': 'cython',
|
||||||
|
@ -47,7 +47,7 @@ function! ale_linters#python#flake8#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('python', {
|
call ale#linter#Define('python', {
|
||||||
\ 'name': 'flake8',
|
\ 'name': 'flake8',
|
||||||
\ 'executable': 'flake8',
|
\ 'executable': 'flake8',
|
||||||
\ 'command': 'flake8 -',
|
\ 'command': 'flake8 -',
|
||||||
|
@ -40,7 +40,7 @@ function! ale_linters#ruby#rubocop#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('ruby', {
|
call ale#linter#Define('ruby', {
|
||||||
\ 'name': 'rubocop',
|
\ 'name': 'rubocop',
|
||||||
\ 'executable': 'rubocop',
|
\ 'executable': 'rubocop',
|
||||||
\ 'command': 'rubocop --format emacs --stdin _',
|
\ 'command': 'rubocop --format emacs --stdin _',
|
||||||
|
@ -6,7 +6,7 @@ endif
|
|||||||
|
|
||||||
let g:loaded_ale_linters_sass_sasslint = 1
|
let g:loaded_ale_linters_sass_sasslint = 1
|
||||||
|
|
||||||
call ALEAddLinter('sass', {
|
call ale#linter#Define('sass', {
|
||||||
\ 'name': 'sasslint',
|
\ 'name': 'sasslint',
|
||||||
\ 'executable': 'sass-lint',
|
\ 'executable': 'sass-lint',
|
||||||
\ 'command': g:ale#util#stdin_wrapper . ' .sass sass-lint -v -q -f compact',
|
\ 'command': g:ale#util#stdin_wrapper . ' .sass sass-lint -v -q -f compact',
|
||||||
|
@ -49,7 +49,7 @@ function! ale_linters#scala#scalac#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('scala', {
|
call ale#linter#Define('scala', {
|
||||||
\ 'name': 'scalac',
|
\ 'name': 'scalac',
|
||||||
\ 'executable': 'scalac',
|
\ 'executable': 'scalac',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
|
@ -6,7 +6,7 @@ endif
|
|||||||
|
|
||||||
let g:loaded_ale_linters_scss_sasslint = 1
|
let g:loaded_ale_linters_scss_sasslint = 1
|
||||||
|
|
||||||
call ALEAddLinter('scss', {
|
call ale#linter#Define('scss', {
|
||||||
\ 'name': 'sasslint',
|
\ 'name': 'sasslint',
|
||||||
\ 'executable': 'sass-lint',
|
\ 'executable': 'sass-lint',
|
||||||
\ 'command': g:ale#util#stdin_wrapper . ' .scss sass-lint -v -q -f compact',
|
\ 'command': g:ale#util#stdin_wrapper . ' .scss sass-lint -v -q -f compact',
|
||||||
|
@ -41,7 +41,7 @@ function! ale_linters#scss#scsslint#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('scss', {
|
call ale#linter#Define('scss', {
|
||||||
\ 'name': 'scsslint',
|
\ 'name': 'scsslint',
|
||||||
\ 'executable': 'scss-lint',
|
\ 'executable': 'scss-lint',
|
||||||
\ 'command': 'scss-lint --stdin-file-path=%s',
|
\ 'command': 'scss-lint --stdin-file-path=%s',
|
||||||
|
@ -74,7 +74,7 @@ function! ale_linters#sh#shell#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('sh', {
|
call ale#linter#Define('sh', {
|
||||||
\ 'name': 'shell',
|
\ 'name': 'shell',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable_callback': 'ale_linters#sh#shell#GetExecutable',
|
\ 'executable_callback': 'ale_linters#sh#shell#GetExecutable',
|
||||||
|
@ -22,7 +22,7 @@ else
|
|||||||
let s:exclude_option = ''
|
let s:exclude_option = ''
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call ALEAddLinter('sh', {
|
call ale#linter#Define('sh', {
|
||||||
\ 'name': 'shellcheck',
|
\ 'name': 'shellcheck',
|
||||||
\ 'executable': 'shellcheck',
|
\ 'executable': 'shellcheck',
|
||||||
\ 'command': 'shellcheck ' . s:exclude_option . ' -f gcc -',
|
\ 'command': 'shellcheck ' . s:exclude_option . ' -f gcc -',
|
||||||
|
@ -43,7 +43,7 @@ function! ale_linters#typescript#tslint#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('typescript', {
|
call ale#linter#Define('typescript', {
|
||||||
\ 'name': 'tslint',
|
\ 'name': 'tslint',
|
||||||
\ 'executable': 'tslint',
|
\ 'executable': 'tslint',
|
||||||
\ 'command': g:ale#util#stdin_wrapper . ' .ts tslint',
|
\ 'command': g:ale#util#stdin_wrapper . ' .ts tslint',
|
||||||
|
@ -42,7 +42,7 @@ function! ale_linters#verilog#iverilog#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('verilog', {
|
call ale#linter#Define('verilog', {
|
||||||
\ 'name': 'iverilog',
|
\ 'name': 'iverilog',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable': 'iverilog',
|
\ 'executable': 'iverilog',
|
||||||
|
@ -44,7 +44,7 @@ function! ale_linters#verilog#verilator#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('verilog', {
|
call ale#linter#Define('verilog', {
|
||||||
\ 'name': 'verilator',
|
\ 'name': 'verilator',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable': 'verilator',
|
\ 'executable': 'verilator',
|
||||||
|
@ -9,7 +9,7 @@ let g:loaded_ale_linters_vim_vint = 1
|
|||||||
|
|
||||||
let s:format = '-f "{file_path}:{line_number}:{column_number}: {severity}: {description} (see {reference})'
|
let s:format = '-f "{file_path}:{line_number}:{column_number}: {severity}: {description} (see {reference})'
|
||||||
|
|
||||||
call ALEAddLinter('vim', {
|
call ale#linter#Define('vim', {
|
||||||
\ 'name': 'vint',
|
\ 'name': 'vint',
|
||||||
\ 'executable': 'vint',
|
\ 'executable': 'vint',
|
||||||
\ 'command': g:ale#util#stdin_wrapper . ' .vim vint -w --no-color ' . s:format,
|
\ 'command': g:ale#util#stdin_wrapper . ' .vim vint -w --no-color ' . s:format,
|
||||||
|
@ -40,7 +40,7 @@ function! ale_linters#yaml#yamllint#Handle(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call ALEAddLinter('yaml', {
|
call ale#linter#Define('yaml', {
|
||||||
\ 'name': 'yamllint',
|
\ 'name': 'yamllint',
|
||||||
\ 'executable': 'yamllint',
|
\ 'executable': 'yamllint',
|
||||||
\ 'command': g:ale#util#stdin_wrapper . ' .yml yamllint -f parsable',
|
\ 'command': g:ale#util#stdin_wrapper . ' .yml yamllint -f parsable',
|
||||||
|
48
autoload/ale.vim
Normal file
48
autoload/ale.vim
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" Description: Primary code path for the plugin
|
||||||
|
" Manages execution of linters when requested by autocommands
|
||||||
|
|
||||||
|
let s:lint_timer = -1
|
||||||
|
|
||||||
|
function! ale#Queue(delay) abort
|
||||||
|
if s:lint_timer != -1
|
||||||
|
call timer_stop(s:lint_timer)
|
||||||
|
let s:lint_timer = -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let linters = ale#linter#Get(&filetype)
|
||||||
|
if len(linters) == 0
|
||||||
|
" There are no linters to lint with, so stop here.
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:delay > 0
|
||||||
|
let s:lint_timer = timer_start(a:delay, function('ale#Lint'))
|
||||||
|
else
|
||||||
|
call ale#Lint()
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#Lint(...) abort
|
||||||
|
let buffer = bufnr('%')
|
||||||
|
let linters = ale#linter#Get(&filetype)
|
||||||
|
|
||||||
|
" Set a variable telling us to clear the loclist later.
|
||||||
|
let g:ale_buffer_should_reset_map[buffer] = 1
|
||||||
|
|
||||||
|
for linter in linters
|
||||||
|
" Check if a given linter has a program which can be executed.
|
||||||
|
if has_key(linter, 'executable_callback')
|
||||||
|
let l:executable = ale#util#GetFunction(linter.executable_callback)(buffer)
|
||||||
|
else
|
||||||
|
let l:executable = linter.executable
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !executable(l:executable)
|
||||||
|
" The linter's program cannot be executed, so skip it.
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
call ale#engine#Invoke(buffer, linter)
|
||||||
|
endfor
|
||||||
|
endfunction
|
16
autoload/ale/cleanup.vim
Normal file
16
autoload/ale/cleanup.vim
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" Description: Utility functions related to cleaning state.
|
||||||
|
|
||||||
|
function! ale#cleanup#Buffer(buffer) abort
|
||||||
|
if has_key(g:ale_buffer_should_reset_map, a:buffer)
|
||||||
|
call remove(g:ale_buffer_should_reset_map, a:buffer)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(g:ale_buffer_loclist_map, a:buffer)
|
||||||
|
call remove(g:ale_buffer_loclist_map, a:buffer)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(g:ale_buffer_sign_dummy_map, a:buffer)
|
||||||
|
call remove(g:ale_buffer_sign_dummy_map, a:buffer)
|
||||||
|
endif
|
||||||
|
endfunction
|
@ -1,12 +1,6 @@
|
|||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
" Description: Echoes lint message for the current line, if any
|
" Description: Echoes lint message for the current line, if any
|
||||||
|
|
||||||
if exists('g:loaded_ale_cursor')
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
let g:loaded_ale_cursor = 1
|
|
||||||
|
|
||||||
" Return a formatted message according to g:ale_echo_msg_format variable
|
" Return a formatted message according to g:ale_echo_msg_format variable
|
||||||
function! s:GetMessage(linter, type, text) abort
|
function! s:GetMessage(linter, type, text) abort
|
||||||
let msg = g:ale_echo_msg_format
|
let msg = g:ale_echo_msg_format
|
||||||
@ -26,7 +20,7 @@ endfunction
|
|||||||
|
|
||||||
" This function will perform a binary search to find a message from the
|
" This function will perform a binary search to find a message from the
|
||||||
" loclist to echo when the cursor moves.
|
" loclist to echo when the cursor moves.
|
||||||
function! s:BinarySearch(loclist, line, column)
|
function! s:BinarySearch(loclist, line, column) abort
|
||||||
let min = 0
|
let min = 0
|
||||||
let max = len(a:loclist) - 1
|
let max = len(a:loclist) - 1
|
||||||
let last_column_match = -1
|
let last_column_match = -1
|
||||||
@ -59,7 +53,7 @@ function! s:BinarySearch(loclist, line, column)
|
|||||||
endwhile
|
endwhile
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#cursor#TruncatedEcho(message)
|
function! ale#cursor#TruncatedEcho(message) abort
|
||||||
let message = a:message
|
let message = a:message
|
||||||
" Change tabs to spaces.
|
" Change tabs to spaces.
|
||||||
let message = substitute(message, "\t", ' ', 'g')
|
let message = substitute(message, "\t", ' ', 'g')
|
||||||
@ -79,7 +73,7 @@ function! ale#cursor#TruncatedEcho(message)
|
|||||||
endtry
|
endtry
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#cursor#EchoCursorWarning(...)
|
function! ale#cursor#EchoCursorWarning(...) abort
|
||||||
" Only echo the warnings in normal mode, otherwise we will get problems.
|
" Only echo the warnings in normal mode, otherwise we will get problems.
|
||||||
if mode() !=# 'n'
|
if mode() !=# 'n'
|
||||||
return
|
return
|
||||||
@ -108,7 +102,7 @@ endfunction
|
|||||||
|
|
||||||
let s:cursor_timer = -1
|
let s:cursor_timer = -1
|
||||||
|
|
||||||
function! ale#cursor#EchoCursorWarningWithDelay()
|
function! ale#cursor#EchoCursorWarningWithDelay() abort
|
||||||
if s:cursor_timer != -1
|
if s:cursor_timer != -1
|
||||||
call timer_stop(s:cursor_timer)
|
call timer_stop(s:cursor_timer)
|
||||||
let s:cursor_timer = -1
|
let s:cursor_timer = -1
|
@ -1,19 +1,6 @@
|
|||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
" Description: Main entry point for this plugin
|
" Description: Backend execution and job management
|
||||||
" Loads linters and manages lint jobs
|
" Executes linters in the background, using NeoVim or Vim 8 jobs
|
||||||
|
|
||||||
if exists('g:loaded_ale_zmain')
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
let g:loaded_ale_zmain = 1
|
|
||||||
|
|
||||||
let s:lint_timer = -1
|
|
||||||
let s:linters = {}
|
|
||||||
|
|
||||||
if !exists('g:ale_linters')
|
|
||||||
let g:ale_linters = {}
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Stores information for each job including:
|
" Stores information for each job including:
|
||||||
"
|
"
|
||||||
@ -22,20 +9,18 @@ endif
|
|||||||
" output: The array of lines for the output of the job.
|
" output: The array of lines for the output of the job.
|
||||||
let s:job_info_map = {}
|
let s:job_info_map = {}
|
||||||
|
|
||||||
" Globals which each part of the plugin should use.
|
function! s:GetJobID(job) abort
|
||||||
let g:ale_buffer_loclist_map = {}
|
if has('nvim')
|
||||||
let g:ale_buffer_should_reset_map = {}
|
"In NeoVim, job values are just IDs.
|
||||||
let g:ale_buffer_sign_dummy_map = {}
|
return a:job
|
||||||
|
|
||||||
function! s:GetFunction(string_or_ref)
|
|
||||||
if type(a:string_or_ref) == type('')
|
|
||||||
return function(a:string_or_ref)
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return a:string_or_ref
|
" In Vim 8, the job is a special variable, and we open a channel for each
|
||||||
|
" job. We'll use the ID of the channel instead as the job ID.
|
||||||
|
return ch_info(job_getchannel(a:job)).id
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:ClearJob(job)
|
function! s:ClearJob(job) abort
|
||||||
let job_id = s:GetJobID(a:job)
|
let job_id = s:GetJobID(a:job)
|
||||||
let linter = s:job_info_map[job_id].linter
|
let linter = s:job_info_map[job_id].linter
|
||||||
|
|
||||||
@ -55,7 +40,7 @@ function! s:ClearJob(job)
|
|||||||
call remove(linter, 'job')
|
call remove(linter, 'job')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:GatherOutput(job, data)
|
function! s:GatherOutput(job, data) abort
|
||||||
let job_id = s:GetJobID(a:job)
|
let job_id = s:GetJobID(a:job)
|
||||||
|
|
||||||
if !has_key(s:job_info_map, job_id)
|
if !has_key(s:job_info_map, job_id)
|
||||||
@ -65,51 +50,15 @@ function! s:GatherOutput(job, data)
|
|||||||
call extend(s:job_info_map[job_id].output, a:data)
|
call extend(s:job_info_map[job_id].output, a:data)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:GatherOutputNeoVim(job, data, event)
|
function! s:GatherOutputVim(channel, data) abort
|
||||||
call s:GatherOutput(a:job, a:data)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:GatherOutputVim(channel, data)
|
|
||||||
call s:GatherOutput(ch_getjob(a:channel), [a:data])
|
call s:GatherOutput(ch_getjob(a:channel), [a:data])
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:LocItemCompare(left, right)
|
function! s:GatherOutputNeoVim(job, data, event) abort
|
||||||
if a:left['lnum'] < a:right['lnum']
|
call s:GatherOutput(a:job, a:data)
|
||||||
return -1
|
|
||||||
endif
|
|
||||||
|
|
||||||
if a:left['lnum'] > a:right['lnum']
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
if a:left['col'] < a:right['col']
|
|
||||||
return -1
|
|
||||||
endif
|
|
||||||
|
|
||||||
if a:left['col'] > a:right['col']
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
return 0
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:FixLoclist(buffer, loclist)
|
function! s:HandleExit(job) abort
|
||||||
" Some errors have line numbers beyond the end of the file,
|
|
||||||
" so we need to adjust them so they set the error at the last line
|
|
||||||
" of the file instead.
|
|
||||||
let last_line_number = ale#util#GetLineCount(a:buffer)
|
|
||||||
|
|
||||||
for item in a:loclist
|
|
||||||
if item.lnum == 0
|
|
||||||
" When errors appear at line 0, put them at line 1 instead.
|
|
||||||
let item.lnum = 1
|
|
||||||
elseif item.lnum > last_line_number
|
|
||||||
let item.lnum = last_line_number
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:HandleExit(job)
|
|
||||||
if a:job ==# 'no process'
|
if a:job ==# 'no process'
|
||||||
" Stop right away when the job is not valid in Vim 8.
|
" Stop right away when the job is not valid in Vim 8.
|
||||||
return
|
return
|
||||||
@ -129,15 +78,10 @@ function! s:HandleExit(job)
|
|||||||
let output = job_info.output
|
let output = job_info.output
|
||||||
let buffer = job_info.buffer
|
let buffer = job_info.buffer
|
||||||
|
|
||||||
let linter_loclist = s:GetFunction(linter.callback)(buffer, output)
|
let linter_loclist = ale#util#GetFunction(linter.callback)(buffer, output)
|
||||||
|
|
||||||
" Make some adjustments to the loclists to fix common problems.
|
" Make some adjustments to the loclists to fix common problems.
|
||||||
call s:FixLoclist(buffer, linter_loclist)
|
call s:FixLocList(buffer, linter_loclist)
|
||||||
|
|
||||||
" Remember which linter returned these items for later use.
|
|
||||||
for obj in linter_loclist
|
|
||||||
let obj.linter_name = linter.name
|
|
||||||
endfor
|
|
||||||
|
|
||||||
if g:ale_buffer_should_reset_map[buffer]
|
if g:ale_buffer_should_reset_map[buffer]
|
||||||
let g:ale_buffer_should_reset_map[buffer] = 0
|
let g:ale_buffer_should_reset_map[buffer] = 0
|
||||||
@ -150,7 +94,7 @@ function! s:HandleExit(job)
|
|||||||
" Sort the loclist again.
|
" Sort the loclist again.
|
||||||
" We need a sorted list so we can run a binary search against it
|
" We need a sorted list so we can run a binary search against it
|
||||||
" for efficient lookup of the messages in the cursor handler.
|
" for efficient lookup of the messages in the cursor handler.
|
||||||
call sort(g:ale_buffer_loclist_map[buffer], 's:LocItemCompare')
|
call sort(g:ale_buffer_loclist_map[buffer], 'ale#util#LocItemCompare')
|
||||||
|
|
||||||
if g:ale_set_loclist
|
if g:ale_set_loclist
|
||||||
call setloclist(0, g:ale_buffer_loclist_map[buffer])
|
call setloclist(0, g:ale_buffer_loclist_map[buffer])
|
||||||
@ -164,26 +108,31 @@ function! s:HandleExit(job)
|
|||||||
" matchadd('ALEError', '\%200l\%17v')
|
" matchadd('ALEError', '\%200l\%17v')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:GetJobID(job)
|
function! s:HandleExitNeoVim(job, data, event) abort
|
||||||
if has('nvim')
|
|
||||||
"In NeoVim, job values are just IDs.
|
|
||||||
return a:job
|
|
||||||
endif
|
|
||||||
|
|
||||||
" In Vim 8, the job is a special variable, and we open a channel for each
|
|
||||||
" job. We'll use the ID of the channel instead as the job ID.
|
|
||||||
return ch_info(job_getchannel(a:job)).id
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:HandleExitNeoVim(job, data, event)
|
|
||||||
call s:HandleExit(a:job)
|
call s:HandleExit(a:job)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:HandleExitVim(channel)
|
function! s:HandleExitVim(channel) abort
|
||||||
call s:HandleExit(ch_getjob(a:channel))
|
call s:HandleExit(ch_getjob(a:channel))
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:ApplyLinter(buffer, linter)
|
function! s:FixLocList(buffer, loclist) abort
|
||||||
|
" Some errors have line numbers beyond the end of the file,
|
||||||
|
" so we need to adjust them so they set the error at the last line
|
||||||
|
" of the file instead.
|
||||||
|
let last_line_number = ale#util#GetLineCount(a:buffer)
|
||||||
|
|
||||||
|
for item in a:loclist
|
||||||
|
if item.lnum == 0
|
||||||
|
" When errors appear at line 0, put them at line 1 instead.
|
||||||
|
let item.lnum = 1
|
||||||
|
elseif item.lnum > last_line_number
|
||||||
|
let item.lnum = last_line_number
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#engine#Invoke(buffer, linter) abort
|
||||||
if has_key(a:linter, 'job')
|
if has_key(a:linter, 'job')
|
||||||
" Stop previous jobs for the same linter.
|
" Stop previous jobs for the same linter.
|
||||||
call s:ClearJob(a:linter.job)
|
call s:ClearJob(a:linter.job)
|
||||||
@ -191,7 +140,7 @@ function! s:ApplyLinter(buffer, linter)
|
|||||||
|
|
||||||
if has_key(a:linter, 'command_callback')
|
if has_key(a:linter, 'command_callback')
|
||||||
" If there is a callback for generating a command, call that instead.
|
" If there is a callback for generating a command, call that instead.
|
||||||
let command = s:GetFunction(a:linter.command_callback)(a:buffer)
|
let command = ale#util#GetFunction(a:linter.command_callback)(a:buffer)
|
||||||
else
|
else
|
||||||
let command = a:linter.command
|
let command = a:linter.command
|
||||||
endif
|
endif
|
||||||
@ -274,8 +223,7 @@ function! s:ApplyLinter(buffer, linter)
|
|||||||
call jobsend(job, input)
|
call jobsend(job, input)
|
||||||
call jobclose(job, 'stdin')
|
call jobclose(job, 'stdin')
|
||||||
elseif has('win32')
|
elseif has('win32')
|
||||||
" On Windows, we have to send the buffer lines ourselves,
|
" On some Vim versions, we have to send the buffer data ourselves.
|
||||||
" as there are issues with Windows and 'in_buf'
|
|
||||||
let input = join(getbufline(a:buffer, 1, '$'), "\n") . "\n"
|
let input = join(getbufline(a:buffer, 1, '$'), "\n") . "\n"
|
||||||
let channel = job_getchannel(job)
|
let channel = job_getchannel(job)
|
||||||
|
|
||||||
@ -286,152 +234,3 @@ function! s:ApplyLinter(buffer, linter)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:TimerHandler(...)
|
|
||||||
let filetype = &filetype
|
|
||||||
let linters = ALEGetLinters(filetype)
|
|
||||||
|
|
||||||
let buffer = bufnr('%')
|
|
||||||
|
|
||||||
" Set a variable telling us to clear the loclist later.
|
|
||||||
let g:ale_buffer_should_reset_map[buffer] = 1
|
|
||||||
|
|
||||||
for linter in linters
|
|
||||||
" Check if a given linter has a program which can be executed.
|
|
||||||
if has_key(linter, 'executable_callback')
|
|
||||||
let l:executable = s:GetFunction(linter.executable_callback)(buffer)
|
|
||||||
else
|
|
||||||
let l:executable = linter.executable
|
|
||||||
endif
|
|
||||||
|
|
||||||
if !executable(l:executable)
|
|
||||||
" The linter's program cannot be executed, so skip it.
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
|
|
||||||
call s:ApplyLinter(buffer, linter)
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function s:BufferCleanup(buffer)
|
|
||||||
if has_key(g:ale_buffer_should_reset_map, a:buffer)
|
|
||||||
call remove(g:ale_buffer_should_reset_map, a:buffer)
|
|
||||||
endif
|
|
||||||
|
|
||||||
if has_key(g:ale_buffer_loclist_map, a:buffer)
|
|
||||||
call remove(g:ale_buffer_loclist_map, a:buffer)
|
|
||||||
endif
|
|
||||||
|
|
||||||
if has_key(g:ale_buffer_sign_dummy_map, a:buffer)
|
|
||||||
call remove(g:ale_buffer_sign_dummy_map, a:buffer)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ALEAddLinter(filetype, linter)
|
|
||||||
if !has_key(s:linters, a:filetype)
|
|
||||||
let s:linters[a:filetype] = []
|
|
||||||
endif
|
|
||||||
|
|
||||||
let new_linter = {
|
|
||||||
\ 'name': a:linter.name,
|
|
||||||
\ 'callback': a:linter.callback,
|
|
||||||
\}
|
|
||||||
|
|
||||||
if has_key(a:linter, 'executable_callback')
|
|
||||||
let new_linter.executable_callback = a:linter.executable_callback
|
|
||||||
else
|
|
||||||
let new_linter.executable = a:linter.executable
|
|
||||||
endif
|
|
||||||
|
|
||||||
if has_key(a:linter, 'command_callback')
|
|
||||||
let new_linter.command_callback = a:linter.command_callback
|
|
||||||
else
|
|
||||||
let new_linter.command = a:linter.command
|
|
||||||
endif
|
|
||||||
|
|
||||||
if has_key(a:linter, 'output_stream')
|
|
||||||
let new_linter.output_stream = a:linter.output_stream
|
|
||||||
else
|
|
||||||
let new_linter.output_stream = 'stdout'
|
|
||||||
endif
|
|
||||||
|
|
||||||
" TODO: Assert the value of the output_stream to be something sensible.
|
|
||||||
|
|
||||||
call add(s:linters[a:filetype], new_linter)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ALEGetLinters(filetype)
|
|
||||||
if !has_key(s:linters, a:filetype)
|
|
||||||
return []
|
|
||||||
endif
|
|
||||||
|
|
||||||
if has_key(g:ale_linters, a:filetype)
|
|
||||||
let linters = []
|
|
||||||
" Filter loaded linters according to list of linters specified in option
|
|
||||||
for linter in s:linters[a:filetype]
|
|
||||||
if index(g:ale_linters[a:filetype], linter.name) != -1
|
|
||||||
call add(linters, linter)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
return linters
|
|
||||||
endif
|
|
||||||
|
|
||||||
return s:linters[a:filetype]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ALELint(delay)
|
|
||||||
let filetype = &filetype
|
|
||||||
let linters = ALEGetLinters(filetype)
|
|
||||||
|
|
||||||
if s:lint_timer != -1
|
|
||||||
call timer_stop(s:lint_timer)
|
|
||||||
let s:lint_timer = -1
|
|
||||||
endif
|
|
||||||
|
|
||||||
if len(linters) == 0
|
|
||||||
" There are no linters to lint with, so stop here.
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if a:delay > 0
|
|
||||||
let s:lint_timer = timer_start(a:delay, function('s:TimerHandler'))
|
|
||||||
else
|
|
||||||
call s:TimerHandler()
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Load all of the linters for each filetype.
|
|
||||||
runtime! ale_linters/*/*.vim
|
|
||||||
|
|
||||||
if !g:ale_has_required_features
|
|
||||||
echoerr 'ALE requires NeoVim >= 0.1.5 or Vim 8 with +timers +job +channel'
|
|
||||||
echoerr 'Please update your editor appropriately.'
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
if g:ale_lint_on_text_changed
|
|
||||||
augroup ALERunOnTextChangedGroup
|
|
||||||
autocmd!
|
|
||||||
autocmd TextChanged,TextChangedI * call ALELint(g:ale_lint_delay)
|
|
||||||
augroup END
|
|
||||||
endif
|
|
||||||
|
|
||||||
if g:ale_lint_on_enter
|
|
||||||
augroup ALERunOnEnterGroup
|
|
||||||
autocmd!
|
|
||||||
autocmd BufEnter,BufRead * call ALELint(100)
|
|
||||||
augroup END
|
|
||||||
endif
|
|
||||||
|
|
||||||
if g:ale_lint_on_save
|
|
||||||
augroup ALERunOnSaveGroup
|
|
||||||
autocmd!
|
|
||||||
autocmd BufWrite * call ALELint(0)
|
|
||||||
augroup END
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Clean up buffers automatically when they are unloaded.
|
|
||||||
augroup ALEBuffferCleanup
|
|
||||||
autocmd!
|
|
||||||
autocmd BufUnload * call s:BufferCleanup('<abuf>')
|
|
||||||
augroup END
|
|
@ -4,13 +4,7 @@ scriptencoding utf-8
|
|||||||
" linter which outputs warnings and errors in a format accepted by one of
|
" linter which outputs warnings and errors in a format accepted by one of
|
||||||
" these functions can simply use one of these pre-defined error handlers.
|
" these functions can simply use one of these pre-defined error handlers.
|
||||||
|
|
||||||
if exists('g:loaded_ale_handlers')
|
function! ale#handlers#HandleGCCFormat(buffer, lines) abort
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
let g:loaded_ale_handlers = 1
|
|
||||||
|
|
||||||
function! ale#handlers#HandleGCCFormat(buffer, lines)
|
|
||||||
" Look for lines like the following.
|
" Look for lines like the following.
|
||||||
"
|
"
|
||||||
" <stdin>:8:5: warning: conversion lacks type at end of format [-Wformat=]
|
" <stdin>:8:5: warning: conversion lacks type at end of format [-Wformat=]
|
||||||
@ -40,7 +34,7 @@ function! ale#handlers#HandleGCCFormat(buffer, lines)
|
|||||||
return output
|
return output
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#handlers#HandleCSSLintFormat(buffer, lines)
|
function! ale#handlers#HandleCSSLintFormat(buffer, lines) abort
|
||||||
" Matches patterns line the following:
|
" Matches patterns line the following:
|
||||||
"
|
"
|
||||||
" something.css: line 2, col 1, Error - Expected RBRACE at line 2, col 1. (errors)
|
" something.css: line 2, col 1, Error - Expected RBRACE at line 2, col 1. (errors)
|
66
autoload/ale/linter.vim
Normal file
66
autoload/ale/linter.vim
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" Description: Linter registration and lazy-loading
|
||||||
|
" Retrieves linters as requested by the engine, loading them if needed.
|
||||||
|
|
||||||
|
let s:linters = {}
|
||||||
|
|
||||||
|
function! ale#linter#Define(filetype, linter) abort
|
||||||
|
if !has_key(s:linters, a:filetype)
|
||||||
|
let s:linters[a:filetype] = []
|
||||||
|
endif
|
||||||
|
|
||||||
|
let new_linter = {
|
||||||
|
\ 'name': a:linter.name,
|
||||||
|
\ 'callback': a:linter.callback,
|
||||||
|
\}
|
||||||
|
|
||||||
|
if has_key(a:linter, 'executable_callback')
|
||||||
|
let new_linter.executable_callback = a:linter.executable_callback
|
||||||
|
else
|
||||||
|
let new_linter.executable = a:linter.executable
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(a:linter, 'command_callback')
|
||||||
|
let new_linter.command_callback = a:linter.command_callback
|
||||||
|
else
|
||||||
|
let new_linter.command = a:linter.command
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(a:linter, 'output_stream')
|
||||||
|
let new_linter.output_stream = a:linter.output_stream
|
||||||
|
else
|
||||||
|
let new_linter.output_stream = 'stdout'
|
||||||
|
endif
|
||||||
|
|
||||||
|
" TODO: Assert the value of the output_stream to be something sensible.
|
||||||
|
|
||||||
|
call add(s:linters[a:filetype], new_linter)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#linter#Get(filetype) abort
|
||||||
|
if a:filetype ==# ''
|
||||||
|
" Empty filetype? Nothing to be done about that.
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(s:linters, a:filetype)
|
||||||
|
" We already loaded a linter, great!
|
||||||
|
return s:linters[a:filetype]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(g:ale_linters, a:filetype)
|
||||||
|
" Filter loaded linters according to list of linters specified in option.
|
||||||
|
for linter in g:ale_linters[a:filetype]
|
||||||
|
execute 'runtime! ale_linters/' . a:filetype . '/' . linter . '.vim'
|
||||||
|
endfor
|
||||||
|
else
|
||||||
|
execute 'runtime! ale_linters/' . a:filetype . '/*.vim'
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !has_key(s:linters, a:filetype)
|
||||||
|
" If we couldn't load any linters, let everyone know.
|
||||||
|
let s:linters[a:filetype] = []
|
||||||
|
endif
|
||||||
|
|
||||||
|
return s:linters[a:filetype]
|
||||||
|
endfunction
|
@ -1,12 +1,7 @@
|
|||||||
scriptencoding utf-8
|
scriptencoding utf8
|
||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
" Description: Draws error and warning signs into signcolumn
|
" Description: Draws error and warning signs into signcolumn
|
||||||
|
|
||||||
if exists('g:loaded_ale_sign')
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
let g:loaded_ale_sign = 1
|
|
||||||
let b:dummy_sign_set_map = {}
|
let b:dummy_sign_set_map = {}
|
||||||
|
|
||||||
if !hlexists('ALEErrorSign')
|
if !hlexists('ALEErrorSign')
|
||||||
@ -40,7 +35,7 @@ execute 'sign define ALEWarningSign text=' . g:ale_sign_warning
|
|||||||
\ . ' texthl=ALEWarningSign'
|
\ . ' texthl=ALEWarningSign'
|
||||||
sign define ALEDummySign
|
sign define ALEDummySign
|
||||||
|
|
||||||
function! ale#sign#FindCurrentSigns(buffer)
|
function! ale#sign#FindCurrentSigns(buffer) abort
|
||||||
" Matches output like :
|
" Matches output like :
|
||||||
" line=4 id=1 name=ALEErrorSign
|
" line=4 id=1 name=ALEErrorSign
|
||||||
" строка=1 id=1000001 имя=ALEErrorSign
|
" строка=1 id=1000001 имя=ALEErrorSign
|
||||||
@ -66,7 +61,7 @@ endfunction
|
|||||||
" Given a loclist, combine the loclist into a list of signs such that only
|
" Given a loclist, combine the loclist into a list of signs such that only
|
||||||
" one sign appears per line. Error lines will take precedence.
|
" one sign appears per line. Error lines will take precedence.
|
||||||
" The loclist will have been previously sorted.
|
" The loclist will have been previously sorted.
|
||||||
function! ale#sign#CombineSigns(loclist)
|
function! ale#sign#CombineSigns(loclist) abort
|
||||||
let signlist = []
|
let signlist = []
|
||||||
|
|
||||||
for obj in a:loclist
|
for obj in a:loclist
|
||||||
@ -98,7 +93,7 @@ function! ale#sign#CombineSigns(loclist)
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" This function will set the signs which show up on the left.
|
" This function will set the signs which show up on the left.
|
||||||
function! ale#sign#SetSigns(buffer, loclist)
|
function! ale#sign#SetSigns(buffer, loclist) abort
|
||||||
let signlist = ale#sign#CombineSigns(a:loclist)
|
let signlist = ale#sign#CombineSigns(a:loclist)
|
||||||
|
|
||||||
if len(signlist) > 0 || g:ale_sign_column_always
|
if len(signlist) > 0 || g:ale_sign_column_always
|
@ -1,7 +1,7 @@
|
|||||||
" Author: KabbAmine <amine.kabb@gmail.com>
|
" Author: KabbAmine <amine.kabb@gmail.com>
|
||||||
" Description: Statusline related function(s)
|
" Description: Statusline related function(s)
|
||||||
|
|
||||||
function! ALEGetStatusLine() abort
|
function! ale#statusline#Status() abort
|
||||||
" Returns a formatted string that can be integrated in the
|
" Returns a formatted string that can be integrated in the
|
||||||
" statusline
|
" statusline
|
||||||
|
|
@ -1,13 +1,7 @@
|
|||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
" Description: Contains miscellaneous functions
|
" Description: Contains miscellaneous functions
|
||||||
|
|
||||||
if exists('g:loaded_ale_util')
|
function! s:FindWrapperScript() abort
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
let g:loaded_ale_util = 1
|
|
||||||
|
|
||||||
function! s:FindWrapperScript()
|
|
||||||
for parent in split(&runtimepath, ',')
|
for parent in split(&runtimepath, ',')
|
||||||
" Expand the path to deal with ~ issues.
|
" Expand the path to deal with ~ issues.
|
||||||
let path = expand(parent . '/' . 'stdin-wrapper')
|
let path = expand(parent . '/' . 'stdin-wrapper')
|
||||||
@ -24,20 +18,48 @@ endfunction
|
|||||||
|
|
||||||
let g:ale#util#stdin_wrapper = s:FindWrapperScript()
|
let g:ale#util#stdin_wrapper = s:FindWrapperScript()
|
||||||
|
|
||||||
" Return the number of lines for a given buffer.
|
|
||||||
function! ale#util#GetLineCount(buffer)
|
|
||||||
return len(getbufline(a:buffer, 1, '$'))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Given a buffer and a filename, find the nearest file by searching upwards
|
|
||||||
" through the paths relative to the given buffer.
|
|
||||||
function! ale#util#FindNearestFile(buffer, filename)
|
|
||||||
return findfile(a:filename, fnamemodify(bufname(a:buffer), ':p') . ';')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" A null file for sending output to nothing.
|
" A null file for sending output to nothing.
|
||||||
let g:ale#util#nul_file = '/dev/null'
|
let g:ale#util#nul_file = '/dev/null'
|
||||||
|
|
||||||
if has('win32')
|
if has('win32')
|
||||||
let g:ale#util#nul_file = 'nul'
|
let g:ale#util#nul_file = 'nul'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" Return the number of lines for a given buffer.
|
||||||
|
function! ale#util#GetLineCount(buffer) abort
|
||||||
|
return len(getbufline(a:buffer, 1, '$'))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Given a buffer and a filename, find the nearest file by searching upwards
|
||||||
|
" through the paths relative to the given buffer.
|
||||||
|
function! ale#util#FindNearestFile(buffer, filename) abort
|
||||||
|
return findfile(a:filename, fnamemodify(bufname(a:buffer), ':p') . ';')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#util#GetFunction(string_or_ref) abort
|
||||||
|
if type(a:string_or_ref) == type('')
|
||||||
|
return function(a:string_or_ref)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return a:string_or_ref
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#util#LocItemCompare(left, right) abort
|
||||||
|
if a:left['lnum'] < a:right['lnum']
|
||||||
|
return -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:left['lnum'] > a:right['lnum']
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:left['col'] < a:right['col']
|
||||||
|
return -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:left['col'] > a:right['col']
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
35
doc/ale.txt
35
doc/ale.txt
@ -289,11 +289,30 @@ g:ale_statusline_format *g:ale_statusline_format*
|
|||||||
Type: |List|
|
Type: |List|
|
||||||
Default: `['%d error(s)', '%d warning(s)', 'OK']`
|
Default: `['%d error(s)', '%d warning(s)', 'OK']`
|
||||||
|
|
||||||
This variable defines the format of |`ALEGetStatusLine()`| output.
|
This variable defines the format of |`ale#statusline#status()`| output.
|
||||||
- The 1st element is for errors
|
- The 1st element is for errors
|
||||||
- The 2nd element is for warnings
|
- The 2nd element is for warnings
|
||||||
- The 3rd element is for when no errors are detected
|
- The 3rd element is for when no errors are detected
|
||||||
|
|
||||||
|
g:airline#extensions#ale#enabled *g:airline#extensions#ale#enabled*
|
||||||
|
|
||||||
|
Type: |Number|
|
||||||
|
Default: `1`
|
||||||
|
|
||||||
|
Enables or disables the |airline|'s native extension for ale, which displays
|
||||||
|
warnings and errors in the status line, prefixed by
|
||||||
|
|airline#extensions#ale#error_symbol| and
|
||||||
|
|airline#extensions#ale#warning_symbol|.
|
||||||
|
|
||||||
|
g:airline#extensions#ale#enabled *g:airline#extensions#ale#enabled*
|
||||||
|
|
||||||
|
Type: |Number|
|
||||||
|
Default: `1`
|
||||||
|
|
||||||
|
Enables or disables the |airline|'s native extension for ale, which displays
|
||||||
|
warnings and errors in the status line, prefixed by
|
||||||
|
|airline#extensions#ale#error_symbol| and
|
||||||
|
|airline#extensions#ale#warning_symbol|.
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
4. Linter Specific Options *ale-linter-options*
|
4. Linter Specific Options *ale-linter-options*
|
||||||
@ -413,14 +432,14 @@ g:ale_javascript_jshint_executable *g:ale_javascript_jshint_executable*
|
|||||||
===============================================================================
|
===============================================================================
|
||||||
5. API *ale-api*
|
5. API *ale-api*
|
||||||
|
|
||||||
ALELint(delay) *ALELint()*
|
ale#Queue(delay) *ale#Queue()*
|
||||||
Run linters for the current buffer, based on the filetype of the buffer,
|
Run linters for the current buffer, based on the filetype of the buffer,
|
||||||
with a given `delay`. A `delay` of `0` will run the linters immediately.
|
with a given `delay`. A `delay` of `0` will run the linters immediately.
|
||||||
The linters will always be run in the background. Calling this function
|
The linters will always be run in the background. Calling this function
|
||||||
again from the same buffer
|
again from the same buffer
|
||||||
|
|
||||||
|
|
||||||
ALEAddLinter(filetype, linter) *ALEAddLinter()*
|
ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
||||||
Given a |String| for a filetype and a |Dictionary| Describing a linter
|
Given a |String| for a filetype and a |Dictionary| Describing a linter
|
||||||
configuration, add a linter for the given filetype. The dictionaries each
|
configuration, add a linter for the given filetype. The dictionaries each
|
||||||
offer the following options:
|
offer the following options:
|
||||||
@ -492,21 +511,21 @@ ALEAddLinter(filetype, linter) *ALEAddLinter()*
|
|||||||
'command': g:ale#util#stdin_wrapper . ' .hs ghc -fno-code -v0',
|
'command': g:ale#util#stdin_wrapper . ' .hs ghc -fno-code -v0',
|
||||||
<
|
<
|
||||||
|
|
||||||
ALEGetLinters(filetype) *ALEGetLinters()*
|
ale#linter#Get(filetype) *ale#linter#Get()*
|
||||||
Return all of linters configured for a given filetype as a |List| of
|
Return all of linters configured for a given filetype as a |List| of
|
||||||
|Dictionary| values in the format specified by |ALEAddLinter()|.
|
|Dictionary| values in the format specified by |ale#linter#Define()|.
|
||||||
|
|
||||||
|
|
||||||
ALEGetStatusLine() *ALEGetStatusLine()*
|
ale#statusline#Status() *ale#statusline#Status()*
|
||||||
Return a formatted string that can be added to the statusline.
|
Return a formatted string that can be added to the statusline.
|
||||||
The output's format is defined in |`g:ale_statusline_format`|.
|
The output's format is defined in |`g:ale_statusline_format`|.
|
||||||
To enable it, the following should be present in your |statusline| settings: >
|
To enable it, the following should be present in your |statusline| settings: >
|
||||||
%{ALEGetStatusLine()}
|
%{ale#statusline#status()}
|
||||||
|
|
||||||
|
|
||||||
g:ale#util#stdin_wrapper *g:ale#util#stdin_wrapper*
|
g:ale#util#stdin_wrapper *g:ale#util#stdin_wrapper*
|
||||||
This variable names a wrapper script for sending stdin input to programs
|
This variable names a wrapper script for sending stdin input to programs
|
||||||
which cannot accept input via stdin. See |ALEAddLinter| for more.
|
which cannot accept input via stdin. See |ale#linter#Define()| for more.
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
" Description: This file sets up configuration settings for the ALE plugin.
|
" Description: Main entry point for the plugin: sets up prefs and autocommands
|
||||||
" Flags can be set in vimrc files and so on to disable particular features
|
" Preferences can be set in vimrc files and so on to configure ale
|
||||||
|
|
||||||
if exists('g:loaded_ale_flags')
|
if exists('g:loaded_ale')
|
||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
|
let g:loaded_ale = 1
|
||||||
let g:loaded_ale_flags = 1
|
|
||||||
|
|
||||||
" A flag for detecting if the required features are set.
|
" A flag for detecting if the required features are set.
|
||||||
if has('nvim')
|
if has('nvim')
|
||||||
@ -15,6 +14,15 @@ else
|
|||||||
let g:ale_has_required_features = has('timers') && has('job') && has('channel')
|
let g:ale_has_required_features = has('timers') && has('job') && has('channel')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if !g:ale_has_required_features
|
||||||
|
echoerr 'ALE requires NeoVim >= 0.1.5 or Vim 8 with +timers +job +channel'
|
||||||
|
echoerr 'Please update your editor appropriately.'
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
" This list configures which linters are enabled for which languages.
|
||||||
|
let g:ale_linters = get(g:, 'ale_linters', {})
|
||||||
|
|
||||||
" This flag can be set to 0 to disable linting when text is changed.
|
" This flag can be set to 0 to disable linting when text is changed.
|
||||||
let g:ale_lint_on_text_changed = get(g:, 'ale_lint_on_text_changed', 1)
|
let g:ale_lint_on_text_changed = get(g:, 'ale_lint_on_text_changed', 1)
|
||||||
|
|
||||||
@ -64,3 +72,43 @@ let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%s')
|
|||||||
" Strings used for severity in the echoed message
|
" 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_error_str = get(g:, 'ale_echo_msg_error_str', 'Error')
|
||||||
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
|
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
|
||||||
|
|
||||||
|
if g:ale_lint_on_text_changed
|
||||||
|
augroup ALERunOnTextChangedGroup
|
||||||
|
autocmd!
|
||||||
|
autocmd TextChanged,TextChangedI * call ale#Queue(g:ale_lint_delay)
|
||||||
|
augroup END
|
||||||
|
endif
|
||||||
|
|
||||||
|
if g:ale_lint_on_enter
|
||||||
|
augroup ALERunOnEnterGroup
|
||||||
|
autocmd!
|
||||||
|
autocmd BufEnter,BufRead * call ale#Queue(100)
|
||||||
|
augroup END
|
||||||
|
endif
|
||||||
|
|
||||||
|
if g:ale_lint_on_save
|
||||||
|
augroup ALERunOnSaveGroup
|
||||||
|
autocmd!
|
||||||
|
autocmd BufWrite * call ale#Queue(0)
|
||||||
|
augroup END
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Clean up buffers automatically when they are unloaded.
|
||||||
|
augroup ALEBufferCleanup
|
||||||
|
autocmd!
|
||||||
|
autocmd BufUnload * call ale#cleanup#Buffer('<abuf>')
|
||||||
|
augroup END
|
||||||
|
|
||||||
|
" Globals which each part of the plugin should use.
|
||||||
|
let g:ale_buffer_loclist_map = {}
|
||||||
|
let g:ale_buffer_should_reset_map = {}
|
||||||
|
let g:ale_buffer_sign_dummy_map = {}
|
||||||
|
|
||||||
|
" Backwards compatibility
|
||||||
|
function! ALELint(delay)
|
||||||
|
call ale#Queue(a:delay)
|
||||||
|
endfunction
|
||||||
|
function! ALEGetStatusLine()
|
||||||
|
call ale#statusline#Status()
|
||||||
|
endfunction
|
Loading…
Reference in New Issue
Block a user