mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-06 20:54:26 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d837169f1d | ||
|
|
9778a6e5b5 | ||
|
|
0927634916 | ||
|
|
711de2c1be | ||
|
|
fa18195e34 | ||
|
|
0059bcd1d0 | ||
|
|
9d0a55edec | ||
|
|
950204b133 | ||
|
|
bbb6e70377 |
@@ -1,9 +1,9 @@
|
||||
FROM tweekmonster/vim-testbed:latest
|
||||
|
||||
RUN install_vim -tag v8.0.0027 -build \
|
||||
-tag v8.1.0519 -build \
|
||||
-tag v8.1.0204 -build \
|
||||
-tag neovim:v0.2.0 -build \
|
||||
-tag neovim:v0.3.5 -build
|
||||
-tag neovim:v0.3.0 -build
|
||||
|
||||
ENV PACKAGES="\
|
||||
bash \
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2016-2019, w0rp <devw0rp@gmail.com>
|
||||
Copyright (c) 2016-2018, w0rp <devw0rp@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
53
README.md
53
README.md
@@ -1,13 +1,13 @@
|
||||
# Asynchronous Lint Engine [](https://travis-ci.com/w0rp/ale) [](https://ci.appveyor.com/project/w0rp/ale) [](https://gitter.im/vim-ale/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
# Asynchronous Lint Engine [](https://travis-ci.org/w0rp/ale) [](https://ci.appveyor.com/project/w0rp/ale) [](https://gitter.im/vim-ale/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||
ALE (Asynchronous Lint Engine) is a plugin providing linting (syntax checking
|
||||
and semantic errors) in NeoVim 0.2.0+ and Vim 8 while you edit your text files,
|
||||
ALE (Asynchronous Lint Engine) is a plugin for providing linting (checking
|
||||
syntax and semantics) in NeoVim 0.2.0+ and Vim 8 while you edit your text files,
|
||||
and acts as a Vim [Language Server Protocol](https://langserver.org/) client.
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/3518142/59195938-3a81b100-8b85-11e9-8e8d-6a601b1db908.gif" alt="A linting example with the darkspectrum color scheme in GVim." title="A linting example with the darkspectrum color scheme in GVim.">
|
||||
<img src="img/example.gif?raw=true" alt="A linting example with the darkspectrum color scheme in GVim." title="A linting example with the darkspectrum color scheme in GVim.">
|
||||
|
||||
ALE makes use of NeoVim and Vim 8 job control functions and timers to
|
||||
run linters on the contents of text buffers and return errors as
|
||||
@@ -26,7 +26,7 @@ features, including:
|
||||
|
||||
* Diagnostics (via Language Server Protocol linters)
|
||||
* Go To Definition (`:ALEGoToDefinition`)
|
||||
* Completion (Built in completion support, or with Deoplete)
|
||||
* Completion (`let g:ale_completion_enabled = 1` before ALE is loaded)
|
||||
* Finding references (`:ALEFindReferences`)
|
||||
* Hover information (`:ALEHover`)
|
||||
* Symbol search (`:ALESymbolSearch`)
|
||||
@@ -159,36 +159,12 @@ ALE offers some support for completion via hijacking of omnicompletion while you
|
||||
type. All of ALE's completion information must come from Language Server
|
||||
Protocol linters, or from `tsserver` for TypeScript.
|
||||
|
||||
ALE integrates with [Deoplete](https://github.com/Shougo/deoplete.nvim) as a
|
||||
completion source, named `'ale'`. You can configure Deoplete to only use ALE as
|
||||
the source of completion information, or mix it with other sources.
|
||||
|
||||
```vim
|
||||
" Use ALE and also some plugin 'foobar' as completion sources for all code.
|
||||
call deoplete#custom#option('sources', {
|
||||
\ '_': ['ale', 'foobar'],
|
||||
\})
|
||||
```
|
||||
|
||||
ALE also offers its own automatic completion support, which does not require any
|
||||
other plugins, and can be enabled by changing a setting before ALE is loaded.
|
||||
|
||||
```vim
|
||||
" Enable completion where available.
|
||||
" This setting must be set before ALE is loaded.
|
||||
"
|
||||
" You should not turn this setting on if you wish to use ALE as a completion
|
||||
" source for other completion plugins, like Deoplete.
|
||||
let g:ale_completion_enabled = 1
|
||||
```
|
||||
|
||||
ALE provides an omni-completion function you can use for triggering
|
||||
completion manually with `<C-x><C-o>`.
|
||||
|
||||
```vim
|
||||
set omnifunc=ale#completion#OmniFunc
|
||||
```
|
||||
|
||||
See `:help ale-completion` for more information.
|
||||
|
||||
<a name="usage-go-to-definition"></a>
|
||||
@@ -258,14 +234,14 @@ any other tools. Simply clone the plugin into your `pack` directory.
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.vim/pack/git-plugins/start
|
||||
git clone --depth 1 https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale
|
||||
git clone https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale
|
||||
```
|
||||
|
||||
#### NeoVim on Unix
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start
|
||||
git clone --depth 1 https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale
|
||||
git clone https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale
|
||||
```
|
||||
|
||||
#### Vim 8 on Windows
|
||||
@@ -273,7 +249,7 @@ git clone --depth 1 https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pac
|
||||
```bash
|
||||
# Run these commands in the "Git for Windows" Bash terminal
|
||||
mkdir -p ~/vimfiles/pack/git-plugins/start
|
||||
git clone --depth 1 https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale
|
||||
git clone https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale
|
||||
```
|
||||
|
||||
#### Generating Vim help files
|
||||
@@ -541,7 +517,7 @@ let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
|
||||
|
||||
Will give you:
|
||||
|
||||

|
||||

|
||||
|
||||
See `:help g:ale_echo_msg_format` for more information.
|
||||
|
||||
@@ -722,10 +698,11 @@ while you type. ALE uses a timeout which is cancelled and reset every time you
|
||||
type, and this delay can be increased so linters are run less often. See
|
||||
`:help g:ale_lint_delay` for more information.
|
||||
|
||||
If you don't wish to run linters while you type, you can disable that behaviour.
|
||||
Set `g:ale_lint_on_text_changed` to `never`. You won't get as frequent error
|
||||
checking, but ALE shouldn't block your ability to edit a document after you save
|
||||
a file, so the asynchronous nature of the plugin will still be an advantage.
|
||||
If you don't wish to run linters while you type, you can disable that
|
||||
behaviour. Set `g:ale_lint_on_text_changed` to `never` or `normal`. You won't
|
||||
get as frequent error checking, but ALE shouldn't block your ability to edit a
|
||||
document after you save a file, so the asynchronous nature of the plugin will
|
||||
still be an advantage.
|
||||
|
||||
If you are still concerned, you can turn the automatic linting off altogether,
|
||||
including the option `g:ale_lint_on_enter`, and you can run ALE manually with
|
||||
|
||||
@@ -5,10 +5,7 @@ call ale#Set('asm_gcc_executable', 'gcc')
|
||||
call ale#Set('asm_gcc_options', '-Wall')
|
||||
|
||||
function! ale_linters#asm#gcc#GetCommand(buffer) abort
|
||||
" `-o /dev/null` or `-o null` is needed to catch all errors,
|
||||
" -fsyntax-only doesn't catch everything.
|
||||
return '%e -x assembler'
|
||||
\ . ' -o ' . g:ale#util#nul_file
|
||||
return '%e -x assembler -fsyntax-only '
|
||||
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||
\ . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -'
|
||||
endfunction
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
call ale#Set('c_clangd_executable', 'clangd')
|
||||
call ale#Set('c_clangd_options', '')
|
||||
|
||||
function! ale_linters#c#clangd#GetProjectRoot(buffer) abort
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
|
||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
||||
endfunction
|
||||
|
||||
function! ale_linters#c#clangd#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options'))
|
||||
endfunction
|
||||
@@ -13,5 +19,5 @@ call ale#linter#Define('c', {
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {b -> ale#Var(b, 'c_clangd_executable')},
|
||||
\ 'command': function('ale_linters#c#clangd#GetCommand'),
|
||||
\ 'project_root': function('ale#c#FindProjectRoot'),
|
||||
\ 'project_root': function('ale_linters#c#clangd#GetProjectRoot'),
|
||||
\})
|
||||
|
||||
@@ -11,12 +11,9 @@ call ale#Set('c_clangtidy_executable', 'clang-tidy')
|
||||
" http://clang.llvm.org/extra/clang-tidy/checks/list.html
|
||||
|
||||
call ale#Set('c_clangtidy_checks', [])
|
||||
" Set this option to manually set some options for clang-tidy to use as compile
|
||||
" flags.
|
||||
" Set this option to manually set some options for clang-tidy.
|
||||
" This will disable compile_commands.json detection.
|
||||
call ale#Set('c_clangtidy_options', '')
|
||||
" Set this option to manually set options for clang-tidy directly.
|
||||
call ale#Set('c_clangtidy_extra_options', '')
|
||||
call ale#Set('c_build_dir', '')
|
||||
|
||||
function! ale_linters#c#clangtidy#GetCommand(buffer) abort
|
||||
@@ -28,12 +25,8 @@ function! ale_linters#c#clangtidy#GetCommand(buffer) abort
|
||||
\ ? ale#Var(a:buffer, 'c_clangtidy_options')
|
||||
\ : ''
|
||||
|
||||
" Get the options to pass directly to clang-tidy
|
||||
let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options')
|
||||
|
||||
return '%e'
|
||||
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
|
||||
\ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '')
|
||||
\ . ' %s'
|
||||
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
|
||||
\ . (!empty(l:options) ? ' -- ' . l:options : '')
|
||||
|
||||
@@ -5,17 +5,23 @@ call ale#Set('c_cppcheck_executable', 'cppcheck')
|
||||
call ale#Set('c_cppcheck_options', '--enable=style')
|
||||
|
||||
function! ale_linters#c#cppcheck#GetCommand(buffer) abort
|
||||
let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer)
|
||||
let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer)
|
||||
let l:buffer_path_include = empty(l:compile_commands_option)
|
||||
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
|
||||
" Search upwards from the file for compile_commands.json.
|
||||
"
|
||||
" If we find it, we'll `cd` to where the compile_commands.json file is,
|
||||
" then use the file to set up import paths, etc.
|
||||
let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
|
||||
let l:cd_command = !empty(l:compile_commmands_path)
|
||||
\ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
|
||||
\ : ''
|
||||
let l:compile_commands_option = !empty(l:compile_commmands_path)
|
||||
\ ? '--project=compile_commands.json '
|
||||
\ : ''
|
||||
|
||||
return l:cd_command
|
||||
\ . '%e -q --language=c'
|
||||
\ . ale#Pad(l:compile_commands_option)
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options'))
|
||||
\ . l:buffer_path_include
|
||||
\ . '%e -q --language=c '
|
||||
\ . l:compile_commands_option
|
||||
\ . ale#Var(a:buffer, 'c_cppcheck_options')
|
||||
\ . ' %t'
|
||||
endfunction
|
||||
|
||||
|
||||
@@ -5,15 +5,13 @@ call ale#Set('c_cquery_executable', 'cquery')
|
||||
call ale#Set('c_cquery_cache_directory', expand('~/.cache/cquery'))
|
||||
|
||||
function! ale_linters#c#cquery#GetProjectRoot(buffer) abort
|
||||
" Try to find cquery configuration files first.
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.cquery')
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
|
||||
if !empty(l:config)
|
||||
return fnamemodify(l:config, ':h')
|
||||
if empty(l:project_root)
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery')
|
||||
endif
|
||||
|
||||
" Fall back on default project root detection.
|
||||
return ale#c#FindProjectRoot(a:buffer)
|
||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
||||
endfunction
|
||||
|
||||
function! ale_linters#c#cquery#GetInitializationOptions(buffer) abort
|
||||
|
||||
@@ -9,11 +9,7 @@ function! ale_linters#c#gcc#GetCommand(buffer, output) abort
|
||||
|
||||
" -iquote with the directory the file is in makes #include work for
|
||||
" headers in the same directory.
|
||||
"
|
||||
" `-o /dev/null` or `-o null` is needed to catch all errors,
|
||||
" -fsyntax-only doesn't catch everything.
|
||||
return '%e -S -x c'
|
||||
\ . ' -o ' . g:ale#util#nul_file
|
||||
return '%e -S -x c -fsyntax-only'
|
||||
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||
\ . ale#Pad(l:cflags)
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'c_gcc_options')) . ' -'
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
" Author: Raphael Hoegger - https://github.com/pfuender
|
||||
" Description: Cookstyle (RuboCop based), a code style analyzer for Ruby files
|
||||
|
||||
call ale#Set('chef_cookstyle_executable', 'cookstyle')
|
||||
call ale#Set('chef_cookstyle_options', '')
|
||||
|
||||
function! ale_linters#chef#cookstyle#GetCommand(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'chef_cookstyle_options')
|
||||
|
||||
return '%e' . ale#Pad(escape(l:options, '~')) . ' --force-exclusion --format json --stdin ' . ' %s'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#chef#cookstyle#Handle(buffer, lines) abort
|
||||
if len(a:lines) == 0
|
||||
return []
|
||||
endif
|
||||
|
||||
let l:errors = ale#util#FuzzyJSONDecode(a:lines[0], {})
|
||||
|
||||
if !has_key(l:errors, 'summary')
|
||||
\|| l:errors['summary']['offense_count'] == 0
|
||||
\|| empty(l:errors['files'])
|
||||
return []
|
||||
endif
|
||||
|
||||
let l:output = []
|
||||
|
||||
for l:error in l:errors['files'][0]['offenses']
|
||||
let l:start_col = str2nr(l:error['location']['start_column'])
|
||||
let l:end_col = str2nr(l:error['location']['last_column'])
|
||||
|
||||
if !l:end_col
|
||||
let l:end_col = l:start_col + 1
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'lnum': str2nr(l:error['location']['line']),
|
||||
\ 'col': l:start_col,
|
||||
\ 'end_col': l:end_col,
|
||||
\ 'code': l:error['cop_name'],
|
||||
\ 'text': l:error['message'],
|
||||
\ 'type': l:error['severity'] is? 'convention' ? 'W' : 'E',
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('chef', {
|
||||
\ 'name': 'cookstyle',
|
||||
\ 'executable': {b -> ale#Var(b, 'chef_cookstyle_executable')},
|
||||
\ 'command': function('ale_linters#chef#cookstyle#GetCommand'),
|
||||
\ 'callback': 'ale_linters#chef#cookstyle#Handle',
|
||||
\})
|
||||
@@ -1,34 +0,0 @@
|
||||
" Author: Masashi Iizuka <liquidz.uo@gmail.com>
|
||||
" Description: linter for clojure using clj-kondo https://github.com/borkdude/clj-kondo
|
||||
|
||||
function! ale_linters#clojure#clj_kondo#HandleCljKondoFormat(buffer, lines) abort
|
||||
" output format
|
||||
" <filename>:<line>:<column>: <issue type>: <message>
|
||||
let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\d+):(\d+):? ((Exception|error|warning): ?(.+))$'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
let l:type = 'E'
|
||||
|
||||
if l:match[4] is? 'warning'
|
||||
let l:type = 'W'
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'col': l:match[2] + 0,
|
||||
\ 'text': l:match[3],
|
||||
\ 'type': l:type,
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('clojure', {
|
||||
\ 'name': 'clj-kondo',
|
||||
\ 'output_stream': 'stdout',
|
||||
\ 'executable': 'clj-kondo',
|
||||
\ 'command': 'clj-kondo --lint %t',
|
||||
\ 'callback': 'ale_linters#clojure#clj_kondo#HandleCljKondoFormat',
|
||||
\})
|
||||
@@ -12,8 +12,7 @@ function! ale_linters#cpp#clangcheck#GetCommand(buffer) abort
|
||||
let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
|
||||
|
||||
if empty(l:build_dir)
|
||||
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||
let l:build_dir = ale#path#Dirname(l:json_file)
|
||||
let l:build_dir = ale#path#Dirname(ale#c#FindCompileCommands(a:buffer))
|
||||
endif
|
||||
|
||||
" The extra arguments in the command are used to prevent .plist files from
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
call ale#Set('cpp_clangd_executable', 'clangd')
|
||||
call ale#Set('cpp_clangd_options', '')
|
||||
|
||||
function! ale_linters#cpp#clangd#GetProjectRoot(buffer) abort
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
|
||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
||||
endfunction
|
||||
|
||||
function! ale_linters#cpp#clangd#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options'))
|
||||
endfunction
|
||||
@@ -13,5 +19,5 @@ call ale#linter#Define('cpp', {
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {b -> ale#Var(b, 'cpp_clangd_executable')},
|
||||
\ 'command': function('ale_linters#cpp#clangd#GetCommand'),
|
||||
\ 'project_root': function('ale#c#FindProjectRoot'),
|
||||
\ 'project_root': function('ale_linters#cpp#clangd#GetProjectRoot'),
|
||||
\})
|
||||
|
||||
@@ -5,12 +5,9 @@
|
||||
call ale#Set('cpp_clangtidy_executable', 'clang-tidy')
|
||||
" Set this option to check the checks clang-tidy will apply.
|
||||
call ale#Set('cpp_clangtidy_checks', [])
|
||||
" Set this option to manually set some options for clang-tidy to use as compile
|
||||
" flags.
|
||||
" Set this option to manually set some options for clang-tidy.
|
||||
" This will disable compile_commands.json detection.
|
||||
call ale#Set('cpp_clangtidy_options', '')
|
||||
" Set this option to manually set options for clang-tidy directly.
|
||||
call ale#Set('cpp_clangtidy_extra_options', '')
|
||||
call ale#Set('c_build_dir', '')
|
||||
|
||||
function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
|
||||
@@ -22,12 +19,8 @@ function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
|
||||
\ ? ale#Var(a:buffer, 'cpp_clangtidy_options')
|
||||
\ : ''
|
||||
|
||||
" Get the options to pass directly to clang-tidy
|
||||
let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options')
|
||||
|
||||
return '%e'
|
||||
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
|
||||
\ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '')
|
||||
\ . ' %s'
|
||||
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
|
||||
\ . (!empty(l:options) ? ' -- ' . l:options : '')
|
||||
|
||||
@@ -5,17 +5,23 @@ call ale#Set('cpp_cppcheck_executable', 'cppcheck')
|
||||
call ale#Set('cpp_cppcheck_options', '--enable=style')
|
||||
|
||||
function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort
|
||||
let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer)
|
||||
let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer)
|
||||
let l:buffer_path_include = empty(l:compile_commands_option)
|
||||
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
|
||||
" Search upwards from the file for compile_commands.json.
|
||||
"
|
||||
" If we find it, we'll `cd` to where the compile_commands.json file is,
|
||||
" then use the file to set up import paths, etc.
|
||||
let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
|
||||
let l:cd_command = !empty(l:compile_commmands_path)
|
||||
\ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
|
||||
\ : ''
|
||||
let l:compile_commands_option = !empty(l:compile_commmands_path)
|
||||
\ ? '--project=compile_commands.json '
|
||||
\ : ''
|
||||
|
||||
return l:cd_command
|
||||
\ . '%e -q --language=c++'
|
||||
\ . ale#Pad(l:compile_commands_option)
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options'))
|
||||
\ . l:buffer_path_include
|
||||
\ . '%e -q --language=c++ '
|
||||
\ . l:compile_commands_option
|
||||
\ . ale#Var(a:buffer, 'cpp_cppcheck_options')
|
||||
\ . ' %t'
|
||||
endfunction
|
||||
|
||||
|
||||
@@ -5,15 +5,13 @@ call ale#Set('cpp_cquery_executable', 'cquery')
|
||||
call ale#Set('cpp_cquery_cache_directory', expand('~/.cache/cquery'))
|
||||
|
||||
function! ale_linters#cpp#cquery#GetProjectRoot(buffer) abort
|
||||
" Try to find cquery configuration files first.
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.cquery')
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
|
||||
if !empty(l:config)
|
||||
return fnamemodify(l:config, ':h')
|
||||
if empty(l:project_root)
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery')
|
||||
endif
|
||||
|
||||
" Fall back on default project root detection.
|
||||
return ale#c#FindProjectRoot(a:buffer)
|
||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
||||
endfunction
|
||||
|
||||
function! ale_linters#cpp#cquery#GetInitializationOptions(buffer) abort
|
||||
|
||||
@@ -9,11 +9,7 @@ function! ale_linters#cpp#gcc#GetCommand(buffer, output) abort
|
||||
|
||||
" -iquote with the directory the file is in makes #include work for
|
||||
" headers in the same directory.
|
||||
"
|
||||
" `-o /dev/null` or `-o null` is needed to catch all errors,
|
||||
" -fsyntax-only doesn't catch everything.
|
||||
return '%e -S -x c++'
|
||||
\ . ' -o ' . g:ale#util#nul_file
|
||||
return '%e -S -x c++ -fsyntax-only'
|
||||
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||
\ . ale#Pad(l:cflags)
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'cpp_gcc_options')) . ' -'
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
" Author: harttle <yangjvn@126.com>
|
||||
" Description: fecs for CSS files
|
||||
|
||||
call ale#linter#Define('css', {
|
||||
\ 'name': 'fecs',
|
||||
\ 'executable': function('ale#handlers#fecs#GetExecutable'),
|
||||
\ 'command': function('ale#handlers#fecs#GetCommand'),
|
||||
\ 'callback': 'ale#handlers#fecs#Handle',
|
||||
\})
|
||||
@@ -1,93 +0,0 @@
|
||||
" Author: Autoine Gagne - https://github.com/AntoineGagne
|
||||
" Description: Define a checker that runs dialyzer on Erlang files.
|
||||
|
||||
let g:ale_erlang_dialyzer_executable =
|
||||
\ get(g:, 'ale_erlang_dialyzer_executable', 'dialyzer')
|
||||
let g:ale_erlang_dialyzer_plt_file =
|
||||
\ get(g:, 'ale_erlang_dialyzer_plt_file', '')
|
||||
let g:ale_erlang_dialyzer_rebar3_profile =
|
||||
\ get(g:, 'ale_erlang_dialyzer_rebar3_profile', 'default')
|
||||
|
||||
function! ale_linters#erlang#dialyzer#GetRebar3Profile(buffer) abort
|
||||
return ale#Var(a:buffer, 'erlang_dialyzer_rebar3_profile')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#erlang#dialyzer#FindPlt(buffer) abort
|
||||
let l:plt_file = ''
|
||||
let l:rebar3_profile = ale_linters#erlang#dialyzer#GetRebar3Profile(a:buffer)
|
||||
let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build' . l:rebar3_profile)
|
||||
|
||||
if !empty(l:plt_file_directory)
|
||||
let l:plt_file = split(globpath(l:plt_file_directory, '/*_plt'), '\n')
|
||||
endif
|
||||
|
||||
if !empty(l:plt_file)
|
||||
return l:plt_file[0]
|
||||
endif
|
||||
|
||||
if !empty($REBAR_PLT_DIR)
|
||||
return expand('$REBAR_PLT_DIR/dialyzer/plt')
|
||||
endif
|
||||
|
||||
return expand('$HOME/.dialyzer_plt')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#erlang#dialyzer#GetPlt(buffer) abort
|
||||
let l:plt_file = ale#Var(a:buffer, 'erlang_dialyzer_plt_file')
|
||||
|
||||
if !empty(l:plt_file)
|
||||
return l:plt_file
|
||||
endif
|
||||
|
||||
return ale_linters#erlang#dialyzer#FindPlt(a:buffer)
|
||||
endfunction
|
||||
|
||||
function! ale_linters#erlang#dialyzer#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'erlang_dialyzer_executable')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#erlang#dialyzer#GetCommand(buffer) abort
|
||||
let l:command = ale#Escape(ale_linters#erlang#dialyzer#GetExecutable(a:buffer))
|
||||
\ . ' -n'
|
||||
\ . ' --plt ' . ale#Escape(ale_linters#erlang#dialyzer#GetPlt(a:buffer))
|
||||
\ . ' -Wunmatched_returns'
|
||||
\ . ' -Werror_handling'
|
||||
\ . ' -Wrace_conditions'
|
||||
\ . ' -Wunderspecs'
|
||||
\ . ' %s'
|
||||
|
||||
return l:command
|
||||
endfunction
|
||||
|
||||
function! ale_linters#erlang#dialyzer#Handle(buffer, lines) abort
|
||||
" Match patterns like the following:
|
||||
"
|
||||
" erl_tidy_prv_fmt.erl:3: Callback info about the provider behaviour is not available
|
||||
let l:pattern = '^\S\+:\(\d\+\): \(.\+\)$'
|
||||
let l:output = []
|
||||
|
||||
for l:line in a:lines
|
||||
let l:match = matchlist(l:line, l:pattern)
|
||||
|
||||
if len(l:match) != 0
|
||||
let l:code = l:match[2]
|
||||
|
||||
call add(l:output, {
|
||||
\ 'lnum': str2nr(l:match[1]),
|
||||
\ 'lcol': 0,
|
||||
\ 'text': l:code,
|
||||
\ 'type': 'W'
|
||||
\})
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('erlang', {
|
||||
\ 'name': 'dialyzer',
|
||||
\ 'executable': function('ale_linters#erlang#dialyzer#GetExecutable'),
|
||||
\ 'command': function('ale_linters#erlang#dialyzer#GetCommand'),
|
||||
\ 'callback': function('ale_linters#erlang#dialyzer#Handle'),
|
||||
\ 'lint_file': 1
|
||||
\})
|
||||
@@ -1,30 +0,0 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Author: Jerko Steiner <https://github.com/jeremija>
|
||||
" Description: https://github.com/saibing/gopls
|
||||
|
||||
call ale#Set('go_gopls_executable', 'gopls')
|
||||
call ale#Set('go_gopls_options', '--mode stdio')
|
||||
|
||||
function! ale_linters#go#gopls#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'go_gopls_options'))
|
||||
endfunction
|
||||
|
||||
function! ale_linters#go#gopls#FindProjectRoot(buffer) abort
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'go.mod')
|
||||
let l:mods = ':h'
|
||||
|
||||
if empty(l:project_root)
|
||||
let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git')
|
||||
let l:mods = ':h:h'
|
||||
endif
|
||||
|
||||
return !empty(l:project_root) ? fnamemodify(l:project_root, l:mods) : ''
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('go', {
|
||||
\ 'name': 'gopls',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {b -> ale#Var(b, 'go_gopls_executable')},
|
||||
\ 'command': function('ale_linters#go#gopls#GetCommand'),
|
||||
\ 'project_root': function('ale_linters#go#gopls#FindProjectRoot'),
|
||||
\})
|
||||
@@ -4,8 +4,7 @@
|
||||
call ale#Set('haskell_cabal_ghc_options', '-fno-code -v0')
|
||||
|
||||
function! ale_linters#haskell#cabal_ghc#GetCommand(buffer) abort
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . 'cabal exec -- ghc '
|
||||
return 'cabal exec -- ghc '
|
||||
\ . ale#Var(a:buffer, 'haskell_cabal_ghc_options')
|
||||
\ . ' %t'
|
||||
endfunction
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
call ale#Set('haskell_stack_ghc_options', '-fno-code -v0')
|
||||
|
||||
function! ale_linters#haskell#stack_ghc#GetCommand(buffer) abort
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . ale#handlers#haskell#GetStackExecutable(a:buffer)
|
||||
return ale#handlers#haskell#GetStackExecutable(a:buffer)
|
||||
\ . ' ghc -- '
|
||||
\ . ale#Var(a:buffer, 'haskell_stack_ghc_options')
|
||||
\ . ' %t'
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
" Author: harttle <yangjvn@126.com>
|
||||
" Description: fecs for HTMl files
|
||||
|
||||
call ale#linter#Define('html', {
|
||||
\ 'name': 'fecs',
|
||||
\ 'executable': function('ale#handlers#fecs#GetExecutable'),
|
||||
\ 'command': function('ale#handlers#fecs#GetCommand'),
|
||||
\ 'callback': 'ale#handlers#fecs#Handle',
|
||||
\})
|
||||
@@ -1,10 +1,6 @@
|
||||
" Author: Devon Meunier <devon.meunier@gmail.com>
|
||||
" Description: checkstyle for Java files
|
||||
|
||||
call ale#Set('java_checkstyle_executable', 'checkstyle')
|
||||
call ale#Set('java_checkstyle_config', 'google_checks.xml')
|
||||
call ale#Set('java_checkstyle_options', '')
|
||||
|
||||
function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
|
||||
let l:output = []
|
||||
|
||||
@@ -21,10 +17,6 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
|
||||
\})
|
||||
endfor
|
||||
|
||||
if !empty(l:output)
|
||||
return l:output
|
||||
endif
|
||||
|
||||
" old checkstyle versions
|
||||
let l:pattern = '\v(.+):(\d+): ([^:]+): (.+)$'
|
||||
|
||||
@@ -40,21 +32,18 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
|
||||
endfunction
|
||||
|
||||
function! ale_linters#java#checkstyle#GetCommand(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'java_checkstyle_options')
|
||||
let l:config_option = ale#Var(a:buffer, 'java_checkstyle_config')
|
||||
let l:config = l:options !~# '\v(^| )-c' && !empty(l:config_option)
|
||||
\ ? ale#path#FindNearestFile(a:buffer, l:config_option)
|
||||
\ : ''
|
||||
|
||||
return '%e'
|
||||
\ . ale#Pad(l:options)
|
||||
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
|
||||
return 'checkstyle '
|
||||
\ . ale#Var(a:buffer, 'java_checkstyle_options')
|
||||
\ . ' %s'
|
||||
endfunction
|
||||
|
||||
if !exists('g:ale_java_checkstyle_options')
|
||||
let g:ale_java_checkstyle_options = '-c /google_checks.xml'
|
||||
endif
|
||||
|
||||
call ale#linter#Define('java', {
|
||||
\ 'name': 'checkstyle',
|
||||
\ 'executable': {b -> ale#Var(b, 'java_checkstyle_executable')},
|
||||
\ 'executable': 'checkstyle',
|
||||
\ 'command': function('ale_linters#java#checkstyle#GetCommand'),
|
||||
\ 'callback': 'ale_linters#java#checkstyle#Handle',
|
||||
\ 'lint_file': 1,
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
" Author: Horacio Sanson <https://github.com/hsanson>
|
||||
" Description: Support for the Eclipse language server https://github.com/eclipse/eclipse.jdt.ls
|
||||
|
||||
let s:version_cache = {}
|
||||
|
||||
call ale#Set('java_eclipselsp_path', ale#path#Simplify($HOME . '/eclipse.jdt.ls'))
|
||||
call ale#Set('java_eclipselsp_config_path', '')
|
||||
call ale#Set('java_eclipselsp_workspace_path', '')
|
||||
call ale#Set('java_eclipselsp_executable', 'java')
|
||||
|
||||
function! ale_linters#java#eclipselsp#Executable(buffer) abort
|
||||
return ale#Var(a:buffer, 'java_eclipselsp_executable')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#java#eclipselsp#TargetPath(buffer) abort
|
||||
return ale#Var(a:buffer, 'java_eclipselsp_path')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#java#eclipselsp#JarPath(buffer) abort
|
||||
let l:path = ale_linters#java#eclipselsp#TargetPath(a:buffer)
|
||||
|
||||
" Search jar file within repository path when manually built using mvn
|
||||
let l:repo_path = l:path . '/org.eclipse.jdt.ls.product/target/repository'
|
||||
let l:files = globpath(l:repo_path, '**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
|
||||
|
||||
if len(l:files) == 1
|
||||
return l:files[0]
|
||||
endif
|
||||
|
||||
" Search jar file within VSCode extensions folder.
|
||||
let l:files = globpath(l:path, '**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
|
||||
|
||||
if len(l:files) == 1
|
||||
return l:files[0]
|
||||
endif
|
||||
|
||||
" Search jar file within system package path
|
||||
let l:files = globpath('/usr/share/java/jdtls/plugins', 'org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
|
||||
|
||||
if len(l:files) == 1
|
||||
return l:files[0]
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale_linters#java#eclipselsp#ConfigurationPath(buffer) abort
|
||||
let l:path = fnamemodify(ale_linters#java#eclipselsp#JarPath(a:buffer), ':p:h:h')
|
||||
let l:config_path = ale#Var(a:buffer, 'java_eclipselsp_config_path')
|
||||
|
||||
if !empty(l:config_path)
|
||||
return ale#path#Simplify(l:config_path)
|
||||
endif
|
||||
|
||||
if has('win32')
|
||||
let l:path = l:path . '/config_win'
|
||||
elseif has('macunix')
|
||||
let l:path = l:path . '/config_mac'
|
||||
else
|
||||
let l:path = l:path . '/config_linux'
|
||||
endif
|
||||
|
||||
return ale#path#Simplify(l:path)
|
||||
endfunction
|
||||
|
||||
function! ale_linters#java#eclipselsp#VersionCheck(version_lines) abort
|
||||
return s:GetVersion('', a:version_lines)
|
||||
endfunction
|
||||
|
||||
function! s:GetVersion(executable, version_lines) abort
|
||||
let l:version = []
|
||||
|
||||
for l:line in a:version_lines
|
||||
let l:match = matchlist(l:line, '\(\d\+\)\.\(\d\+\)\.\(\d\+\)')
|
||||
|
||||
if !empty(l:match)
|
||||
let l:version = [l:match[1] + 0, l:match[2] + 0, l:match[3] + 0]
|
||||
let s:version_cache[a:executable] = l:version
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:version
|
||||
endfunction
|
||||
|
||||
function! ale_linters#java#eclipselsp#CommandWithVersion(buffer, version_lines, meta) abort
|
||||
let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer)
|
||||
let l:version = s:GetVersion(l:executable, a:version_lines)
|
||||
|
||||
return ale_linters#java#eclipselsp#Command(a:buffer, l:version)
|
||||
endfunction
|
||||
|
||||
function! ale_linters#java#eclipselsp#WorkspacePath(buffer) abort
|
||||
let l:wspath = ale#Var(a:buffer, 'java_eclipselsp_workspace_path')
|
||||
|
||||
if !empty(l:wspath)
|
||||
return l:wspath
|
||||
endif
|
||||
|
||||
return ale#path#Dirname(ale#java#FindProjectRoot(a:buffer))
|
||||
endfunction
|
||||
|
||||
function! ale_linters#java#eclipselsp#Command(buffer, version) abort
|
||||
let l:path = ale#Var(a:buffer, 'java_eclipselsp_path')
|
||||
|
||||
let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer)
|
||||
|
||||
let l:cmd = [ ale#Escape(l:executable),
|
||||
\ '-Declipse.application=org.eclipse.jdt.ls.core.id1',
|
||||
\ '-Dosgi.bundles.defaultStartLevel=4',
|
||||
\ '-Declipse.product=org.eclipse.jdt.ls.core.product',
|
||||
\ '-Dlog.level=ALL',
|
||||
\ '-noverify',
|
||||
\ '-Xmx1G',
|
||||
\ '-jar',
|
||||
\ ale#Escape(ale_linters#java#eclipselsp#JarPath(a:buffer)),
|
||||
\ '-configuration',
|
||||
\ ale#Escape(ale_linters#java#eclipselsp#ConfigurationPath(a:buffer)),
|
||||
\ '-data',
|
||||
\ ale#Escape(ale_linters#java#eclipselsp#WorkspacePath(a:buffer))
|
||||
\ ]
|
||||
|
||||
if ale#semver#GTE(a:version, [1, 9])
|
||||
call add(l:cmd, '--add-modules=ALL-SYSTEM')
|
||||
call add(l:cmd, '--add-opens java.base/java.util=ALL-UNNAMED')
|
||||
call add(l:cmd, '--add-opens java.base/java.lang=ALL-UNNAMED')
|
||||
endif
|
||||
|
||||
return join(l:cmd, ' ')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#java#eclipselsp#RunWithVersionCheck(buffer) abort
|
||||
let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer)
|
||||
|
||||
if empty(l:executable)
|
||||
return ''
|
||||
endif
|
||||
|
||||
let l:cache = s:version_cache
|
||||
|
||||
if has_key(s:version_cache, l:executable)
|
||||
return ale_linters#java#eclipselsp#Command(a:buffer, s:version_cache[l:executable])
|
||||
endif
|
||||
|
||||
let l:command = ale#Escape(l:executable) . ' -version'
|
||||
|
||||
return ale#command#Run(
|
||||
\ a:buffer,
|
||||
\ l:command,
|
||||
\ function('ale_linters#java#eclipselsp#CommandWithVersion')
|
||||
\)
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('java', {
|
||||
\ 'name': 'eclipselsp',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': function('ale_linters#java#eclipselsp#Executable'),
|
||||
\ 'command': function('ale_linters#java#eclipselsp#RunWithVersionCheck'),
|
||||
\ 'language': 'java',
|
||||
\ 'project_root': function('ale#java#FindProjectRoot'),
|
||||
\})
|
||||
@@ -21,11 +21,6 @@ function! ale_linters#java#javac#RunWithImportPaths(buffer) abort
|
||||
let l:command = ale#gradle#BuildClasspathCommand(a:buffer)
|
||||
endif
|
||||
|
||||
" Try to use Ant if Gradle and Maven aren't available
|
||||
if empty(l:command)
|
||||
let l:command = ale#ant#BuildClasspathCommand(a:buffer)
|
||||
endif
|
||||
|
||||
if empty(l:command)
|
||||
return ale_linters#java#javac#GetCommand(a:buffer, [], {})
|
||||
endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
" Author: Horacio Sanson <https://github.com/hsanson>
|
||||
" Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac
|
||||
|
||||
call ale#Set('java_javalsp_executable', '')
|
||||
call ale#Set('java_javalsp_executable', 'java')
|
||||
|
||||
function! ale_linters#java#javalsp#Executable(buffer) abort
|
||||
return ale#Var(a:buffer, 'java_javalsp_executable')
|
||||
@@ -10,25 +10,7 @@ endfunction
|
||||
function! ale_linters#java#javalsp#Command(buffer) abort
|
||||
let l:executable = ale_linters#java#javalsp#Executable(a:buffer)
|
||||
|
||||
if fnamemodify(l:executable, ':t') is# 'java'
|
||||
" For backward compatibility.
|
||||
let l:cmd = [
|
||||
\ ale#Escape(l:executable),
|
||||
\ '--add-exports jdk.compiler/com.sun.tools.javac.api=javacs',
|
||||
\ '--add-exports jdk.compiler/com.sun.tools.javac.code=javacs',
|
||||
\ '--add-exports jdk.compiler/com.sun.tools.javac.comp=javacs',
|
||||
\ '--add-exports jdk.compiler/com.sun.tools.javac.main=javacs',
|
||||
\ '--add-exports jdk.compiler/com.sun.tools.javac.tree=javacs',
|
||||
\ '--add-exports jdk.compiler/com.sun.tools.javac.model=javacs',
|
||||
\ '--add-exports jdk.compiler/com.sun.tools.javac.util=javacs',
|
||||
\ '--add-opens jdk.compiler/com.sun.tools.javac.api=javacs',
|
||||
\ '-m javacs/org.javacs.Main',
|
||||
\]
|
||||
|
||||
return join(l:cmd, ' ')
|
||||
else
|
||||
return ale#Escape(l:executable)
|
||||
endif
|
||||
return ale#Escape(l:executable) . ' -Xverify:none -m javacs/org.javacs.Main'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('java', {
|
||||
|
||||
@@ -6,5 +6,5 @@ call ale#linter#Define('javascript', {
|
||||
\ 'output_stream': 'both',
|
||||
\ 'executable': function('ale#handlers#eslint#GetExecutable'),
|
||||
\ 'command': function('ale#handlers#eslint#GetCommand'),
|
||||
\ 'callback': 'ale#handlers#eslint#HandleJSON',
|
||||
\ 'callback': 'ale#handlers#eslint#Handle',
|
||||
\})
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
" Author: harttle <yangjvn@126.com>
|
||||
" Description: fecs for JavaScript files
|
||||
|
||||
call ale#linter#Define('javascript', {
|
||||
\ 'name': 'fecs',
|
||||
\ 'executable': function('ale#handlers#fecs#GetExecutable'),
|
||||
\ 'command': function('ale#handlers#fecs#GetCommand'),
|
||||
\ 'read_buffer': 0,
|
||||
\ 'callback': 'ale#handlers#fecs#Handle',
|
||||
\})
|
||||
@@ -14,7 +14,7 @@ endfunction
|
||||
function! ale_linters#javascript#xo#GetCommand(buffer) abort
|
||||
return ale#Escape(ale_linters#javascript#xo#GetExecutable(a:buffer))
|
||||
\ . ' ' . ale#Var(a:buffer, 'javascript_xo_options')
|
||||
\ . ' --reporter json --stdin --stdin-filename %s'
|
||||
\ . ' --reporter unix --stdin --stdin-filename %s'
|
||||
endfunction
|
||||
|
||||
" xo uses eslint and the output format is the same
|
||||
@@ -22,5 +22,5 @@ call ale#linter#Define('javascript', {
|
||||
\ 'name': 'xo',
|
||||
\ 'executable': function('ale_linters#javascript#xo#GetExecutable'),
|
||||
\ 'command': function('ale_linters#javascript#xo#GetCommand'),
|
||||
\ 'callback': 'ale#handlers#eslint#HandleJSON',
|
||||
\ 'callback': 'ale#handlers#eslint#Handle',
|
||||
\})
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
call ale#Set('objc_clangd_executable', 'clangd')
|
||||
call ale#Set('objc_clangd_options', '')
|
||||
|
||||
function! ale_linters#objc#clangd#GetProjectRoot(buffer) abort
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
|
||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
||||
endfunction
|
||||
|
||||
function! ale_linters#objc#clangd#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'objc_clangd_options'))
|
||||
endfunction
|
||||
@@ -13,5 +19,5 @@ call ale#linter#Define('objc', {
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {b -> ale#Var(b, 'objc_clangd_executable')},
|
||||
\ 'command': function('ale_linters#objc#clangd#GetCommand'),
|
||||
\ 'project_root': function('ale#c#FindProjectRoot'),
|
||||
\ 'project_root': function('ale_linters#objc#clangd#GetProjectRoot'),
|
||||
\})
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
call ale#Set('objcpp_clangd_executable', 'clangd')
|
||||
call ale#Set('objcpp_clangd_options', '')
|
||||
|
||||
function! ale_linters#objcpp#clangd#GetProjectRoot(buffer) abort
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
|
||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
||||
endfunction
|
||||
|
||||
function! ale_linters#objcpp#clangd#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'objcpp_clangd_options'))
|
||||
endfunction
|
||||
@@ -13,5 +19,5 @@ call ale#linter#Define('objcpp', {
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {b -> ale#Var(b, 'objcpp_clangd_executable')},
|
||||
\ 'command': function('ale_linters#objcpp#clangd#GetCommand'),
|
||||
\ 'project_root': function('ale#c#FindProjectRoot'),
|
||||
\ 'project_root': function('ale_linters#objcpp#clangd#GetProjectRoot'),
|
||||
\})
|
||||
|
||||
@@ -10,13 +10,13 @@ call ale#Set('php_phpcs_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
function! ale_linters#php#phpcs#GetCommand(buffer) abort
|
||||
let l:standard = ale#Var(a:buffer, 'php_phpcs_standard')
|
||||
let l:standard_option = !empty(l:standard)
|
||||
\ ? '--standard=' . ale#Escape(l:standard)
|
||||
\ ? '--standard=' . l:standard
|
||||
\ : ''
|
||||
let l:options = ale#Var(a:buffer, 'php_phpcs_options')
|
||||
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . '%e -s --report=emacs --stdin-path=%s'
|
||||
\ . ale#Pad(l:standard_option)
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'php_phpcs_options'))
|
||||
return '%e -s --report=emacs --stdin-path=%s'
|
||||
\ . ale#Pad(l:standard_option)
|
||||
\ . ale#Pad(l:options)
|
||||
endfunction
|
||||
|
||||
function! ale_linters#php#phpcs#Handle(buffer, lines) abort
|
||||
@@ -36,7 +36,6 @@ function! ale_linters#php#phpcs#Handle(buffer, lines) abort
|
||||
\ 'col': l:match[2] + 0,
|
||||
\ 'text': l:text,
|
||||
\ 'type': l:type is# 'error' ? 'E' : 'W',
|
||||
\ 'sub_type': 'style',
|
||||
\})
|
||||
endfor
|
||||
|
||||
|
||||
@@ -3,42 +3,23 @@
|
||||
|
||||
" Set to change the ruleset
|
||||
let g:ale_php_phpstan_executable = get(g:, 'ale_php_phpstan_executable', 'phpstan')
|
||||
let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '')
|
||||
let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '4')
|
||||
let g:ale_php_phpstan_configuration = get(g:, 'ale_php_phpstan_configuration', '')
|
||||
let g:ale_php_phpstan_autoload = get(g:, 'ale_php_phpstan_autoload', '')
|
||||
|
||||
function! ale_linters#php#phpstan#GetCommand(buffer, version) abort
|
||||
let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration')
|
||||
let l:configuration_option = !empty(l:configuration)
|
||||
\ ? ' -c ' . ale#Escape(l:configuration)
|
||||
\ : ''
|
||||
|
||||
let l:autoload = ale#Var(a:buffer, 'php_phpstan_autoload')
|
||||
let l:autoload_option = !empty(l:autoload)
|
||||
\ ? ' -a ' . ale#Escape(l:autoload)
|
||||
\ : ''
|
||||
|
||||
let l:level = ale#Var(a:buffer, 'php_phpstan_level')
|
||||
let l:config_file_exists = ale#path#FindNearestFile(a:buffer, 'phpstan.neon')
|
||||
|
||||
if empty(l:level) && empty(l:config_file_exists)
|
||||
" if no configuration file is found, then use 4 as a default level
|
||||
let l:level = '4'
|
||||
endif
|
||||
|
||||
let l:level_option = !empty(l:level)
|
||||
\ ? ' -l ' . ale#Escape(l:level)
|
||||
\ ? ' -c ' . l:configuration
|
||||
\ : ''
|
||||
|
||||
let l:error_format = ale#semver#GTE(a:version, [0, 10, 3])
|
||||
\ ? ' --error-format raw'
|
||||
\ : ' --errorFormat raw'
|
||||
|
||||
return '%e analyze --no-progress'
|
||||
return '%e analyze -l'
|
||||
\ . ale#Var(a:buffer, 'php_phpstan_level')
|
||||
\ . l:error_format
|
||||
\ . l:configuration_option
|
||||
\ . l:autoload_option
|
||||
\ . l:level_option
|
||||
\ . ' %s'
|
||||
endfunction
|
||||
|
||||
@@ -54,7 +35,7 @@ function! ale_linters#php#phpstan#Handle(buffer, lines) abort
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[2] + 0,
|
||||
\ 'text': l:match[3],
|
||||
\ 'type': 'E',
|
||||
\ 'type': 'W',
|
||||
\})
|
||||
endfor
|
||||
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
" Author: Jesse Harris - https://github.com/zigford
|
||||
" Description: This file adds support for powershell scripts synatax errors
|
||||
|
||||
call ale#Set('powershell_powershell_executable', 'pwsh')
|
||||
|
||||
function! ale_linters#powershell#powershell#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'powershell_powershell_executable')
|
||||
endfunction
|
||||
|
||||
" Some powershell magic to show syntax errors without executing the script
|
||||
" thanks to keith hill:
|
||||
" https://rkeithhill.wordpress.com/2007/10/30/powershell-quicktip-preparsing-scripts-to-check-for-syntax-errors/
|
||||
function! ale_linters#powershell#powershell#GetCommand(buffer) abort
|
||||
let l:script = ['Param($Script);
|
||||
\ trap {$_;continue} & {
|
||||
\ $Contents = Get-Content -Path $Script;
|
||||
\ $Contents = [string]::Join([Environment]::NewLine, $Contents);
|
||||
\ [void]$ExecutionContext.InvokeCommand.NewScriptBlock($Contents);
|
||||
\ };']
|
||||
|
||||
return ale#powershell#RunPowerShell(
|
||||
\ a:buffer, 'powershell_powershell', l:script)
|
||||
endfunction
|
||||
|
||||
" Parse powershell error output using regex into a list of dicts
|
||||
function! ale_linters#powershell#powershell#Handle(buffer, lines) abort
|
||||
let l:output = []
|
||||
" Our 3 patterns we need to scrape the data for the dicts
|
||||
let l:patterns = [
|
||||
\ '\v^At line:(\d+) char:(\d+)',
|
||||
\ '\v^(At|\+| )@!.*',
|
||||
\ '\vFullyQualifiedErrorId : (\w+)',
|
||||
\]
|
||||
|
||||
let l:matchcount = 0
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:patterns)
|
||||
" We want to work with 3 matches per syntax error
|
||||
let l:matchcount = l:matchcount + 1
|
||||
|
||||
if l:matchcount == 1 || str2nr(l:match[1])
|
||||
" First match consists of 2 capture groups, and
|
||||
" can capture the line and col
|
||||
if exists('l:item')
|
||||
" We may be here because the last syntax
|
||||
" didn't emit a code, and so only had 2
|
||||
" matches
|
||||
call add(l:output, l:item)
|
||||
let l:matchcount = 1
|
||||
endif
|
||||
|
||||
let l:item = {
|
||||
\ 'lnum': str2nr(l:match[1]),
|
||||
\ 'col': str2nr(l:match[2]),
|
||||
\ 'type': 'E',
|
||||
\}
|
||||
elseif l:matchcount == 2
|
||||
" Second match[0] grabs the full line in order
|
||||
" to handles the text
|
||||
let l:item['text'] = l:match[0]
|
||||
else
|
||||
" Final match handles the code, however
|
||||
" powershell only emits 1 code for all errors
|
||||
" so, we get the final code on the last error
|
||||
" and loop over the previously added items to
|
||||
" append the code we now know
|
||||
call add(l:output, l:item)
|
||||
unlet l:item
|
||||
|
||||
if len(l:match[1]) > 0
|
||||
for l:i in l:output
|
||||
let l:i['code'] = l:match[1]
|
||||
endfor
|
||||
endif
|
||||
|
||||
" Reset the matchcount so we can begin gathering
|
||||
" matches for the next syntax error
|
||||
let l:matchcount = 0
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('powershell', {
|
||||
\ 'name': 'powershell',
|
||||
\ 'executable_callback': 'ale_linters#powershell#powershell#GetExecutable',
|
||||
\ 'command_callback': 'ale_linters#powershell#powershell#GetCommand',
|
||||
\ 'output_stream': 'stdout',
|
||||
\ 'callback': 'ale_linters#powershell#powershell#Handle',
|
||||
\})
|
||||
@@ -13,6 +13,37 @@ function! ale_linters#powershell#psscriptanalyzer#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'powershell_psscriptanalyzer_executable')
|
||||
endfunction
|
||||
|
||||
" Write a powershell script to a temp file for execution
|
||||
" return the command used to execute it
|
||||
function! s:TemporaryPSScript(buffer, input) abort
|
||||
let l:filename = 'script.ps1'
|
||||
" Create a temp dir to house our temp .ps1 script
|
||||
" a temp dir is needed as powershell needs the .ps1
|
||||
" extension
|
||||
let l:tempdir = ale#util#Tempname() . (has('win32') ? '\' : '/')
|
||||
let l:tempscript = l:tempdir . l:filename
|
||||
" Create the temporary directory for the file, unreadable by 'other'
|
||||
" users.
|
||||
call mkdir(l:tempdir, '', 0750)
|
||||
" Automatically delete the directory later.
|
||||
call ale#command#ManageDirectory(a:buffer, l:tempdir)
|
||||
" Write the script input out to a file.
|
||||
call ale#util#Writefile(a:buffer, a:input, l:tempscript)
|
||||
|
||||
return l:tempscript
|
||||
endfunction
|
||||
|
||||
function! ale_linters#powershell#psscriptanalyzer#RunPowerShell(buffer, command) abort
|
||||
let l:executable = ale_linters#powershell#psscriptanalyzer#GetExecutable(
|
||||
\ a:buffer)
|
||||
let l:tempscript = s:TemporaryPSScript(a:buffer, a:command)
|
||||
|
||||
return ale#Escape(l:executable)
|
||||
\ . ' -Exe Bypass -NoProfile -File '
|
||||
\ . ale#Escape(l:tempscript)
|
||||
\ . ' %t'
|
||||
endfunction
|
||||
|
||||
" Run Invoke-ScriptAnalyzer and output each linting message as 4 seperate lines
|
||||
" for each parsing
|
||||
function! ale_linters#powershell#psscriptanalyzer#GetCommand(buffer) abort
|
||||
@@ -29,10 +60,8 @@ function! ale_linters#powershell#psscriptanalyzer#GetCommand(buffer) abort
|
||||
\ $_.Message;
|
||||
\ $_.RuleName}']
|
||||
|
||||
return ale#powershell#RunPowerShell(
|
||||
\ a:buffer,
|
||||
\ 'powershell_psscriptanalyzer',
|
||||
\ l:script)
|
||||
return ale_linters#powershell#psscriptanalyzer#RunPowerShell(
|
||||
\ a:buffer, l:script)
|
||||
endfunction
|
||||
|
||||
" add every 4 lines to an item(Dict) and every item to a list
|
||||
@@ -69,8 +98,8 @@ endfunction
|
||||
|
||||
call ale#linter#Define('powershell', {
|
||||
\ 'name': 'psscriptanalyzer',
|
||||
\ 'executable': function('ale_linters#powershell#psscriptanalyzer#GetExecutable'),
|
||||
\ 'command': function('ale_linters#powershell#psscriptanalyzer#GetCommand'),
|
||||
\ 'executable_callback': 'ale_linters#powershell#psscriptanalyzer#GetExecutable',
|
||||
\ 'command_callback': 'ale_linters#powershell#psscriptanalyzer#GetCommand',
|
||||
\ 'output_stream': 'stdout',
|
||||
\ 'callback': 'ale_linters#powershell#psscriptanalyzer#Handle',
|
||||
\})
|
||||
|
||||
@@ -31,20 +31,6 @@ function! ale_linters#pug#puglint#GetCommand(buffer) abort
|
||||
\ . ' -r inline %t'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#pug#puglint#Handle(buffer, lines) abort
|
||||
for l:line in a:lines[:10]
|
||||
if l:line =~# '^SyntaxError: '
|
||||
return [{
|
||||
\ 'lnum': 1,
|
||||
\ 'text': 'puglint configuration error (type :ALEDetail for more information)',
|
||||
\ 'detail': join(a:lines, "\n"),
|
||||
\}]
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ale#handlers#unix#HandleAsError(a:buffer, a:lines)
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('pug', {
|
||||
\ 'name': 'puglint',
|
||||
\ 'executable': {b -> ale#node#FindExecutable(b, 'pug_puglint', [
|
||||
@@ -52,5 +38,5 @@ call ale#linter#Define('pug', {
|
||||
\ ])},
|
||||
\ 'output_stream': 'stderr',
|
||||
\ 'command': function('ale_linters#pug#puglint#GetCommand'),
|
||||
\ 'callback': 'ale_linters#pug#puglint#Handle',
|
||||
\ 'callback': 'ale#handlers#unix#HandleAsError',
|
||||
\})
|
||||
|
||||
@@ -6,7 +6,6 @@ call ale#Set('python_pylint_options', '')
|
||||
call ale#Set('python_pylint_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('python_pylint_change_directory', 1)
|
||||
call ale#Set('python_pylint_auto_pipenv', 0)
|
||||
call ale#Set('python_pylint_use_msg_id', 0)
|
||||
|
||||
function! ale_linters#python#pylint#GetExecutable(buffer) abort
|
||||
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pylint_auto_pipenv'))
|
||||
@@ -65,17 +64,11 @@ function! ale_linters#python#pylint#Handle(buffer, lines) abort
|
||||
continue
|
||||
endif
|
||||
|
||||
if ale#Var(a:buffer, 'python_pylint_use_msg_id') is# 1
|
||||
let l:code_out = l:code
|
||||
else
|
||||
let l:code_out = l:match[4]
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'col': l:match[2] + 1,
|
||||
\ 'text': l:match[5],
|
||||
\ 'code': l:code_out,
|
||||
\ 'code': l:match[4],
|
||||
\ 'type': l:code[:0] is# 'E' ? 'E' : 'W',
|
||||
\})
|
||||
endfor
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
" Author: David Buchan-Swanson <github@deecewan.com>
|
||||
" Description: Integrate ALE with reason-language-server.
|
||||
|
||||
call ale#Set('reason_ls_executable', '')
|
||||
|
||||
function! ale_linters#reason#ls#FindProjectRoot(buffer) abort
|
||||
let l:reason_config = ale#path#FindNearestFile(a:buffer, 'bsconfig.json')
|
||||
|
||||
if !empty(l:reason_config)
|
||||
return fnamemodify(l:reason_config, ':h')
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('reason', {
|
||||
\ 'name': 'reason-language-server',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {buffer -> ale#Var(buffer, 'reason_ls_executable')},
|
||||
\ 'command': '%e',
|
||||
\ 'project_root': function('ale_linters#reason#ls#FindProjectRoot'),
|
||||
\ 'language': 'reason',
|
||||
\})
|
||||
@@ -2,7 +2,7 @@
|
||||
" Description: A language server for Rust
|
||||
|
||||
call ale#Set('rust_rls_executable', 'rls')
|
||||
call ale#Set('rust_rls_toolchain', '')
|
||||
call ale#Set('rust_rls_toolchain', 'nightly')
|
||||
call ale#Set('rust_rls_config', {})
|
||||
|
||||
function! ale_linters#rust#rls#GetCommand(buffer) abort
|
||||
|
||||
@@ -10,7 +10,6 @@ call ale#Set('sh_shellcheck_exclusions', get(g:, 'ale_linters_sh_shellcheck_excl
|
||||
call ale#Set('sh_shellcheck_executable', 'shellcheck')
|
||||
call ale#Set('sh_shellcheck_dialect', 'auto')
|
||||
call ale#Set('sh_shellcheck_options', '')
|
||||
call ale#Set('sh_shellcheck_change_directory', 1)
|
||||
|
||||
function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
|
||||
let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
|
||||
@@ -41,15 +40,12 @@ function! ale_linters#sh#shellcheck#GetCommand(buffer, version) abort
|
||||
let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions')
|
||||
let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect')
|
||||
let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : ''
|
||||
let l:cd_string = ale#Var(a:buffer, 'sh_shellcheck_change_directory')
|
||||
\ ? ale#path#BufferCdString(a:buffer)
|
||||
\ : ''
|
||||
|
||||
if l:dialect is# 'auto'
|
||||
let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer)
|
||||
endif
|
||||
|
||||
return l:cd_string
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . '%e'
|
||||
\ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
" Author: Dan Loman <https://github.com/namolnad>
|
||||
" Description: Support for sourcekit-lsp https://github.com/apple/sourcekit-lsp
|
||||
|
||||
call ale#Set('sourcekit_lsp_executable', 'sourcekit-lsp')
|
||||
|
||||
call ale#linter#Define('swift', {
|
||||
\ 'name': 'sourcekitlsp',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {b -> ale#Var(b, 'sourcekit_lsp_executable')},
|
||||
\ 'command': '%e',
|
||||
\ 'project_root': function('ale#swift#FindProjectRoot'),
|
||||
\ 'language': 'swift',
|
||||
\})
|
||||
@@ -1,49 +0,0 @@
|
||||
" Author: Keith Maxwell <keith.maxwell@gmail.com>
|
||||
" Description: terraform fmt to check for errors
|
||||
|
||||
call ale#Set('terraform_terraform_executable', 'terraform')
|
||||
|
||||
function! ale_linters#terraform#terraform#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'terraform_terraform_executable')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#terraform#terraform#GetCommand(buffer) abort
|
||||
return ale#Escape(ale_linters#terraform#terraform#GetExecutable(a:buffer))
|
||||
\ . ' fmt -no-color --check=true -'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#terraform#terraform#Handle(buffer, lines) abort
|
||||
let l:head = '^Error running fmt: In <standard input>: '
|
||||
let l:output = []
|
||||
let l:patterns = [
|
||||
\ l:head.'At \(\d\+\):\(\d\+\): \(.*\)$',
|
||||
\ l:head.'\(.*\)$'
|
||||
\]
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:patterns)
|
||||
if len(l:match[2]) > 0
|
||||
call add(l:output, {
|
||||
\ 'lnum': str2nr(l:match[1]),
|
||||
\ 'col': str2nr(l:match[2]),
|
||||
\ 'text': l:match[3],
|
||||
\ 'type': 'E',
|
||||
\})
|
||||
else
|
||||
call add(l:output, {
|
||||
\ 'lnum': line('$'),
|
||||
\ 'text': l:match[1],
|
||||
\ 'type': 'E',
|
||||
\})
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('terraform', {
|
||||
\ 'name': 'terraform',
|
||||
\ 'output_stream': 'stderr',
|
||||
\ 'executable': function('ale_linters#terraform#terraform#GetExecutable'),
|
||||
\ 'command': function('ale_linters#terraform#terraform#GetCommand'),
|
||||
\ 'callback': 'ale_linters#terraform#terraform#Handle',
|
||||
\})
|
||||
@@ -1,21 +0,0 @@
|
||||
" Author: Ricardo Liang <ricardoliang@gmail.com>
|
||||
" Description: Texlab language server (Rust rewrite)
|
||||
|
||||
call ale#Set('tex_texlab_executable', 'texlab')
|
||||
call ale#Set('tex_texlab_options', '')
|
||||
|
||||
function! ale_linters#tex#texlab#GetProjectRoot(buffer) abort
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale_linters#tex#texlab#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'tex_texlab_options'))
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('tex', {
|
||||
\ 'name': 'texlab',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {b -> ale#Var(b, 'tex_texlab_executable')},
|
||||
\ 'command': function('ale_linters#tex#texlab#GetCommand'),
|
||||
\ 'project_root': function('ale_linters#tex#texlab#GetProjectRoot'),
|
||||
\})
|
||||
@@ -5,5 +5,5 @@ call ale#linter#Define('typescript', {
|
||||
\ 'name': 'eslint',
|
||||
\ 'executable': function('ale#handlers#eslint#GetExecutable'),
|
||||
\ 'command': function('ale#handlers#eslint#GetCommand'),
|
||||
\ 'callback': 'ale#handlers#eslint#HandleJSON',
|
||||
\ 'callback': 'ale#handlers#eslint#Handle',
|
||||
\})
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
call ale#Set('typescript_xo_executable', 'xo')
|
||||
call ale#Set('typescript_xo_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('typescript_xo_options', '')
|
||||
|
||||
function! ale_linters#typescript#xo#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'typescript_xo', [
|
||||
\ 'node_modules/.bin/xo',
|
||||
\])
|
||||
endfunction
|
||||
|
||||
function! ale_linters#typescript#xo#GetCommand(buffer) abort
|
||||
return ale#Escape(ale_linters#typescript#xo#GetExecutable(a:buffer))
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'typescript_xo_options'))
|
||||
\ . ' --reporter json --stdin --stdin-filename %s'
|
||||
endfunction
|
||||
|
||||
" xo uses eslint and the output format is the same
|
||||
call ale#linter#Define('typescript', {
|
||||
\ 'name': 'xo',
|
||||
\ 'executable': function('ale_linters#typescript#xo#GetExecutable'),
|
||||
\ 'command': function('ale_linters#typescript#xo#GetCommand'),
|
||||
\ 'callback': 'ale#handlers#eslint#HandleJSON',
|
||||
\})
|
||||
@@ -97,7 +97,7 @@ function! s:Lint(buffer, should_lint_file, timer_id) abort
|
||||
" Apply ignore lists for linters only if needed.
|
||||
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
|
||||
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
|
||||
let l:linters = !empty(l:ignore_config) || l:disable_lsp
|
||||
let l:linters = !empty(l:ignore_config)
|
||||
\ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config, l:disable_lsp)
|
||||
\ : l:linters
|
||||
|
||||
@@ -156,7 +156,7 @@ function! ale#Queue(delay, ...) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:current_ale_version = [2, 5, 0]
|
||||
let s:current_ale_version = [2, 4, 0]
|
||||
|
||||
" A function used to check for ALE features in files outside of the project.
|
||||
function! ale#Has(feature) abort
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
" Author: Andrew Lee <andrewl@mbda.fun>.
|
||||
" Inspired by ale/gradle.vim by Michael Pardo <michael@michaelpardo.com>
|
||||
" Description: Functions for working with Ant projects.
|
||||
|
||||
" Given a buffer number, find an Ant project root
|
||||
function! ale#ant#FindProjectRoot(buffer) abort
|
||||
let l:build_xml_path = ale#path#FindNearestFile(a:buffer, 'build.xml')
|
||||
|
||||
if !empty(l:build_xml_path)
|
||||
return fnamemodify(l:build_xml_path, ':h')
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" Given a buffer number, find the path to the `ant` executable. Returns an empty
|
||||
" string if cannot find the executable.
|
||||
function! ale#ant#FindExecutable(buffer) abort
|
||||
if executable('ant')
|
||||
return 'ant'
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" Given a buffer number, build a command to print the classpath of the root
|
||||
" project. Returns an empty string if cannot build the command.
|
||||
function! ale#ant#BuildClasspathCommand(buffer) abort
|
||||
let l:executable = ale#ant#FindExecutable(a:buffer)
|
||||
let l:project_root = ale#ant#FindProjectRoot(a:buffer)
|
||||
|
||||
if !empty(l:executable) && !empty(l:project_root)
|
||||
return ale#path#CdString(l:project_root)
|
||||
\ . ale#Escape(l:executable)
|
||||
\ . ' classpath'
|
||||
\ . ' -S'
|
||||
\ . ' -q'
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
@@ -96,13 +96,6 @@ function! ale#assert#Fixer(expected_result) abort
|
||||
AssertEqual a:expected_result, l:result
|
||||
endfunction
|
||||
|
||||
function! ale#assert#FixerNotExecuted() abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))[-1]
|
||||
|
||||
Assert empty(l:result), "The fixer will be executed when it shouldn't be"
|
||||
endfunction
|
||||
|
||||
function! ale#assert#LinterNotExecuted() abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
@@ -165,7 +158,6 @@ endfunction
|
||||
function! ale#assert#SetUpFixerTestCommands() abort
|
||||
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
|
||||
command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>)
|
||||
command! -nargs=0 AssertFixerNotExecuted :call ale#assert#FixerNotExecuted()
|
||||
endfunction
|
||||
|
||||
" A dummy function for making sure this module is loaded.
|
||||
@@ -324,8 +316,4 @@ function! ale#assert#TearDownFixerTest() abort
|
||||
if exists(':AssertFixer')
|
||||
delcommand AssertFixer
|
||||
endif
|
||||
|
||||
if exists(':AssertFixerNotExecuted')
|
||||
delcommand AssertFixerNotExecuted
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@@ -23,9 +23,27 @@ function! ale#c#GetBuildDirectory(buffer) abort
|
||||
return l:build_dir
|
||||
endif
|
||||
|
||||
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||
return ale#path#Dirname(ale#c#FindCompileCommands(a:buffer))
|
||||
endfunction
|
||||
|
||||
return ale#path#Dirname(l:json_file)
|
||||
|
||||
function! ale#c#FindProjectRoot(buffer) abort
|
||||
for l:project_filename in g:__ale_c_project_filenames
|
||||
let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
|
||||
|
||||
if !empty(l:full_path)
|
||||
let l:path = fnamemodify(l:full_path, ':h')
|
||||
|
||||
" Correct .git path detection.
|
||||
if fnamemodify(l:path, ':t') is# '.git'
|
||||
let l:path = fnamemodify(l:path, ':h')
|
||||
endif
|
||||
|
||||
return l:path
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale#c#AreSpecialCharsBalanced(option) abort
|
||||
@@ -102,7 +120,7 @@ endfunction
|
||||
|
||||
function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
|
||||
if !g:ale_c_parse_makefile
|
||||
return v:null
|
||||
return ''
|
||||
endif
|
||||
|
||||
let l:buffer_filename = expand('#' . a:buffer . ':t')
|
||||
@@ -122,17 +140,14 @@ function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
|
||||
return ale#c#ParseCFlags(l:makefile_dir, l:cflag_line)
|
||||
endfunction
|
||||
|
||||
" Given a buffer number, find the project directory containing
|
||||
" compile_commands.json, and the path to the compile_commands.json file.
|
||||
"
|
||||
" If compile_commands.json cannot be found, two empty strings will be
|
||||
" returned.
|
||||
" Given a buffer number, find the build subdirectory with compile commands
|
||||
" The subdirectory is returned without the trailing /
|
||||
function! ale#c#FindCompileCommands(buffer) abort
|
||||
" Look above the current source file to find compile_commands.json
|
||||
let l:json_file = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
|
||||
if !empty(l:json_file)
|
||||
return [fnamemodify(l:json_file, ':h'), l:json_file]
|
||||
return l:json_file
|
||||
endif
|
||||
|
||||
" Search in build directories if we can't find it in the project.
|
||||
@@ -142,42 +157,12 @@ function! ale#c#FindCompileCommands(buffer) abort
|
||||
let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json'
|
||||
|
||||
if filereadable(l:json_file)
|
||||
return [l:path, l:json_file]
|
||||
return l:json_file
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
return ['', '']
|
||||
endfunction
|
||||
|
||||
" Find the project root for C/C++ projects.
|
||||
"
|
||||
" The location of compile_commands.json will be used to find project roots.
|
||||
"
|
||||
" If compile_commands.json cannot be found, other common configuration files
|
||||
" will be used to detect the project root.
|
||||
function! ale#c#FindProjectRoot(buffer) abort
|
||||
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||
|
||||
" Fall back on detecting the project root based on other filenames.
|
||||
if empty(l:root)
|
||||
for l:project_filename in g:__ale_c_project_filenames
|
||||
let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
|
||||
|
||||
if !empty(l:full_path)
|
||||
let l:path = fnamemodify(l:full_path, ':h')
|
||||
|
||||
" Correct .git path detection.
|
||||
if fnamemodify(l:path, ':t') is# '.git'
|
||||
let l:path = fnamemodify(l:path, ':h')
|
||||
endif
|
||||
|
||||
return l:path
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
return l:root
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" Cache compile_commands.json data in a Dictionary, so we don't need to read
|
||||
@@ -209,14 +194,10 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
|
||||
let l:raw_data = []
|
||||
silent! let l:raw_data = json_decode(join(readfile(a:compile_commands_file), ''))
|
||||
|
||||
if type(l:raw_data) isnot v:t_list
|
||||
let l:raw_data = []
|
||||
endif
|
||||
|
||||
let l:file_lookup = {}
|
||||
let l:dir_lookup = {}
|
||||
|
||||
for l:entry in (type(l:raw_data) is v:t_list ? l:raw_data : [])
|
||||
for l:entry in l:raw_data
|
||||
let l:basename = tolower(fnamemodify(l:entry.file, ':t'))
|
||||
let l:file_lookup[l:basename] = get(l:file_lookup, l:basename, []) + [l:entry]
|
||||
|
||||
@@ -238,32 +219,9 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
||||
" Search for an exact file match first.
|
||||
let l:basename = tolower(expand('#' . a:buffer . ':t'))
|
||||
let l:file_list = get(a:file_lookup, l:basename, [])
|
||||
" A source file matching the header filename.
|
||||
let l:source_file = ''
|
||||
|
||||
if empty(l:file_list) && l:basename =~? '\.h$\|\.hpp$'
|
||||
for l:suffix in ['.c', '.cpp']
|
||||
let l:key = fnamemodify(l:basename, ':r') . l:suffix
|
||||
let l:file_list = get(a:file_lookup, l:key, [])
|
||||
|
||||
if !empty(l:file_list)
|
||||
let l:source_file = l:key
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
for l:item in l:file_list
|
||||
" Load the flags for this file, or for a source file matching the
|
||||
" header file.
|
||||
if has_key(l:item, 'command')
|
||||
\&& (
|
||||
\ bufnr(l:item.file) is a:buffer
|
||||
\ || (
|
||||
\ !empty(l:source_file)
|
||||
\ && l:item.file[-len(l:source_file):] is? l:source_file
|
||||
\ )
|
||||
\)
|
||||
if bufnr(l:item.file) is a:buffer && has_key(l:item, 'command')
|
||||
return ale#c#ParseCFlags(l:item.directory, l:item.command)
|
||||
endif
|
||||
endfor
|
||||
@@ -293,25 +251,25 @@ function! ale#c#FlagsFromCompileCommands(buffer, compile_commands_file) abort
|
||||
endfunction
|
||||
|
||||
function! ale#c#GetCFlags(buffer, output) abort
|
||||
let l:cflags = v:null
|
||||
let l:cflags = ' '
|
||||
|
||||
if ale#Var(a:buffer, 'c_parse_makefile') && !empty(a:output)
|
||||
let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output)
|
||||
endif
|
||||
|
||||
if ale#Var(a:buffer, 'c_parse_compile_commands')
|
||||
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||
let l:json_file = ale#c#FindCompileCommands(a:buffer)
|
||||
|
||||
if !empty(l:json_file)
|
||||
let l:cflags = ale#c#FlagsFromCompileCommands(a:buffer, l:json_file)
|
||||
endif
|
||||
endif
|
||||
|
||||
if l:cflags is v:null
|
||||
if l:cflags is# ' '
|
||||
let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))
|
||||
endif
|
||||
|
||||
return l:cflags isnot v:null ? l:cflags : ''
|
||||
return l:cflags
|
||||
endfunction
|
||||
|
||||
function! ale#c#GetMakeCommand(buffer) abort
|
||||
|
||||
@@ -159,20 +159,18 @@ function! ale#completion#Filter(buffer, filetype, suggestions, prefix) abort
|
||||
endfunction
|
||||
|
||||
function! s:ReplaceCompletionOptions() abort
|
||||
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
|
||||
|
||||
if l:source is# 'ale-automatic' || l:source is# 'ale-manual'
|
||||
" Remember the old omnifunc value, if there is one.
|
||||
" If we don't store an old one, we'll just never reset the option.
|
||||
" This will stop some random exceptions from appearing.
|
||||
if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc)
|
||||
let b:ale_old_omnifunc = &l:omnifunc
|
||||
endif
|
||||
|
||||
let &l:omnifunc = 'ale#completion#AutomaticOmniFunc'
|
||||
" Remember the old omnifunc value, if there is one.
|
||||
" If we don't store an old one, we'll just never reset the option.
|
||||
" This will stop some random exceptions from appearing.
|
||||
if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc)
|
||||
let b:ale_old_omnifunc = &l:omnifunc
|
||||
endif
|
||||
|
||||
if l:source is# 'ale-automatic'
|
||||
let &l:omnifunc = 'ale#completion#OmniFunc'
|
||||
|
||||
let l:info = get(b:, 'ale_completion_info', {})
|
||||
|
||||
if !get(l:info, 'manual')
|
||||
if !exists('b:ale_old_completeopt')
|
||||
let b:ale_old_completeopt = &l:completeopt
|
||||
endif
|
||||
@@ -201,65 +199,47 @@ function! ale#completion#RestoreCompletionOptions() abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#completion#GetCompletionPosition() abort
|
||||
if !exists('b:ale_completion_info')
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:line = b:ale_completion_info.line
|
||||
let l:column = b:ale_completion_info.column
|
||||
let l:regex = s:GetFiletypeValue(s:omni_start_map, &filetype)
|
||||
let l:up_to_column = getline(l:line)[: l:column - 2]
|
||||
let l:match = matchstr(l:up_to_column, l:regex)
|
||||
|
||||
return l:column - len(l:match) - 1
|
||||
endfunction
|
||||
|
||||
function! ale#completion#GetCompletionResult() abort
|
||||
if exists('b:ale_completion_result')
|
||||
return b:ale_completion_result
|
||||
endif
|
||||
|
||||
return v:null
|
||||
endfunction
|
||||
|
||||
function! ale#completion#AutomaticOmniFunc(findstart, base) abort
|
||||
function! ale#completion#OmniFunc(findstart, base) abort
|
||||
if a:findstart
|
||||
return ale#completion#GetCompletionPosition()
|
||||
let l:line = b:ale_completion_info.line
|
||||
let l:column = b:ale_completion_info.column
|
||||
let l:regex = s:GetFiletypeValue(s:omni_start_map, &filetype)
|
||||
let l:up_to_column = getline(l:line)[: l:column - 2]
|
||||
let l:match = matchstr(l:up_to_column, l:regex)
|
||||
|
||||
return l:column - len(l:match) - 1
|
||||
else
|
||||
let l:result = ale#completion#GetCompletionResult()
|
||||
" Parse a new response if there is one.
|
||||
if exists('b:ale_completion_response')
|
||||
\&& exists('b:ale_completion_parser')
|
||||
let l:response = b:ale_completion_response
|
||||
let l:parser = b:ale_completion_parser
|
||||
|
||||
unlet b:ale_completion_response
|
||||
unlet b:ale_completion_parser
|
||||
|
||||
let b:ale_completion_result = function(l:parser)(l:response)
|
||||
endif
|
||||
|
||||
call s:ReplaceCompletionOptions()
|
||||
|
||||
return l:result isnot v:null ? l:result : []
|
||||
return get(b:, 'ale_completion_result', [])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#completion#Show(result) abort
|
||||
function! ale#completion#Show(response, completion_parser) abort
|
||||
if ale#util#Mode() isnot# 'i'
|
||||
return
|
||||
endif
|
||||
|
||||
" Set the list in the buffer, temporarily replace omnifunc with our
|
||||
" function, and then start omni-completion.
|
||||
let b:ale_completion_result = a:result
|
||||
|
||||
" Don't try to open the completion menu if there's nothing to show.
|
||||
if empty(b:ale_completion_result)
|
||||
return
|
||||
endif
|
||||
|
||||
let b:ale_completion_response = a:response
|
||||
let b:ale_completion_parser = a:completion_parser
|
||||
" Replace completion options shortly before opening the menu.
|
||||
call s:ReplaceCompletionOptions()
|
||||
|
||||
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
|
||||
|
||||
if l:source is# 'ale-automatic' || l:source is# 'ale-manual'
|
||||
call timer_start(
|
||||
\ 0,
|
||||
\ {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")}
|
||||
\)
|
||||
endif
|
||||
call timer_start(0, {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")})
|
||||
endfunction
|
||||
|
||||
function! s:CompletionStillValid(request_id) abort
|
||||
@@ -269,11 +249,7 @@ function! s:CompletionStillValid(request_id) abort
|
||||
\&& has_key(b:, 'ale_completion_info')
|
||||
\&& b:ale_completion_info.request_id == a:request_id
|
||||
\&& b:ale_completion_info.line == l:line
|
||||
\&& (
|
||||
\ b:ale_completion_info.column == l:column
|
||||
\ || b:ale_completion_info.source is# 'deoplete'
|
||||
\ || b:ale_completion_info.source is# 'ale-omnifunc'
|
||||
\)
|
||||
\&& b:ale_completion_info.column == l:column
|
||||
endfunction
|
||||
|
||||
function! ale#completion#ParseTSServerCompletions(response) abort
|
||||
@@ -380,8 +356,6 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
||||
if get(l:item, 'insertTextFormat') is s:LSP_INSERT_TEXT_FORMAT_PLAIN
|
||||
\&& type(get(l:item, 'textEdit')) is v:t_dict
|
||||
let l:text = l:item.textEdit.newText
|
||||
elseif type(get(l:item, 'insertText')) is v:t_string
|
||||
let l:text = l:item.insertText
|
||||
else
|
||||
let l:text = l:item.label
|
||||
endif
|
||||
@@ -468,7 +442,8 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
|
||||
endif
|
||||
elseif l:command is# 'completionEntryDetails'
|
||||
call ale#completion#Show(
|
||||
\ ale#completion#ParseTSServerCompletionEntryDetails(a:response),
|
||||
\ a:response,
|
||||
\ 'ale#completion#ParseTSServerCompletionEntryDetails',
|
||||
\)
|
||||
endif
|
||||
endfunction
|
||||
@@ -480,7 +455,8 @@ function! ale#completion#HandleLSPResponse(conn_id, response) abort
|
||||
endif
|
||||
|
||||
call ale#completion#Show(
|
||||
\ ale#completion#ParseLSPCompletions(a:response),
|
||||
\ a:response,
|
||||
\ 'ale#completion#ParseLSPCompletions',
|
||||
\)
|
||||
endfunction
|
||||
|
||||
@@ -521,7 +497,10 @@ function! s:OnReady(linter, lsp_details) abort
|
||||
let l:message = ale#lsp#message#Completion(
|
||||
\ l:buffer,
|
||||
\ b:ale_completion_info.line,
|
||||
\ b:ale_completion_info.column,
|
||||
\ min([
|
||||
\ b:ale_completion_info.line_length,
|
||||
\ b:ale_completion_info.column,
|
||||
\ ]) + 1,
|
||||
\ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix),
|
||||
\)
|
||||
endif
|
||||
@@ -538,28 +517,15 @@ function! s:OnReady(linter, lsp_details) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" This function can be called to check if ALE can provide completion data for
|
||||
" the current buffer. 1 will be returned if there's a potential source of
|
||||
" completion data ALE can use, and 0 will be returned otherwise.
|
||||
function! ale#completion#CanProvideCompletions() abort
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
return 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" This function can be used to manually trigger autocomplete, even when
|
||||
" g:ale_completion_enabled is set to false
|
||||
function! ale#completion#GetCompletions(source) abort
|
||||
function! ale#completion#GetCompletions(manual) abort
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
|
||||
let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
|
||||
|
||||
if a:source is# 'ale-automatic' && empty(l:prefix)
|
||||
return 0
|
||||
if !a:manual && empty(l:prefix)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:line_length = len(getline('.'))
|
||||
@@ -571,51 +537,21 @@ function! ale#completion#GetCompletions(source) abort
|
||||
\ 'prefix': l:prefix,
|
||||
\ 'conn_id': 0,
|
||||
\ 'request_id': 0,
|
||||
\ 'source': a:source,
|
||||
\ 'manual': a:manual,
|
||||
\}
|
||||
unlet! b:ale_completion_result
|
||||
|
||||
let l:buffer = bufnr('')
|
||||
let l:Callback = function('s:OnReady')
|
||||
|
||||
let l:started = 0
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||
let l:started = 1
|
||||
endif
|
||||
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:started
|
||||
endfunction
|
||||
|
||||
function! ale#completion#OmniFunc(findstart, base) abort
|
||||
if a:findstart
|
||||
let l:started = ale#completion#GetCompletions('ale-omnifunc')
|
||||
|
||||
if !l:started
|
||||
" This is the special value for cancelling completions silently.
|
||||
" See :help complete-functions
|
||||
return -3
|
||||
endif
|
||||
|
||||
return ale#completion#GetCompletionPosition()
|
||||
else
|
||||
let l:result = ale#completion#GetCompletionResult()
|
||||
|
||||
while l:result is v:null && !complete_check()
|
||||
sleep 2ms
|
||||
let l:result = ale#completion#GetCompletionResult()
|
||||
endwhile
|
||||
|
||||
return l:result isnot v:null ? l:result : []
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:TimerHandler(...) abort
|
||||
if !get(b:, 'ale_completion_enabled', g:ale_completion_enabled)
|
||||
if !g:ale_completion_enabled
|
||||
return
|
||||
endif
|
||||
|
||||
@@ -626,7 +562,7 @@ function! s:TimerHandler(...) abort
|
||||
" When running the timer callback, we have to be sure that the cursor
|
||||
" hasn't moved from where it was when we requested completions by typing.
|
||||
if s:timer_pos == [l:line, l:column] && ale#util#Mode() is# 'i'
|
||||
call ale#completion#GetCompletions('ale-automatic')
|
||||
call ale#completion#GetCompletions(0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@@ -640,7 +576,7 @@ function! ale#completion#StopTimer() abort
|
||||
endfunction
|
||||
|
||||
function! ale#completion#Queue() abort
|
||||
if !get(b:, 'ale_completion_enabled', g:ale_completion_enabled)
|
||||
if !g:ale_completion_enabled
|
||||
return
|
||||
endif
|
||||
|
||||
|
||||
@@ -238,12 +238,6 @@ function! ale#debugging#Info() abort
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#InfoToClipboard() abort
|
||||
if !has('clipboard')
|
||||
call s:Echo('clipboard not available. Try :ALEInfoToFile instead.')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
redir => l:output
|
||||
silent call ale#debugging#Info()
|
||||
redir END
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
|
||||
let s:go_to_definition_map = {}
|
||||
|
||||
" Enable automatic updates of the tagstack
|
||||
let g:ale_update_tagstack = get(g:, 'ale_update_tagstack', 1)
|
||||
|
||||
" Used to get the definition map in tests.
|
||||
function! ale#definition#GetMap() abort
|
||||
return deepcopy(s:go_to_definition_map)
|
||||
@@ -20,20 +17,6 @@ function! ale#definition#ClearLSPData() abort
|
||||
let s:go_to_definition_map = {}
|
||||
endfunction
|
||||
|
||||
function! ale#definition#UpdateTagStack() abort
|
||||
let l:should_update_tagstack = exists('*gettagstack') && exists('*settagstack') && g:ale_update_tagstack
|
||||
|
||||
if l:should_update_tagstack
|
||||
" Grab the old location (to jump back to) and the word under the
|
||||
" cursor (as a label for the tagstack)
|
||||
let l:old_location = [bufnr('%'), line('.'), col('.'), 0]
|
||||
let l:tagname = expand('<cword>')
|
||||
let l:winid = win_getid()
|
||||
call settagstack(l:winid, {'items': [{'from': l:old_location, 'tagname': l:tagname}]}, 'a')
|
||||
call settagstack(l:winid, {'curidx': len(gettagstack(l:winid)['items']) + 1})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#definition#HandleTSServerResponse(conn_id, response) abort
|
||||
if get(a:response, 'command', '') is# 'definition'
|
||||
\&& has_key(s:go_to_definition_map, a:response.request_seq)
|
||||
@@ -44,7 +27,6 @@ function! ale#definition#HandleTSServerResponse(conn_id, response) abort
|
||||
let l:line = a:response.body[0].start.line
|
||||
let l:column = a:response.body[0].start.offset
|
||||
|
||||
call ale#definition#UpdateTagStack()
|
||||
call ale#util#Open(l:filename, l:line, l:column, l:options)
|
||||
endif
|
||||
endif
|
||||
@@ -69,7 +51,6 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
|
||||
let l:line = l:item.range.start.line + 1
|
||||
let l:column = l:item.range.start.character + 1
|
||||
|
||||
call ale#definition#UpdateTagStack()
|
||||
call ale#util#Open(l:filename, l:line, l:column, l:options)
|
||||
break
|
||||
endfor
|
||||
|
||||
@@ -710,10 +710,6 @@ function! ale#engine#Cleanup(buffer) abort
|
||||
return
|
||||
endif
|
||||
|
||||
if exists('*ale#lsp#CloseDocument')
|
||||
call ale#lsp#CloseDocument(a:buffer)
|
||||
endif
|
||||
|
||||
if !has_key(g:ale_buffer_info, a:buffer)
|
||||
return
|
||||
endif
|
||||
|
||||
@@ -128,7 +128,7 @@ function! ale#events#Init() abort
|
||||
endif
|
||||
|
||||
if g:ale_lint_on_insert_leave
|
||||
autocmd InsertLeave * if ale#Var(str2nr(expand('<abuf>')), 'lint_on_insert_leave') | call ale#Queue(0) | endif
|
||||
autocmd InsertLeave * call ale#Queue(0)
|
||||
endif
|
||||
|
||||
if g:ale_echo_cursor || g:ale_cursor_detail
|
||||
|
||||
@@ -1,61 +1,45 @@
|
||||
call ale#Set('fix_on_save_ignore', {})
|
||||
|
||||
" Apply fixes queued up for buffers which may be hidden.
|
||||
" Vim doesn't let you modify hidden buffers.
|
||||
function! ale#fix#ApplyQueuedFixes(buffer) abort
|
||||
let l:data = get(g:ale_fix_buffer_data, a:buffer, {'done': 0})
|
||||
let l:has_bufline_api = exists('*deletebufline') && exists('*setbufline')
|
||||
function! ale#fix#ApplyQueuedFixes() abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:data = get(g:ale_fix_buffer_data, l:buffer, {'done': 0})
|
||||
|
||||
if !l:data.done || (!l:has_bufline_api && a:buffer isnot bufnr(''))
|
||||
if !l:data.done
|
||||
return
|
||||
endif
|
||||
|
||||
call remove(g:ale_fix_buffer_data, a:buffer)
|
||||
call remove(g:ale_fix_buffer_data, l:buffer)
|
||||
|
||||
if l:data.changes_made
|
||||
let l:start_line = len(l:data.output) + 1
|
||||
let l:end_line = len(l:data.lines_before)
|
||||
|
||||
if l:end_line >= l:start_line
|
||||
let l:save = winsaveview()
|
||||
silent execute l:start_line . ',' . l:end_line . 'd_'
|
||||
call winrestview(l:save)
|
||||
endif
|
||||
|
||||
" If the file is in DOS mode, we have to remove carriage returns from
|
||||
" the ends of lines before calling setline(), or we will see them
|
||||
" twice.
|
||||
let l:new_lines = getbufvar(a:buffer, '&fileformat') is# 'dos'
|
||||
let l:lines_to_set = getbufvar(l:buffer, '&fileformat') is# 'dos'
|
||||
\ ? map(copy(l:data.output), 'substitute(v:val, ''\r\+$'', '''', '''')')
|
||||
\ : l:data.output
|
||||
let l:first_line_to_remove = len(l:new_lines) + 1
|
||||
|
||||
" Use a Vim API for setting lines in other buffers, if available.
|
||||
if l:has_bufline_api
|
||||
call setbufline(a:buffer, 1, l:new_lines)
|
||||
call deletebufline(a:buffer, l:first_line_to_remove, '$')
|
||||
" Fall back on setting lines the old way, for the current buffer.
|
||||
else
|
||||
let l:old_line_length = len(l:data.lines_before)
|
||||
|
||||
if l:old_line_length >= l:first_line_to_remove
|
||||
let l:save = winsaveview()
|
||||
silent execute
|
||||
\ l:first_line_to_remove . ',' . l:old_line_length . 'd_'
|
||||
call winrestview(l:save)
|
||||
endif
|
||||
|
||||
call setline(1, l:new_lines)
|
||||
endif
|
||||
call setline(1, l:lines_to_set)
|
||||
|
||||
if l:data.should_save
|
||||
if a:buffer is bufnr('')
|
||||
if empty(&buftype)
|
||||
noautocmd :w!
|
||||
else
|
||||
set nomodified
|
||||
endif
|
||||
if empty(&buftype)
|
||||
noautocmd :w!
|
||||
else
|
||||
call writefile(l:new_lines, expand(a:buffer . ':p')) " no-custom-checks
|
||||
call setbufvar(a:buffer, '&modified', 0)
|
||||
set nomodified
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if l:data.should_save
|
||||
let l:should_lint = ale#Var(a:buffer, 'fix_on_save')
|
||||
\ && ale#Var(a:buffer, 'lint_on_save')
|
||||
let l:should_lint = g:ale_fix_on_save
|
||||
else
|
||||
let l:should_lint = l:data.changes_made
|
||||
endif
|
||||
@@ -66,7 +50,7 @@ function! ale#fix#ApplyQueuedFixes(buffer) abort
|
||||
" fixing problems.
|
||||
if g:ale_enabled
|
||||
\&& l:should_lint
|
||||
\&& !ale#events#QuitRecently(a:buffer)
|
||||
\&& !ale#events#QuitRecently(l:buffer)
|
||||
call ale#Queue(0, l:data.should_save ? 'lint_file' : '')
|
||||
endif
|
||||
endfunction
|
||||
@@ -97,7 +81,7 @@ function! ale#fix#ApplyFixes(buffer, output) abort
|
||||
|
||||
" We can only change the lines of a buffer which is currently open,
|
||||
" so try and apply the fixes to the current buffer.
|
||||
call ale#fix#ApplyQueuedFixes(a:buffer)
|
||||
call ale#fix#ApplyQueuedFixes()
|
||||
endfunction
|
||||
|
||||
function! s:HandleExit(job_info, buffer, job_output, data) abort
|
||||
@@ -281,21 +265,7 @@ function! s:AddSubCallbacks(full_list, callbacks) abort
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! s:IgnoreFixers(callback_list, filetype, config) abort
|
||||
if type(a:config) is v:t_list
|
||||
let l:ignore_list = a:config
|
||||
else
|
||||
let l:ignore_list = []
|
||||
|
||||
for l:part in split(a:filetype , '\.')
|
||||
call extend(l:ignore_list, get(a:config, l:part, []))
|
||||
endfor
|
||||
endif
|
||||
|
||||
call filter(a:callback_list, 'index(l:ignore_list, v:val) < 0')
|
||||
endfunction
|
||||
|
||||
function! s:GetCallbacks(buffer, fixing_flag, fixers) abort
|
||||
function! s:GetCallbacks(buffer, fixers) abort
|
||||
if len(a:fixers)
|
||||
let l:callback_list = a:fixers
|
||||
elseif type(get(b:, 'ale_fixers')) is v:t_list
|
||||
@@ -320,12 +290,8 @@ function! s:GetCallbacks(buffer, fixing_flag, fixers) abort
|
||||
endif
|
||||
endif
|
||||
|
||||
if a:fixing_flag is# 'save_file'
|
||||
let l:config = ale#Var(a:buffer, 'fix_on_save_ignore')
|
||||
|
||||
if !empty(l:config)
|
||||
call s:IgnoreFixers(l:callback_list, &filetype, l:config)
|
||||
endif
|
||||
if empty(l:callback_list)
|
||||
return []
|
||||
endif
|
||||
|
||||
let l:corrected_list = []
|
||||
@@ -373,7 +339,7 @@ function! ale#fix#Fix(buffer, fixing_flag, ...) abort
|
||||
endif
|
||||
|
||||
try
|
||||
let l:callback_list = s:GetCallbacks(a:buffer, a:fixing_flag, a:000)
|
||||
let l:callback_list = s:GetCallbacks(a:buffer, a:000)
|
||||
catch /E700\|BADNAME/
|
||||
let l:function_name = join(split(split(v:exception, ':')[3]))
|
||||
let l:echo_message = printf(
|
||||
@@ -413,4 +379,5 @@ endfunction
|
||||
" Set up an autocmd command to try and apply buffer fixes when available.
|
||||
augroup ALEBufferFixGroup
|
||||
autocmd!
|
||||
autocmd BufEnter * call ale#fix#ApplyQueuedFixes(str2nr(expand('<abuf>')))
|
||||
autocmd BufEnter * call ale#fix#ApplyQueuedFixes()
|
||||
augroup END
|
||||
|
||||
@@ -27,11 +27,6 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix PEP8 issues with black.',
|
||||
\ },
|
||||
\ 'fecs': {
|
||||
\ 'function': 'ale#fixers#fecs#Fix',
|
||||
\ 'suggested_filetypes': ['javascript', 'css', 'html'],
|
||||
\ 'description': 'Apply fecs format to a file.',
|
||||
\ },
|
||||
\ 'tidy': {
|
||||
\ 'function': 'ale#fixers#tidy#Fix',
|
||||
\ 'suggested_filetypes': ['html'],
|
||||
@@ -190,11 +185,6 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['hack'],
|
||||
\ 'description': 'Fix Hack files with hackfmt.',
|
||||
\ },
|
||||
\ 'floskell': {
|
||||
\ 'function': 'ale#fixers#floskell#Fix',
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
\ 'description': 'Fix Haskell files with floskell.',
|
||||
\ },
|
||||
\ 'hfmt': {
|
||||
\ 'function': 'ale#fixers#hfmt#Fix',
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
@@ -220,11 +210,6 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['ocaml'],
|
||||
\ 'description': 'Fix OCaml files with ocamlformat.',
|
||||
\ },
|
||||
\ 'ocp-indent': {
|
||||
\ 'function': 'ale#fixers#ocp_indent#Fix',
|
||||
\ 'suggested_filetypes': ['ocaml'],
|
||||
\ 'description': 'Fix OCaml files with ocp-indent.',
|
||||
\ },
|
||||
\ 'refmt': {
|
||||
\ 'function': 'ale#fixers#refmt#Fix',
|
||||
\ 'suggested_filetypes': ['reason'],
|
||||
@@ -262,8 +247,8 @@ let s:default_registry = {
|
||||
\ },
|
||||
\ 'xo': {
|
||||
\ 'function': 'ale#fixers#xo#Fix',
|
||||
\ 'suggested_filetypes': ['javascript', 'typescript'],
|
||||
\ 'description': 'Fix JavaScript/TypeScript files using xo --fix.',
|
||||
\ 'suggested_filetypes': ['javascript'],
|
||||
\ 'description': 'Fix JavaScript files using xo --fix.',
|
||||
\ },
|
||||
\ 'qmlfmt': {
|
||||
\ 'function': 'ale#fixers#qmlfmt#Fix',
|
||||
@@ -295,26 +280,6 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['kt'],
|
||||
\ 'description': 'Fix Kotlin files with ktlint.',
|
||||
\ },
|
||||
\ 'styler': {
|
||||
\ 'function': 'ale#fixers#styler#Fix',
|
||||
\ 'suggested_filetypes': ['r', 'rmarkdown'],
|
||||
\ 'description': 'Fix R files with styler.',
|
||||
\ },
|
||||
\ 'latexindent': {
|
||||
\ 'function': 'ale#fixers#latexindent#Fix',
|
||||
\ 'suggested_filetypes': ['tex'],
|
||||
\ 'description' : 'Indent code within environments, commands, after headings and within special code blocks.',
|
||||
\ },
|
||||
\ 'pgformatter': {
|
||||
\ 'function': 'ale#fixers#pgformatter#Fix',
|
||||
\ 'suggested_filetypes': ['sql'],
|
||||
\ 'description': 'A PostgreSQL SQL syntax beautifier',
|
||||
\ },
|
||||
\ 'reorder-python-imports': {
|
||||
\ 'function': 'ale#fixers#reorder_python_imports#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Sort Python imports with reorder-python-imports.',
|
||||
\ },
|
||||
\}
|
||||
|
||||
" Reset the function registry to the default entries.
|
||||
|
||||
@@ -35,18 +35,9 @@ endfunction
|
||||
|
||||
function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
|
||||
let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
|
||||
let l:config = ale#handlers#eslint#FindConfig(a:buffer)
|
||||
|
||||
" Use the configuration file from the options, if configured.
|
||||
if l:options =~# '\v(^| )-c|(^| )--config'
|
||||
let l:config = ''
|
||||
let l:has_config = 1
|
||||
else
|
||||
let l:config = ale#handlers#eslint#FindConfig(a:buffer)
|
||||
let l:has_config = !empty(l:config)
|
||||
endif
|
||||
|
||||
if !l:has_config
|
||||
if empty(l:config)
|
||||
return 0
|
||||
endif
|
||||
|
||||
@@ -54,7 +45,6 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||
if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
|
||||
return {
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ale#Pad(l:options)
|
||||
\ . ' --stdin-filename %s --stdin --fix-to-stdout',
|
||||
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
|
||||
\}
|
||||
@@ -64,7 +54,6 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||
if ale#semver#GTE(a:version, [4, 9, 0])
|
||||
return {
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ale#Pad(l:options)
|
||||
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
|
||||
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
|
||||
\}
|
||||
@@ -72,8 +61,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||
|
||||
return {
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ale#Pad(l:options)
|
||||
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
|
||||
\ . ' -c ' . ale#Escape(l:config)
|
||||
\ . ' --fix %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
" Author: harttle <yangjvn@126.com>
|
||||
" Description: Apply fecs format to a file.
|
||||
|
||||
function! ale#fixers#fecs#Fix(buffer) abort
|
||||
let l:executable = ale#handlers#fecs#GetExecutable(a:buffer)
|
||||
|
||||
if !executable(l:executable)
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:config_options = ' format --replace=true %t'
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . l:config_options,
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
@@ -1,20 +0,0 @@
|
||||
" Author: robertjlooby <robertjlooby@gmail.com>
|
||||
" Description: Integration of floskell with ALE.
|
||||
|
||||
call ale#Set('haskell_floskell_executable', 'floskell')
|
||||
|
||||
function! ale#fixers#floskell#GetExecutable(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'haskell_floskell_executable')
|
||||
|
||||
return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'floskell')
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#floskell#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#floskell#GetExecutable(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:executable
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
@@ -1,18 +0,0 @@
|
||||
" Author: riley-martine <riley.martine@protonmail.com>
|
||||
" Description: Integration of latexindent with ALE.
|
||||
|
||||
call ale#Set('tex_latexindent_executable', 'latexindent')
|
||||
call ale#Set('tex_latexindent_options', '')
|
||||
|
||||
function! ale#fixers#latexindent#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'tex_latexindent_executable')
|
||||
let l:options = ale#Var(a:buffer, 'tex_latexindent_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' -l -w'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
@@ -1,18 +0,0 @@
|
||||
" Author: Kanenobu Mitsuru
|
||||
" Description: Integration of ocp-indent with ALE.
|
||||
|
||||
call ale#Set('ocaml_ocp_indent_executable', 'ocp-indent')
|
||||
call ale#Set('ocaml_ocp_indent_options', '')
|
||||
call ale#Set('ocaml_ocp_indent_config', '')
|
||||
|
||||
function! ale#fixers#ocp_indent#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ocaml_ocp_indent_executable')
|
||||
let l:config = ale#Var(a:buffer, 'ocaml_ocp_indent_config')
|
||||
let l:options = ale#Var(a:buffer, 'ocaml_ocp_indent_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:config) ? '' : ' --config=' . ale#Escape(l:config))
|
||||
\ . (empty(l:options) ? '': ' ' . l:options)
|
||||
\}
|
||||
endfunction
|
||||
@@ -1,12 +0,0 @@
|
||||
call ale#Set('sql_pgformatter_executable', 'pg_format')
|
||||
call ale#Set('sql_pgformatter_options', '')
|
||||
|
||||
function! ale#fixers#pgformatter#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'sql_pgformatter_executable')
|
||||
let l:options = ale#Var(a:buffer, 'sql_pgformatter_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options),
|
||||
\}
|
||||
endfunction
|
||||
@@ -1,25 +0,0 @@
|
||||
" Author: jake <me@jake.computer>
|
||||
" Description: Fixing Python imports with reorder-python-imports.
|
||||
|
||||
call ale#Set('python_reorder_python_imports_executable', 'reorder-python-imports')
|
||||
call ale#Set('python_reorder_python_imports_options', '')
|
||||
call ale#Set('python_reorder_python_imports_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! ale#fixers#reorder_python_imports#Fix(buffer) abort
|
||||
let l:executable = ale#python#FindExecutable(
|
||||
\ a:buffer,
|
||||
\ 'python_reorder_python_imports',
|
||||
\ ['reorder-python-imports'],
|
||||
\)
|
||||
|
||||
if !executable(l:executable)
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'python_reorder_python_imports_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '') . ' -',
|
||||
\}
|
||||
endfunction
|
||||
@@ -1,16 +0,0 @@
|
||||
" Author: tvatter <thibault.vatter@gmail.com>
|
||||
" Description: Fixing R files with styler.
|
||||
|
||||
call ale#Set('r_styler_executable', 'Rscript')
|
||||
call ale#Set('r_styler_options', 'tidyverse_style')
|
||||
|
||||
function! ale#fixers#styler#Fix(buffer) abort
|
||||
return {
|
||||
\ 'command': 'Rscript --vanilla -e '
|
||||
\ . '"suppressPackageStartupMessages(library(styler));'
|
||||
\ . 'style_file(commandArgs(TRUE), style = '
|
||||
\ . ale#Var(a:buffer, 'r_styler_options') . ')"'
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
@@ -3,17 +3,15 @@ scriptencoding utf-8
|
||||
" Description: Utilities for ccls
|
||||
|
||||
function! ale#handlers#ccls#GetProjectRoot(buffer) abort
|
||||
" Try to find ccls configuration files first.
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.ccls-root')
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls-root')
|
||||
|
||||
if empty(l:config)
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.ccls')
|
||||
if empty(l:project_root)
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
endif
|
||||
|
||||
if !empty(l:config)
|
||||
return fnamemodify(l:config, ':h')
|
||||
if empty(l:project_root)
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls')
|
||||
endif
|
||||
|
||||
" Fall back on default project root detection.
|
||||
return ale#c#FindProjectRoot(a:buffer)
|
||||
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
|
||||
endfunction
|
||||
|
||||
@@ -1,46 +1,5 @@
|
||||
" Description: Handle errors for cppcheck.
|
||||
|
||||
function! ale#handlers#cppcheck#GetCdCommand(buffer) abort
|
||||
let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer)
|
||||
let l:cd_command = !empty(l:dir) ? ale#path#CdString(l:dir) : ''
|
||||
|
||||
return l:cd_command
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#cppcheck#GetBufferPathIncludeOptions(buffer) abort
|
||||
let l:buffer_path_include = ''
|
||||
|
||||
" Get path to this buffer so we can include it into cppcheck with -I
|
||||
" This could be expanded to get more -I directives from the compile
|
||||
" command in compile_commands.json, if it's found.
|
||||
let l:buffer_path = fnamemodify(bufname(a:buffer), ':p:h')
|
||||
let l:buffer_path_include = ' -I' . ale#Escape(l:buffer_path)
|
||||
|
||||
return l:buffer_path_include
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#cppcheck#GetCompileCommandsOptions(buffer) abort
|
||||
" If the current buffer is modified, using compile_commands.json does no
|
||||
" good, so include the file's directory instead. It's not quite as good as
|
||||
" using --project, but is at least equivalent to running cppcheck on this
|
||||
" file manually from the file's directory.
|
||||
let l:modified = getbufvar(a:buffer, '&modified')
|
||||
|
||||
if l:modified
|
||||
return ''
|
||||
endif
|
||||
|
||||
" Search upwards from the file for compile_commands.json.
|
||||
"
|
||||
" If we find it, we'll `cd` to where the compile_commands.json file is,
|
||||
" then use the file to set up import paths, etc.
|
||||
let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer)
|
||||
|
||||
return !empty(l:json_path)
|
||||
\ ? '--project=' . ale#Escape(l:json_path[len(l:dir) + 1: ])
|
||||
\ : ''
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#cppcheck#HandleCppCheckFormat(buffer, lines) abort
|
||||
" Look for lines like the following.
|
||||
"
|
||||
|
||||
@@ -44,9 +44,16 @@ function! ale#handlers#eslint#GetCommand(buffer) abort
|
||||
|
||||
return ale#node#Executable(a:buffer, l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' -f json --stdin --stdin-filename %s'
|
||||
\ . ' -f unix --stdin --stdin-filename %s'
|
||||
endfunction
|
||||
|
||||
let s:col_end_patterns = [
|
||||
\ '\vParsing error: Unexpected token (.+) ?',
|
||||
\ '\v''(.+)'' is not defined.',
|
||||
\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]',
|
||||
\ '\vUnexpected (console) statement',
|
||||
\]
|
||||
|
||||
function! s:AddHintsForTypeScriptParsingErrors(output) abort
|
||||
for l:item in a:output
|
||||
let l:item.text = substitute(
|
||||
@@ -83,71 +90,22 @@ function! s:CheckForBadConfig(buffer, lines) abort
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:parseJSON(buffer, lines) abort
|
||||
try
|
||||
let l:parsed = json_decode(a:lines[-1])
|
||||
catch
|
||||
return []
|
||||
endtry
|
||||
|
||||
if type(l:parsed) != v:t_list || empty(l:parsed)
|
||||
return []
|
||||
function! ale#handlers#eslint#Handle(buffer, lines) abort
|
||||
if s:CheckForBadConfig(a:buffer, a:lines)
|
||||
return [{
|
||||
\ 'lnum': 1,
|
||||
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
|
||||
\ 'detail': join(a:lines, "\n"),
|
||||
\}]
|
||||
endif
|
||||
|
||||
let l:errors = l:parsed[0]['messages']
|
||||
|
||||
if empty(l:errors)
|
||||
return []
|
||||
if a:lines == ['Could not connect']
|
||||
return [{
|
||||
\ 'lnum': 1,
|
||||
\ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.',
|
||||
\}]
|
||||
endif
|
||||
|
||||
let l:output = []
|
||||
|
||||
for l:error in l:errors
|
||||
let l:obj = ({
|
||||
\ 'lnum': get(l:error, 'line', 0),
|
||||
\ 'text': get(l:error, 'message', ''),
|
||||
\ 'type': 'E',
|
||||
\})
|
||||
|
||||
if get(l:error, 'severity', 0) is# 1
|
||||
let l:obj.type = 'W'
|
||||
endif
|
||||
|
||||
if has_key(l:error, 'ruleId')
|
||||
let l:code = l:error['ruleId']
|
||||
|
||||
" Sometimes ESLint returns null here
|
||||
if !empty(l:code)
|
||||
let l:obj.code = l:code
|
||||
endif
|
||||
endif
|
||||
|
||||
if has_key(l:error, 'column')
|
||||
let l:obj.col = l:error['column']
|
||||
endif
|
||||
|
||||
if has_key(l:error, 'endColumn')
|
||||
let l:obj.end_col = l:error['endColumn'] - 1
|
||||
endif
|
||||
|
||||
if has_key(l:error, 'endLine')
|
||||
let l:obj.end_lnum = l:error['endLine']
|
||||
endif
|
||||
|
||||
call add(l:output, l:obj)
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
let s:col_end_patterns = [
|
||||
\ '\vParsing error: Unexpected token (.+) ?',
|
||||
\ '\v''(.+)'' is not defined.',
|
||||
\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]',
|
||||
\ '\vUnexpected (console) statement',
|
||||
\]
|
||||
|
||||
function! s:parseLines(buffer, lines) abort
|
||||
" Matches patterns line the following:
|
||||
"
|
||||
" /path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]
|
||||
@@ -162,6 +120,12 @@ function! s:parseLines(buffer, lines) abort
|
||||
for l:match in ale#util#GetMatches(a:lines, [l:pattern, l:parsing_pattern])
|
||||
let l:text = l:match[3]
|
||||
|
||||
if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore')
|
||||
if l:text =~# '^File ignored'
|
||||
continue
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:obj = {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'col': l:match[2] + 0,
|
||||
@@ -188,59 +152,9 @@ function! s:parseLines(buffer, lines) abort
|
||||
call add(l:output, l:obj)
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
function! s:FilterResult(buffer, obj) abort
|
||||
if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore')
|
||||
if a:obj.text =~# '^File ignored'
|
||||
return 0
|
||||
endif
|
||||
endif
|
||||
|
||||
if has_key(a:obj, 'code') && a:obj.code is# 'no-trailing-spaces'
|
||||
\&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
|
||||
return 0
|
||||
endif
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! s:HandleESLintOutput(buffer, lines, type) abort
|
||||
if s:CheckForBadConfig(a:buffer, a:lines)
|
||||
return [{
|
||||
\ 'lnum': 1,
|
||||
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
|
||||
\ 'detail': join(a:lines, "\n"),
|
||||
\}]
|
||||
endif
|
||||
|
||||
if a:lines == ['Could not connect']
|
||||
return [{
|
||||
\ 'lnum': 1,
|
||||
\ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.',
|
||||
\}]
|
||||
endif
|
||||
|
||||
if a:type is# 'json'
|
||||
let l:output = s:parseJSON(a:buffer, a:lines)
|
||||
else
|
||||
let l:output = s:parseLines(a:buffer, a:lines)
|
||||
endif
|
||||
|
||||
call filter(l:output, {idx, obj -> s:FilterResult(a:buffer, obj)})
|
||||
|
||||
if expand('#' . a:buffer . ':t') =~? '\.tsx\?$'
|
||||
call s:AddHintsForTypeScriptParsingErrors(l:output)
|
||||
endif
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#eslint#HandleJSON(buffer, lines) abort
|
||||
return s:HandleESLintOutput(a:buffer, a:lines, 'json')
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#eslint#Handle(buffer, lines) abort
|
||||
return s:HandleESLintOutput(a:buffer, a:lines, 'lines')
|
||||
endfunction
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
" Author: harttle <yangjvn@126.com>
|
||||
" Description: fecs http://fecs.baidu.com/
|
||||
|
||||
call ale#Set('javascript_fecs_executable', 'fecs')
|
||||
call ale#Set('javascript_fecs_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! ale#handlers#fecs#GetCommand(buffer) abort
|
||||
return '%e check --colors=false --rule=true %t'
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#fecs#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'javascript_fecs', [
|
||||
\ 'node_modules/.bin/fecs',
|
||||
\ 'node_modules/fecs/bin/fecs',
|
||||
\])
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#fecs#Handle(buffer, lines) abort
|
||||
" Matches patterns looking like the following
|
||||
"
|
||||
" fecs WARN → line 20, col 25: Unexpected console statement. (no-console)
|
||||
" fecs ERROR → line 24, col 36: Missing radix parameter. (radix)
|
||||
"
|
||||
let l:pattern = '\v^.*(WARN|ERROR)\s+→\s+line (\d+),\s+col\s+(\d+):\s+(.*)$'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
let l:obj = {
|
||||
\ 'lnum': l:match[2] + 0,
|
||||
\ 'col': l:match[3] + 0,
|
||||
\ 'text': l:match[4]
|
||||
\}
|
||||
|
||||
let l:code_match = matchlist(l:match[4], '\v^(.{-})\s*\((.+)\)$')
|
||||
|
||||
if !empty(l:code_match)
|
||||
let l:obj.code = l:code_match[2]
|
||||
let l:obj.text = l:code_match[1]
|
||||
endif
|
||||
|
||||
if l:match[1] is# 'WARN'
|
||||
let l:obj.type = 'W'
|
||||
elseif l:match[1] is# 'ERROR'
|
||||
let l:obj.type = 'E'
|
||||
endif
|
||||
|
||||
call add(l:output, l:obj)
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
@@ -11,7 +11,6 @@ let s:pragma_error = '#pragma once in main file'
|
||||
" <stdin>:10:27: error: invalid operands to binary - (have ‘int’ and ‘char *’)
|
||||
" -:189:7: note: $/${} is unnecessary on arithmetic variables. [SC2004]
|
||||
let s:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+)$'
|
||||
let s:inline_pattern = '\v inlined from .* at \<stdin\>:(\d+):(\d+):$'
|
||||
|
||||
function! s:IsHeaderFile(filename) abort
|
||||
return a:filename =~? '\v\.(h|hpp)$'
|
||||
@@ -26,28 +25,6 @@ function! s:RemoveUnicodeQuotes(text) abort
|
||||
return l:text
|
||||
endfunction
|
||||
|
||||
function! s:ParseInlinedFunctionProblems(buffer, lines) abort
|
||||
let l:output = []
|
||||
let l:pos_match = []
|
||||
|
||||
for l:line in a:lines
|
||||
let l:match = matchlist(l:line, s:pattern)
|
||||
|
||||
if !empty(l:match) && !empty(l:pos_match)
|
||||
call add(l:output, {
|
||||
\ 'lnum': str2nr(l:pos_match[1]),
|
||||
\ 'col': str2nr(l:pos_match[2]),
|
||||
\ 'type': (l:match[4] is# 'error' || l:match[4] is# 'fatal error') ? 'E' : 'W',
|
||||
\ 'text': s:RemoveUnicodeQuotes(l:match[5]),
|
||||
\})
|
||||
endif
|
||||
|
||||
let l:pos_match = matchlist(l:line, s:inline_pattern)
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
" Report problems inside of header files just for gcc and clang
|
||||
function! s:ParseProblemsInHeaders(buffer, lines) abort
|
||||
let l:output = []
|
||||
@@ -152,7 +129,6 @@ endfunction
|
||||
function! ale#handlers#gcc#HandleGCCFormatWithIncludes(buffer, lines) abort
|
||||
let l:output = ale#handlers#gcc#HandleGCCFormat(a:buffer, a:lines)
|
||||
|
||||
call extend(l:output, s:ParseInlinedFunctionProblems(a:buffer, a:lines))
|
||||
call extend(l:output, s:ParseProblemsInHeaders(a:buffer, a:lines))
|
||||
|
||||
return l:output
|
||||
|
||||
@@ -56,20 +56,14 @@ function! ale#handlers#rust#HandleRustErrors(buffer, lines) abort
|
||||
endif
|
||||
|
||||
if !empty(l:span)
|
||||
let l:output_line = {
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:span.line_start,
|
||||
\ 'end_lnum': l:span.line_end,
|
||||
\ 'col': l:span.column_start,
|
||||
\ 'end_col': l:span.column_end-1,
|
||||
\ 'text': empty(l:span.label) ? l:error.message : printf('%s: %s', l:error.message, l:span.label),
|
||||
\ 'type': toupper(l:error.level[0]),
|
||||
\}
|
||||
|
||||
if has_key(l:error, 'rendered') && !empty(l:error.rendered)
|
||||
let l:output_line.detail = l:error.rendered
|
||||
endif
|
||||
|
||||
call add(l:output, l:output_line)
|
||||
\})
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
@@ -49,33 +49,14 @@ endfunction
|
||||
|
||||
" Given a loclist for current items to highlight, remove all highlights
|
||||
" except these which have matching loclist item entries.
|
||||
|
||||
function! ale#highlight#RemoveHighlights() abort
|
||||
for l:match in getmatches()
|
||||
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
|
||||
if l:match.group =~# '^ALE'
|
||||
call matchdelete(l:match.id)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:highlight_line(bufnr, lnum, group) abort
|
||||
call matchaddpos(a:group, [a:lnum])
|
||||
endfunction
|
||||
|
||||
function! s:highlight_range(bufnr, range, group) abort
|
||||
" Set all of the positions, which are chunked into Lists which
|
||||
" are as large as will be accepted by matchaddpos.
|
||||
call map(
|
||||
\ ale#highlight#CreatePositions(
|
||||
\ a:range.lnum,
|
||||
\ a:range.col,
|
||||
\ a:range.end_lnum,
|
||||
\ a:range.end_col
|
||||
\ ),
|
||||
\ 'matchaddpos(a:group, v:val)'
|
||||
\)
|
||||
endfunction
|
||||
|
||||
function! ale#highlight#UpdateHighlights() abort
|
||||
let l:item_list = get(b:, 'ale_enabled', 1) && g:ale_enabled
|
||||
\ ? get(b:, 'ale_highlight_items', [])
|
||||
@@ -98,14 +79,17 @@ function! ale#highlight#UpdateHighlights() abort
|
||||
let l:group = 'ALEError'
|
||||
endif
|
||||
|
||||
let l:range = {
|
||||
\ 'lnum': l:item.lnum,
|
||||
\ 'col': l:item.col,
|
||||
\ 'end_lnum': get(l:item, 'end_lnum', l:item.lnum),
|
||||
\ 'end_col': get(l:item, 'end_col', l:item.col)
|
||||
\}
|
||||
let l:line = l:item.lnum
|
||||
let l:col = l:item.col
|
||||
let l:end_line = get(l:item, 'end_lnum', l:line)
|
||||
let l:end_col = get(l:item, 'end_col', l:col)
|
||||
|
||||
call s:highlight_range(l:item.bufnr, l:range, l:group)
|
||||
" Set all of the positions, which are chunked into Lists which
|
||||
" are as large as will be accepted by matchaddpos.
|
||||
call map(
|
||||
\ ale#highlight#CreatePositions(l:line, l:col, l:end_line, l:end_col),
|
||||
\ 'matchaddpos(l:group, v:val)'
|
||||
\)
|
||||
endfor
|
||||
|
||||
" If highlights are enabled and signs are not enabled, we should still
|
||||
@@ -127,7 +111,7 @@ function! ale#highlight#UpdateHighlights() abort
|
||||
endif
|
||||
|
||||
if l:available_groups[l:group]
|
||||
call s:highlight_line(l:item.bufnr, l:item.lnum, l:group)
|
||||
call matchaddpos(l:group, [l:item.lnum])
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
@@ -16,11 +16,5 @@ function! ale#java#FindProjectRoot(buffer) abort
|
||||
return fnamemodify(l:maven_pom_file, ':h')
|
||||
endif
|
||||
|
||||
let l:ant_root = ale#ant#FindProjectRoot(a:buffer)
|
||||
|
||||
if !empty(l:ant_root)
|
||||
return l:ant_root
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
@@ -13,13 +13,10 @@ let s:default_ale_linter_aliases = {
|
||||
\ 'Dockerfile': 'dockerfile',
|
||||
\ 'csh': 'sh',
|
||||
\ 'plaintex': 'tex',
|
||||
\ 'rmarkdown': 'r',
|
||||
\ 'systemverilog': 'verilog',
|
||||
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
|
||||
\ 'vimwiki': 'markdown',
|
||||
\ 'vue': ['vue', 'javascript'],
|
||||
\ 'xsd': ['xsd', 'xml'],
|
||||
\ 'xslt': ['xslt', 'xml'],
|
||||
\ 'zsh': 'sh',
|
||||
\}
|
||||
|
||||
@@ -358,14 +355,12 @@ function! ale#linter#Define(filetype, linter) abort
|
||||
" This command will throw from the sandbox.
|
||||
let &l:equalprg=&l:equalprg
|
||||
|
||||
let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter)
|
||||
|
||||
if !has_key(s:linters, a:filetype)
|
||||
let s:linters[a:filetype] = []
|
||||
endif
|
||||
|
||||
" Remove previously defined linters with the same name.
|
||||
call filter(s:linters[a:filetype], 'v:val.name isnot# a:linter.name')
|
||||
let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter)
|
||||
|
||||
call add(s:linters[a:filetype], l:new_linter)
|
||||
endfunction
|
||||
|
||||
|
||||
@@ -71,8 +71,8 @@ function! s:FixList(buffer, list) abort
|
||||
return l:new_list
|
||||
endfunction
|
||||
|
||||
function! s:WinFindBuf(buffer) abort
|
||||
return exists('*win_findbuf') ? win_findbuf(str2nr(a:buffer)) : [0]
|
||||
function! s:BufWinId(buffer) abort
|
||||
return exists('*bufwinid') ? bufwinid(str2nr(a:buffer)) : 0
|
||||
endfunction
|
||||
|
||||
function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||
@@ -88,19 +88,17 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||
call setqflist([], 'r', {'title': l:title})
|
||||
endif
|
||||
elseif g:ale_set_loclist
|
||||
" If windows support is off, win_findbuf() may not exist.
|
||||
" If windows support is off, bufwinid() may not exist.
|
||||
" We'll set result in the current window, which might not be correct,
|
||||
" but it's better than nothing.
|
||||
let l:ids = s:WinFindBuf(a:buffer)
|
||||
let l:id = s:BufWinId(a:buffer)
|
||||
|
||||
for l:id in l:ids
|
||||
if has('nvim')
|
||||
call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title)
|
||||
else
|
||||
call setloclist(l:id, s:FixList(a:buffer, a:loclist))
|
||||
call setloclist(l:id, [], 'r', {'title': l:title})
|
||||
endif
|
||||
endfor
|
||||
if has('nvim')
|
||||
call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title)
|
||||
else
|
||||
call setloclist(l:id, s:FixList(a:buffer, a:loclist))
|
||||
call setloclist(l:id, [], 'r', {'title': l:title})
|
||||
endif
|
||||
endif
|
||||
|
||||
" Open a window to show the problems if we need to.
|
||||
@@ -183,13 +181,11 @@ function! s:CloseWindowIfNeeded(buffer) abort
|
||||
cclose
|
||||
endif
|
||||
else
|
||||
let l:win_ids = s:WinFindBuf(a:buffer)
|
||||
let l:win_id = s:BufWinId(a:buffer)
|
||||
|
||||
for l:win_id in l:win_ids
|
||||
if g:ale_set_loclist && empty(getloclist(l:win_id))
|
||||
lclose
|
||||
endif
|
||||
endfor
|
||||
if g:ale_set_loclist && empty(getloclist(l:win_id))
|
||||
lclose
|
||||
endif
|
||||
endif
|
||||
" Ignore 'Cannot close last window' errors.
|
||||
catch /E444/
|
||||
|
||||
@@ -111,7 +111,7 @@ function! ale#loclist_jumping#Jump(direction, ...) abort
|
||||
|
||||
if !empty(l:nearest)
|
||||
normal! m`
|
||||
call cursor([l:nearest[0], max([l:nearest[1], 1])])
|
||||
call cursor(l:nearest)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
@@ -321,69 +321,7 @@ endfunction
|
||||
|
||||
function! s:SendInitMessage(conn) abort
|
||||
let [l:init_id, l:init_data] = ale#lsp#CreateMessageData(
|
||||
\ ale#lsp#message#Initialize(
|
||||
\ a:conn.root,
|
||||
\ a:conn.init_options,
|
||||
\ {
|
||||
\ 'workspace': {
|
||||
\ 'applyEdit': v:false,
|
||||
\ 'didChangeConfiguration': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'symbol': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'workspaceFolders': v:false,
|
||||
\ 'configuration': v:false,
|
||||
\ },
|
||||
\ 'textDocument': {
|
||||
\ 'synchronization': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'willSave': v:false,
|
||||
\ 'willSaveWaitUntil': v:false,
|
||||
\ 'didSave': v:true,
|
||||
\ },
|
||||
\ 'completion': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'completionItem': {
|
||||
\ 'snippetSupport': v:false,
|
||||
\ 'commitCharactersSupport': v:false,
|
||||
\ 'documentationFormat': ['plaintext'],
|
||||
\ 'deprecatedSupport': v:false,
|
||||
\ 'preselectSupport': v:false,
|
||||
\ },
|
||||
\ 'contextSupport': v:false,
|
||||
\ },
|
||||
\ 'hover': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'contentFormat': ['plaintext'],
|
||||
\ },
|
||||
\ 'references': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'documentSymbol': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'hierarchicalDocumentSymbolSupport': v:false,
|
||||
\ },
|
||||
\ 'definition': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'linkSupport': v:false,
|
||||
\ },
|
||||
\ 'typeDefinition': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'publishDiagnostics': {
|
||||
\ 'relatedInformation': v:true,
|
||||
\ },
|
||||
\ 'codeAction': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'rename': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ },
|
||||
\ },
|
||||
\ ),
|
||||
\ ale#lsp#message#Initialize(a:conn.root, a:conn.init_options),
|
||||
\)
|
||||
let a:conn.init_request_id = l:init_id
|
||||
call s:SendMessageData(a:conn, l:init_data)
|
||||
@@ -546,35 +484,6 @@ function! ale#lsp#OpenDocument(conn_id, buffer, language_id) abort
|
||||
return l:opened
|
||||
endfunction
|
||||
|
||||
" Notify LSP servers or tsserver that a document is closed, if opened before.
|
||||
" If a document is closed, 1 will be returned, otherwise 0 will be returned.
|
||||
"
|
||||
" Only the buffer number is required here. A message will be sent to every
|
||||
" language server that was notified previously of the document being opened.
|
||||
function! ale#lsp#CloseDocument(buffer) abort
|
||||
let l:closed = 0
|
||||
|
||||
" The connection keys are sorted so the messages are easier to test, and
|
||||
" so messages are sent in a consistent order.
|
||||
for l:conn_id in sort(keys(s:connections))
|
||||
let l:conn = s:connections[l:conn_id]
|
||||
|
||||
if l:conn.initialized && has_key(l:conn.open_documents, a:buffer)
|
||||
if l:conn.is_tsserver
|
||||
let l:message = ale#lsp#tsserver_message#Close(a:buffer)
|
||||
else
|
||||
let l:message = ale#lsp#message#DidClose(a:buffer)
|
||||
endif
|
||||
|
||||
call ale#lsp#Send(l:conn_id, l:message)
|
||||
call remove(l:conn.open_documents, a:buffer)
|
||||
let l:closed = 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:closed
|
||||
endfunction
|
||||
|
||||
" Notify LSP servers or tsserver that a document has changed, if needed.
|
||||
" If a notification is sent, 1 will be returned, otherwise 0 will be returned.
|
||||
function! ale#lsp#NotifyForChanges(conn_id, buffer) abort
|
||||
|
||||
@@ -28,13 +28,14 @@ function! ale#lsp#message#GetNextVersionID() abort
|
||||
return l:id
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#message#Initialize(root_path, options, capabilities) abort
|
||||
function! ale#lsp#message#Initialize(root_path, initialization_options) abort
|
||||
" TODO: Define needed capabilities.
|
||||
" NOTE: rootPath is deprecated in favour of rootUri
|
||||
return [0, 'initialize', {
|
||||
\ 'processId': getpid(),
|
||||
\ 'rootPath': a:root_path,
|
||||
\ 'capabilities': a:capabilities,
|
||||
\ 'initializationOptions': a:options,
|
||||
\ 'capabilities': {},
|
||||
\ 'initializationOptions': a:initialization_options,
|
||||
\ 'rootUri': ale#path#ToURI(a:root_path),
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
@@ -28,7 +28,7 @@ function! ale#lsp#response#ReadDiagnostics(response) abort
|
||||
for l:diagnostic in a:response.params.diagnostics
|
||||
let l:severity = get(l:diagnostic, 'severity', 0)
|
||||
let l:loclist_item = {
|
||||
\ 'text': substitute(l:diagnostic.message, '\(\r\n\|\n\|\r\)', ' ', 'g'),
|
||||
\ 'text': l:diagnostic.message,
|
||||
\ 'type': 'E',
|
||||
\ 'lnum': l:diagnostic.range.start.line + 1,
|
||||
\ 'col': l:diagnostic.range.start.character + 1,
|
||||
@@ -90,7 +90,7 @@ function! ale#lsp#response#ReadTSServerDiagnostics(response) abort
|
||||
\ 'lnum': l:diagnostic.start.line,
|
||||
\ 'col': l:diagnostic.start.offset,
|
||||
\ 'end_lnum': l:diagnostic.end.line,
|
||||
\ 'end_col': l:diagnostic.end.offset - 1,
|
||||
\ 'end_col': l:diagnostic.end.offset,
|
||||
\}
|
||||
|
||||
if has_key(l:diagnostic, 'code')
|
||||
|
||||
@@ -8,16 +8,8 @@ if !has_key(s:, 'lsp_linter_map')
|
||||
let s:lsp_linter_map = {}
|
||||
endif
|
||||
|
||||
" A Dictionary to track one-shot handlers for custom LSP requests
|
||||
let s:custom_handlers_map = get(s:, 'custom_handlers_map', {})
|
||||
|
||||
" Check if diagnostics for a particular linter should be ignored.
|
||||
function! s:ShouldIgnore(buffer, linter_name) abort
|
||||
" Ignore all diagnostics if LSP integration is disabled.
|
||||
if ale#Var(a:buffer, 'disable_lsp')
|
||||
return 1
|
||||
endif
|
||||
|
||||
let l:config = ale#Var(a:buffer, 'linters_ignore')
|
||||
|
||||
" Don't load code for ignoring diagnostics if there's nothing to ignore.
|
||||
@@ -34,13 +26,15 @@ 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 . '$')
|
||||
let l:buffer = bufnr(l:filename)
|
||||
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
||||
|
||||
if empty(l:info)
|
||||
return
|
||||
endif
|
||||
|
||||
call ale#engine#MarkLinterInactive(l:info, l:linter_name)
|
||||
|
||||
if s:ShouldIgnore(l:buffer, l:linter_name)
|
||||
return
|
||||
endif
|
||||
@@ -52,7 +46,7 @@ endfunction
|
||||
|
||||
function! s:HandleTSServerDiagnostics(response, error_type) abort
|
||||
let l:linter_name = 'tsserver'
|
||||
let l:buffer = bufnr('^' . a:response.body.file . '$')
|
||||
let l:buffer = bufnr(a:response.body.file)
|
||||
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
||||
|
||||
if empty(l:info)
|
||||
@@ -387,10 +381,6 @@ function! s:CheckWithLSP(linter, details) abort
|
||||
if a:linter.lsp is# 'tsserver'
|
||||
let l:message = ale#lsp#tsserver_message#Geterr(l:buffer)
|
||||
let l:notified = ale#lsp#Send(l:id, l:message) != 0
|
||||
|
||||
if l:notified
|
||||
call ale#engine#MarkLinterActive(l:info, a:linter)
|
||||
endif
|
||||
else
|
||||
let l:notified = ale#lsp#NotifyForChanges(l:id, l:buffer)
|
||||
endif
|
||||
@@ -401,6 +391,10 @@ function! s:CheckWithLSP(linter, details) abort
|
||||
let l:save_message = ale#lsp#message#DidSave(l:buffer)
|
||||
let l:notified = ale#lsp#Send(l:id, l:save_message) != 0
|
||||
endif
|
||||
|
||||
if l:notified
|
||||
call ale#engine#MarkLinterActive(l:info, a:linter)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort
|
||||
@@ -410,57 +404,9 @@ endfunction
|
||||
" Clear LSP linter data for the linting engine.
|
||||
function! ale#lsp_linter#ClearLSPData() abort
|
||||
let s:lsp_linter_map = {}
|
||||
let s:custom_handlers_map = {}
|
||||
endfunction
|
||||
|
||||
" Just for tests.
|
||||
function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
|
||||
let s:lsp_linter_map = a:replacement_map
|
||||
endfunction
|
||||
|
||||
function! s:HandleLSPResponseToCustomRequests(conn_id, response) abort
|
||||
if has_key(a:response, 'id')
|
||||
\&& has_key(s:custom_handlers_map, a:response.id)
|
||||
let l:Handler = remove(s:custom_handlers_map, a:response.id)
|
||||
call l:Handler(a:response)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnReadyForCustomRequests(args, linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
let l:request_id = ale#lsp#Send(l:id, a:args.message)
|
||||
|
||||
if l:request_id > 0 && has_key(a:args, 'handler')
|
||||
let l:Callback = function('s:HandleLSPResponseToCustomRequests')
|
||||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
let s:custom_handlers_map[l:request_id] = a:args.handler
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Send a custom request to an LSP linter.
|
||||
function! ale#lsp_linter#SendRequest(buffer, linter_name, message, ...) abort
|
||||
let l:filetype = ale#linter#ResolveFiletype(getbufvar(a:buffer, '&filetype'))
|
||||
let l:linter_list = ale#linter#GetAll(l:filetype)
|
||||
let l:linter_list = filter(l:linter_list, {_, v -> v.name is# a:linter_name})
|
||||
|
||||
if len(l:linter_list) < 1
|
||||
throw 'Linter "' . a:linter_name . '" not found!'
|
||||
endif
|
||||
|
||||
let l:linter = l:linter_list[0]
|
||||
|
||||
if empty(l:linter.lsp)
|
||||
throw 'Linter "' . a:linter_name . '" does not support LSP!'
|
||||
endif
|
||||
|
||||
let l:is_notification = a:message[0]
|
||||
let l:callback_args = {'message': a:message}
|
||||
|
||||
if !l:is_notification && a:0
|
||||
let l:callback_args.handler = a:1
|
||||
endif
|
||||
|
||||
let l:Callback = function('s:OnReadyForCustomRequests', [l:callback_args])
|
||||
|
||||
return ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback)
|
||||
endfunction
|
||||
|
||||
@@ -3,20 +3,13 @@
|
||||
|
||||
" simplify a path, and fix annoying issues with paths on Windows.
|
||||
"
|
||||
" Forward slashes are changed to back slashes so path equality works better
|
||||
" on Windows. Back slashes are changed to forward slashes on Unix.
|
||||
"
|
||||
" Unix paths can technically contain back slashes, but in practice no path
|
||||
" should, and replacing back slashes with forward slashes makes linters work
|
||||
" in environments like MSYS.
|
||||
" Forward slashes are changed to back slashes so path equality works better.
|
||||
"
|
||||
" Paths starting with more than one forward slash are changed to only one
|
||||
" forward slash, to prevent the paths being treated as special MSYS paths.
|
||||
function! ale#path#Simplify(path) abort
|
||||
if has('unix')
|
||||
let l:unix_path = substitute(a:path, '\\', '/', 'g')
|
||||
|
||||
return substitute(simplify(l:unix_path), '^//\+', '/', 'g') " no-custom-checks
|
||||
return substitute(simplify(a:path), '^//\+', '/', 'g') " no-custom-checks
|
||||
endif
|
||||
|
||||
let l:win_path = substitute(a:path, '/', '\\', 'g')
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
" Author: zigford <zigford@gmail.com>
|
||||
" Description: Functions for integrating with Powershell linters.
|
||||
|
||||
" Write a powershell script to a temp file for execution
|
||||
" return the command used to execute it
|
||||
function! s:TemporaryPSScript(buffer, input) abort
|
||||
let l:filename = 'script.ps1'
|
||||
" Create a temp dir to house our temp .ps1 script
|
||||
" a temp dir is needed as powershell needs the .ps1
|
||||
" extension
|
||||
let l:tempdir = ale#util#Tempname() . (has('win32') ? '\' : '/')
|
||||
let l:tempscript = l:tempdir . l:filename
|
||||
" Create the temporary directory for the file, unreadable by 'other'
|
||||
" users.
|
||||
call mkdir(l:tempdir, '', 0750)
|
||||
" Automatically delete the directory later.
|
||||
call ale#command#ManageDirectory(a:buffer, l:tempdir)
|
||||
" Write the script input out to a file.
|
||||
call ale#util#Writefile(a:buffer, a:input, l:tempscript)
|
||||
|
||||
return l:tempscript
|
||||
endfunction
|
||||
|
||||
function! ale#powershell#RunPowerShell(buffer, base_var_name, command) abort
|
||||
let l:executable = ale#Var(a:buffer, a:base_var_name . '_executable')
|
||||
let l:tempscript = s:TemporaryPSScript(a:buffer, a:command)
|
||||
|
||||
return ale#Escape(l:executable)
|
||||
\ . ' -Exe Bypass -NoProfile -File '
|
||||
\ . ale#Escape(l:tempscript)
|
||||
\ . ' %t'
|
||||
endfunction
|
||||
@@ -25,7 +25,7 @@ function! ale#python#FindProjectRootIni(buffer) abort
|
||||
\|| filereadable(l:path . '/tox.ini')
|
||||
\|| filereadable(l:path . '/mypy.ini')
|
||||
\|| filereadable(l:path . '/pycodestyle.cfg')
|
||||
\|| filereadable(l:path . '/.flake8')
|
||||
\|| filereadable(l:path . '/flake8.cfg')
|
||||
\|| filereadable(l:path . '/.flake8rc')
|
||||
\|| filereadable(l:path . '/pylama.ini')
|
||||
\|| filereadable(l:path . '/pylintrc')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
" Author: Eddie Lebow https://github.com/elebow
|
||||
" Description: Functions for integrating with Ruby tools
|
||||
|
||||
" Find the nearest dir containing "app", "db", and "config", and assume it is
|
||||
" Find the nearest dir contining "app", "db", and "config", and assume it is
|
||||
" the root of a Rails app.
|
||||
function! ale#ruby#FindRailsRoot(buffer) abort
|
||||
for l:name in ['app', 'config', 'db']
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
" Author: Dan Loman <https://github.com/namolnad>
|
||||
" Description: Functions for integrating with Swift tools
|
||||
|
||||
" Find the nearest dir containing a Package.swift file and assume it is the root of the Swift project.
|
||||
function! ale#swift#FindProjectRoot(buffer) abort
|
||||
let l:swift_config = ale#path#FindNearestFile(a:buffer, 'Package.swift')
|
||||
|
||||
if !empty(l:swift_config)
|
||||
return fnamemodify(l:swift_config, ':h')
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
@@ -422,7 +422,7 @@ function! ale#util#Writefile(buffer, lines, filename) abort
|
||||
\ ? map(copy(a:lines), 'substitute(v:val, ''\r*$'', ''\r'', '''')')
|
||||
\ : a:lines
|
||||
|
||||
call writefile(l:corrected_lines, a:filename, 'S') " no-custom-checks
|
||||
call writefile(l:corrected_lines, a:filename) " no-custom-checks
|
||||
endfunction
|
||||
|
||||
if !exists('s:patial_timers')
|
||||
|
||||
@@ -81,7 +81,7 @@ function! ale#virtualtext#ShowCursorWarning(...) abort
|
||||
call ale#virtualtext#Clear()
|
||||
|
||||
if !empty(l:loc)
|
||||
let l:msg = l:loc.text
|
||||
let l:msg = get(l:loc, 'detail', l:loc.text)
|
||||
let l:hl_group = 'ALEVirtualTextInfo'
|
||||
let l:type = get(l:loc, 'type', 'E')
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ g:ale_c_clangtidy_options *g:ale_c_clangtidy_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable can be changed to modify compiler flags given to clang-tidy.
|
||||
This variable can be changed to modify flags given to clang-tidy.
|
||||
|
||||
- Setting this variable to a non-empty string,
|
||||
- and working in a buffer where no compilation database is found using
|
||||
@@ -169,14 +169,6 @@ g:ale_c_clangtidy_options *g:ale_c_clangtidy_options*
|
||||
of the |g:ale_c_build_dir_names| directories of the project tree.
|
||||
|
||||
|
||||
g:ale_c_clangtidy_extra_options *g:ale_c_clangtidy_extra_options*
|
||||
*b:ale_c_clangtidy_extra_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable can be changed to modify flags given to clang-tidy.
|
||||
|
||||
|
||||
===============================================================================
|
||||
cppcheck *ale-c-cppcheck*
|
||||
|
||||
|
||||
@@ -2,26 +2,6 @@
|
||||
ALE Chef Integration *ale-chef-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
cookstyle *ale-chef-cookstyle*
|
||||
|
||||
g:ale_chef_cookstyle_options *g:ale_chef_cookstyle_options*
|
||||
*b:ale_chef_cookstyle_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable can be changed to modify flags given to cookstyle.
|
||||
|
||||
|
||||
g:ale_chef_cookstyle_executable *g:ale_chef_cookstyle_executable*
|
||||
*b:ale_chef_cookstyle_executable*
|
||||
Type: |String|
|
||||
Default: `'cookstyle'`
|
||||
|
||||
This variable can be changed to point to the cookstyle binary in case it's
|
||||
not on the $PATH or a specific version/path must be used.
|
||||
|
||||
|
||||
===============================================================================
|
||||
foodcritic *ale-chef-foodcritic*
|
||||
|
||||
|
||||
@@ -2,13 +2,6 @@
|
||||
ALE Clojure Integration *ale-clojure-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
clj-kondo *ale-clojure-clj-kondo*
|
||||
|
||||
A minimal and opinionated linter for code that sparks joy.
|
||||
|
||||
https://github.com/borkdude/clj-kondo
|
||||
|
||||
===============================================================================
|
||||
joker *ale-clojure-joker*
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable can be changed to modify compiler flags given to clang-tidy.
|
||||
This variable can be changed to modify flags given to clang-tidy.
|
||||
|
||||
- Setting this variable to a non-empty string,
|
||||
- and working in a buffer where no compilation database is found using
|
||||
@@ -138,14 +138,6 @@ g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options*
|
||||
of the |g:ale_c_build_dir_names| directories of the project tree.
|
||||
|
||||
|
||||
g:ale_cpp_clangtidy_extra_options *g:ale_cpp_clangtidy_extra_options*
|
||||
*b:ale_cpp_clangtidy_extra_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable can be changed to modify flags given to clang-tidy.
|
||||
|
||||
|
||||
===============================================================================
|
||||
clazy *ale-cpp-clazy*
|
||||
|
||||
|
||||
@@ -2,14 +2,6 @@
|
||||
ALE CSS Integration *ale-css-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
fecs *ale-css-fecs*
|
||||
|
||||
`fecs` options for CSS is the same as the options for JavaScript, and both of
|
||||
them reads `./.fecsrc` as the default configuration file. See:
|
||||
|ale-javascript-fecs|.
|
||||
|
||||
|
||||
===============================================================================
|
||||
prettier *ale-css-prettier*
|
||||
|
||||
|
||||
@@ -151,9 +151,9 @@ ALE is tested with a suite of tests executed in Travis CI and AppVeyor. ALE
|
||||
runs tests with the following versions of Vim in the following environments.
|
||||
|
||||
1. Vim 8.0.0027 on Linux via Travis CI.
|
||||
2. Vim 8.1.0519 on Linux via Travis CI.
|
||||
2. Vim 8.1.0204 on Linux via Travis CI.
|
||||
3. NeoVim 0.2.0 on Linux via Travis CI.
|
||||
4. NeoVim 0.3.5 on Linux via Travis CI.
|
||||
4. NeoVim 0.3.0 on Linux via Travis CI.
|
||||
5. Vim 8 (stable builds) on Windows via AppVeyor.
|
||||
|
||||
If you are developing ALE code on Linux, Mac OSX, or BSD, you can run ALEs
|
||||
@@ -351,7 +351,6 @@ given the above setup are as follows.
|
||||
|
||||
`GivenCommandOutput [...]` - Define output for ale#command#Run.
|
||||
`AssertFixer results` - Check the fixer results
|
||||
`AssertFixerNotExecuted` - Check that fixers will not be executed.
|
||||
|
||||
|
||||
===============================================================================
|
||||
|
||||
@@ -3,35 +3,6 @@ ALE Erlang Integration *ale-erlang-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
dialyzer *ale-erlang-dialyzer*
|
||||
|
||||
g:ale_erlang_dialyzer_executable *g:ale_erlang_dialyzer_executable*
|
||||
*b:ale_erlang_dialyzer_executable*
|
||||
Type: |String|
|
||||
Default: `'dialyzer'`
|
||||
|
||||
This variable can be changed to specify the dialyzer executable.
|
||||
|
||||
|
||||
g:ale_erlang_dialyzer_plt_file *g:ale_erlang_dialyzer_plt_file*
|
||||
*b:ale_erlang_dialyzer_plt_file*
|
||||
Type: |String|
|
||||
|
||||
This variable can be changed to specify the path to the PLT file. By
|
||||
default, it will search for the PLT file inside the `_build` directory. If
|
||||
there isn't one, it will fallback to the path `$REBAR_PLT_DIR/dialyzer/plt`.
|
||||
Otherwise, it will default to `$HOME/.dialyzer_plt`.
|
||||
|
||||
|
||||
g:ale_erlang_dialyzer_rebar3_profile *g:ale_erlang_dialyzer_rebar3_profile*
|
||||
*b:ale_erlang_dialyzer_rebar3_profile*
|
||||
Type: |String|
|
||||
Default: `'default'`
|
||||
|
||||
This variable can be changed to specify the profile that is used to
|
||||
run dialyzer with rebar3.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
erlc *ale-erlang-erlc*
|
||||
|
||||
g:ale_erlang_erlc_options *g:ale_erlang_erlc_options*
|
||||
|
||||
179
doc/ale-go.txt
179
doc/ale-go.txt
@@ -30,23 +30,6 @@ g:ale_go_go_executable *g:ale_go_go_options*
|
||||
the `gomod` fixer.
|
||||
|
||||
|
||||
===============================================================================
|
||||
bingo *ale-go-bingo*
|
||||
|
||||
g:ale_go_bingo_executable *g:ale_go_bingo_executable*
|
||||
*b:ale_go_bingo_executable*
|
||||
Type: |String|
|
||||
Default: `'bingo'`
|
||||
|
||||
Location of the bingo binary file.
|
||||
|
||||
|
||||
g:ale_go_bingo_options *g:ale_go_bingo_options*
|
||||
*b:ale_go_bingo_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
|
||||
===============================================================================
|
||||
gobuild *ale-go-gobuild*
|
||||
|
||||
@@ -70,60 +53,6 @@ g:ale_go_gofmt_options *g:ale_go_gofmt_options*
|
||||
This variable can be set to pass additional options to the gofmt fixer.
|
||||
|
||||
|
||||
===============================================================================
|
||||
golangci-lint *ale-go-golangci-lint*
|
||||
|
||||
`golangci-lint` is a `lint_file` linter, which only lints files that are
|
||||
written to disk. This differs from the default behavior of linting the buffer.
|
||||
See: |ale-lint-file|
|
||||
|
||||
g:ale_go_golangci_lint_executable *g:ale_go_golangci_lint_executable*
|
||||
*b:ale_go_golangci_lint_executable*
|
||||
Type: |String|
|
||||
Default: `'golangci-lint'`
|
||||
|
||||
The executable that will be run for golangci-lint.
|
||||
|
||||
|
||||
g:ale_go_golangci_lint_options *g:ale_go_golangci_lint_options*
|
||||
*b:ale_go_golangci_lint_options*
|
||||
Type: |String|
|
||||
Default: `'--enable-all'`
|
||||
|
||||
This variable can be changed to alter the command-line arguments to the
|
||||
golangci-lint invocation.
|
||||
|
||||
|
||||
g:ale_go_golangci_lint_package *g:ale_go_golangci_lint_package*
|
||||
*b:ale_go_golangci_lint_package*
|
||||
Type: |Number|
|
||||
Default: `0`
|
||||
|
||||
When set to `1`, the whole Go package will be checked instead of only the
|
||||
current file.
|
||||
|
||||
|
||||
===============================================================================
|
||||
golangserver *ale-go-golangserver*
|
||||
|
||||
g:ale_go_langserver_executable *g:ale_go_langserver_executable*
|
||||
*b:ale_go_langserver_executable*
|
||||
Type: |String|
|
||||
Default: `'go-langserver'`
|
||||
|
||||
Location of the go-langserver binary file.
|
||||
|
||||
|
||||
g:ale_go_langserver_options *g:ale_go_langserver_options*
|
||||
*b:ale_go_langserver_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
Additional options passed to the go-langserver command. Note that the
|
||||
`-gocodecompletion` option is ignored because it is handled automatically
|
||||
by the |g:ale_completion_enabled| variable.
|
||||
|
||||
|
||||
===============================================================================
|
||||
golint *ale-go-golint*
|
||||
|
||||
@@ -143,6 +72,17 @@ g:ale_go_golint_options *g:ale_go_golint_options*
|
||||
This variable can be set to pass additional options to the golint linter.
|
||||
|
||||
|
||||
===============================================================================
|
||||
govet *ale-go-govet*
|
||||
|
||||
g:ale_go_govet_options *g:ale_go_govet_options*
|
||||
*b:ale_go_govet_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable can be set to pass additional options to the go vet linter.
|
||||
|
||||
|
||||
===============================================================================
|
||||
gometalinter *ale-go-gometalinter*
|
||||
|
||||
@@ -181,34 +121,6 @@ g:ale_go_gometalinter_lint_package *g:ale_go_gometalinter_lint_package*
|
||||
current file.
|
||||
|
||||
|
||||
===============================================================================
|
||||
gopls *ale-go-gopls*
|
||||
|
||||
g:ale_go_gopls_executable *g:ale_go_gopls_executable*
|
||||
*b:ale_go_gopls_executable*
|
||||
Type: |String|
|
||||
Default: `'gopls'`
|
||||
|
||||
Location of the gopls binary file.
|
||||
|
||||
|
||||
g:ale_go_gopls_options *g:ale_go_gopls_options*
|
||||
*b:ale_go_gopls_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
|
||||
===============================================================================
|
||||
govet *ale-go-govet*
|
||||
|
||||
g:ale_go_govet_options *g:ale_go_govet_options*
|
||||
*b:ale_go_govet_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable can be set to pass additional options to the go vet linter.
|
||||
|
||||
|
||||
===============================================================================
|
||||
staticcheck *ale-go-staticcheck*
|
||||
|
||||
@@ -230,5 +142,74 @@ g:ale_go_staticcheck_lint_package *g:ale_go_staticcheck_lint_package*
|
||||
current file.
|
||||
|
||||
|
||||
===============================================================================
|
||||
golangserver *ale-go-golangserver*
|
||||
|
||||
g:ale_go_langserver_executable *g:ale_go_langserver_executable*
|
||||
*b:ale_go_langserver_executable*
|
||||
Type: |String|
|
||||
Default: `'go-langserver'`
|
||||
|
||||
Location of the go-langserver binary file.
|
||||
|
||||
g:ale_go_langserver_options *g:ale_go_langserver_options*
|
||||
*b:ale_go_langserver_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
Additional options passed to the go-langserver command. Note that the
|
||||
`-gocodecompletion` option is ignored because it is handled automatically
|
||||
by the |g:ale_completion_enabled| variable.
|
||||
|
||||
|
||||
===============================================================================
|
||||
golangci-lint *ale-go-golangci-lint*
|
||||
|
||||
`golangci-lint` is a `lint_file` linter, which only lints files that are
|
||||
written to disk. This differs from the default behavior of linting the buffer.
|
||||
See: |ale-lint-file|
|
||||
|
||||
g:ale_go_golangci_lint_executable *g:ale_go_golangci_lint_executable*
|
||||
*b:ale_go_golangci_lint_executable*
|
||||
Type: |String|
|
||||
Default: `'golangci-lint'`
|
||||
|
||||
The executable that will be run for golangci-lint.
|
||||
|
||||
|
||||
g:ale_go_golangci_lint_options *g:ale_go_golangci_lint_options*
|
||||
*b:ale_go_golangci_lint_options*
|
||||
Type: |String|
|
||||
Default: `'--enable-all'`
|
||||
|
||||
This variable can be changed to alter the command-line arguments to the
|
||||
golangci-lint invocation.
|
||||
|
||||
|
||||
g:ale_go_golangci_lint_package *g:ale_go_golangci_lint_package*
|
||||
*b:ale_go_golangci_lint_package*
|
||||
Type: |Number|
|
||||
Default: `0`
|
||||
|
||||
When set to `1`, the whole Go package will be checked instead of only the
|
||||
current file.
|
||||
|
||||
|
||||
===============================================================================
|
||||
bingo *ale-go-bingo*
|
||||
|
||||
g:ale_go_bingo_executable *g:ale_go_bingo_executable*
|
||||
*b:ale_go_bingo_executable*
|
||||
Type: |String|
|
||||
Default: `'go-bingo'`
|
||||
|
||||
Location of the go-bingo binary file.
|
||||
|
||||
g:ale_go_bingo_options *g:ale_go_bingo_options*
|
||||
*b:ale_go_bingo_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||
|
||||
@@ -12,16 +12,6 @@ g:ale_haskell_brittany_executable *g:ale_haskell_brittany_executable*
|
||||
|
||||
This variable can be changed to use a different executable for brittany.
|
||||
|
||||
===============================================================================
|
||||
floskell *ale-haskell-floskell*
|
||||
|
||||
g:ale_haskell_floskell_executable *g:ale_haskell_floskell_executable*
|
||||
*b:ale_haskell_floskell_executable*
|
||||
Type: |String|
|
||||
Default: `'floskell'`
|
||||
|
||||
This variable can be changed to use a different executable for floskell.
|
||||
|
||||
===============================================================================
|
||||
ghc *ale-haskell-ghc*
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ ALE HCL Integration *ale-hcl-options*
|
||||
===============================================================================
|
||||
terraform-fmt *ale-hcl-terraform-fmt*
|
||||
|
||||
See |ale-terraform-fmt-fixer| for information about the available options.
|
||||
See |ale-terraform-fmt| for information about the available options.
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||
|
||||
@@ -2,14 +2,6 @@
|
||||
ALE HTML Integration *ale-html-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
fecs *ale-html-fecs*
|
||||
|
||||
`fecs` options for HTMl is the same as the options for JavaScript,
|
||||
and both of them reads `./.fecsrc` as the default configuration file.
|
||||
See: |ale-javascript-fecs|.
|
||||
|
||||
|
||||
===============================================================================
|
||||
htmlhint *ale-html-htmlhint*
|
||||
|
||||
|
||||
103
doc/ale-java.txt
103
doc/ale-java.txt
@@ -5,41 +5,14 @@ ALE Java Integration *ale-java-options*
|
||||
===============================================================================
|
||||
checkstyle *ale-java-checkstyle*
|
||||
|
||||
g:ale_java_checkstyle_config *g:ale_java_checkstyle_config*
|
||||
*b:ale_java_checkstyle_config*
|
||||
|
||||
Type: |String|
|
||||
Default: `'google_checks.xml'`
|
||||
|
||||
A path to a checkstyle configuration file.
|
||||
|
||||
If a configuration file is specified with |g:ale_java_checkstyle_options|,
|
||||
it will be preferred over this setting.
|
||||
|
||||
The path to the configuration file can be an absolute path or a relative
|
||||
path. ALE will search for the relative path in parent directories.
|
||||
|
||||
|
||||
g:ale_java_checkstyle_executable *g:ale_java_checkstyle_executable*
|
||||
*b:ale_java_checkstyle_executable*
|
||||
|
||||
Type: |String|
|
||||
Default: 'checkstyle'
|
||||
|
||||
This variable can be changed to modify the executable used for checkstyle.
|
||||
|
||||
|
||||
g:ale_java_checkstyle_options *g:ale_java_checkstyle_options*
|
||||
*b:ale_java_checkstyle_options*
|
||||
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
Type: String
|
||||
Default: '-c /google_checks.xml'
|
||||
|
||||
This variable can be changed to modify flags given to checkstyle.
|
||||
|
||||
If a configuration file is specified with `-c`, it will be used instead of
|
||||
configuration files set with |g:ale_java_checkstyle_config|.
|
||||
|
||||
|
||||
===============================================================================
|
||||
javac *ale-java-javac*
|
||||
@@ -117,83 +90,15 @@ or
|
||||
|
||||
This generates a dist/mac or dist/windows directory that contains the
|
||||
language server. To let ALE use this language server you need to set the
|
||||
g:ale_java_javalsp_executable variable to the absolute path of the launcher
|
||||
g:ale_java_javalsp_executable variable to the absolute path of the java
|
||||
executable in this directory.
|
||||
|
||||
g:ale_java_javalsp_executable *g:ale_java_javalsp_executable*
|
||||
*b:ale_java_javalsp_executable*
|
||||
Type: |String|
|
||||
Default: `'launcher'`
|
||||
|
||||
This variable must be set to the absolute path of the language server launcher
|
||||
executable. For example:
|
||||
>
|
||||
let g:ale_java_javalsp_executable=/java-language-server/dist/mac/bin/launcher
|
||||
<
|
||||
|
||||
===============================================================================
|
||||
eclipselsp *ale-java-eclipselsp*
|
||||
|
||||
To enable Eclipse LSP linter you need to clone and build the eclipse.jdt.ls
|
||||
language server from https://github.com/eclipse/eclipse.jdt.ls. Simply
|
||||
clone the source code repo and then build the plugin:
|
||||
|
||||
./mvnw clean verify
|
||||
|
||||
Note: currently, the build can only run when launched with JDK 8. JDK 9 or more
|
||||
recent versions can be used to run the server though.
|
||||
|
||||
After build completes the files required to run the language server will be
|
||||
located inside the repository folder `eclipse.jdt.ls`. Please ensure to set
|
||||
|g:ale_java_eclipselsp_path| to the absolute path of that folder.
|
||||
|
||||
You could customize compiler options and code assists of the server.
|
||||
Under your project folder, modify the file `.settings/org.eclipse.jdt.core.prefs`
|
||||
with options presented at
|
||||
https://help.eclipse.org/neon/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/JavaCore.html.
|
||||
|
||||
g:ale_java_eclipselsp_path *g:ale_java_eclipselsp_path*
|
||||
*b:ale_java_eclipselsp_path*
|
||||
|
||||
Type: |String|
|
||||
Default: `'$HOME/eclipse.jdt.ls'`
|
||||
|
||||
Absolute path to the location of the eclipse.jdt.ls repository folder. Or if
|
||||
you have VSCode extension installed the absolute path to the VSCode extensions
|
||||
folder (e.g. $HOME/.vscode/extensions/redhat.java-0.4x.0 in Linux).
|
||||
|
||||
|
||||
g:ale_java_eclipselsp_executable *g:ale_java_eclipse_executable*
|
||||
*b:ale_java_eclipse_executable*
|
||||
Type: |String|
|
||||
Default: `'java'`
|
||||
|
||||
This variable can be set to change the executable path used for java.
|
||||
|
||||
|
||||
g:ale_java_eclipselsp_config_path *g:ale_java_eclipse_config_path*
|
||||
*b:ale_java_eclipse_config_path*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
Set this variable to change the configuration directory path used by
|
||||
eclipselsp (e.g. `$HOME/.jdtls` in Linux).
|
||||
By default ALE will attempt to use the configuration within the installation
|
||||
directory.
|
||||
This setting is particularly useful when eclipselsp is installed in a
|
||||
non-writable directory like `/usr/share/java/jdtls`, as is the case when
|
||||
installed via system package.
|
||||
|
||||
|
||||
g:ale_java_eclipselsp_workspace_path *g:ale_java_eclipselsp_workspace_path*
|
||||
*b:ale_java_eclipselsp_workspace_path*
|
||||
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
If you have Eclipse installed is good idea to set this variable to the
|
||||
absolute path of the Eclipse workspace. If not set this value will be set to
|
||||
the parent folder of the project root.
|
||||
This variable can be changed to use a different executable for java.
|
||||
|
||||
|
||||
===============================================================================
|
||||
|
||||
@@ -73,33 +73,6 @@ g:ale_javascript_eslint_suppress_missing_config
|
||||
configuration files are found.
|
||||
|
||||
|
||||
===============================================================================
|
||||
fecs *ale-javascript-fecs*
|
||||
|
||||
`fecs` is a lint tool for HTML/CSS/JavaScript, can be installed via:
|
||||
|
||||
`$ npm install --save-dev fecs`
|
||||
|
||||
And the configuration file is located at `./fecsrc`, see http://fecs.baidu.com
|
||||
for more options.
|
||||
|
||||
|
||||
g:ale_javascript_fecs_executable *g:ale_javascript_fecs_executable*
|
||||
*b:ale_javascript_fecs_executable*
|
||||
Type: |String|
|
||||
Default: `'fecs'`
|
||||
|
||||
See |ale-integrations-local-executables|
|
||||
|
||||
|
||||
g:ale_javascript_fecs_use_global *g:ale_javascript_fecs_use_global*
|
||||
*b:ale_javascript_fecs_use_global*
|
||||
Type: |Number|
|
||||
Default: `get(g:, 'ale_use_global_executables', 0)`
|
||||
|
||||
See |ale-integrations-local-executables|
|
||||
|
||||
|
||||
===============================================================================
|
||||
flow *ale-javascript-flow*
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user