From 2f164fee9b1322a425844fce328b9444a99876e3 Mon Sep 17 00:00:00 2001 From: Amir Salihefendic Date: Wed, 4 Jul 2018 12:53:25 +0200 Subject: [PATCH] Updated plugins --- .../cloudformation/cfn_python_lint.vim | 35 ++ .../ale/ale_linters/elixir/mix.vim | 61 +++ .../ale/ale_linters/html/tidy.vim | 13 +- .../ale/ale_linters/javascript/tsserver.vim | 26 ++ .../ale/ale_linters/pyrex/cython.vim | 41 +- .../ale/ale_linters/python/flake8.vim | 13 +- .../ale/ale_linters/python/prospector.vim | 4 + .../ale/ale_linters/python/pyre.vim | 29 ++ .../ale/ale_linters/ruby/reek.vim | 58 ++- .../ale/ale_linters/rust/cargo.vim | 15 +- .../ale/ale_linters/sh/language_server.vim | 33 ++ .../ale/ale_linters/yaml/yamllint.vim | 32 +- sources_non_forked/ale/autoload/ale.vim | 86 ++-- .../ale/autoload/ale/autocmd.vim | 77 ---- .../ale/autoload/ale/balloon.vim | 6 +- .../ale/autoload/ale/completion.vim | 13 +- .../ale/autoload/ale/cursor.vim | 4 - .../ale/autoload/ale/debugging.vim | 5 + .../ale/autoload/ale/definition.vim | 7 +- .../ale/autoload/ale/engine.vim | 146 +------ .../ale/autoload/ale/engine/ignore.vim | 46 ++ .../ale/autoload/ale/events.vim | 68 ++- sources_non_forked/ale/autoload/ale/fix.vim | 32 +- .../ale/autoload/ale/fix/registry.vim | 24 +- .../ale/autoload/ale/fixers/dartfmt.vim | 18 + .../ale/autoload/ale/fixers/prettier.vim | 20 +- .../ale/autoload/ale/fixers/tidy.vim | 26 ++ sources_non_forked/ale/autoload/ale/hover.vim | 8 +- sources_non_forked/ale/autoload/ale/job.vim | 27 +- .../ale/autoload/ale/linter.vim | 79 +--- sources_non_forked/ale/autoload/ale/lsp.vim | 114 +++-- .../ale/autoload/ale/lsp/reset.vim | 4 +- .../ale/autoload/ale/lsp_linter.vim | 252 +++++++++++ .../ale/autoload/ale/preview.vim | 27 +- .../ale/autoload/ale/references.vim | 7 +- .../ale/autoload/ale/socket.vim | 144 +++++++ .../ale/autoload/ale/statusline.vim | 52 --- .../ale/autoload/ale/toggle.vim | 2 +- sources_non_forked/ale/autoload/ale/util.vim | 51 ++- .../ale/doc/ale-cloudformation.txt | 14 + sources_non_forked/ale/doc/ale-dart.txt | 33 ++ .../ale/doc/ale-development.txt | 223 ++++++++++ sources_non_forked/ale/doc/ale-html.txt | 8 + sources_non_forked/ale/doc/ale-pyrex.txt | 25 ++ sources_non_forked/ale/doc/ale-python.txt | 24 ++ sources_non_forked/ale/doc/ale-rust.txt | 9 + sources_non_forked/ale/doc/ale-sh.txt | 19 + sources_non_forked/ale/doc/ale.txt | 88 +++- sources_non_forked/ale/plugin/ale.vim | 32 +- .../ctrlp.vim/autoload/ctrlp.vim | 16 +- .../lightline.vim/autoload/lightline.vim | 8 +- .../lightline.vim/plugin/lightline.vim | 8 +- .../nerdtree/nerdtree_plugin/fs_menu.vim | 7 +- sources_non_forked/nginx.vim/syntax/nginx.vim | 1 + .../vim-fugitive/autoload/fugitive.vim | 397 +++++++++++++----- .../vim-fugitive/doc/fugitive.txt | 12 +- .../vim-fugitive/ftdetect/fugitive.vim | 1 + .../vim-fugitive/plugin/fugitive.vim | 26 +- .../vim-gitgutter/autoload/gitgutter/diff.vim | 4 + sources_non_forked/vim-go/CHANGELOG.md | 21 + sources_non_forked/vim-go/autoload/go/cmd.vim | 22 +- .../vim-go/autoload/go/iferr.vim | 16 + .../vim-go/autoload/go/tool.vim | 10 +- sources_non_forked/vim-go/doc/vim-go.txt | 27 +- .../vim-go/ftplugin/go/commands.vim | 3 + .../vim-go/ftplugin/go/mappings.vim | 2 + sources_non_forked/vim-go/plugin/go.vim | 1 + sources_non_forked/vim-repeat/README.markdown | 27 +- .../vim-snippets/snippets/vim.snippets | 14 +- .../vim-surround/plugin/surround.vim | 2 +- 70 files changed, 2044 insertions(+), 761 deletions(-) create mode 100644 sources_non_forked/ale/ale_linters/cloudformation/cfn_python_lint.vim create mode 100644 sources_non_forked/ale/ale_linters/elixir/mix.vim create mode 100644 sources_non_forked/ale/ale_linters/javascript/tsserver.vim create mode 100644 sources_non_forked/ale/ale_linters/python/pyre.vim create mode 100644 sources_non_forked/ale/ale_linters/sh/language_server.vim delete mode 100644 sources_non_forked/ale/autoload/ale/autocmd.vim create mode 100644 sources_non_forked/ale/autoload/ale/engine/ignore.vim create mode 100644 sources_non_forked/ale/autoload/ale/fixers/dartfmt.vim create mode 100644 sources_non_forked/ale/autoload/ale/fixers/tidy.vim create mode 100644 sources_non_forked/ale/autoload/ale/lsp_linter.vim create mode 100644 sources_non_forked/ale/autoload/ale/socket.vim create mode 100644 sources_non_forked/ale/doc/ale-cloudformation.txt create mode 100644 sources_non_forked/ale/doc/ale-development.txt create mode 100644 sources_non_forked/ale/doc/ale-pyrex.txt create mode 100644 sources_non_forked/vim-fugitive/ftdetect/fugitive.vim create mode 100644 sources_non_forked/vim-go/autoload/go/iferr.vim diff --git a/sources_non_forked/ale/ale_linters/cloudformation/cfn_python_lint.vim b/sources_non_forked/ale/ale_linters/cloudformation/cfn_python_lint.vim new file mode 100644 index 00000000..d0ac7b28 --- /dev/null +++ b/sources_non_forked/ale/ale_linters/cloudformation/cfn_python_lint.vim @@ -0,0 +1,35 @@ +" Author: Yasuhiro Kiyota +" Description: Support cfn-python-lint for AWS Cloudformation template file + +function! ale_linters#cloudformation#cfn_python_lint#Handle(buffer, lines) abort + " Matches patterns line the following: + " + " sample.template.yaml:96:7:96:15:E3012:Property Resources/Sample/Properties/FromPort should be of type Integer + let l:pattern = '\v^(.*):(\d+):(\d+):(\d+):(\d+):([[:alnum:]]+):(.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:code = l:match[6] + + if ale#path#IsBufferPath(a:buffer, l:match[1]) + call add(l:output, { + \ 'lnum': l:match[2], + \ 'col': l:match[3], + \ 'end_lnum': l:match[4], + \ 'end_col': l:match[5], + \ 'code': l:code, + \ 'type': l:code[:0] is# 'E' ? 'E' : 'W', + \ 'text': l:match[7] + \}) + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('cloudformation', { +\ 'name': 'cloudformation', +\ 'executable': 'cfn-lint', +\ 'command': 'cfn-lint --template %t --format parseable', +\ 'callback': 'ale_linters#cloudformation#cfn_python_lint#Handle', +\}) diff --git a/sources_non_forked/ale/ale_linters/elixir/mix.vim b/sources_non_forked/ale/ale_linters/elixir/mix.vim new file mode 100644 index 00000000..1a95e37f --- /dev/null +++ b/sources_non_forked/ale/ale_linters/elixir/mix.vim @@ -0,0 +1,61 @@ +" Author: evnu - https://github.com/evnu +" Author: colbydehart - https://github.com/colbydehart +" Description: Mix compile checking for Elixir files + +function! ale_linters#elixir#mix#Handle(buffer, lines) abort + " Matches patterns like the following: + " + " Error format + " ** (CompileError) apps/sim/lib/sim/server.ex:87: undefined function update_in/4 + " + " TODO: Warning format + " warning: variable "foobar" does not exist and is being expanded to "foobar()", please use parentheses to remove the ambiguity or change the variable name + + let l:pattern = '\v\(([^\)]+Error)\) ([^:]+):([^:]+): (.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:type = 'E' + let l:text = l:match[4] + + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': l:match[3] + 0, + \ 'col': 0, + \ 'type': l:type, + \ 'text': l:text, + \}) + endfor + + return l:output +endfunction + +function! ale_linters#elixir#mix#FindProjectRoot(buffer) abort + let l:mix_file = ale#path#FindNearestFile(a:buffer, 'mix.exs') + if !empty(l:mix_file) + return fnamemodify(l:mix_file, ':p:h') + endif + return '.' +endfunction + +function! ale_linters#elixir#mix#GetCommand(buffer) abort + let l:project_root = ale_linters#elixir#mix#FindProjectRoot(a:buffer) + + let l:temp_dir = ale#engine#CreateDirectory(a:buffer) + + let l:mix_build_path = has('win32') + \ ? 'set MIX_BUILD_PATH=' . ale#Escape(l:temp_dir) . ' &&' + \ : 'MIX_BUILD_PATH=' . ale#Escape(l:temp_dir) + + return ale#path#CdString(l:project_root) + \ . l:mix_build_path + \ . ' mix compile %s' +endfunction + +call ale#linter#Define('elixir', { +\ 'name': 'mix', +\ 'executable': 'mix', +\ 'command_callback': 'ale_linters#elixir#mix#GetCommand', +\ 'callback': 'ale_linters#elixir#mix#Handle', +\ 'lint_file': 1, +\}) diff --git a/sources_non_forked/ale/ale_linters/html/tidy.vim b/sources_non_forked/ale/ale_linters/html/tidy.vim index 3af64d74..913cdade 100644 --- a/sources_non_forked/ale/ale_linters/html/tidy.vim +++ b/sources_non_forked/ale/ale_linters/html/tidy.vim @@ -1,21 +1,10 @@ " Author: KabbAmine " Description: This file adds support for checking HTML code with tidy. -" CLI options let g:ale_html_tidy_executable = get(g:, 'ale_html_tidy_executable', 'tidy') -" remove in 2.0 -" Look for the old _args variable first. -let s:deprecation_warning_echoed = 0 -let s:default_options = get(g:, 'ale_html_tidy_args', '-q -e -language en') -let g:ale_html_tidy_options = get(g:, 'ale_html_tidy_options', s:default_options) +let g:ale_html_tidy_options = get(g:, 'ale_html_tidy_options', '-q -e -language en') function! ale_linters#html#tidy#GetCommand(buffer) abort - " remove in 2.0 - if exists('g:ale_html_tidy_args') && !s:deprecation_warning_echoed - execute 'echom ''Rename your g:ale_html_tidy_args setting to g:ale_html_tidy_options instead. Support for this will removed in ALE 2.0.''' - let s:deprecation_warning_echoed = 1 - endif - " Specify file encoding in options " (Idea taken from https://github.com/scrooloose/syntastic/blob/master/syntax_checkers/html/tidy.vim) let l:file_encoding = get({ diff --git a/sources_non_forked/ale/ale_linters/javascript/tsserver.vim b/sources_non_forked/ale/ale_linters/javascript/tsserver.vim new file mode 100644 index 00000000..62dded10 --- /dev/null +++ b/sources_non_forked/ale/ale_linters/javascript/tsserver.vim @@ -0,0 +1,26 @@ +" Author: Chaucerbao, w0rp +" Description: tsserver integration for ALE + +call ale#Set('javascript_tsserver_executable', 'tsserver') +call ale#Set('javascript_tsserver_config_path', '') +call ale#Set('javascript_tsserver_use_global', get(g:, 'ale_use_global_executables', 0)) + +" These functions need to be defined just to comply with the API for LSP. +function! ale_linters#javascript#tsserver#GetProjectRoot(buffer) abort + return '' +endfunction + +function! ale_linters#javascript#tsserver#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'javascript_tsserver', [ + \ 'node_modules/.bin/tsserver', + \]) +endfunction + +call ale#linter#Define('javascript', { +\ 'name': 'tsserver', +\ 'lsp': 'tsserver', +\ 'executable_callback': 'ale_linters#javascript#tsserver#GetExecutable', +\ 'command_callback': 'ale_linters#javascript#tsserver#GetExecutable', +\ 'project_root_callback': 'ale_linters#javascript#tsserver#GetProjectRoot', +\ 'language': '', +\}) diff --git a/sources_non_forked/ale/ale_linters/pyrex/cython.vim b/sources_non_forked/ale/ale_linters/pyrex/cython.vim index bd5a447f..9b6b39d7 100644 --- a/sources_non_forked/ale/ale_linters/pyrex/cython.vim +++ b/sources_non_forked/ale/ale_linters/pyrex/cython.vim @@ -1,10 +1,43 @@ -" Author: w0rp +" Author: w0rp , +" Nicolas Pauss " Description: cython syntax checking for cython files. +call ale#Set('pyrex_cython_executable', 'cython') +call ale#Set('pyrex_cython_options', '--warning-extra') + +function! ale_linters#pyrex#cython#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'pyrex_cython_executable') +endfunction + +function! ale_linters#pyrex#cython#GetCommand(buffer) abort + let l:local_dir = ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) + + return ale#Escape(ale_linters#pyrex#cython#GetExecutable(a:buffer)) + \ . ' --working ' . l:local_dir . ' --include-dir ' . l:local_dir + \ . ' ' . ale#Var(a:buffer, 'pyrex_cython_options') + \ . ' --output-file ' . g:ale#util#nul_file . ' %t' +endfunction + +function! ale_linters#pyrex#cython#Handle(buffer, lines) abort + let l:pattern = '\v^(\w+: )?[^:]+:(\d+):?(\d+)?:? ?(.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 0, + \ 'text': l:match[4], + \ 'type': l:match[1][0] is# 'w' ? 'W' : 'E', + \}) + endfor + + return l:output +endfunction + call ale#linter#Define('pyrex', { \ 'name': 'cython', \ 'output_stream': 'stderr', -\ 'executable': 'cython', -\ 'command': 'cython --warning-extra -o ' . g:ale#util#nul_file . ' %t', -\ 'callback': 'ale#handlers#unix#HandleAsError', +\ 'executable_callback': 'ale_linters#pyrex#cython#GetExecutable', +\ 'command_callback': 'ale_linters#pyrex#cython#GetCommand', +\ 'callback': 'ale_linters#pyrex#cython#Handle', \}) diff --git a/sources_non_forked/ale/ale_linters/python/flake8.vim b/sources_non_forked/ale/ale_linters/python/flake8.vim index fdc4ac94..358f51a4 100644 --- a/sources_non_forked/ale/ale_linters/python/flake8.vim +++ b/sources_non_forked/ale/ale_linters/python/flake8.vim @@ -1,13 +1,8 @@ " Author: w0rp " Description: flake8 for python files -" remove in 2.0 -" Support an old setting as a fallback. -let s:deprecation_warning_echoed = 0 -let s:default_options = get(g:, 'ale_python_flake8_args', '') - call ale#Set('python_flake8_executable', 'flake8') -call ale#Set('python_flake8_options', s:default_options) +call ale#Set('python_flake8_options', '') call ale#Set('python_flake8_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_flake8_change_directory', 1) @@ -40,12 +35,6 @@ function! ale_linters#python#flake8#VersionCheck(buffer) abort endfunction function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort - " remove in 2.0 - if exists('g:ale_python_flake8_args') && !s:deprecation_warning_echoed - execute 'echom ''Rename your g:ale_python_flake8_args setting to g:ale_python_flake8_options instead. Support for this will removed in ALE 2.0.''' - let s:deprecation_warning_echoed = 1 - endif - let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory') \ ? ale#path#BufferCdString(a:buffer) \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/prospector.vim b/sources_non_forked/ale/ale_linters/python/prospector.vim index eadfee47..fff37147 100644 --- a/sources_non_forked/ale/ale_linters/python/prospector.vim +++ b/sources_non_forked/ale/ale_linters/python/prospector.vim @@ -30,6 +30,10 @@ endfunction function! ale_linters#python#prospector#Handle(buffer, lines) abort let l:output = [] + if empty(a:lines) + return [] + endif + let l:prospector_error = json_decode(join(a:lines, '')) for l:error in l:prospector_error.messages diff --git a/sources_non_forked/ale/ale_linters/python/pyre.vim b/sources_non_forked/ale/ale_linters/python/pyre.vim new file mode 100644 index 00000000..13f77d68 --- /dev/null +++ b/sources_non_forked/ale/ale_linters/python/pyre.vim @@ -0,0 +1,29 @@ +" Author: dsifford +" Description: A performant type-checker supporting LSP for Python 3 created by Facebook + +call ale#Set('python_pyre_executable', 'pyre') +call ale#Set('python_pyre_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#python#pyre#GetExecutable(buffer) abort + return ale#python#FindExecutable(a:buffer, 'python_pyre', ['pyre']) +endfunction + +function! ale_linters#python#pyre#GetCommand(buffer) abort + let l:executable = ale_linters#python#pyre#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv$' + \ ? ' run pyre persistent' + \ : ' persistent' + + return ale#Escape(l:executable) . l:exec_args +endfunction + +call ale#linter#Define('python', { +\ 'name': 'pyre', +\ 'lsp': 'stdio', +\ 'executable_callback': 'ale_linters#python#pyre#GetExecutable', +\ 'command_callback': 'ale_linters#python#pyre#GetCommand', +\ 'language': 'python', +\ 'project_root_callback': 'ale#python#FindProjectRoot', +\ 'completion_filter': 'ale#completion#python#CompletionItemFilter', +\}) diff --git a/sources_non_forked/ale/ale_linters/ruby/reek.vim b/sources_non_forked/ale/ale_linters/ruby/reek.vim index a11b9cf8..aa5d8d70 100644 --- a/sources_non_forked/ale/ale_linters/ruby/reek.vim +++ b/sources_non_forked/ale/ale_linters/ruby/reek.vim @@ -4,21 +4,27 @@ call ale#Set('ruby_reek_show_context', 0) call ale#Set('ruby_reek_show_wiki_link', 0) -function! ale_linters#ruby#reek#Handle(buffer, lines) abort - let l:output = [] +function! ale_linters#ruby#reek#VersionCheck(buffer) abort + " If we have previously stored the version number in a cache, then + " don't look it up again. + if ale#semver#HasVersion('reek') + " Returning an empty string skips this command. + return '' + endif - for l:error in ale#util#FuzzyJSONDecode(a:lines, []) - for l:location in l:error.lines - call add(l:output, { - \ 'lnum': l:location, - \ 'type': 'W', - \ 'text': s:BuildText(a:buffer, l:error), - \ 'code': l:error.smell_type, - \}) - endfor - endfor + return 'reek --version' +endfunction - return l:output +function! ale_linters#ruby#reek#GetCommand(buffer, version_output) abort + let l:version = ale#semver#GetVersion('reek', a:version_output) + + " Tell reek what the filename is if the version of reek is new enough. + let l:display_name_args = ale#semver#GTE(l:version, [5, 0, 0]) + \ ? ' --stdin-filename %s' + \ : '' + + return 'reek -f json --no-progress --no-color' + \ . l:display_name_args endfunction function! s:BuildText(buffer, error) abort @@ -37,9 +43,29 @@ function! s:BuildText(buffer, error) abort return join(l:parts, ' ') endfunction +function! ale_linters#ruby#reek#Handle(buffer, lines) abort + let l:output = [] + + for l:error in ale#util#FuzzyJSONDecode(a:lines, []) + for l:location in l:error.lines + call add(l:output, { + \ 'lnum': l:location, + \ 'type': 'W', + \ 'text': s:BuildText(a:buffer, l:error), + \ 'code': l:error.smell_type, + \}) + endfor + endfor + + return l:output +endfunction + call ale#linter#Define('ruby', { -\ 'name': 'reek', -\ 'executable': 'reek', -\ 'command': 'reek -f json --no-progress --no-color', +\ 'name': 'reek', +\ 'executable': 'reek', +\ 'command_chain': [ +\ {'callback': 'ale_linters#ruby#reek#VersionCheck'}, +\ {'callback': 'ale_linters#ruby#reek#GetCommand'}, +\ ], \ 'callback': 'ale_linters#ruby#reek#Handle', \}) diff --git a/sources_non_forked/ale/ale_linters/rust/cargo.vim b/sources_non_forked/ale/ale_linters/rust/cargo.vim index ef0c3bd1..e6c3870a 100644 --- a/sources_non_forked/ale/ale_linters/rust/cargo.vim +++ b/sources_non_forked/ale/ale_linters/rust/cargo.vim @@ -6,6 +6,7 @@ call ale#Set('rust_cargo_use_check', 1) call ale#Set('rust_cargo_check_all_targets', 0) call ale#Set('rust_cargo_check_examples', 0) call ale#Set('rust_cargo_check_tests', 0) +call ale#Set('rust_cargo_avoid_whole_workspace', 1) call ale#Set('rust_cargo_default_feature_behavior', 'default') call ale#Set('rust_cargo_include_features', '') @@ -45,6 +46,18 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort let l:include_features = ' --features ' . ale#Escape(l:include_features) endif + let l:avoid_whole_workspace = ale#Var(a:buffer, 'rust_cargo_avoid_whole_workspace') + let l:nearest_cargo_prefix = '' + + if l:avoid_whole_workspace + let l:nearest_cargo = ale#path#FindNearestFile(a:buffer, 'Cargo.toml') + let l:nearest_cargo_dir = fnamemodify(l:nearest_cargo, ':h') + + if l:nearest_cargo_dir isnot# '.' + let l:nearest_cargo_prefix = 'cd '. ale#Escape(l:nearest_cargo_dir) .' && ' + endif + endif + let l:default_feature_behavior = ale#Var(a:buffer, 'rust_cargo_default_feature_behavior') if l:default_feature_behavior is# 'all' let l:include_features = '' @@ -55,7 +68,7 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort let l:default_feature = '' endif - return 'cargo ' + return l:nearest_cargo_prefix . 'cargo ' \ . (l:use_check ? 'check' : 'build') \ . (l:use_all_targets ? ' --all-targets' : '') \ . (l:use_examples ? ' --examples' : '') diff --git a/sources_non_forked/ale/ale_linters/sh/language_server.vim b/sources_non_forked/ale/ale_linters/sh/language_server.vim new file mode 100644 index 00000000..2f66e27b --- /dev/null +++ b/sources_non_forked/ale/ale_linters/sh/language_server.vim @@ -0,0 +1,33 @@ +" Author: Christian Höltje (https://docwhat.org/) +" Description: BASH Language server integration for ALE +scriptencoding utf-8 + +call ale#Set('sh_language_server_executable', 'bash-language-server') +call ale#Set('sh_language_server_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale_linters#sh#language_server#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'sh_language_server', [ + \ 'node_modules/.bin/bash-language-server', + \]) +endfunction + +function! ale_linters#sh#language_server#GetCommand(buffer) abort + let l:exe = ale#Escape(ale_linters#sh#language_server#GetExecutable(a:buffer)) + + return l:exe . ' start' +endfunction + +function! ale_linters#sh#language_server#GetProjectRoot(buffer) abort + let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git') + + return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : '' +endfunction + +call ale#linter#Define('sh', { +\ 'name': 'language_server', +\ 'lsp': 'stdio', +\ 'executable_callback': 'ale_linters#sh#language_server#GetExecutable', +\ 'command_callback': 'ale_linters#sh#language_server#GetCommand', +\ 'language': 'sh', +\ 'project_root_callback': 'ale_linters#sh#language_server#GetProjectRoot', +\}) diff --git a/sources_non_forked/ale/ale_linters/yaml/yamllint.vim b/sources_non_forked/ale/ale_linters/yaml/yamllint.vim index 731f8012..f100667e 100644 --- a/sources_non_forked/ale/ale_linters/yaml/yamllint.vim +++ b/sources_non_forked/ale/ale_linters/yaml/yamllint.vim @@ -20,21 +20,31 @@ function! ale_linters#yaml#yamllint#Handle(buffer, lines) abort " Matches patterns line the following: " something.yaml:1:1: [warning] missing document start "---" (document-start) " something.yml:2:1: [error] syntax error: expected the node content, but found '' - let l:pattern = '^.*:\(\d\+\):\(\d\+\): \[\(error\|warning\)\] \(.\+\)$' + let l:pattern = '\v^.*:(\d+):(\d+): \[(error|warning)\] (.+)$' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) - let l:line = l:match[1] + 0 - let l:col = l:match[2] + 0 - let l:type = l:match[3] - let l:text = l:match[4] + let l:item = { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 0, + \ 'text': l:match[4], + \ 'type': l:match[3] is# 'error' ? 'E' : 'W', + \} - call add(l:output, { - \ 'lnum': l:line, - \ 'col': l:col, - \ 'text': l:text, - \ 'type': l:type is# 'error' ? 'E' : 'W', - \}) + let l:code_match = matchlist(l:item.text, '\v^(.+) \(([^)]+)\)$') + + if !empty(l:code_match) + if l:code_match[2] is# 'trailing-spaces' + \&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + " Skip warnings for trailing whitespace if the option is off. + continue + endif + + let l:item.text = l:code_match[1] + let l:item.code = l:code_match[2] + endif + + call add(l:output, l:item) endfor return l:output diff --git a/sources_non_forked/ale/autoload/ale.vim b/sources_non_forked/ale/autoload/ale.vim index f31446cb..dcc12150 100644 --- a/sources_non_forked/ale/autoload/ale.vim +++ b/sources_non_forked/ale/autoload/ale.vim @@ -6,35 +6,12 @@ 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_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 s:lint_timer = -1 let s:queued_buffer_number = -1 let s:should_lint_file_for_buffer = {} -let s:error_delay_ms = 1000 * 60 * 2 - -let s:timestamp_map = {} - -" Given a key for a script variable for tracking the time to wait until -" a given function should be called, a funcref for a function to call, and -" a List of arguments, call the function and return whatever value it returns. -" -" If the function throws an exception, then the function will not be called -" for a while, and 0 will be returned instead. -function! ale#CallWithCooldown(timestamp_key, func, arglist) abort - let l:now = ale#util#ClockMilliseconds() - - if l:now < get(s:timestamp_map, a:timestamp_key, -1) - return 0 - endif - - let s:timestamp_map[a:timestamp_key] = l:now + s:error_delay_ms - - let l:return_value = call(a:func, a:arglist) - - let s:timestamp_map[a:timestamp_key] = -1 - - return l:return_value -endfunction " Return 1 if a file is too large for ALE to handle. function! ale#FileTooLarge(buffer) abort @@ -114,30 +91,22 @@ function! ale#Queue(delay, ...) abort let l:linting_flag = get(a:000, 0, '') let l:buffer = get(a:000, 1, bufnr('')) - return ale#CallWithCooldown( - \ 'dont_queue_until', - \ function('s:ALEQueueImpl'), - \ [a:delay, l:linting_flag, l:buffer], - \) -endfunction - -function! s:ALEQueueImpl(delay, linting_flag, buffer) abort - if a:linting_flag isnot# '' && a:linting_flag isnot# 'lint_file' + if l:linting_flag isnot# '' && l:linting_flag isnot# 'lint_file' throw "linting_flag must be either '' or 'lint_file'" endif - if type(a:buffer) != type(0) + if type(l:buffer) != type(0) throw 'buffer_number must be a Number' endif - if ale#ShouldDoNothing(a:buffer) + if ale#ShouldDoNothing(l:buffer) return endif " Remember that we want to check files for this buffer. " We will remember this until we finally run the linters, via any event. - if a:linting_flag is# 'lint_file' - let s:should_lint_file_for_buffer[a:buffer] = 1 + if l:linting_flag is# 'lint_file' + let s:should_lint_file_for_buffer[l:buffer] = 1 endif if s:lint_timer != -1 @@ -145,24 +114,24 @@ function! s:ALEQueueImpl(delay, linting_flag, buffer) abort let s:lint_timer = -1 endif - let l:linters = ale#linter#Get(getbufvar(a:buffer, '&filetype')) + let l:linters = ale#linter#Get(getbufvar(l:buffer, '&filetype')) " Don't set up buffer data and so on if there are no linters to run. if empty(l:linters) " If we have some previous buffer data, then stop any jobs currently " running and clear everything. - if has_key(g:ale_buffer_info, a:buffer) - call ale#engine#RunLinters(a:buffer, [], 1) + if has_key(g:ale_buffer_info, l:buffer) + call ale#engine#RunLinters(l:buffer, [], 1) endif return endif if a:delay > 0 - let s:queued_buffer_number = a:buffer + let s:queued_buffer_number = l:buffer let s:lint_timer = timer_start(a:delay, function('ale#Lint')) else - call ale#Lint(-1, a:buffer) + call ale#Lint(-1, l:buffer) endif endfunction @@ -178,30 +147,29 @@ function! ale#Lint(...) abort let l:buffer = bufnr('') endif - return ale#CallWithCooldown( - \ 'dont_lint_until', - \ function('s:ALELintImpl'), - \ [l:buffer], - \) -endfunction - -function! s:ALELintImpl(buffer) abort - if ale#ShouldDoNothing(a:buffer) + if ale#ShouldDoNothing(l:buffer) return endif " Use the filetype from the buffer - let l:linters = ale#linter#Get(getbufvar(a:buffer, '&filetype')) + let l:filetype = getbufvar(l:buffer, '&filetype') + let l:linters = ale#linter#Get(l:filetype) let l:should_lint_file = 0 " Check if we previously requested checking the file. - if has_key(s:should_lint_file_for_buffer, a:buffer) - unlet s:should_lint_file_for_buffer[a:buffer] + if has_key(s:should_lint_file_for_buffer, l:buffer) + unlet s:should_lint_file_for_buffer[l:buffer] " Lint files if they exist. - let l:should_lint_file = filereadable(expand('#' . a:buffer . ':p')) + let l:should_lint_file = filereadable(expand('#' . l:buffer . ':p')) endif - call ale#engine#RunLinters(a:buffer, l:linters, l:should_lint_file) + " Apply ignore lists for linters only if needed. + let l:ignore_config = ale#Var(l:buffer, 'linters_ignore') + let l:linters = !empty(l:ignore_config) + \ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config) + \ : l:linters + + call ale#engine#RunLinters(l:buffer, l:linters, l:should_lint_file) endfunction " Reset flags indicating that files should be checked for all buffers. @@ -209,10 +177,6 @@ function! ale#ResetLintFileMarkers() abort let s:should_lint_file_for_buffer = {} endfunction -function! ale#ResetErrorDelays() abort - let s:timestamp_map = {} -endfunction - let g:ale_has_override = get(g:, 'ale_has_override', {}) " Call has(), but check a global Dictionary so we can force flags on or off diff --git a/sources_non_forked/ale/autoload/ale/autocmd.vim b/sources_non_forked/ale/autoload/ale/autocmd.vim deleted file mode 100644 index 8570adaa..00000000 --- a/sources_non_forked/ale/autoload/ale/autocmd.vim +++ /dev/null @@ -1,77 +0,0 @@ -function! ale#autocmd#InitAuGroups() abort - " This value used to be a Boolean as a Number, and is now a String. - let l:text_changed = '' . g:ale_lint_on_text_changed - - augroup ALEPatternOptionsGroup - autocmd! - autocmd BufEnter,BufRead * call ale#pattern_options#SetOptions(str2nr(expand(''))) - augroup END - - augroup ALERunOnTextChangedGroup - autocmd! - if g:ale_enabled - if l:text_changed is? 'always' || l:text_changed is# '1' - autocmd TextChanged,TextChangedI * call ale#Queue(g:ale_lint_delay) - elseif l:text_changed is? 'normal' - autocmd TextChanged * call ale#Queue(g:ale_lint_delay) - elseif l:text_changed is? 'insert' - autocmd TextChangedI * call ale#Queue(g:ale_lint_delay) - endif - endif - augroup END - - augroup ALERunOnEnterGroup - autocmd! - if g:ale_enabled - " Handle everything that needs to happen when buffers are entered. - autocmd BufEnter * call ale#events#EnterEvent(str2nr(expand(''))) - endif - if g:ale_enabled && g:ale_lint_on_enter - autocmd BufWinEnter,BufRead * call ale#Queue(0, 'lint_file', str2nr(expand(''))) - " Track when the file is changed outside of Vim. - autocmd FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand(''))) - endif - augroup END - - augroup ALERunOnFiletypeChangeGroup - autocmd! - if g:ale_enabled && g:ale_lint_on_filetype_changed - " Only start linting if the FileType actually changes after - " opening a buffer. The FileType will fire when buffers are opened. - autocmd FileType * call ale#events#FileTypeEvent( - \ str2nr(expand('')), - \ expand('') - \) - endif - augroup END - - augroup ALERunOnSaveGroup - autocmd! - autocmd BufWritePost * call ale#events#SaveEvent(str2nr(expand(''))) - augroup END - - augroup ALERunOnInsertLeave - autocmd! - if g:ale_enabled && g:ale_lint_on_insert_leave - autocmd InsertLeave * call ale#Queue(0) - endif - augroup END - - augroup ALECursorGroup - autocmd! - if g:ale_enabled && g:ale_echo_cursor - autocmd CursorMoved,CursorHold * call ale#cursor#EchoCursorWarningWithDelay() - " Look for a warning to echo as soon as we leave Insert mode. - " The script's position variable used when moving the cursor will - " not be changed here. - autocmd InsertLeave * call ale#cursor#EchoCursorWarning() - endif - augroup END - - if !g:ale_enabled - augroup! ALERunOnTextChangedGroup - augroup! ALERunOnEnterGroup - augroup! ALERunOnInsertLeave - augroup! ALECursorGroup - endif -endfunction diff --git a/sources_non_forked/ale/autoload/ale/balloon.vim b/sources_non_forked/ale/autoload/ale/balloon.vim index d49dcbf9..7a380da2 100644 --- a/sources_non_forked/ale/autoload/ale/balloon.vim +++ b/sources_non_forked/ale/autoload/ale/balloon.vim @@ -34,7 +34,11 @@ function! ale#balloon#Expr() abort endfunction function! ale#balloon#Disable() abort - set noballooneval noballoonevalterm + if has('balloon_eval_term') + set noballoonevalterm + endif + + set noballooneval set balloonexpr= endfunction diff --git a/sources_non_forked/ale/autoload/ale/completion.vim b/sources_non_forked/ale/autoload/ale/completion.vim index d8c2b4e2..694cb655 100644 --- a/sources_non_forked/ale/autoload/ale/completion.vim +++ b/sources_non_forked/ale/autoload/ale/completion.vim @@ -134,7 +134,11 @@ function! s:ReplaceCompleteopt() abort let b:ale_old_completopt = &l:completeopt endif - let &l:completeopt = 'menu,menuone,preview,noselect,noinsert' + if &l:completeopt =~# 'preview' + let &l:completeopt = 'menu,menuone,preview,noselect,noinsert' + else + let &l:completeopt = 'menu,menuone,noselect,noinsert' + endif endfunction function! ale#completion#OmniFunc(findstart, base) abort @@ -389,14 +393,13 @@ function! s:GetLSPCompletions(linter) abort \ ? function('ale#completion#HandleTSServerResponse') \ : function('ale#completion#HandleLSPResponse') - let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback) + let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) if empty(l:lsp_details) return 0 endif let l:id = l:lsp_details.connection_id - let l:root = l:lsp_details.project_root if a:linter.lsp is# 'tsserver' let l:message = ale#lsp#tsserver_message#Completions( @@ -408,7 +411,7 @@ function! s:GetLSPCompletions(linter) abort else " Send a message saying the buffer has changed first, otherwise " completions won't know what text is nearby. - call ale#lsp#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root) + call ale#lsp#NotifyForChanges(l:lsp_details) " For LSP completions, we need to clamp the column to the length of " the line. python-language-server and perhaps others do not implement @@ -424,7 +427,7 @@ function! s:GetLSPCompletions(linter) abort \) endif - let l:request_id = ale#lsp#Send(l:id, l:message, l:root) + let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) if l:request_id let b:ale_completion_info.conn_id = l:id diff --git a/sources_non_forked/ale/autoload/ale/cursor.vim b/sources_non_forked/ale/autoload/ale/cursor.vim index e3dd4208..73dbebb2 100644 --- a/sources_non_forked/ale/autoload/ale/cursor.vim +++ b/sources_non_forked/ale/autoload/ale/cursor.vim @@ -56,10 +56,6 @@ function! s:StopCursorTimer() abort endfunction function! ale#cursor#EchoCursorWarning(...) abort - return ale#CallWithCooldown('dont_echo_until', function('s:EchoImpl'), []) -endfunction - -function! s:EchoImpl() abort if !g:ale_echo_cursor return endif diff --git a/sources_non_forked/ale/autoload/ale/debugging.vim b/sources_non_forked/ale/autoload/ale/debugging.vim index f32e4308..34c13770 100644 --- a/sources_non_forked/ale/autoload/ale/debugging.vim +++ b/sources_non_forked/ale/autoload/ale/debugging.vim @@ -214,10 +214,15 @@ function! ale#debugging#Info() abort " This must be done after linters are loaded. let l:variable_list = s:GetLinterVariables(l:filetype, l:enabled_names) + let l:fixers = ale#fix#registry#SuggestedFixers(l:filetype) + let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1])) + let l:fixers_string = join(map(copy(l:fixers), '"\n " . v:val'), '') + call s:Echo(' Current Filetype: ' . l:filetype) call s:Echo('Available Linters: ' . string(l:all_names)) call s:EchoLinterAliases(l:all_linters) call s:Echo(' Enabled Linters: ' . string(l:enabled_names)) + call s:Echo(' Suggested Fixers: ' . l:fixers_string) call s:Echo(' Linter Variables:') call s:Echo('') call s:EchoLinterVariables(l:variable_list) diff --git a/sources_non_forked/ale/autoload/ale/definition.vim b/sources_non_forked/ale/autoload/ale/definition.vim index a17eb2e7..6c70b64c 100644 --- a/sources_non_forked/ale/autoload/ale/definition.vim +++ b/sources_non_forked/ale/autoload/ale/definition.vim @@ -65,14 +65,13 @@ function! s:GoToLSPDefinition(linter, options) abort \ ? function('ale#definition#HandleTSServerResponse') \ : function('ale#definition#HandleLSPResponse') - let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback) + let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) if empty(l:lsp_details) return 0 endif let l:id = l:lsp_details.connection_id - let l:root = l:lsp_details.project_root if a:linter.lsp is# 'tsserver' let l:message = ale#lsp#tsserver_message#Definition( @@ -83,7 +82,7 @@ function! s:GoToLSPDefinition(linter, options) abort else " Send a message saying the buffer has changed first, or the " definition position probably won't make sense. - call ale#lsp#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root) + call ale#lsp#NotifyForChanges(l:lsp_details) let l:column = min([l:column, len(getline(l:line))]) @@ -93,7 +92,7 @@ function! s:GoToLSPDefinition(linter, options) abort let l:message = ale#lsp#message#Definition(l:buffer, l:line, l:column) endif - let l:request_id = ale#lsp#Send(l:id, l:message, l:root) + let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) let s:go_to_definition_map[l:request_id] = { \ 'open_in_tab': get(a:options, 'open_in_tab', 0), diff --git a/sources_non_forked/ale/autoload/ale/engine.vim b/sources_non_forked/ale/autoload/ale/engine.vim index 10589869..d97b6937 100644 --- a/sources_non_forked/ale/autoload/ale/engine.vim +++ b/sources_non_forked/ale/autoload/ale/engine.vim @@ -14,11 +14,6 @@ if !has_key(s:, 'job_info_map') let s:job_info_map = {} endif -" Associates LSP connection IDs with linter names. -if !has_key(s:, 'lsp_linter_map') - let s:lsp_linter_map = {} -endif - if !has_key(s:, 'executable_cache_map') let s:executable_cache_map = {} endif @@ -79,16 +74,6 @@ function! ale#engine#InitBufferInfo(buffer) abort return 0 endfunction -" Clear LSP linter data for the linting engine. -function! ale#engine#ClearLSPData() abort - let s:lsp_linter_map = {} -endfunction - -" Just for tests. -function! ale#engine#SetLSPLinterMap(replacement_map) abort - let s:lsp_linter_map = a:replacement_map -endfunction - " This function is documented and part of the public API. " " Return 1 if ALE is busy checking a given buffer @@ -241,88 +226,6 @@ function! s:HandleExit(job_id, exit_code) abort call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist) endfunction -function! s:HandleLSPDiagnostics(conn_id, response) abort - let l:linter_name = s:lsp_linter_map[a:conn_id] - let l:filename = ale#path#FromURI(a:response.params.uri) - let l:buffer = bufnr(l:filename) - - if l:buffer <= 0 - return - endif - - let l:loclist = ale#lsp#response#ReadDiagnostics(a:response) - - call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist) -endfunction - -function! s:HandleTSServerDiagnostics(response, error_type) abort - let l:buffer = bufnr(a:response.body.file) - let l:info = get(g:ale_buffer_info, l:buffer, {}) - - if empty(l:info) - return - endif - - let l:thislist = ale#lsp#response#ReadTSServerDiagnostics(a:response) - - " tsserver sends syntax and semantic errors in separate messages, so we - " have to collect the messages separately for each buffer and join them - " back together again. - if a:error_type is# 'syntax' - let l:info.syntax_loclist = l:thislist - else - let l:info.semantic_loclist = l:thislist - endif - - let l:loclist = get(l:info, 'semantic_loclist', []) - \ + get(l:info, 'syntax_loclist', []) - - call ale#engine#HandleLoclist('tsserver', l:buffer, l:loclist) -endfunction - -function! s:HandleLSPErrorMessage(linter_name, response) abort - if !g:ale_history_enabled || !g:ale_history_log_output - return - endif - - if empty(a:linter_name) - return - endif - - let l:message = ale#lsp#response#GetErrorMessage(a:response) - - if empty(l:message) - return - endif - - " This global variable is set here so we don't load the debugging.vim file - " until someone uses :ALEInfo. - let g:ale_lsp_error_messages = get(g:, 'ale_lsp_error_messages', {}) - - if !has_key(g:ale_lsp_error_messages, a:linter_name) - let g:ale_lsp_error_messages[a:linter_name] = [] - endif - - call add(g:ale_lsp_error_messages[a:linter_name], l:message) -endfunction - -function! ale#engine#HandleLSPResponse(conn_id, response) abort - let l:method = get(a:response, 'method', '') - let l:linter_name = get(s:lsp_linter_map, a:conn_id, '') - - if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error') - call s:HandleLSPErrorMessage(l:linter_name, a:response) - elseif l:method is# 'textDocument/publishDiagnostics' - call s:HandleLSPDiagnostics(a:conn_id, a:response) - elseif get(a:response, 'type', '') is# 'event' - \&& get(a:response, 'event', '') is# 'semanticDiag' - call s:HandleTSServerDiagnostics(a:response, 'semantic') - elseif get(a:response, 'type', '') is# 'event' - \&& get(a:response, 'event', '') is# 'syntaxDiag' - call s:HandleTSServerDiagnostics(a:response, 'syntax') - endif -endfunction - function! ale#engine#SetResults(buffer, loclist) abort let l:linting_is_done = !ale#engine#IsCheckingBuffer(a:buffer) @@ -367,9 +270,6 @@ function! ale#engine#SetResults(buffer, loclist) abort " Call user autocommands. This allows users to hook into ALE's lint cycle. silent doautocmd User ALELintPost - " remove in 2.0 - " Old DEPRECATED name; call it for backwards compatibility. - silent doautocmd User ALELint endif endfunction @@ -739,44 +639,6 @@ function! s:StopCurrentJobs(buffer, include_lint_file_jobs) abort let l:info.active_linter_list = l:new_active_linter_list endfunction -function! s:CheckWithLSP(buffer, linter) abort - let l:info = g:ale_buffer_info[a:buffer] - let l:lsp_details = ale#linter#StartLSP( - \ a:buffer, - \ a:linter, - \ function('ale#engine#HandleLSPResponse'), - \) - - if empty(l:lsp_details) - return 0 - endif - - let l:id = l:lsp_details.connection_id - let l:root = l:lsp_details.project_root - - " Remember the linter this connection is for. - let s:lsp_linter_map[l:id] = a:linter.name - - let l:change_message = a:linter.lsp is# 'tsserver' - \ ? ale#lsp#tsserver_message#Geterr(a:buffer) - \ : ale#lsp#message#DidChange(a:buffer) - let l:request_id = ale#lsp#Send(l:id, l:change_message, l:root) - - " If this was a file save event, also notify the server of that. - if a:linter.lsp isnot# 'tsserver' - \&& getbufvar(a:buffer, 'ale_save_event_fired', 0) - let l:save_message = ale#lsp#message#DidSave(a:buffer) - let l:request_id = ale#lsp#Send(l:id, l:save_message, l:root) - endif - - if l:request_id != 0 - if index(l:info.active_linter_list, a:linter.name) < 0 - call add(l:info.active_linter_list, a:linter.name) - endif - endif - - return l:request_id != 0 -endfunction function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort " Figure out which linters are still enabled, and remove @@ -832,7 +694,7 @@ endfunction " Returns 1 if the linter was successfully run. function! s:RunLinter(buffer, linter) abort if !empty(a:linter.lsp) - return s:CheckWithLSP(a:buffer, a:linter) + return ale#lsp_linter#CheckWithLSP(a:buffer, a:linter) else let l:executable = ale#linter#GetExecutable(a:buffer, a:linter) @@ -914,7 +776,7 @@ endfunction " The time taken will be a very rough approximation, and more time may be " permitted than is specified. function! ale#engine#WaitForJobs(deadline) abort - let l:start_time = ale#util#ClockMilliseconds() + let l:start_time = ale#events#ClockMilliseconds() if l:start_time == 0 throw 'Failed to read milliseconds from the clock!' @@ -945,7 +807,7 @@ function! ale#engine#WaitForJobs(deadline) abort for l:job_id in l:job_list if ale#job#IsRunning(l:job_id) - let l:now = ale#util#ClockMilliseconds() + let l:now = ale#events#ClockMilliseconds() if l:now - l:start_time > a:deadline " Stop waiting after a timeout, so we don't wait forever. @@ -982,7 +844,7 @@ function! ale#engine#WaitForJobs(deadline) abort if l:has_new_jobs " We have to wait more. Offset the timeout by the time taken so far. - let l:now = ale#util#ClockMilliseconds() + let l:now = ale#events#ClockMilliseconds() let l:new_deadline = a:deadline - (l:now - l:start_time) if l:new_deadline <= 0 diff --git a/sources_non_forked/ale/autoload/ale/engine/ignore.vim b/sources_non_forked/ale/autoload/ale/engine/ignore.vim new file mode 100644 index 00000000..65347e21 --- /dev/null +++ b/sources_non_forked/ale/autoload/ale/engine/ignore.vim @@ -0,0 +1,46 @@ +" Author: w0rp +" Description: Code for ignoring linters. Only loaded and if configured. + +" Given a filetype and a configuration for ignoring linters, return a List of +" Strings for linter names to ignore. +function! ale#engine#ignore#GetList(filetype, config) abort + if type(a:config) is type([]) + return a:config + endif + + if type(a:config) is type({}) + let l:names_to_remove = [] + + for l:part in split(a:filetype , '\.') + call extend(l:names_to_remove, get(a:config, l:part, [])) + endfor + + return l:names_to_remove + endif + + return [] +endfunction + +" Given a List of linter descriptions, exclude the linters to be ignored. +function! ale#engine#ignore#Exclude(filetype, all_linters, config) abort + let l:names_to_remove = ale#engine#ignore#GetList(a:filetype, a:config) + let l:filtered_linters = [] + + for l:linter in a:all_linters + let l:name_list = [l:linter.name] + l:linter.aliases + let l:should_include = 1 + + for l:name in l:name_list + if index(l:names_to_remove, l:name) >= 0 + let l:should_include = 0 + break + endif + endfor + + if l:should_include + call add(l:filtered_linters, l:linter) + endif + endfor + + return l:filtered_linters +endfunction diff --git a/sources_non_forked/ale/autoload/ale/events.vim b/sources_non_forked/ale/autoload/ale/events.vim index 3d2aa32d..4bc5cde1 100644 --- a/sources_non_forked/ale/autoload/ale/events.vim +++ b/sources_non_forked/ale/autoload/ale/events.vim @@ -1,14 +1,25 @@ " Author: w0rp +" Description: ALE functions for autocmd events. + +" Get the number of milliseconds since some vague, but consistent, point in +" the past. +" +" This function can be used for timing execution, etc. +" +" The time will be returned as a Number. +function! ale#events#ClockMilliseconds() abort + return float2nr(reltimefloat(reltime()) * 1000) +endfunction function! ale#events#QuitEvent(buffer) abort " Remember when ALE is quitting for BufWrite, etc. - call setbufvar(a:buffer, 'ale_quitting', ale#util#ClockMilliseconds()) + call setbufvar(a:buffer, 'ale_quitting', ale#events#ClockMilliseconds()) endfunction function! ale#events#QuitRecently(buffer) abort let l:time = getbufvar(a:buffer, 'ale_quitting', 0) - return l:time && ale#util#ClockMilliseconds() - l:time < 1000 + return l:time && ale#events#ClockMilliseconds() - l:time < 1000 endfunction function! ale#events#SaveEvent(buffer) abort @@ -67,3 +78,56 @@ function! ale#events#FileChangedEvent(buffer) abort call s:LintOnEnter(a:buffer) endif endfunction + +function! ale#events#Init() abort + " This value used to be a Boolean as a Number, and is now a String. + let l:text_changed = '' . g:ale_lint_on_text_changed + + augroup ALEEvents + autocmd! + + " These events always need to be set up. + autocmd BufEnter,BufRead * call ale#pattern_options#SetOptions(str2nr(expand(''))) + autocmd BufWritePost * call ale#events#SaveEvent(str2nr(expand(''))) + + if g:ale_enabled + if l:text_changed is? 'always' || l:text_changed is# '1' + autocmd TextChanged,TextChangedI * call ale#Queue(g:ale_lint_delay) + elseif l:text_changed is? 'normal' + autocmd TextChanged * call ale#Queue(g:ale_lint_delay) + elseif l:text_changed is? 'insert' + autocmd TextChangedI * call ale#Queue(g:ale_lint_delay) + endif + + " Handle everything that needs to happen when buffers are entered. + autocmd BufEnter * call ale#events#EnterEvent(str2nr(expand(''))) + + if g:ale_lint_on_enter + autocmd BufWinEnter,BufRead * call ale#Queue(0, 'lint_file', str2nr(expand(''))) + " Track when the file is changed outside of Vim. + autocmd FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand(''))) + endif + + if g:ale_lint_on_filetype_changed + " Only start linting if the FileType actually changes after + " opening a buffer. The FileType will fire when buffers are opened. + autocmd FileType * call ale#events#FileTypeEvent( + \ str2nr(expand('')), + \ expand('') + \) + endif + + if g:ale_lint_on_insert_leave + autocmd InsertLeave * call ale#Queue(0) + endif + + if g:ale_echo_cursor + autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarningWithDelay() | endif + " Look for a warning to echo as soon as we leave Insert mode. + " The script's position variable used when moving the cursor will + " not be changed here. + autocmd InsertLeave * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarning() | endif + endif + endif + augroup END +endfunction diff --git a/sources_non_forked/ale/autoload/ale/fix.vim b/sources_non_forked/ale/autoload/ale/fix.vim index 51df1458..1e056200 100644 --- a/sources_non_forked/ale/autoload/ale/fix.vim +++ b/sources_non_forked/ale/autoload/ale/fix.vim @@ -356,9 +356,21 @@ function! s:RunFixer(options) abort call ale#fix#ApplyFixes(l:buffer, l:input) endfunction -function! s:GetCallbacks(buffer, linters) abort - if len(a:linters) - let l:callback_list = a:linters +function! s:AddSubCallbacks(full_list, callbacks) abort + if type(a:callbacks) == type('') + call add(a:full_list, a:callbacks) + elseif type(a:callbacks) == type([]) + call extend(a:full_list, a:callbacks) + else + return 0 + endif + + return 1 +endfunction + +function! s:GetCallbacks(buffer, fixers) abort + if len(a:fixers) + let l:callback_list = a:fixers elseif type(get(b:, 'ale_fixers')) is type([]) " Lists can be used for buffer-local variables only let l:callback_list = b:ale_fixers @@ -367,16 +379,18 @@ function! s:GetCallbacks(buffer, linters) abort " callbacks to run. let l:fixers = ale#Var(a:buffer, 'fixers') let l:callback_list = [] + let l:matched = 0 for l:sub_type in split(&filetype, '\.') - let l:sub_type_callacks = get(l:fixers, l:sub_type, []) - - if type(l:sub_type_callacks) == type('') - call add(l:callback_list, l:sub_type_callacks) - else - call extend(l:callback_list, l:sub_type_callacks) + if s:AddSubCallbacks(l:callback_list, get(l:fixers, l:sub_type)) + let l:matched = 1 endif endfor + + " If we couldn't find fixers for a filetype, default to '*' fixers. + if !l:matched + call s:AddSubCallbacks(l:callback_list, get(l:fixers, '*')) + endif endif if empty(l:callback_list) diff --git a/sources_non_forked/ale/autoload/ale/fix/registry.vim b/sources_non_forked/ale/autoload/ale/fix/registry.vim index 7b55acfc..539234c0 100644 --- a/sources_non_forked/ale/autoload/ale/fix/registry.vim +++ b/sources_non_forked/ale/autoload/ale/fix/registry.vim @@ -22,6 +22,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['python'], \ 'description': 'Fix PEP8 issues with black.', \ }, +\ 'tidy': { +\ 'function': 'ale#fixers#tidy#Fix', +\ 'suggested_filetypes': ['html'], +\ 'description': 'Fix HTML files with tidy.', +\ }, \ 'prettier_standard': { \ 'function': 'ale#fixers#prettier_standard#Fix', \ 'suggested_filetypes': ['javascript'], @@ -51,7 +56,7 @@ let s:default_registry = { \ }, \ 'prettier': { \ 'function': 'ale#fixers#prettier#Fix', -\ 'suggested_filetypes': ['javascript', 'typescript', 'json', 'css', 'scss', 'less', 'markdown', 'graphql', 'vue'], +\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue'], \ 'description': 'Apply prettier to a file.', \ }, \ 'prettier_eslint': { @@ -205,6 +210,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['qml'], \ 'description': 'Fix QML files with qmlfmt.', \ }, +\ 'dartfmt': { +\ 'function': 'ale#fixers#dartfmt#Fix', +\ 'suggested_filetypes': ['dart'], +\ 'description': 'Fix Dart files with dartfmt.', +\ }, \} " Reset the function registry to the default entries. @@ -345,8 +355,7 @@ function! ale#fix#registry#CompleteFixers(ArgLead, CmdLine, CursorPos) abort return filter(ale#fix#registry#GetApplicableFixers(&filetype), 'v:val =~? a:ArgLead') endfunction -" Suggest functions to use from the registry. -function! ale#fix#registry#Suggest(filetype) abort +function! ale#fix#registry#SuggestedFixers(filetype) abort let l:type_list = split(a:filetype, '\.') let l:filetype_fixer_list = [] @@ -372,6 +381,15 @@ function! ale#fix#registry#Suggest(filetype) abort endif endfor + return [l:filetype_fixer_list, l:generic_fixer_list] +endfunction + +" Suggest functions to use from the registry. +function! ale#fix#registry#Suggest(filetype) abort + let l:suggested = ale#fix#registry#SuggestedFixers(a:filetype) + let l:filetype_fixer_list = l:suggested[0] + let l:generic_fixer_list = l:suggested[1] + let l:filetype_fixer_header = !empty(l:filetype_fixer_list) \ ? ['Try the following fixers appropriate for the filetype:', ''] \ : [] diff --git a/sources_non_forked/ale/autoload/ale/fixers/dartfmt.vim b/sources_non_forked/ale/autoload/ale/fixers/dartfmt.vim new file mode 100644 index 00000000..0687d6d1 --- /dev/null +++ b/sources_non_forked/ale/autoload/ale/fixers/dartfmt.vim @@ -0,0 +1,18 @@ +" Author: reisub0 +" Description: Integration of dartfmt with ALE. + +call ale#Set('dart_dartfmt_executable', 'dartfmt') +call ale#Set('dart_dartfmt_options', '') + +function! ale#fixers#dartfmt#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'dart_dartfmt_executable') + let l:options = ale#Var(a:buffer, 'dart_dartfmt_options') + + return { + \ 'command': ale#Escape(l:executable) + \ . ' -w' + \ . (empty(l:options) ? '' : ' ' . l:options) + \ . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/sources_non_forked/ale/autoload/ale/fixers/prettier.vim b/sources_non_forked/ale/autoload/ale/fixers/prettier.vim index dcc35813..e8f4e92e 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/prettier.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/prettier.vim @@ -30,8 +30,26 @@ endfunction function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort let l:executable = ale#fixers#prettier#GetExecutable(a:buffer) let l:options = ale#Var(a:buffer, 'javascript_prettier_options') - let l:version = ale#semver#GetVersion(l:executable, a:version_output) + let l:parser = '' + + " Append the --parser flag depending on the current filetype (unless it's + " already set in g:javascript_prettier_options). + if empty(expand('#' . a:buffer . ':e')) && match(l:options, '--parser') == -1 + let l:prettier_parsers = ['typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue'] + let l:parser = 'babylon' + + for l:filetype in split(getbufvar(a:buffer, '&filetype'), '\.') + if index(l:prettier_parsers, l:filetype) > -1 + let l:parser = l:filetype + break + endif + endfor + endif + + if !empty(l:parser) + let l:options = (!empty(l:options) ? l:options . ' ' : '') . '--parser ' . l:parser + endif " 1.4.0 is the first version with --stdin-filepath if ale#semver#GTE(l:version, [1, 4, 0]) diff --git a/sources_non_forked/ale/autoload/ale/fixers/tidy.vim b/sources_non_forked/ale/autoload/ale/fixers/tidy.vim new file mode 100644 index 00000000..1af4120b --- /dev/null +++ b/sources_non_forked/ale/autoload/ale/fixers/tidy.vim @@ -0,0 +1,26 @@ +" Author: meain +" Description: Fixing HTML files with tidy. + +call ale#Set('html_tidy_executable', 'tidy') +call ale#Set('html_tidy_use_global', get(g:, 'ale_use_global_executables', 0)) + +function! ale#fixers#tidy#Fix(buffer) abort + let l:executable = ale#node#FindExecutable( + \ a:buffer, + \ 'html_tidy', + \ ['tidy'], + \) + + if !executable(l:executable) + return 0 + endif + + let l:config = ale#path#FindNearestFile(a:buffer, '.tidyrc') + let l:config_options = !empty(l:config) + \ ? ' -q --tidy-mark no --show-errors 0 --show-warnings 0 -config ' . ale#Escape(l:config) + \ : ' -q --tidy-mark no --show-errors 0 --show-warnings 0' + + return { + \ 'command': ale#Escape(l:executable) . l:config_options, + \} +endfunction diff --git a/sources_non_forked/ale/autoload/ale/hover.vim b/sources_non_forked/ale/autoload/ale/hover.vim index 3bf92488..6d131adc 100644 --- a/sources_non_forked/ale/autoload/ale/hover.vim +++ b/sources_non_forked/ale/autoload/ale/hover.vim @@ -97,14 +97,14 @@ function! s:ShowDetails(linter, buffer, line, column, opt) abort \ ? function('ale#hover#HandleTSServerResponse') \ : function('ale#hover#HandleLSPResponse') - let l:lsp_details = ale#linter#StartLSP(a:buffer, a:linter, l:Callback) + let l:lsp_details = ale#lsp_linter#StartLSP(a:buffer, a:linter, l:Callback) if empty(l:lsp_details) return 0 endif let l:id = l:lsp_details.connection_id - let l:root = l:lsp_details.project_root + let l:language_id = l:lsp_details.language_id if a:linter.lsp is# 'tsserver' let l:column = a:column @@ -117,14 +117,14 @@ function! s:ShowDetails(linter, buffer, line, column, opt) abort else " Send a message saying the buffer has changed first, or the " hover position probably won't make sense. - call ale#lsp#Send(l:id, ale#lsp#message#DidChange(a:buffer), l:root) + call ale#lsp#NotifyForChanges(l:lsp_details) let l:column = min([a:column, len(getbufline(a:buffer, a:line)[0])]) let l:message = ale#lsp#message#Hover(a:buffer, a:line, l:column) endif - let l:request_id = ale#lsp#Send(l:id, l:message, l:root) + let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) let s:hover_map[l:request_id] = { \ 'buffer': a:buffer, diff --git a/sources_non_forked/ale/autoload/ale/job.vim b/sources_non_forked/ale/autoload/ale/job.vim index 6ffc2a06..e0266cba 100644 --- a/sources_non_forked/ale/autoload/ale/job.vim +++ b/sources_non_forked/ale/autoload/ale/job.vim @@ -26,34 +26,11 @@ function! s:KillHandler(timer) abort call job_stop(l:job, 'kill') endfunction -" Note that jobs and IDs are the same thing on NeoVim. -function! ale#job#JoinNeovimOutput(job, last_line, data, mode, callback) abort - if a:mode is# 'raw' - call a:callback(a:job, join(a:data, "\n")) - return '' - endif - - let l:lines = a:data[:-2] - - if len(a:data) > 1 - let l:lines[0] = a:last_line . l:lines[0] - let l:new_last_line = a:data[-1] - else - let l:new_last_line = a:last_line . get(a:data, 0, '') - endif - - for l:line in l:lines - call a:callback(a:job, l:line) - endfor - - return l:new_last_line -endfunction - function! s:NeoVimCallback(job, data, event) abort let l:info = s:job_map[a:job] if a:event is# 'stdout' - let l:info.out_cb_line = ale#job#JoinNeovimOutput( + let l:info.out_cb_line = ale#util#JoinNeovimOutput( \ a:job, \ l:info.out_cb_line, \ a:data, @@ -61,7 +38,7 @@ function! s:NeoVimCallback(job, data, event) abort \ ale#util#GetFunction(l:info.out_cb), \) elseif a:event is# 'stderr' - let l:info.err_cb_line = ale#job#JoinNeovimOutput( + let l:info.err_cb_line = ale#util#JoinNeovimOutput( \ a:job, \ l:info.err_cb_line, \ a:data, diff --git a/sources_non_forked/ale/autoload/ale/linter.vim b/sources_non_forked/ale/autoload/ale/linter.vim index 5eb2fd82..299f5dad 100644 --- a/sources_non_forked/ale/autoload/ale/linter.vim +++ b/sources_non_forked/ale/autoload/ale/linter.vim @@ -15,6 +15,7 @@ let s:default_ale_linter_aliases = { \ 'csh': 'sh', \ 'plaintex': 'tex', \ 'systemverilog': 'verilog', +\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'], \ 'vimwiki': 'markdown', \ 'zsh': 'sh', \} @@ -451,81 +452,3 @@ function! ale#linter#GetAddress(buffer, linter) abort \ ? ale#util#GetFunction(a:linter.address_callback)(a:buffer) \ : a:linter.address endfunction - -" Given a buffer, an LSP linter, and a callback to register for handling -" messages, start up an LSP linter and get ready to receive errors or -" completions. -function! ale#linter#StartLSP(buffer, linter, callback) abort - let l:command = '' - let l:address = '' - let l:root = ale#util#GetFunction(a:linter.project_root_callback)(a:buffer) - - if empty(l:root) && a:linter.lsp isnot# 'tsserver' - " If there's no project root, then we can't check files with LSP, - " unless we are using tsserver, which doesn't use project roots. - return {} - endif - - let l:initialization_options = {} - if has_key(a:linter, 'initialization_options_callback') - let l:initialization_options = ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer) - elseif has_key(a:linter, 'initialization_options') - let l:initialization_options = a:linter.initialization_options - endif - - if a:linter.lsp is# 'socket' - let l:address = ale#linter#GetAddress(a:buffer, a:linter) - let l:conn_id = ale#lsp#ConnectToAddress( - \ l:address, - \ l:root, - \ a:callback, - \ l:initialization_options, - \) - else - let l:executable = ale#linter#GetExecutable(a:buffer, a:linter) - - if !executable(l:executable) - return {} - endif - - let l:command = ale#job#PrepareCommand( - \ a:buffer, - \ ale#linter#GetCommand(a:buffer, a:linter), - \) - let l:conn_id = ale#lsp#StartProgram( - \ l:executable, - \ l:command, - \ l:root, - \ a:callback, - \ l:initialization_options, - \) - endif - - let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer) - - if !l:conn_id - if g:ale_history_enabled && !empty(l:command) - call ale#history#Add(a:buffer, 'failed', l:conn_id, l:command) - endif - - return {} - endif - - if ale#lsp#OpenDocumentIfNeeded(l:conn_id, a:buffer, l:root, l:language_id) - if g:ale_history_enabled && !empty(l:command) - call ale#history#Add(a:buffer, 'started', l:conn_id, l:command) - endif - endif - - " The change message needs to be sent for tsserver before doing anything. - if a:linter.lsp is# 'tsserver' - call ale#lsp#Send(l:conn_id, ale#lsp#tsserver_message#Change(a:buffer)) - endif - - return { - \ 'connection_id': l:conn_id, - \ 'command': l:command, - \ 'project_root': l:root, - \ 'language_id': l:language_id, - \} -endfunction diff --git a/sources_non_forked/ale/autoload/ale/lsp.vim b/sources_non_forked/ale/autoload/ale/lsp.vim index df4f16dc..e44b5bc3 100644 --- a/sources_non_forked/ale/autoload/ale/lsp.vim +++ b/sources_non_forked/ale/autoload/ale/lsp.vim @@ -3,20 +3,23 @@ " A List of connections, used for tracking servers which have been connected " to, and programs which are run. -let s:connections = [] +let s:connections = get(s:, 'connections', []) let g:ale_lsp_next_message_id = 1 -function! s:NewConnection(initialization_options) abort +" Exposed only so tests can get at it. +" Do not call this function basically anywhere. +function! ale#lsp#NewConnection(initialization_options) abort " id: The job ID as a Number, or the server address as a string. " data: The message data received so far. " executable: An executable only set for program connections. - " open_documents: A list of buffers we told the server we opened. + " open_documents: A Dictionary mapping buffers to b:changedtick, keeping + " track of when documents were opened, and when we last changed them. " callback_list: A list of callbacks for handling LSP responses. let l:conn = { \ 'id': '', \ 'data': '', \ 'projects': {}, - \ 'open_documents': [], + \ 'open_documents': {}, \ 'callback_list': [], \ 'initialization_options': a:initialization_options, \} @@ -26,9 +29,14 @@ function! s:NewConnection(initialization_options) abort return l:conn endfunction +" Remove an LSP connection with a given ID. This is only for tests. +function! ale#lsp#RemoveConnectionWithID(id) abort + call filter(s:connections, 'v:val.id isnot a:id') +endfunction + function! s:FindConnection(key, value) abort for l:conn in s:connections - if has_key(l:conn, a:key) && get(l:conn, a:key) == a:value + if has_key(l:conn, a:key) && get(l:conn, a:key) is# a:value return l:conn endif endfor @@ -233,9 +241,8 @@ function! ale#lsp#HandleMessage(conn, message) abort endfor endfunction -function! s:HandleChannelMessage(channel, message) abort - let l:info = ch_info(a:channel) - let l:address = l:info.hostname . l:info.address +function! s:HandleChannelMessage(channel_id, message) abort + let l:address = ale#socket#GetAddress(a:channel_id) let l:conn = s:FindConnection('id', l:address) call ale#lsp#HandleMessage(l:conn, a:message) @@ -280,7 +287,7 @@ function! ale#lsp#StartProgram(executable, command, project_root, callback, init let l:conn = s:FindConnection('executable', a:executable) " Get the current connection or a new one. - let l:conn = !empty(l:conn) ? l:conn : s:NewConnection(a:initialization_options) + let l:conn = !empty(l:conn) ? l:conn : ale#lsp#NewConnection(a:initialization_options) let l:conn.executable = a:executable if !has_key(l:conn, 'id') || !ale#job#IsRunning(l:conn.id) @@ -309,18 +316,16 @@ endfunction function! ale#lsp#ConnectToAddress(address, project_root, callback, initialization_options) abort let l:conn = s:FindConnection('id', a:address) " Get the current connection or a new one. - let l:conn = !empty(l:conn) ? l:conn : s:NewConnection(a:initialization_options) + let l:conn = !empty(l:conn) ? l:conn : ale#lsp#NewConnection(a:initialization_options) - if !has_key(l:conn, 'channel') || ch_status(l:conn.channel) isnot# 'open' - let l:conn.channnel = ch_open(a:address, { - \ 'mode': 'raw', - \ 'waittime': 0, + if !has_key(l:conn, 'channel_id') || !ale#socket#IsOpen(l:conn.channel_id) + let l:conn.channel_id = ale#socket#Open(a:address, { \ 'callback': function('s:HandleChannelMessage'), \}) endif - if ch_status(l:conn.channnel) is# 'fail' - return 0 + if l:conn.channel_id < 0 + return '' endif let l:conn.id = a:address @@ -328,15 +333,15 @@ function! ale#lsp#ConnectToAddress(address, project_root, callback, initializati call uniq(sort(add(l:conn.callback_list, a:callback))) call ale#lsp#RegisterProject(l:conn, a:project_root) - return 1 + return a:address endfunction " Stop all LSP connections, closing all jobs and channels, and removing any " queued messages. function! ale#lsp#StopAll() abort for l:conn in s:connections - if has_key(l:conn, 'channel') - call ch_close(l:conn.channel) + if has_key(l:conn, 'channel_id') + call ale#socket#Close(l:conn.channel_id) else call ale#job#Stop(l:conn.id) endif @@ -348,9 +353,9 @@ endfunction function! s:SendMessageData(conn, data) abort if has_key(a:conn, 'executable') call ale#job#SendRaw(a:conn.id, a:data) - elseif has_key(a:conn, 'channel') && ch_status(a:conn.channnel) is# 'open' + elseif has_key(a:conn, 'channel_id') && ale#socket#IsOpen(a:conn.channel_id) " Send the message to the server - call ch_sendraw(a:conn.channel, a:data) + call ale#socket#Send(a:conn.channel_id, a:data) else return 0 endif @@ -406,21 +411,72 @@ function! ale#lsp#Send(conn_id, message, ...) abort return l:id == 0 ? -1 : l:id endfunction -function! ale#lsp#OpenDocumentIfNeeded(conn_id, buffer, project_root, language_id) abort - let l:conn = s:FindConnection('id', a:conn_id) +" The Document details Dictionary should contain the following keys. +" +" buffer - The buffer number for the document. +" connection_id - The connection ID for the LSP server. +" command - The command to run to start the LSP connection. +" project_root - The project root for the LSP project. +" language_id - The language ID for the project, like 'python', 'rust', etc. + +" Create a new Dictionary containing more connection details, with the +" following information added: +" +" conn - An existing LSP connection for the document. +" document_open - 1 if the document is currently open, 0 otherwise. +function! s:ExtendDocumentDetails(details) abort + let l:extended = copy(a:details) + let l:conn = s:FindConnection('id', a:details.connection_id) + + let l:extended.conn = l:conn + let l:extended.document_open = !empty(l:conn) + \ && has_key(l:conn.open_documents, a:details.buffer) + + return l:extended +endfunction + +" Notify LSP servers or tsserver if a document is opened, if needed. +" If a document is opened, 1 will be returned, otherwise 0 will be returned. +function! ale#lsp#OpenDocument(basic_details) abort + let l:d = s:ExtendDocumentDetails(a:basic_details) let l:opened = 0 - if !empty(l:conn) && index(l:conn.open_documents, a:buffer) < 0 - if empty(a:language_id) - let l:message = ale#lsp#tsserver_message#Open(a:buffer) + if !empty(l:d.conn) && !l:d.document_open + if empty(l:d.language_id) + let l:message = ale#lsp#tsserver_message#Open(l:d.buffer) else - let l:message = ale#lsp#message#DidOpen(a:buffer, a:language_id) + let l:message = ale#lsp#message#DidOpen(l:d.buffer, l:d.language_id) endif - call ale#lsp#Send(a:conn_id, l:message, a:project_root) - call add(l:conn.open_documents, a:buffer) + call ale#lsp#Send(l:d.connection_id, l:message, l:d.project_root) + let l:d.conn.open_documents[l:d.buffer] = getbufvar(l:d.buffer, 'changedtick') let l:opened = 1 endif return l:opened endfunction + +" Notify LSP servers or tsserver that a document has changed, if needed. +" If a notification is sent, 1 will be returned, otherwise 0 will be returned. +function! ale#lsp#NotifyForChanges(basic_details) abort + let l:d = s:ExtendDocumentDetails(a:basic_details) + let l:notified = 0 + + if l:d.document_open + let l:new_tick = getbufvar(l:d.buffer, 'changedtick') + + if l:d.conn.open_documents[l:d.buffer] < l:new_tick + if empty(l:d.language_id) + let l:message = ale#lsp#tsserver_message#Change(l:d.buffer) + else + let l:message = ale#lsp#message#DidChange(l:d.buffer) + endif + + call ale#lsp#Send(l:d.connection_id, l:message, l:d.project_root) + let l:d.conn.open_documents[l:d.buffer] = l:new_tick + let l:notified = 1 + endif + endif + + return l:notified +endfunction diff --git a/sources_non_forked/ale/autoload/ale/lsp/reset.vim b/sources_non_forked/ale/autoload/ale/lsp/reset.vim index c206ed08..c7c97a47 100644 --- a/sources_non_forked/ale/autoload/ale/lsp/reset.vim +++ b/sources_non_forked/ale/autoload/ale/lsp/reset.vim @@ -7,9 +7,9 @@ function! ale#lsp#reset#StopAllLSPs() abort call ale#definition#ClearLSPData() endif - if exists('*ale#engine#ClearLSPData') + if exists('*ale#lsp_linter#ClearLSPData') " Clear the mapping for connections, etc. - call ale#engine#ClearLSPData() + call ale#lsp_linter#ClearLSPData() " Remove the problems for all of the LSP linters in every buffer. for l:buffer_string in keys(g:ale_buffer_info) diff --git a/sources_non_forked/ale/autoload/ale/lsp_linter.vim b/sources_non_forked/ale/autoload/ale/lsp_linter.vim new file mode 100644 index 00000000..9e72362b --- /dev/null +++ b/sources_non_forked/ale/autoload/ale/lsp_linter.vim @@ -0,0 +1,252 @@ +" Author: w0rp +" Description: Integration between linters and LSP/tsserver. + +" This code isn't loaded if a user never users LSP features or linters. + +" Associates LSP connection IDs with linter names. +if !has_key(s:, 'lsp_linter_map') + let s:lsp_linter_map = {} +endif + +" Check if diagnostics for a particular linter should be ignored. +function! s:ShouldIgnore(buffer, linter_name) abort + let l:config = ale#Var(a:buffer, 'linters_ignore') + + " Don't load code for ignoring diagnostics if there's nothing to ignore. + if empty(l:config) + return 0 + endif + + let l:filetype = getbufvar(a:buffer, '&filetype') + let l:ignore_list = ale#engine#ignore#GetList(l:filetype, l:config) + + return index(l:ignore_list, a:linter_name) >= 0 +endfunction + +function! s:HandleLSPDiagnostics(conn_id, response) abort + let l:linter_name = s:lsp_linter_map[a:conn_id] + let l:filename = ale#path#FromURI(a:response.params.uri) + let l:buffer = bufnr(l:filename) + + if s:ShouldIgnore(l:buffer, l:linter_name) + return + endif + + if l:buffer <= 0 + return + endif + + let l:loclist = ale#lsp#response#ReadDiagnostics(a:response) + + call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist) +endfunction + +function! s:HandleTSServerDiagnostics(response, error_type) abort + let l:linter_name = 'tsserver' + let l:buffer = bufnr(a:response.body.file) + let l:info = get(g:ale_buffer_info, l:buffer, {}) + + if empty(l:info) + return + endif + + if s:ShouldIgnore(l:buffer, l:linter_name) + return + endif + + let l:thislist = ale#lsp#response#ReadTSServerDiagnostics(a:response) + + " tsserver sends syntax and semantic errors in separate messages, so we + " have to collect the messages separately for each buffer and join them + " back together again. + if a:error_type is# 'syntax' + let l:info.syntax_loclist = l:thislist + else + let l:info.semantic_loclist = l:thislist + endif + + let l:loclist = get(l:info, 'semantic_loclist', []) + \ + get(l:info, 'syntax_loclist', []) + + call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist) +endfunction + +function! s:HandleLSPErrorMessage(linter_name, response) abort + if !g:ale_history_enabled || !g:ale_history_log_output + return + endif + + if empty(a:linter_name) + return + endif + + let l:message = ale#lsp#response#GetErrorMessage(a:response) + + if empty(l:message) + return + endif + + " This global variable is set here so we don't load the debugging.vim file + " until someone uses :ALEInfo. + let g:ale_lsp_error_messages = get(g:, 'ale_lsp_error_messages', {}) + + if !has_key(g:ale_lsp_error_messages, a:linter_name) + let g:ale_lsp_error_messages[a:linter_name] = [] + endif + + call add(g:ale_lsp_error_messages[a:linter_name], l:message) +endfunction + +function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort + let l:method = get(a:response, 'method', '') + let l:linter_name = get(s:lsp_linter_map, a:conn_id, '') + + if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error') + call s:HandleLSPErrorMessage(l:linter_name, a:response) + elseif l:method is# 'textDocument/publishDiagnostics' + call s:HandleLSPDiagnostics(a:conn_id, a:response) + elseif get(a:response, 'type', '') is# 'event' + \&& get(a:response, 'event', '') is# 'semanticDiag' + call s:HandleTSServerDiagnostics(a:response, 'semantic') + elseif get(a:response, 'type', '') is# 'event' + \&& get(a:response, 'event', '') is# 'syntaxDiag' + call s:HandleTSServerDiagnostics(a:response, 'syntax') + endif +endfunction + +" Given a buffer, an LSP linter, and a callback to register for handling +" messages, start up an LSP linter and get ready to receive errors or +" completions. +function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort + let l:command = '' + let l:address = '' + let l:root = ale#util#GetFunction(a:linter.project_root_callback)(a:buffer) + + if empty(l:root) && a:linter.lsp isnot# 'tsserver' + " If there's no project root, then we can't check files with LSP, + " unless we are using tsserver, which doesn't use project roots. + return {} + endif + + let l:initialization_options = {} + + if has_key(a:linter, 'initialization_options_callback') + let l:initialization_options = ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer) + elseif has_key(a:linter, 'initialization_options') + let l:initialization_options = a:linter.initialization_options + endif + + if a:linter.lsp is# 'socket' + let l:address = ale#linter#GetAddress(a:buffer, a:linter) + let l:conn_id = ale#lsp#ConnectToAddress( + \ l:address, + \ l:root, + \ a:callback, + \ l:initialization_options, + \) + else + let l:executable = ale#linter#GetExecutable(a:buffer, a:linter) + + if !executable(l:executable) + return {} + endif + + let l:command = ale#job#PrepareCommand( + \ a:buffer, + \ ale#linter#GetCommand(a:buffer, a:linter), + \) + let l:conn_id = ale#lsp#StartProgram( + \ l:executable, + \ l:command, + \ l:root, + \ a:callback, + \ l:initialization_options, + \) + endif + + let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer) + + if empty(l:conn_id) + if g:ale_history_enabled && !empty(l:command) + call ale#history#Add(a:buffer, 'failed', l:conn_id, l:command) + endif + + return {} + endif + + let l:details = { + \ 'buffer': a:buffer, + \ 'connection_id': l:conn_id, + \ 'command': l:command, + \ 'project_root': l:root, + \ 'language_id': l:language_id, + \} + + if ale#lsp#OpenDocument(l:details) + if g:ale_history_enabled && !empty(l:command) + call ale#history#Add(a:buffer, 'started', l:conn_id, l:command) + endif + endif + + " The change message needs to be sent for tsserver before doing anything. + if a:linter.lsp is# 'tsserver' + call ale#lsp#NotifyForChanges(l:details) + endif + + return l:details +endfunction + +function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort + let l:info = g:ale_buffer_info[a:buffer] + let l:lsp_details = ale#lsp_linter#StartLSP( + \ a:buffer, + \ a:linter, + \ function('ale#lsp_linter#HandleLSPResponse'), + \) + + if empty(l:lsp_details) + return 0 + endif + + let l:id = l:lsp_details.connection_id + let l:root = l:lsp_details.project_root + + " Remember the linter this connection is for. + let s:lsp_linter_map[l:id] = a:linter.name + + if a:linter.lsp is# 'tsserver' + let l:message = ale#lsp#tsserver_message#Geterr(a:buffer) + let l:request_id = ale#lsp#Send(l:id, l:message, l:root) + + let l:notified = l:request_id != 0 + else + let l:notified = ale#lsp#NotifyForChanges(l:lsp_details) + endif + + " If this was a file save event, also notify the server of that. + if a:linter.lsp isnot# 'tsserver' + \&& getbufvar(a:buffer, 'ale_save_event_fired', 0) + let l:save_message = ale#lsp#message#DidSave(a:buffer) + let l:request_id = ale#lsp#Send(l:id, l:save_message, l:root) + + let l:notified = l:request_id != 0 + endif + + if l:notified + if index(l:info.active_linter_list, a:linter.name) < 0 + call add(l:info.active_linter_list, a:linter.name) + endif + endif + + return l:notified +endfunction + +" Clear LSP linter data for the linting engine. +function! ale#lsp_linter#ClearLSPData() abort + let s:lsp_linter_map = {} +endfunction + +" Just for tests. +function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort + let s:lsp_linter_map = a:replacement_map +endfunction diff --git a/sources_non_forked/ale/autoload/ale/preview.vim b/sources_non_forked/ale/autoload/ale/preview.vim index c03cfe51..aefbb691 100644 --- a/sources_non_forked/ale/autoload/ale/preview.vim +++ b/sources_non_forked/ale/autoload/ale/preview.vim @@ -2,22 +2,41 @@ " Description: Preview windows for showing whatever information in. " Open a preview window and show some lines in it. -" An optional second argument can set an alternative filetype for the window. +" A second argument can be passed as a Dictionary with options. They are... +" +" filetype - The filetype to use, defaulting to 'ale-preview' +" stay_here - If 1, stay in the window you came from. function! ale#preview#Show(lines, ...) abort - let l:filetype = get(a:000, 0, 'ale-preview') + let l:options = get(a:000, 0, {}) silent pedit ALEPreviewWindow wincmd P + setlocal modifiable setlocal noreadonly setlocal nobuflisted - let &l:filetype = l:filetype + let &l:filetype = get(l:options, 'filetype', 'ale-preview') setlocal buftype=nofile setlocal bufhidden=wipe :%d call setline(1, a:lines) setlocal nomodifiable setlocal readonly + + if get(l:options, 'stay_here') + wincmd p + endif +endfunction + +" Close the preview window if the filetype matches the given one. +function! ale#preview#CloseIfTypeMatches(filetype) abort + for l:win in getwininfo() + let l:wintype = gettabwinvar(l:win.tabnr, l:win.winnr, '&filetype') + + if l:wintype is# a:filetype + silent! pclose! + endif + endfor endfunction " Show a location selection preview window, given some items. @@ -35,7 +54,7 @@ function! ale#preview#ShowSelection(item_list) abort \) endfor - call ale#preview#Show(l:lines, 'ale-preview-selection') + call ale#preview#Show(l:lines, {'filetype': 'ale-preview-selection'}) let b:ale_preview_item_list = a:item_list endfunction diff --git a/sources_non_forked/ale/autoload/ale/references.vim b/sources_non_forked/ale/autoload/ale/references.vim index 9777519d..89df69eb 100644 --- a/sources_non_forked/ale/autoload/ale/references.vim +++ b/sources_non_forked/ale/autoload/ale/references.vim @@ -72,14 +72,13 @@ function! s:FindReferences(linter) abort \ ? function('ale#references#HandleTSServerResponse') \ : function('ale#references#HandleLSPResponse') - let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback) + let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) if empty(l:lsp_details) return 0 endif let l:id = l:lsp_details.connection_id - let l:root = l:lsp_details.project_root if a:linter.lsp is# 'tsserver' let l:message = ale#lsp#tsserver_message#References( @@ -90,14 +89,14 @@ function! s:FindReferences(linter) abort else " Send a message saying the buffer has changed first, or the " references position probably won't make sense. - call ale#lsp#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root) + call ale#lsp#NotifyForChanges(l:lsp_details) let l:column = min([l:column, len(getline(l:line))]) let l:message = ale#lsp#message#References(l:buffer, l:line, l:column) endif - let l:request_id = ale#lsp#Send(l:id, l:message, l:root) + let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root) let s:references_map[l:request_id] = {} endfunction diff --git a/sources_non_forked/ale/autoload/ale/socket.vim b/sources_non_forked/ale/autoload/ale/socket.vim new file mode 100644 index 00000000..0ca4dea6 --- /dev/null +++ b/sources_non_forked/ale/autoload/ale/socket.vim @@ -0,0 +1,144 @@ +" Author: w0rp +" Description: APIs for working with asynchronous sockets, with an API +" normalised between Vim 8 and NeoVim. Socket connections only work in NeoVim +" 0.3+, and silently do nothing in earlier NeoVim versions. +" +" Important functions are described below. They are: +" +" ale#socket#Open(address, options) -> channel_id (>= 0 if successful) +" ale#socket#IsOpen(channel_id) -> 1 if open, 0 otherwise +" ale#socket#Close(channel_id) +" ale#socket#Send(channel_id, data) +" ale#socket#GetAddress(channel_id) -> Return the address for a job + +let s:channel_map = get(s:, 'channel_map', {}) + +function! s:VimOutputCallback(channel, data) abort + let l:channel_id = ch_info(a:channel).id + + " Only call the callbacks for jobs which are valid. + if l:channel_id >= 0 && has_key(s:channel_map, l:channel_id) + call ale#util#GetFunction(s:channel_map[l:channel_id].callback)(l:channel_id, a:data) + endif +endfunction + +function! s:NeoVimOutputCallback(channel_id, data, event) abort + let l:info = s:channel_map[a:channel_id] + + if a:event is# 'data' + let l:info.last_line = ale#util#JoinNeovimOutput( + \ a:channel_id, + \ l:info.last_line, + \ a:data, + \ l:info.mode, + \ ale#util#GetFunction(l:info.callback), + \) + endif +endfunction + +" Open a socket for a given address. The following options are accepted: +" +" callback - A callback for receiving input. (required) +" +" A non-negative number representing a channel ID will be returned is the +" connection was successful. 0 is a valid channel ID in Vim, so test if the +" connection ID is >= 0. +function! ale#socket#Open(address, options) abort + let l:mode = get(a:options, 'mode', 'raw') + let l:Callback = a:options.callback + + let l:channel_info = { + \ 'address': a:address, + \ 'mode': l:mode, + \ 'callback': a:options.callback, + \} + + if !has('nvim') + " Vim + let l:channel_info.channel = ch_open(a:address, { + \ 'mode': l:mode, + \ 'waittime': 0, + \ 'callback': function('s:VimOutputCallback'), + \}) + let l:vim_info = ch_info(l:channel_info.channel) + let l:channel_id = !empty(l:vim_info) ? l:vim_info.id : -1 + elseif exists('*chansend') && exists('*sockconnect') + " NeoVim 0.3+ + try + let l:channel_id = sockconnect('tcp', a:address, { + \ 'on_data': function('s:NeoVimOutputCallback'), + \}) + let l:channel_info.last_line = '' + catch /connection failed/ + let l:channel_id = -1 + endtry + + " 0 means the connection failed some times in NeoVim, so make the ID + " invalid to match Vim. + if l:channel_id is 0 + let l:channel_id = -1 + endif + + let l:channel_info.channel = l:channel_id + else + " Other Vim versions. + let l:channel_id = -1 + endif + + if l:channel_id >= 0 + let s:channel_map[l:channel_id] = l:channel_info + endif + + return l:channel_id +endfunction + +" Return 1 is a channel is open, 0 otherwise. +function! ale#socket#IsOpen(channel_id) abort + if !has_key(s:channel_map, a:channel_id) + return 0 + endif + + if has('nvim') + " In NeoVim, we have to check if this channel is in the global list. + return index(map(nvim_list_chans(), 'v:val.id'), a:channel_id) >= 0 + endif + + let l:channel = s:channel_map[a:channel_id].channel + return ch_status(l:channel) is# 'open' +endfunction + +" Close a socket, if it's still open. +function! ale#socket#Close(channel_id) abort + " IsRunning isn't called here, so we don't check nvim_list_chans() + if !has_key(s:channel_map, a:channel_id) + return 0 + endif + + let l:channel = remove(s:channel_map, a:channel_id).channel + + if has('nvim') + silent! call chanclose(l:channel) + elseif ch_status(l:channel) is# 'open' + call ch_close(l:channel) + endif +endfunction + +" Send some data to a socket. +function! ale#socket#Send(channel_id, data) abort + if !has_key(s:channel_map, a:channel_id) + return + endif + + let l:channel = s:channel_map[a:channel_id].channel + + if has('nvim') + call chansend(l:channel, a:data) + else + call ch_sendraw(l:channel, a:data) + endif +endfunction + +" Get an address for a channel, or an empty string. +function! ale#socket#GetAddress(channel_id) abort + return get(get(s:channel_map, a:channel_id, {}), 'address', '') +endfunction diff --git a/sources_non_forked/ale/autoload/ale/statusline.vim b/sources_non_forked/ale/autoload/ale/statusline.vim index 851618cc..94fbd6c9 100644 --- a/sources_non_forked/ale/autoload/ale/statusline.vim +++ b/sources_non_forked/ale/autoload/ale/statusline.vim @@ -1,14 +1,6 @@ " Author: KabbAmine " Description: Statusline related function(s) -" remove in 2.0 -" -" A deprecated setting for ale#statusline#Status() -" See :help ale#statusline#Count() for getting status reports. -let g:ale_statusline_format = get(g:, 'ale_statusline_format', -\ ['%d error(s)', '%d warning(s)', 'OK'] -\) - function! s:CreateCountDict() abort " Keys 0 and 1 are for backwards compatibility. " The count object used to be a List of [error_count, warning_count]. @@ -76,47 +68,3 @@ function! ale#statusline#Count(buffer) abort " The Dictionary is copied here before exposing it to other plugins. return copy(s:GetCounts(a:buffer)) endfunction - -" This is the historical format setting which could be configured before. -function! s:StatusForListFormat() abort - let [l:error_format, l:warning_format, l:no_errors] = g:ale_statusline_format - let l:counts = s:GetCounts(bufnr('')) - - " Build strings based on user formatting preferences. - let l:errors = l:counts[0] ? printf(l:error_format, l:counts[0]) : '' - let l:warnings = l:counts[1] ? printf(l:warning_format, l:counts[1]) : '' - - " Different formats based on the combination of errors and warnings. - if empty(l:errors) && empty(l:warnings) - let l:res = l:no_errors - elseif !empty(l:errors) && !empty(l:warnings) - let l:res = printf('%s %s', l:errors, l:warnings) - else - let l:res = empty(l:errors) ? l:warnings : l:errors - endif - - return l:res -endfunction - -" remove in 2.0 -" -" Returns a formatted string that can be integrated in the statusline. -" -" This function is deprecated, and should not be used. Use the airline plugin -" instead, or write your own status function with ale#statusline#Count() -function! ale#statusline#Status() abort - if !get(g:, 'ale_deprecation_ale_statusline_status', 0) - execute 'echom ''ale#statusline#Status() is deprecated, use ale#statusline#Count() to write your own function.''' - let g:ale_deprecation_ale_statusline_status = 1 - endif - - if !exists('g:ale_statusline_format') - return 'OK' - endif - - if type(g:ale_statusline_format) == type([]) - return s:StatusForListFormat() - endif - - return '' -endfunction diff --git a/sources_non_forked/ale/autoload/ale/toggle.vim b/sources_non_forked/ale/autoload/ale/toggle.vim index d8472cd8..6b1affc4 100644 --- a/sources_non_forked/ale/autoload/ale/toggle.vim +++ b/sources_non_forked/ale/autoload/ale/toggle.vim @@ -48,7 +48,7 @@ function! ale#toggle#Toggle() abort endif endif - call ale#autocmd#InitAuGroups() + call ale#events#Init() endfunction function! ale#toggle#Enable() abort diff --git a/sources_non_forked/ale/autoload/ale/util.vim b/sources_non_forked/ale/autoload/ale/util.vim index 4e789b72..d7b6904c 100644 --- a/sources_non_forked/ale/autoload/ale/util.vim +++ b/sources_non_forked/ale/autoload/ale/util.vim @@ -17,11 +17,18 @@ endfunction " but NeoVim does. Small messages can be echoed in Vim 8, and larger messages " have to be shown in preview windows. function! ale#util#ShowMessage(string) abort + if !has('nvim') + call ale#preview#CloseIfTypeMatches('ale-preview.message') + endif + " We have to assume the user is using a monospace font. if has('nvim') || (a:string !~? "\n" && len(a:string) < &columns) execute 'echo a:string' else - call ale#preview#Show(split(a:string, "\n")) + call ale#preview#Show(split(a:string, "\n"), { + \ 'filetype': 'ale-preview.message', + \ 'stay_here': 1, + \}) endif endfunction @@ -39,6 +46,33 @@ if !exists('g:ale#util#nul_file') endif endif +" Given a job, a buffered line of data, a list of parts of lines, a mode data +" is being read in, and a callback, join the lines of output for a NeoVim job +" or socket together, and call the callback with the joined output. +" +" Note that jobs and IDs are the same thing on NeoVim. +function! ale#util#JoinNeovimOutput(job, last_line, data, mode, callback) abort + if a:mode is# 'raw' + call a:callback(a:job, join(a:data, "\n")) + return '' + endif + + let l:lines = a:data[:-2] + + if len(a:data) > 1 + let l:lines[0] = a:last_line . l:lines[0] + let l:new_last_line = a:data[-1] + else + let l:new_last_line = a:last_line . get(a:data, 0, '') + endif + + for l:line in l:lines + call a:callback(a:job, l:line) + endfor + + return l:new_last_line +endfunction + " Return the number of lines for a given buffer. function! ale#util#GetLineCount(buffer) abort return len(getbufline(a:buffer, 1, '$')) @@ -56,7 +90,10 @@ function! ale#util#Open(filename, line, column, options) abort if get(a:options, 'open_in_tab', 0) call ale#util#Execute('tabedit ' . fnameescape(a:filename)) else - call ale#util#Execute('edit ' . fnameescape(a:filename)) + " Open another file only if we need to. + if bufnr(a:filename) isnot bufnr('') + call ale#util#Execute('edit ' . fnameescape(a:filename)) + endif endif call cursor(a:line, a:column) @@ -241,16 +278,6 @@ function! ale#util#InSandbox() abort return 0 endfunction -" Get the number of milliseconds since some vague, but consistent, point in -" the past. -" -" This function can be used for timing execution, etc. -" -" The time will be returned as a Number. -function! ale#util#ClockMilliseconds() abort - return float2nr(reltimefloat(reltime()) * 1000) -endfunction - " Given a single line, or a List of lines, and a single pattern, or a List " of patterns, return all of the matches for the lines(s) from the given " patterns, using matchlist(). diff --git a/sources_non_forked/ale/doc/ale-cloudformation.txt b/sources_non_forked/ale/doc/ale-cloudformation.txt new file mode 100644 index 00000000..59c6af06 --- /dev/null +++ b/sources_non_forked/ale/doc/ale-cloudformation.txt @@ -0,0 +1,14 @@ +=============================================================================== +ALE CloudFormation Integration *ale-cloudformation-options* + + +=============================================================================== +cfn-python-lint *ale-cloudformation-cfn-python-lint* + +cfn-python-lint is a linter for AWS CloudFormation template file. + +https://github.com/awslabs/cfn-python-lint + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: + diff --git a/sources_non_forked/ale/doc/ale-dart.txt b/sources_non_forked/ale/doc/ale-dart.txt index c6faa5c2..a6d88dd8 100644 --- a/sources_non_forked/ale/doc/ale-dart.txt +++ b/sources_non_forked/ale/doc/ale-dart.txt @@ -35,4 +35,37 @@ g:ale_dart_dartanalyzer_executable *g:ale_dart_dartanalyzer_executable* =============================================================================== +dartfmt *ale-dart-dartfmt* + +Installation +------------------------------------------------------------------------------- + +Installing Dart should probably ensure that `dartfmt` is in your `$PATH`. + +In case it is not, try to set the executable option to its absolute path. : > + " Set the executable path for dartfmt to the absolute path to it. + let g:ale_dart_dartfmt_executable = '/usr/lib/dart/bin/dartfmt' + > + +Options +------------------------------------------------------------------------------- + +g:ale_dart_dartfmt_executable *g:ale_dart_dartfmt_executable* + *b:ale_dart_dartfmt_executable* + Type: |String| + Default: `''` + + This variable can be set to specify an absolute path to the + dartfmt executable (or to specify an alternate executable). + + +g:ale_dart_dartfmt_options *g:ale_dart_dartfmt_options* + *b:ale_dart_dartfmt_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to the dartfmt fixer. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/sources_non_forked/ale/doc/ale-development.txt b/sources_non_forked/ale/doc/ale-development.txt new file mode 100644 index 00000000..841371c7 --- /dev/null +++ b/sources_non_forked/ale/doc/ale-development.txt @@ -0,0 +1,223 @@ +*ale-development.txt* For Vim version 8.0. +*ale-development* + +ALE Development Documentation + +=============================================================================== +CONTENTS *ale-development-contents* + + 1. Introduction.........................|ale-development-introduction| + 2. Design Goals.........................|ale-design-goals| + 3. Coding Standards.....................|ale-coding-standards| + 4. Testing ALE..........................|ale-development-tests| + +=============================================================================== +1. Introduction *ale-development-introduction* + +This document contains helpful information for ALE developers, including +design goals, information on how to run the tests, coding standards, and so +on. You should read this document if you want to get involved with ALE +development. + +=============================================================================== +2. Design Goals *ale-design-goals* + +This section lists design goals for ALE, in no particular order. They are as +follows. + +ALE code should be almost 100% VimL. This makes the plugin as portable as +possible. + +ALE should run without needing any other plugins to be installed, to make +installation simple. ALE can integrate with other plugins for more advanced +functionality, non-essential functionality, or improving on basic first party +functionality. + +ALE should check files with as many tools as possible by default, except where +they cause security issues or make excessive use of resources on modern +machines. + +ALE should be free of breaking changes to the public API, which is comprised of +documented functions and options, until a major version is planned. Breaking +changes should be preceded by a deprecation phase complete with warnings. +Changes required for security may be an exception. + +ALE supports Vim 8 and above, and NeoVim 0.2.0 or newer. These are the +earliest versions of Vim and NeoVim which support |job|, |timer|, |closure|, +and |lambda| features. All ALE code should be written so it is compatible with +these versions of Vim, or with version checks so particular features can +degrade or fail gracefully. + +Just about everything should be documented and covered with tests. + +By and large, people shouldn't pay for the functionality they don't use. Care +should be taken when adding new features, so supporting new features doesn't +degrade the general performance of anything ALE does. + +LSP support will become more important as time goes on. ALE should provide +better support for LSP features as time goes on. + +When merging pull requests, you should respond with `Cheers! :beers:`, purely +for comedy value. + +=============================================================================== +3. Coding Standards *ale-coding-standards* + +The following general coding standards should be adhered to for Vim code. + +* Check your Vim code with `Vint` and do everything it says. ALE will check + your Vim code with Vint automatically. See: https://github.com/Kuniwak/vint + Read ALE's `Dockerfile` to see which version of `Vint` it uses. +* Try to write descriptive and concise names for variables and functions. + Names shouldn't be too short or too long. Think about others reading your + code later on. +* Use `snake_case` names for variables and arguments, and `PascalCase` names + for functions. Prefix every variable name with its scope. (`l:`, `g:`, etc.) +* Try to keep lines no longer than 80 characters, but this isn't an absolute + requirement. +* Use 4 spaces for every level of indentation in Vim code. +* Add a blank line before every `function`, `if`, `for`, `while`, or `return`, + which doesn't start a new level of indentation. This makes the logic in + your code easier to follow. +* End every file with a trailing newline character, but not with extra blank + lines. Remove trailing whitespace from the ends of lines. +* Write the full names of commands instead of abbreviations. For example, write + `function` instead of `func`, and `endif` instead of `end`. +* Write functions with `!`, so files can be reloaded. Use the |abort| keyword + for all functions, so functions exit on the first error. +* Make sure to credit yourself in files you have authored with `Author:` + and `Description:` comments. + +In addition to the above general guidelines for the style of your code, you +should also follow some additional rules designed to prevent mistakes. Some of +these are reported with ALE's `custom-linting-rules` script. See +|ale-development-tests|. + +* Don't leave stray `:echo` lines in code. Use `execute 'echo' ...` if you must + echo something. +* For strings use |is#| instead of |==#|, `is?` instead of `==?`, `isnot#` + instead of `!=#`, and `isnot?` instead of `!=?`. This is because `'x' ==# 0` + returns 1, while `'x' is# 0` returns 0, so you will experience fewer issues + when numbers are compared with strings. `is` and `isnot` also do not throw + errors when other objects like List or Dictionaries are compared with + strings. +* Don't use the `getcwd()` function in the ALE codebase. Most of ALE's code + runs from asynchronous callback functions, and these functions can execute + from essentially random buffers. Therefore, the `getcwd()` output is + useless. Use `expand('#' . a:buffer . ':p:h')` instead. Don't use + `expand('%...')` for the same reason. +* Don't use the `simplify()` function. It doesn't simplify paths enough. Use + `ale#path#Simplify()` instead. +* Don't use the `shellescape()` function. It doesn't escape arguments properly + on Windows. Use `ale#Escape()` instead, which will avoid escaping where it + isn't needed, and generally escape arguments better on Windows. + +Apply the following guidelines when writing Vader test files. + +* Use 2 spaces for Vader test files, instead of the 4 spaces for Vim files. +* If you write `Before` and `After` blocks, you should typically write them at + the top of the file, so they run for all tests. There may be some tests + where it make sense to modify the `Before` and `After` code part of the way + through the file. +* If you modify any settings or global variables, reset them in `After` + blocks. The Vader `Save` and `Restore` commands can be useful for this + purpose. +* If you load or define linters in tests, write `call ale#linter#Reset()` in + an `After` block. +* Just write `Execute` blocks for Vader tests, and don't bother writing `Then` + blocks. `Then` blocks execute after `After` blocks in older versions, and + that can be confusing. + +Apply the following rules when writing Bash scripts. + +* Run `shellcheck`, and do everything it says. + See: https://github.com/koalaman/shellcheck +* Try to write scripts so they will run on Linux, BSD, or Mac OSX. + +=============================================================================== +4. Testing ALE *ale-development-tests* + +ALE is tested with a suite of tests executed in Travis CI and AppVeyor. ALE +runs tests with the following versions of Vim in the following environments. + +1. Vim 8.0.0027 on Linux via Travis CI. +2. NeoVim 0.2.0 on Linux via Travis CI. +3. NeoVim 0.3.0 on Linux via Travis CI. +4. Vim 8 (stable builds) on Windows via AppVeyor. + +If you are developing ALE code on Linux, Mac OSX, or BSD, you can run ALEs +tests by installing Docker and running the `run-tests` script. Follow the +instructions on the Docker site for installing Docker. +See: https://docs.docker.com/install/ + +NOTE: Don't forget to add your user to the `docker` group on Linux, or Docker +just won't work. See: https://docs.docker.com/install/linux/linux-postinstall/ + +If you run simply `./run-tests` from the ALE repository root directory, the +latest Docker image for tests will be downloaded if needed, and the script +will run all of the tests in Vader, Vint checks, and several Bash scripts for +finding extra issues. Run `./run-tests --help` to see all of the options the +script supports. Note that the script supports selecting particular test files. + +Generally write tests for any changes you make. The following types of tests +are recommended for the following types of code. + +* New/edited error handler callbacks -> Write tests in `test/handler` +* New/edited command callbacks -> Write tests in `test/command_callback` +* New/edited fixer functions -> Write tests in `test/fixers` + +Look at existing tests in the codebase for examples of how to write tests. +Refer to the Vader documentation for general information on how to write Vader +tests: https://github.com/junegunn/vader.vim + +When you add new linters or fixers, make sure to add them into the table in +the README, and also into the |ale-support| list in the main help file. If you +forget to keep them both in sync, you should see an error like the following +in Travis CI. > + + ======================================== + diff README.md and doc/ale.txt tables + ======================================== + Differences follow: + + --- /tmp/readme.qLjNhJdB 2018-07-01 16:29:55.590331972 +0100 + +++ /tmp/doc.dAi8zfVE 2018-07-01 16:29:55.582331877 +0100 + @@ -1 +1 @@ + - ASM: gcc, foobar + + ASM: gcc +< +Make sure to list documentation entries for linters and fixers in individual +help files in the table of contents, and to align help tags to the right +margin. For example, if you add a heading for an `aardvark` tool to +`ale-python.txt` with a badly aligned doc tag, you will see errors like so. > + + ======================================== + Look for badly aligned doc tags + ======================================== + Badly aligned tags follow: + + doc/ale-python.txt:aardvark ... + ======================================== + Look for table of contents issues + ======================================== + + Check for bad ToC sorting: + + Check for mismatched ToC and headings: + + --- /tmp/table-of-contents.mwCFOgSI 2018-07-01 16:33:25.068811878 +0100 + +++ /tmp/headings.L4WU0hsO 2018-07-01 16:33:25.076811973 +0100 + @@ -168,6 +168,7 @@ + pyrex (cython), ale-pyrex-options + cython, ale-pyrex-cython + python, ale-python-options + + aardvark, ale-python-aardvark + autopep8, ale-python-autopep8 + black, ale-python-black + flake8, ale-python-flake8 +< +Make sure to make the table of contents match the headings, and to keep the +doc tags on the right margin. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/sources_non_forked/ale/doc/ale-html.txt b/sources_non_forked/ale/doc/ale-html.txt index 2d8873ef..98fddc58 100644 --- a/sources_non_forked/ale/doc/ale-html.txt +++ b/sources_non_forked/ale/doc/ale-html.txt @@ -71,6 +71,14 @@ g:ale_html_tidy_options *g:ale_html_tidy_options* (mac), sjis (shiftjis), utf-16le, utf-16, utf-8 +g:ale_html_tidy_use_global *g:html_tidy_use_global* + + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== write-good *ale-html-write-good* diff --git a/sources_non_forked/ale/doc/ale-pyrex.txt b/sources_non_forked/ale/doc/ale-pyrex.txt new file mode 100644 index 00000000..245e611f --- /dev/null +++ b/sources_non_forked/ale/doc/ale-pyrex.txt @@ -0,0 +1,25 @@ +=============================================================================== +ALE Pyrex (Cython) Integration *ale-pyrex-options* + + +=============================================================================== +cython *ale-pyrex-cython* + +g:ale_pyrex_cython_executable *g:ale_pyrex_cython_executable* + *b:ale_pyrex_cython_executable* + Type: |String| + Default: `'cython'` + + This variable can be changed to use a different executable for cython. + + +g:ale_pyrex_cython_options *g:ale_pyrex_cython_options* + *b:ale_pyrex_cython_options* + Type: |String| + Default: `'--warning-extra --warning-errors'` + + This variable can be changed to modify flags given to cython. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/sources_non_forked/ale/doc/ale-python.txt b/sources_non_forked/ale/doc/ale-python.txt index b24b531d..de706896 100644 --- a/sources_non_forked/ale/doc/ale-python.txt +++ b/sources_non_forked/ale/doc/ale-python.txt @@ -363,6 +363,30 @@ g:ale_python_pyls_use_global *g:ale_python_pyls_use_global* See |ale-integrations-local-executables| +=============================================================================== +pyre *ale-python-pyre* + +`pyre` will be run from a detected project root, per |ale-python-root|. + + +g:ale_python_pyre_executable *g:ale_python_pyre_executable* + *b:ale_python_pyre_executable* + Type: |String| + Default: `'pyre'` + + See |ale-integrations-local-executables| + + Set this to `'pipenv'` to invoke `'pipenv` `run` `pyre'`. + + +g:ale_python_pyre_use_global *g:ale_python_pyre_use_global* + *b:ale_python_pyre_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== yapf *ale-python-yapf* diff --git a/sources_non_forked/ale/doc/ale-rust.txt b/sources_non_forked/ale/doc/ale-rust.txt index f9afe17d..d61e5b55 100644 --- a/sources_non_forked/ale/doc/ale-rust.txt +++ b/sources_non_forked/ale/doc/ale-rust.txt @@ -108,6 +108,15 @@ g:ale_rust_cargo_include_features *g:ale_rust_cargo_include_features* When defined, ALE will set the `--features` option when invoking `cargo` to perform the lint check. See |g:ale_rust_cargo_default_feature_behavior|. +g:ale_rust_cargo_avoid_whole_workspace *g:ale_rust_cargo_avoid_whole_workspace* + *b:ale_rust_cargo_avoid_whole_workspace* + Type: |Number| + Default: `1` + + When set to 1, and ALE is used to edit a crate that is part of a Cargo + workspace, avoid building the entire entire workspace by invoking + `cargo` directly in the crate's directory. Otherwise, behave as usual. + =============================================================================== rls *ale-rust-rls* diff --git a/sources_non_forked/ale/doc/ale-sh.txt b/sources_non_forked/ale/doc/ale-sh.txt index 941dc59b..7557e522 100644 --- a/sources_non_forked/ale/doc/ale-sh.txt +++ b/sources_non_forked/ale/doc/ale-sh.txt @@ -2,6 +2,25 @@ ALE Shell Integration *ale-sh-options* +=============================================================================== +sh-language-server *ale-sh-language-server* + +g:ale_sh_language_server_executable *g:ale_sh_language_server_executable* + *b:ale_sh_language_server_executable* + Type: |String| + Default: `'bash-language-server'` + + See |ale-integrations-local-executables| + + +g:ale_sh_language_server_use_global *g:ale_sh_language_server_use_global* + *b:ale_sh_language_server_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + =============================================================================== shell *ale-sh-shell* diff --git a/sources_non_forked/ale/doc/ale.txt b/sources_non_forked/ale/doc/ale.txt index 0531589c..232d7630 100644 --- a/sources_non_forked/ale/doc/ale.txt +++ b/sources_non_forked/ale/doc/ale.txt @@ -35,6 +35,8 @@ CONTENTS *ale-contents* foodcritic..........................|ale-chef-foodcritic| clojure...............................|ale-clojure-options| joker...............................|ale-clojure-joker| + cloudformation........................|ale-cloudformation-options| + cfn-python-lint.....................|ale-cloudformation-cfn-python-lint| cmake.................................|ale-cmake-options| cmakelint...........................|ale-cmake-cmakelint| cpp...................................|ale-cpp-options| @@ -57,6 +59,7 @@ CONTENTS *ale-contents* nvcc................................|ale-cuda-nvcc| dart..................................|ale-dart-options| dartanalyzer........................|ale-dart-dartanalyzer| + dartfmt.............................|ale-dart-dartfmt| dockerfile............................|ale-dockerfile-options| hadolint............................|ale-dockerfile-hadolint| elixir................................|ale-elixir-options| @@ -183,6 +186,8 @@ CONTENTS *ale-contents* puglint.............................|ale-pug-puglint| puppet................................|ale-puppet-options| puppetlint..........................|ale-puppet-puppetlint| + pyrex (cython)........................|ale-pyrex-options| + cython..............................|ale-pyrex-cython| python................................|ale-python-options| autopep8............................|ale-python-autopep8| black...............................|ale-python-black| @@ -194,6 +199,7 @@ CONTENTS *ale-contents* pyflakes............................|ale-python-pyflakes| pylint..............................|ale-python-pylint| pyls................................|ale-python-pyls| + pyre................................|ale-python-pyre| yapf................................|ale-python-yapf| qml...................................|ale-qml-options| qmlfmt..............................|ale-qml-qmlfmt| @@ -226,6 +232,7 @@ CONTENTS *ale-contents* prettier............................|ale-scss-prettier| stylelint...........................|ale-scss-stylelint| sh....................................|ale-sh-options| + sh-language-server..................|ale-sh-language-server| shell...............................|ale-sh-shell| shellcheck..........................|ale-sh-shellcheck| shfmt...............................|ale-sh-shfmt| @@ -302,6 +309,9 @@ control functionality used for checking for problems. Try using the |ALEFixSuggest| command for browsing tools that can be used to fix problems for the current buffer. +If you are interested in contributing to the development of ALE, read the +developer documentation. See |ale-development| + =============================================================================== 2. Supported Languages & Tools *ale-support* @@ -317,7 +327,7 @@ Notes: * API Blueprint: `drafter` * AsciiDoc: `alex`!!, `proselint`, `redpen`, `write-good` * Awk: `gawk` -* Bash: `shell` (-n flag), `shellcheck`, `shfmt` +* Bash: `language-server`, `shell` (-n flag), `shellcheck`, `shfmt` * Bourne Shell: `shell` (-n flag), `shellcheck`, `shfmt` * C: `cppcheck`, `cpplint`!!, `clang`, `clangtidy`!!, `clang-format`, `flawfinder`, `gcc` * C++ (filetype cpp): `clang`, `clangcheck`!!, `clangtidy`!!, `clang-format`, `cppcheck`, `cpplint`!!, `cquery`, `flawfinder`, `gcc` @@ -325,6 +335,7 @@ Notes: * C#: `mcs`, `mcsc`!! * Chef: `foodcritic` * Clojure: `joker` +* CloudFormation: `cfn-python-lint` * CMake: `cmakelint` * CoffeeScript: `coffee`, `coffeelint` * Crystal: `crystal`!! @@ -333,9 +344,9 @@ Notes: * Cython (pyrex filetype): `cython` * D: `dmd` * Dafny: `dafny`!! -* Dart: `dartanalyzer`!!, `language_server` +* Dart: `dartanalyzer`!!, `language_server`, dartfmt!! * Dockerfile: `hadolint` -* Elixir: `credo`, `dialyxir`, `dogma`!! +* Elixir: `credo`, `dialyxir`, `dogma`, `mix`!! * Elm: `elm-format, elm-make` * Erb: `erb`, `erubi`, `erubis` * Erlang: `erlc`, `SyntaxErl` @@ -380,7 +391,7 @@ Notes: * proto: `protoc-gen-lint` * Pug: `pug-lint` * Puppet: `puppet`, `puppet-lint` -* Python: `autopep8`, `black`, `flake8`, `isort`, `mypy`, `prospector`, `pycodestyle`, `pyls`, `pylint`!!, `yapf` +* Python: `autopep8`, `black`, `flake8`, `isort`, `mypy`, `prospector`, `pycodestyle`, `pyls`, `pyre`, `pylint`!!, `yapf` * QML: `qmlfmt`, `qmllint` * R: `lintr` * ReasonML: `merlin`, `ols`, `refmt` @@ -935,6 +946,14 @@ g:ale_fixers *g:ale_fixers* `b:ale_fixers` can be set to a |List| of callbacks instead, which can be more convenient. + A special `'*'` key be used as a wildcard filetype for configuring fixers + for every other type of file. For example: > + + " Fix Python files with 'bar'. + " Don't fix 'html' files. + " Fix everything else with 'foo'. + let g:ale_fixers = {'python': ['bar'], 'html': [], '*': ['foo']} +< g:ale_fix_on_save *g:ale_fix_on_save* b:ale_fix_on_save *b:ale_fix_on_save* @@ -1114,6 +1133,7 @@ g:ale_linter_aliases *g:ale_linter_aliases* \ 'csh': 'sh', \ 'plaintex': 'tex', \ 'systemverilog': 'verilog', + \ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'], \ 'vimwiki': 'markdown', \ 'zsh': 'sh', \} @@ -1219,6 +1239,32 @@ g:ale_linters_explicit *g:ale_linters_explicit* as possible, unless otherwise specified. +g:ale_linters_ignore *g:ale_linters_ignore* + *b:ale_linters_ignore* + + Type: |Dictionary| or |List| + Default: `{}` + + Linters to ignore. Commands for ignored linters will not be run, and + diagnostics for LSP linters will be ignored. (See |ale-lsp|) + + This setting can be set to a |Dictionary| mapping filetypes to linter names, + just like |g:ale_linters|, to list linters to ignore. Ignore lists will be + applied after everything else. > + + " Select flake8 and pylint, and ignore pylint, so only flake8 is run. + let g:ale_linters = {'python': ['flake8', 'pylint']} + let g:ale_linters_ignore = {'python': ['pylint']} +< + This setting can be set to simply a |List| of linter names, which is + especially more convenient when using the setting in ftplugin files for + particular buffers. > + + " The same as above, in a ftplugin/python.vim. + let b:ale_linters = ['flake8', 'pylint'] + let b:ale_linters_ignore = ['pylint'] +< + g:ale_list_vertical *g:ale_list_vertical* *b:ale_list_vertical* Type: |Number| @@ -1967,9 +2013,13 @@ ALEDisableBuffer *ALEDisableBuffer* *:ALEDetail* ALEDetail *ALEDetail* - Show the full linter message for the current line in the preview window. - This will only have an effect on lines that contain a linter message. The - preview window can be easily closed with the `q` key. + Show the full linter message for the problem nearest to the cursor on the + given line in the preview window. The preview window can be easily closed + with the `q` key. If there is no message to show, the window will not be + opened. + + If a loclist item has a `detail` key set, the message for that key will be + preferred over `text`. See |ale-loclist-format|. A plug mapping `(ale_detail)` is defined for this command. @@ -2153,13 +2203,16 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* This argument is required, unless the linter is an LSP linter. In which case, this argument must not be - defined, as LSP linters handle diangostics + defined, as LSP linters handle diagnostics automatically. See |ale-lsp-linters|. The keys for each item in the List will be handled in the following manner: *ale-loclist-format* `text` - This error message is required. + `detail` - An optional, more descriptive message. + This message can be displayed with the |ALEDetail| + command instead of the message for `text`, if set. `lnum` - The line number is required. Any strings will be automatically converted to numbers by using `str2nr()`. @@ -2319,8 +2372,16 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* When this argument is set to `'stdio'`, then the linter will be defined as an LSP linter which keeps a - process for a language server runnning, and + process for a language server running, and communicates with it directly via a |channel|. + `executable` or `executable_callback` must be set, + and `command` or `command_callback` must be set. + + When this argument is set to `'socket'`, then the + linter will be defined as an LSP linter via a TCP + socket connection. `address_callback` must be set + with a callback returning an address to connect to. + ALE will not start a server automatically. When this argument is not empty, only one of either `language` or `language_callback` must be defined, @@ -2336,6 +2397,13 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* `initialization_options_callback` may be defined to pass initialization options to the LSP. + `address_callback` A |String| or |Funcref| for a callback function + accepting a buffer number. A |String| should be + returned with an address to connect to. + + This argument must only be set if the `lsp` argument + is set to `'socket'`. + `project_root_callback` A |String| or |Funcref| for a callback function accepting a buffer number. A |String| should be returned representing the path to the project for the @@ -2564,5 +2632,5 @@ free to send an email to devw0rp@gmail.com. Please drink responsibly, or not at all, which is ironically the preference of w0rp, who is teetotal. - +=============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/sources_non_forked/ale/plugin/ale.vim b/sources_non_forked/ale/plugin/ale.vim index bea5a49e..3bd12015 100644 --- a/sources_non_forked/ale/plugin/ale.vim +++ b/sources_non_forked/ale/plugin/ale.vim @@ -32,12 +32,6 @@ if !s:has_features finish endif -" remove in 2.0 -if has('nvim') && !has('nvim-0.2.0') && !get(g:, 'ale_use_deprecated_neovim') - execute 'echom ''ALE support for NeoVim versions below 0.2.0 is deprecated.''' - execute 'echom ''Use `let g:ale_use_deprecated_neovim = 1` to silence this warning for now.''' -endif - " Set this flag so that other plugins can use it, like airline. let g:loaded_ale = 1 @@ -221,35 +215,13 @@ nnoremap (ale_find_references) :ALEFindReferences nnoremap (ale_hover) :ALEHover " Set up autocmd groups now. -call ale#autocmd#InitAuGroups() +call ale#events#Init() " Housekeeping augroup ALECleanupGroup autocmd! " Clean up buffers automatically when they are unloaded. - autocmd BufDelete * call ale#engine#Cleanup(str2nr(expand(''))) + autocmd BufDelete * if exists('*ale#engine#Cleanup') | call ale#engine#Cleanup(str2nr(expand(''))) | endif autocmd QuitPre * call ale#events#QuitEvent(str2nr(expand(''))) augroup END - -" Backwards Compatibility - -" remove in 2.0 -function! ALELint(delay) abort - if !get(g:, 'ale_deprecation_ale_lint', 0) - execute 'echom ''ALELint() is deprecated, use ale#Queue() instead.''' - let g:ale_deprecation_ale_lint = 1 - endif - - call ale#Queue(a:delay) -endfunction - -" remove in 2.0 -function! ALEGetStatusLine() abort - if !get(g:, 'ale_deprecation_ale_get_status_line', 0) - execute 'echom ''ALEGetStatusLine() is deprecated.''' - let g:ale_deprecation_ale_get_status_line = 1 - endif - - return ale#statusline#Status() -endfunction diff --git a/sources_non_forked/ctrlp.vim/autoload/ctrlp.vim b/sources_non_forked/ctrlp.vim/autoload/ctrlp.vim index c5d721e0..6128e28c 100644 --- a/sources_non_forked/ctrlp.vim/autoload/ctrlp.vim +++ b/sources_non_forked/ctrlp.vim/autoload/ctrlp.vim @@ -2595,6 +2595,20 @@ fu! s:ExitIfSingleCandidate() return 0 endfu +fu! s:IsBuiltin() + let builtins = ['tag', 'dir', 'bft', 'rts', 'bkd', 'lns', 'chs', 'mix', 'udo', 'qfx'] + let curtype = s:getextvar('sname') + return s:itemtype < len(s:coretypes) || index(builtins, curtype) > -1 +endfu + +fu! s:DetectFileType(type, ft) + if s:IsBuiltin() || empty(a:ft) || a:ft ==# 'ctrlp' + retu 'ctrlp' + el + retu 'ctrlp.' . a:ft + en +endfu + fu! ctrlp#init(type, ...) if exists('s:init') || s:iscmdwin() | retu | en let [s:ermsg, v:errmsg] = [v:errmsg, ''] @@ -2618,7 +2632,7 @@ fu! ctrlp#init(type, ...) en en cal ctrlp#setlines(s:settype(type)) - set ft=ctrlp + let &filetype = s:DetectFileType(type, &filetype) cal ctrlp#syntax() cal s:SetDefTxt() let curName = s:CurTypeName() diff --git a/sources_non_forked/lightline.vim/autoload/lightline.vim b/sources_non_forked/lightline.vim/autoload/lightline.vim index eea9c9ad..4571c1db 100644 --- a/sources_non_forked/lightline.vim/autoload/lightline.vim +++ b/sources_non_forked/lightline.vim/autoload/lightline.vim @@ -2,7 +2,7 @@ " Filename: autoload/lightline.vim " Author: itchyny " License: MIT License -" Last Change: 2017/12/31 15:55:00. +" Last Change: 2018/06/22 08:50:00. " ============================================================================= let s:save_cpo = &cpo @@ -47,8 +47,10 @@ function! lightline#enable() abort endif augroup lightline autocmd! - autocmd WinEnter,BufWinEnter,FileType,ColorScheme,SessionLoadPost * call lightline#update() - autocmd ColorScheme,SessionLoadPost * call lightline#highlight() + autocmd WinEnter,BufWinEnter,FileType,SessionLoadPost * call lightline#update() + autocmd SessionLoadPost * call lightline#highlight() + autocmd ColorScheme * if !has('vim_starting') || expand('') !=# 'macvim' + \ | call lightline#update() | call lightline#highlight() | endif autocmd CursorMoved,BufUnload * call lightline#update_once() augroup END augroup lightline-disable diff --git a/sources_non_forked/lightline.vim/plugin/lightline.vim b/sources_non_forked/lightline.vim/plugin/lightline.vim index f396010b..fc8f5981 100644 --- a/sources_non_forked/lightline.vim/plugin/lightline.vim +++ b/sources_non_forked/lightline.vim/plugin/lightline.vim @@ -2,7 +2,7 @@ " Filename: plugin/lightline.vim " Author: itchyny " License: MIT License -" Last Change: 2016/03/14 03:31:58. +" Last Change: 2018/06/22 08:49:00. " ============================================================================= if exists('g:loaded_lightline') || v:version < 700 @@ -15,8 +15,10 @@ set cpo&vim augroup lightline autocmd! - autocmd WinEnter,BufWinEnter,FileType,ColorScheme,SessionLoadPost * call lightline#update() - autocmd ColorScheme,SessionLoadPost * call lightline#highlight() + autocmd WinEnter,BufWinEnter,FileType,SessionLoadPost * call lightline#update() + autocmd SessionLoadPost * call lightline#highlight() + autocmd ColorScheme * if !has('vim_starting') || expand('') !=# 'macvim' + \ | call lightline#update() | call lightline#highlight() | endif autocmd CursorMoved,BufUnload * call lightline#update_once() augroup END diff --git a/sources_non_forked/nerdtree/nerdtree_plugin/fs_menu.vim b/sources_non_forked/nerdtree/nerdtree_plugin/fs_menu.vim index ecca9cd3..36e2eae0 100644 --- a/sources_non_forked/nerdtree/nerdtree_plugin/fs_menu.vim +++ b/sources_non_forked/nerdtree/nerdtree_plugin/fs_menu.vim @@ -225,10 +225,11 @@ endfunction function! NERDTreeListNode() let treenode = g:NERDTreeFileNode.GetSelected() if !empty(treenode) - if has("osx") + let s:uname = system("uname") + let stat_cmd = 'stat -c "%s" ' + + if s:uname =~? "Darwin" let stat_cmd = 'stat -f "%z" ' - else - let stat_cmd = 'stat -c "%s" ' endif let cmd = 'size=$(' . stat_cmd . shellescape(treenode.path.str()) . ') && ' . diff --git a/sources_non_forked/nginx.vim/syntax/nginx.vim b/sources_non_forked/nginx.vim/syntax/nginx.vim index ba484434..9e3b16b8 100644 --- a/sources_non_forked/nginx.vim/syntax/nginx.vim +++ b/sources_non_forked/nginx.vim/syntax/nginx.vim @@ -556,6 +556,7 @@ syn keyword ngxDirective ssl_protocols nextgroup=ngxSSLProtocol,ngxSSLProtocolDe syn match ngxSSLProtocol 'TLSv1' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite syn match ngxSSLProtocol 'TLSv1\.1' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite syn match ngxSSLProtocol 'TLSv1\.2' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite +syn match ngxSSLProtocol 'TLSv1\.3' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite " Do not enable highlighting of insecure protocols if sslecure is loaded if !exists('g:loaded_sslsecure') diff --git a/sources_non_forked/vim-fugitive/autoload/fugitive.vim b/sources_non_forked/vim-fugitive/autoload/fugitive.vim index c020d093..22a6ad69 100644 --- a/sources_non_forked/vim-fugitive/autoload/fugitive.vim +++ b/sources_non_forked/vim-fugitive/autoload/fugitive.vim @@ -66,6 +66,14 @@ function! s:shellslash(path) abort endif endfunction +function! s:PlatformSlash(path) abort + if exists('+shellslash') && !&shellslash + return tr(a:path, '/', '\') + else + return a:path + endif +endfunction + let s:executables = {} function! s:executable(binary) abort @@ -83,7 +91,7 @@ endfunction function! fugitive#GitVersion(...) abort if !has_key(s:git_versions, g:fugitive_git_executable) - let s:git_versions[g:fugitive_git_executable] = matchstr(system(g:fugitive_git_executable.' --version'), "\\S\\+\n") + let s:git_versions[g:fugitive_git_executable] = matchstr(system(g:fugitive_git_executable.' --version'), "\\S\\+\\ze\n") endif return s:git_versions[g:fugitive_git_executable] endfunction @@ -107,7 +115,7 @@ function! s:recall() abort endfunction function! s:map(mode, lhs, rhs, ...) abort - let flags = (a:0 ? a:1 : '') . (a:rhs =~# '^' ? '' : '