mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-07 05:04:28 +08:00
Compare commits
143 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b24fd13423 | ||
|
|
7c5825ecbc | ||
|
|
01219f0308 | ||
|
|
af1643a948 | ||
|
|
5a1505ad62 | ||
|
|
3fe2223a48 | ||
|
|
e8de12c9f0 | ||
|
|
f932211309 | ||
|
|
6d88801789 | ||
|
|
59b34dd017 | ||
|
|
f2b231dd76 | ||
|
|
8fda1cebff | ||
|
|
8097d51e33 | ||
|
|
06082ef377 | ||
|
|
d3a3f4011b | ||
|
|
cebbb67ea6 | ||
|
|
32b784219b | ||
|
|
7795898841 | ||
|
|
06a97a8541 | ||
|
|
0fa2d18230 | ||
|
|
d0e87c0df4 | ||
|
|
89fa43551f | ||
|
|
98b0dcd7d6 | ||
|
|
b96574e5b5 | ||
|
|
a486aa1d24 | ||
|
|
7c2f5e83ab | ||
|
|
889e6338fe | ||
|
|
41ff80dc9e | ||
|
|
6746eaeaa0 | ||
|
|
d7dbc8f2cf | ||
|
|
e329413a31 | ||
|
|
e6241ee0d2 | ||
|
|
07c11e4e7f | ||
|
|
ab8e043353 | ||
|
|
e6946de98a | ||
|
|
6ab264ff0f | ||
|
|
d93512fe60 | ||
|
|
7b38e97943 | ||
|
|
f5e44415e8 | ||
|
|
e3784c4c4e | ||
|
|
b531a4e0b3 | ||
|
|
dd6bd6f0fe | ||
|
|
529f57a66f | ||
|
|
b8949aaac3 | ||
|
|
dc42c0f948 | ||
|
|
41ed10be4e | ||
|
|
34431d885b | ||
|
|
61cfb3fefb | ||
|
|
321ee6d26b | ||
|
|
58b7c281c5 | ||
|
|
a6c59faa0f | ||
|
|
3e8c8d3ccb | ||
|
|
b66d202c1d | ||
|
|
05ba522c9a | ||
|
|
34f2943fdd | ||
|
|
84a455185c | ||
|
|
fbe7cea91c | ||
|
|
cda46636f4 | ||
|
|
2e323b529d | ||
|
|
bd1f7e1420 | ||
|
|
6e18c03d80 | ||
|
|
9f814a8ce9 | ||
|
|
67ee2b9586 | ||
|
|
7d7ddf22d3 | ||
|
|
2b12c8ccbf | ||
|
|
5fcb24bb3e | ||
|
|
cf47bda024 | ||
|
|
da262f40dd | ||
|
|
6aeb462171 | ||
|
|
442fb2d22f | ||
|
|
08a5bfcaa9 | ||
|
|
73812c3e41 | ||
|
|
91636cff06 | ||
|
|
d787369f37 | ||
|
|
c4bdf165ca | ||
|
|
ddb559b3be | ||
|
|
ee62cc6898 | ||
|
|
219fb5873c | ||
|
|
b62e306222 | ||
|
|
5388ff1d54 | ||
|
|
266fa1c0a4 | ||
|
|
b70eeaadb4 | ||
|
|
74a43755c6 | ||
|
|
58e8d32d79 | ||
|
|
8aa1578605 | ||
|
|
501af8dd8b | ||
|
|
b1810b2752 | ||
|
|
28c93ab185 | ||
|
|
ab0bf61512 | ||
|
|
20cc6d3e05 | ||
|
|
dd1e1025b8 | ||
|
|
3ae01ba249 | ||
|
|
9c7673e6c9 | ||
|
|
8f5ecf0120 | ||
|
|
d1c56769b7 | ||
|
|
b1230873b6 | ||
|
|
4fe7402e89 | ||
|
|
e47c1965a6 | ||
|
|
c675212ddd | ||
|
|
d25711a516 | ||
|
|
aae6d30b1e | ||
|
|
bafa1c619d | ||
|
|
240bb8abae | ||
|
|
36a50111b9 | ||
|
|
abb38955d3 | ||
|
|
fa5aecc250 | ||
|
|
6e6ad2e430 | ||
|
|
79dde5f0e5 | ||
|
|
6c47d7fc35 | ||
|
|
a5240009ba | ||
|
|
46ab7c5904 | ||
|
|
8700586890 | ||
|
|
221aceb6db | ||
|
|
49db8210f6 | ||
|
|
89f7292138 | ||
|
|
6feeca793a | ||
|
|
53b0e6c37d | ||
|
|
a3521de64e | ||
|
|
e52388b8b1 | ||
|
|
0843efc7a5 | ||
|
|
65ba4b85ec | ||
|
|
bf0d0597cb | ||
|
|
9ad8fd6a1b | ||
|
|
d2c3141f26 | ||
|
|
418f8a6fed | ||
|
|
9c48c584a9 | ||
|
|
38a55fa9fe | ||
|
|
4e1c46947d | ||
|
|
e0f8304860 | ||
|
|
f5a908bf99 | ||
|
|
f2e52b9432 | ||
|
|
40bf6e6b5c | ||
|
|
c5a4bbf8b0 | ||
|
|
1c71da5624 | ||
|
|
701c1e4f17 | ||
|
|
15f23532b7 | ||
|
|
3acfa0813e | ||
|
|
e0871be22b | ||
|
|
6e28eec243 | ||
|
|
86205967ea | ||
|
|
eb6a7b7516 | ||
|
|
0135fb3ad3 | ||
|
|
3e4b8ea466 |
@@ -5,6 +5,11 @@ clone_depth: 10
|
||||
# Use the directory C:\testplugin so test directories will mostly work.
|
||||
clone_folder: C:\testplugin
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /v\d+\.\d+\.(x|\d+)/
|
||||
|
||||
# Cache the vim and vader directories between builds.
|
||||
cache:
|
||||
- C:\vim -> .appveyor.yml
|
||||
|
||||
@@ -3,6 +3,10 @@ sudo: required
|
||||
services:
|
||||
- docker
|
||||
language: generic
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /^v\d+\.\d+\.(x|\d+)$/
|
||||
env:
|
||||
- OPTIONS=--vim-80-only
|
||||
- OPTIONS=--vim-81-only
|
||||
|
||||
31
README.md
31
README.md
@@ -1,4 +1,4 @@
|
||||
# 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.com/dense-analysis/ale) [](https://ci.appveyor.com/project/dense-analysis/ale) [](https://gitter.im/vim-ale/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
|
||||

|
||||
@@ -189,6 +189,14 @@ completion manually with `<C-x><C-o>`.
|
||||
set omnifunc=ale#completion#OmniFunc
|
||||
```
|
||||
|
||||
When working with TypeScript files, ALE supports automatic imports from
|
||||
external modules. This behavior is disabled by default and can be enabled by
|
||||
setting:
|
||||
|
||||
```vim
|
||||
let g:ale_completion_tsserver_autoimport = 1
|
||||
```
|
||||
|
||||
See `:help ale-completion` for more information.
|
||||
|
||||
<a name="usage-go-to-definition"></a>
|
||||
@@ -258,14 +266,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 --depth 1 https://github.com/dense-analysis/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 --depth 1 https://github.com/dense-analysis/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale
|
||||
```
|
||||
|
||||
#### Vim 8 on Windows
|
||||
@@ -273,7 +281,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 --depth 1 https://github.com/dense-analysis/ale.git ~/vimfiles/pack/git-plugins/start/ale
|
||||
```
|
||||
|
||||
#### Generating Vim help files
|
||||
@@ -304,7 +312,7 @@ You can run the following commands in your terminal to do so:
|
||||
|
||||
```bash
|
||||
cd ~/.vim/bundle
|
||||
git clone https://github.com/w0rp/ale.git
|
||||
git clone https://github.com/dense-analysis/ale.git
|
||||
```
|
||||
|
||||
<a name="installation-with-vundle"></a>
|
||||
@@ -315,7 +323,7 @@ You can install this plugin using [Vundle](https://github.com/VundleVim/Vundle.v
|
||||
by using the path on GitHub for this repository.
|
||||
|
||||
```vim
|
||||
Plugin 'w0rp/ale'
|
||||
Plugin 'dense-analysis/ale'
|
||||
```
|
||||
|
||||
See the Vundle documentation for more information.
|
||||
@@ -329,7 +337,7 @@ by adding the GitHub path for this repository to your `~/.vimrc`
|
||||
and running `:PlugInstall`.
|
||||
|
||||
```vim
|
||||
Plug 'w0rp/ale'
|
||||
Plug 'dense-analysis/ale'
|
||||
```
|
||||
|
||||
<a name="contributing"></a>
|
||||
@@ -337,14 +345,14 @@ Plug 'w0rp/ale'
|
||||
## 4. Contributing
|
||||
|
||||
If you would like to see support for more languages and tools, please
|
||||
[create an issue](https://github.com/w0rp/ale/issues)
|
||||
or [create a pull request](https://github.com/w0rp/ale/pulls).
|
||||
[create an issue](https://github.com/dense-analysis/ale/issues)
|
||||
or [create a pull request](https://github.com/dense-analysis/ale/pulls).
|
||||
If your tool can read from stdin or you have code to suggest which is good,
|
||||
support can be happily added for it.
|
||||
|
||||
If you are interested in the general direction of the project, check out the
|
||||
[wiki home page](https://github.com/w0rp/ale/wiki). The wiki includes a
|
||||
Roadmap for the future, and more.
|
||||
[wiki home page](https://github.com/dense-analysis/ale/wiki). The wiki includes
|
||||
a Roadmap for the future, and more.
|
||||
|
||||
If you'd liked to discuss the project more directly, check out the `#vim-ale` channel
|
||||
on Freenode. Web chat is available [here](https://webchat.freenode.net/?channels=vim-ale).
|
||||
@@ -596,6 +604,7 @@ options off.
|
||||
```vim
|
||||
" Write this in your vimrc file
|
||||
let g:ale_lint_on_text_changed = 'never'
|
||||
let g:ale_lint_on_insert_leave = 0
|
||||
" You can disable this option too
|
||||
" if you don't want linters to run on opening a file
|
||||
let g:ale_lint_on_enter = 0
|
||||
|
||||
@@ -19,14 +19,17 @@ call ale#Set('c_clangtidy_options', '')
|
||||
call ale#Set('c_clangtidy_extra_options', '')
|
||||
call ale#Set('c_build_dir', '')
|
||||
|
||||
function! ale_linters#c#clangtidy#GetCommand(buffer) abort
|
||||
function! ale_linters#c#clangtidy#GetCommand(buffer, output) abort
|
||||
let l:checks = join(ale#Var(a:buffer, 'c_clangtidy_checks'), ',')
|
||||
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
|
||||
let l:options = ''
|
||||
|
||||
" Get the extra options if we couldn't find a build directory.
|
||||
let l:options = empty(l:build_dir)
|
||||
\ ? ale#Var(a:buffer, 'c_clangtidy_options')
|
||||
\ : ''
|
||||
if empty(l:build_dir)
|
||||
let l:options = ale#Var(a:buffer, 'c_clangtidy_options')
|
||||
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
|
||||
let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags
|
||||
endif
|
||||
|
||||
" Get the options to pass directly to clang-tidy
|
||||
let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options')
|
||||
@@ -43,7 +46,7 @@ call ale#linter#Define('c', {
|
||||
\ 'name': 'clangtidy',
|
||||
\ 'output_stream': 'stdout',
|
||||
\ 'executable': {b -> ale#Var(b, 'c_clangtidy_executable')},
|
||||
\ 'command': function('ale_linters#c#clangtidy#GetCommand'),
|
||||
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clangtidy#GetCommand'))},
|
||||
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
|
||||
\ 'lint_file': 1,
|
||||
\})
|
||||
|
||||
@@ -13,14 +13,17 @@ call ale#Set('cpp_clangtidy_options', '')
|
||||
call ale#Set('cpp_clangtidy_extra_options', '')
|
||||
call ale#Set('c_build_dir', '')
|
||||
|
||||
function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
|
||||
function! ale_linters#cpp#clangtidy#GetCommand(buffer, output) abort
|
||||
let l:checks = join(ale#Var(a:buffer, 'cpp_clangtidy_checks'), ',')
|
||||
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
|
||||
let l:options = ''
|
||||
|
||||
" Get the extra options if we couldn't find a build directory.
|
||||
let l:options = empty(l:build_dir)
|
||||
\ ? ale#Var(a:buffer, 'cpp_clangtidy_options')
|
||||
\ : ''
|
||||
if empty(l:build_dir)
|
||||
let l:options = ale#Var(a:buffer, 'cpp_clangtidy_options')
|
||||
let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
|
||||
let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags
|
||||
endif
|
||||
|
||||
" Get the options to pass directly to clang-tidy
|
||||
let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options')
|
||||
@@ -37,7 +40,7 @@ call ale#linter#Define('cpp', {
|
||||
\ 'name': 'clangtidy',
|
||||
\ 'output_stream': 'stdout',
|
||||
\ 'executable': {b -> ale#Var(b, 'cpp_clangtidy_executable')},
|
||||
\ 'command': function('ale_linters#cpp#clangtidy#GetCommand'),
|
||||
\ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clangtidy#GetCommand'))},
|
||||
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
|
||||
\ 'lint_file': 1,
|
||||
\})
|
||||
|
||||
95
ale_linters/cs/csc.vim
Normal file
95
ale_linters/cs/csc.vim
Normal file
@@ -0,0 +1,95 @@
|
||||
call ale#Set('cs_csc_options', '')
|
||||
call ale#Set('cs_csc_source', '')
|
||||
call ale#Set('cs_csc_assembly_path', [])
|
||||
call ale#Set('cs_csc_assemblies', [])
|
||||
|
||||
function! s:GetWorkingDirectory(buffer) abort
|
||||
let l:working_directory = ale#Var(a:buffer, 'cs_csc_source')
|
||||
|
||||
if !empty(l:working_directory)
|
||||
return l:working_directory
|
||||
endif
|
||||
|
||||
return expand('#' . a:buffer . ':p:h')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#cs#csc#GetCommand(buffer) abort
|
||||
" Pass assembly paths via the -lib: parameter.
|
||||
let l:path_list = ale#Var(a:buffer, 'cs_csc_assembly_path')
|
||||
|
||||
let l:lib_option = !empty(l:path_list)
|
||||
\ ? '/lib:' . join(map(copy(l:path_list), 'ale#Escape(v:val)'), ',')
|
||||
\ : ''
|
||||
|
||||
" Pass paths to DLL files via the -r: parameter.
|
||||
let l:assembly_list = ale#Var(a:buffer, 'cs_csc_assemblies')
|
||||
|
||||
let l:r_option = !empty(l:assembly_list)
|
||||
\ ? '/r:' . join(map(copy(l:assembly_list), 'ale#Escape(v:val)'), ',')
|
||||
\ : ''
|
||||
|
||||
" register temporary module target file with ale
|
||||
" register temporary module target file with ALE.
|
||||
let l:out = ale#command#CreateFile(a:buffer)
|
||||
|
||||
" The code is compiled as a module and the output is redirected to a
|
||||
" temporary file.
|
||||
return ale#path#CdString(s:GetWorkingDirectory(a:buffer))
|
||||
\ . 'csc /unsafe'
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'cs_csc_options'))
|
||||
\ . ale#Pad(l:lib_option)
|
||||
\ . ale#Pad(l:r_option)
|
||||
\ . ' /out:' . l:out
|
||||
\ . ' /t:module'
|
||||
\ . ' /recurse:' . ale#Escape('*.cs')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#cs#csc#Handle(buffer, lines) abort
|
||||
" Look for lines like the following.
|
||||
"
|
||||
" Tests.cs(12,29): error CSXXXX: ; expected
|
||||
"
|
||||
" NOTE: pattern also captures file name as linter compiles all
|
||||
" files within the source tree rooted at the specified source
|
||||
" path and not just the file loaded in the buffer
|
||||
let l:patterns = [
|
||||
\ '^\v(.+\.cs)\((\d+),(\d+)\)\:\s+([^ ]+)\s+([cC][sS][^ ]+):\s(.+)$',
|
||||
\ '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$',
|
||||
\]
|
||||
let l:output = []
|
||||
|
||||
let l:dir = s:GetWorkingDirectory(a:buffer)
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:patterns)
|
||||
if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS'
|
||||
call add(l:output, {
|
||||
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
|
||||
\ 'lnum': l:match[2] + 0,
|
||||
\ 'col': l:match[3] + 0,
|
||||
\ 'type': l:match[4] is# 'error' ? 'E' : 'W',
|
||||
\ 'code': l:match[5],
|
||||
\ 'text': l:match[6] ,
|
||||
\})
|
||||
elseif strlen(l:match[2]) > 2 && l:match[2][:1] is? 'CS'
|
||||
call add(l:output, {
|
||||
\ 'filename':'<csc>',
|
||||
\ 'lnum': -1,
|
||||
\ 'col': -1,
|
||||
\ 'type': l:match[1] is# 'error' ? 'E' : 'W',
|
||||
\ 'code': l:match[2],
|
||||
\ 'text': l:match[3],
|
||||
\})
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('cs',{
|
||||
\ 'name': 'csc',
|
||||
\ 'output_stream': 'stdout',
|
||||
\ 'executable': 'csc',
|
||||
\ 'command': function('ale_linters#cs#csc#GetCommand'),
|
||||
\ 'callback': 'ale_linters#cs#csc#Handle',
|
||||
\ 'lint_file': 1
|
||||
\})
|
||||
@@ -52,12 +52,16 @@ function! ale_linters#cs#mcsc#Handle(buffer, lines) abort
|
||||
" NOTE: pattern also captures file name as linter compiles all
|
||||
" files within the source tree rooted at the specified source
|
||||
" path and not just the file loaded in the buffer
|
||||
let l:pattern = '^\v(.+\.cs)\((\d+),(\d+)\)\: ([^ ]+) ([^ ]+): (.+)$'
|
||||
let l:patterns = [
|
||||
\ '^\v(.+\.cs)\((\d+),(\d+)\)\:\s+([^ ]+)\s+([cC][sS][^ ]+):\s(.+)$',
|
||||
\ '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$',
|
||||
\]
|
||||
let l:output = []
|
||||
|
||||
let l:dir = s:GetWorkingDirectory(a:buffer)
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
for l:match in ale#util#GetMatches(a:lines, l:patterns)
|
||||
if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS'
|
||||
call add(l:output, {
|
||||
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
|
||||
\ 'lnum': l:match[2] + 0,
|
||||
@@ -66,6 +70,16 @@ function! ale_linters#cs#mcsc#Handle(buffer, lines) abort
|
||||
\ 'code': l:match[5],
|
||||
\ 'text': l:match[6] ,
|
||||
\})
|
||||
elseif strlen(l:match[2]) > 2 && l:match[2][:1] is? 'CS'
|
||||
call add(l:output, {
|
||||
\ 'filename':'<mcs>',
|
||||
\ 'lnum': -1,
|
||||
\ 'col': -1,
|
||||
\ 'type': l:match[1] is# 'error' ? 'E' : 'W',
|
||||
\ 'code': l:match[2],
|
||||
\ 'text': l:match[3],
|
||||
\})
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
|
||||
40
ale_linters/elm/elm_ls.vim
Normal file
40
ale_linters/elm/elm_ls.vim
Normal file
@@ -0,0 +1,40 @@
|
||||
" Author: antew - https://github.com/antew
|
||||
" Description: elm-language-server integration for elm (diagnostics, formatting, and more)
|
||||
|
||||
call ale#Set('elm_ls_executable', 'elm-language-server')
|
||||
call ale#Set('elm_ls_use_global', get(g:, 'ale_use_global_executables', 1))
|
||||
|
||||
" elm-language-server will search for local and global binaries, if empty
|
||||
call ale#Set('elm_ls_elm_path', '')
|
||||
call ale#Set('elm_ls_elm_format_path', '')
|
||||
call ale#Set('elm_ls_elm_test_path', '')
|
||||
call ale#Set('elm_ls_elm_analyse_trigger', 'change')
|
||||
|
||||
function! elm_ls#GetRootDir(buffer) abort
|
||||
let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
|
||||
|
||||
return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : ''
|
||||
endfunction
|
||||
|
||||
function! elm_ls#GetOptions(buffer) abort
|
||||
return {
|
||||
\ 'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'),
|
||||
\ 'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'),
|
||||
\ 'elmTestPath': ale#Var(a:buffer, 'elm_ls_elm_test_path'),
|
||||
\ 'elmAnalyseTrigger': ale#Var(a:buffer, 'elm_ls_elm_analyse_trigger'),
|
||||
\}
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('elm', {
|
||||
\ 'name': 'elm_ls',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {b -> ale#node#FindExecutable(b, 'elm_ls', [
|
||||
\ 'node_modules/.bin/elm-language-server',
|
||||
\ 'node_modules/.bin/elm-lsp',
|
||||
\ 'elm-lsp'
|
||||
\ ])},
|
||||
\ 'command': '%e --stdio',
|
||||
\ 'project_root': function('elm_ls#GetRootDir'),
|
||||
\ 'language': 'elm',
|
||||
\ 'initialization_options': function('elm_ls#GetOptions')
|
||||
\})
|
||||
@@ -1,22 +0,0 @@
|
||||
" Author: antew - https://github.com/antew
|
||||
" Description: LSP integration for elm, currently supports diagnostics (linting)
|
||||
|
||||
call ale#Set('elm_lsp_executable', 'elm-lsp')
|
||||
call ale#Set('elm_lsp_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! elm_lsp#GetRootDir(buffer) abort
|
||||
let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
|
||||
|
||||
return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : ''
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('elm', {
|
||||
\ 'name': 'elm_lsp',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {b -> ale#node#FindExecutable(b, 'elm_lsp', [
|
||||
\ 'node_modules/.bin/elm-lsp',
|
||||
\ ])},
|
||||
\ 'command': '%e --stdio',
|
||||
\ 'project_root': function('elm_lsp#GetRootDir'),
|
||||
\ 'language': 'elm'
|
||||
\})
|
||||
@@ -15,10 +15,10 @@ endfunction
|
||||
function! ale_linters#erlang#dialyzer#FindPlt(buffer) abort
|
||||
let l:plt_file = ''
|
||||
let l:rebar3_profile = ale_linters#erlang#dialyzer#GetRebar3Profile(a:buffer)
|
||||
let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build' . l:rebar3_profile)
|
||||
let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build/' . l:rebar3_profile)
|
||||
|
||||
if !empty(l:plt_file_directory)
|
||||
let l:plt_file = split(globpath(l:plt_file_directory, '/*_plt'), '\n')
|
||||
let l:plt_file = globpath(l:plt_file_directory, '*_plt', 0, 1)
|
||||
endif
|
||||
|
||||
if !empty(l:plt_file)
|
||||
|
||||
@@ -8,7 +8,7 @@ call ale#Set('eruby_ruumba_options', '')
|
||||
function! ale_linters#eruby#ruumba#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'eruby_ruumba_executable')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'ruumba')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'ruumba')
|
||||
\ . ' --format json --force-exclusion '
|
||||
\ . ale#Var(a:buffer, 'eruby_ruumba_options')
|
||||
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))
|
||||
|
||||
@@ -5,11 +5,13 @@ call ale#Set('go_bingo_executable', 'bingo')
|
||||
call ale#Set('go_bingo_options', '--mode stdio')
|
||||
|
||||
function! ale_linters#go#bingo#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'go_bingo_options'))
|
||||
return ale#go#EnvString(a:buffer) . '%e' . ale#Pad(ale#Var(a:buffer, 'go_bingo_options'))
|
||||
endfunction
|
||||
|
||||
function! ale_linters#go#bingo#FindProjectRoot(buffer) abort
|
||||
let l:project_root = ale#path#FindNearestFile(a:buffer, 'go.mod')
|
||||
let l:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off'
|
||||
let l:project_root = l:go_modules_off ?
|
||||
\ '' : ale#path#FindNearestFile(a:buffer, 'go.mod')
|
||||
let l:mods = ':h'
|
||||
|
||||
if empty(l:project_root)
|
||||
|
||||
@@ -11,6 +11,7 @@ function! ale_linters#go#gobuild#GetCommand(buffer) abort
|
||||
|
||||
" Run go test in local directory with relative path
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . ale#go#EnvString(a:buffer)
|
||||
\ . ale#Var(a:buffer, 'go_go_executable') . ' test'
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' -c -o /dev/null ./'
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
" Author: neersighted <bjorn@neersighted.com>
|
||||
" Description: gofmt for Go files
|
||||
|
||||
function! ale_linters#go#gofmt#GetCommand(buffer) abort
|
||||
return ale#go#EnvString(a:buffer)
|
||||
\ . '%e -e %t'
|
||||
endfunction
|
||||
|
||||
|
||||
call ale#linter#Define('go', {
|
||||
\ 'name': 'gofmt',
|
||||
\ 'output_stream': 'stderr',
|
||||
\ 'executable': 'gofmt',
|
||||
\ 'command': 'gofmt -e %t',
|
||||
\ 'command': function('ale_linters#go#gofmt#GetCommand'),
|
||||
\ 'callback': 'ale#handlers#unix#HandleAsError',
|
||||
\})
|
||||
|
||||
@@ -10,13 +10,16 @@ function! ale_linters#go#golangci_lint#GetCommand(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'go_golangci_lint_options')
|
||||
let l:lint_package = ale#Var(a:buffer, 'go_golangci_lint_package')
|
||||
|
||||
|
||||
if l:lint_package
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . ale#go#EnvString(a:buffer)
|
||||
\ . '%e run '
|
||||
\ . l:options
|
||||
endif
|
||||
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . ale#go#EnvString(a:buffer)
|
||||
\ . '%e run '
|
||||
\ . ale#Escape(l:filename)
|
||||
\ . ' ' . l:options
|
||||
|
||||
@@ -7,7 +7,7 @@ call ale#Set('go_golint_options', '')
|
||||
function! ale_linters#go#golint#GetCommand(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'go_golint_options')
|
||||
|
||||
return '%e'
|
||||
return ale#go#EnvString(a:buffer) . '%e'
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' %t'
|
||||
endfunction
|
||||
|
||||
@@ -14,11 +14,13 @@ function! ale_linters#go#gometalinter#GetCommand(buffer) abort
|
||||
" be calculated to absolute paths in the Handler
|
||||
if l:lint_package
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . ale#go#EnvString(a:buffer)
|
||||
\ . '%e'
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
|
||||
endif
|
||||
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . ale#go#EnvString(a:buffer)
|
||||
\ . '%e'
|
||||
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename))
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
|
||||
|
||||
@@ -6,11 +6,15 @@ 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'))
|
||||
return ale#go#EnvString(a:buffer)
|
||||
\ . '%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:go_modules_off = ale#Var(a:buffer, 'go_go111module') is# 'off'
|
||||
let l:project_root = l:go_modules_off ?
|
||||
\ '' : ale#path#FindNearestFile(a:buffer, 'go.mod')
|
||||
let l:mods = ':h'
|
||||
|
||||
if empty(l:project_root)
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
" Description: gosimple for Go files
|
||||
|
||||
function! ale_linters#go#gosimple#GetCommand(buffer) abort
|
||||
return ale#path#BufferCdString(a:buffer) . ' gosimple .'
|
||||
return ale#path#BufferCdString(a:buffer) . ' '
|
||||
\ . ale#go#EnvString(a:buffer) . 'gosimple .'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('go', {
|
||||
|
||||
@@ -6,7 +6,8 @@ function! ale_linters#go#gotype#GetCommand(buffer) abort
|
||||
return ''
|
||||
endif
|
||||
|
||||
return ale#path#BufferCdString(a:buffer) . ' gotype -e .'
|
||||
return ale#path#BufferCdString(a:buffer) . ' '
|
||||
\ . ale#go#EnvString(a:buffer) . 'gotype -e .'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('go', {
|
||||
|
||||
@@ -11,6 +11,7 @@ function! ale_linters#go#govet#GetCommand(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'go_govet_options')
|
||||
|
||||
return ale#path#BufferCdString(a:buffer) . ' '
|
||||
\ . ale#go#EnvString(a:buffer)
|
||||
\ . ale#Var(a:buffer, 'go_go_executable') . ' vet '
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' .'
|
||||
|
||||
@@ -15,8 +15,9 @@ function! ale_linters#go#langserver#GetCommand(buffer) abort
|
||||
endif
|
||||
|
||||
let l:options = uniq(sort(l:options))
|
||||
let l:env = ale#go#EnvString(a:buffer)
|
||||
|
||||
return join(extend(l:executable, l:options), ' ')
|
||||
return l:env . join(extend(l:executable, l:options), ' ')
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('go', {
|
||||
|
||||
@@ -8,17 +8,18 @@ function! ale_linters#go#staticcheck#GetCommand(buffer) abort
|
||||
let l:filename = expand('#' . a:buffer . ':t')
|
||||
let l:options = ale#Var(a:buffer, 'go_staticcheck_options')
|
||||
let l:lint_package = ale#Var(a:buffer, 'go_staticcheck_lint_package')
|
||||
let l:env = ale#go#EnvString(a:buffer)
|
||||
|
||||
" BufferCdString is used so that we can be sure the paths output from
|
||||
" staticcheck can be calculated to absolute paths in the Handler
|
||||
if l:lint_package
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . 'staticcheck'
|
||||
\ . l:env . 'staticcheck'
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
|
||||
endif
|
||||
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . 'staticcheck'
|
||||
\ . l:env . 'staticcheck'
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' ' . ale#Escape(l:filename)
|
||||
endfunction
|
||||
|
||||
35
ale_linters/ink/ls.vim
Normal file
35
ale_linters/ink/ls.vim
Normal file
@@ -0,0 +1,35 @@
|
||||
" Author: Andreww Hayworth <ahayworth@gmail.com>
|
||||
" Description: Integrate ALE with ink-language-server
|
||||
|
||||
call ale#Set('ink_ls_executable', 'ink-language-server')
|
||||
call ale#Set('ink_ls_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('ink_ls_initialization_options', {})
|
||||
|
||||
function! ale_linters#ink#ls#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'ink_ls', [
|
||||
\ 'ink-language-server',
|
||||
\ 'node_modules/.bin/ink-language-server',
|
||||
\])
|
||||
endfunction
|
||||
|
||||
function! ale_linters#ink#ls#GetCommand(buffer) abort
|
||||
let l:executable = ale_linters#ink#ls#GetExecutable(a:buffer)
|
||||
|
||||
return ale#Escape(l:executable) . ' --stdio'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#ink#ls#FindProjectRoot(buffer) abort
|
||||
let l:main_file = get(ale#Var(a:buffer, 'ink_ls_initialization_options'), 'mainStoryPath', 'main.ink')
|
||||
let l:config = ale#path#ResolveLocalPath(a:buffer, l:main_file, expand('#' . a:buffer . ':p'))
|
||||
|
||||
return ale#path#Dirname(l:config)
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('ink', {
|
||||
\ 'name': 'ink-language-server',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': function('ale_linters#ink#ls#GetExecutable'),
|
||||
\ 'command': function('ale_linters#ink#ls#GetCommand'),
|
||||
\ 'project_root': function('ale_linters#ink#ls#FindProjectRoot'),
|
||||
\ 'initialization_options': {b -> ale#Var(b, 'ink_ls_initialization_options')},
|
||||
\})
|
||||
@@ -2,7 +2,7 @@
|
||||
" 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_config', '/google_checks.xml')
|
||||
call ale#Set('java_checkstyle_options', '')
|
||||
|
||||
function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
|
||||
@@ -39,11 +39,21 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
function! s:GetConfig(buffer, config) abort
|
||||
if ale#path#IsAbsolute(a:config)
|
||||
return a:config
|
||||
endif
|
||||
|
||||
let s:file = ale#path#FindNearestFile(a:buffer, a:config)
|
||||
|
||||
return !empty(s:file) ? s:file : a:config
|
||||
endfunction
|
||||
|
||||
function! ale_linters#java#checkstyle#GetCommand(buffer) abort
|
||||
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)
|
||||
\ ? s:GetConfig(a:buffer, l:config_option)
|
||||
\ : ''
|
||||
|
||||
return '%e'
|
||||
|
||||
@@ -2,11 +2,24 @@
|
||||
" Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac
|
||||
|
||||
call ale#Set('java_javalsp_executable', '')
|
||||
call ale#Set('java_javalsp_config', {})
|
||||
|
||||
function! ale_linters#java#javalsp#Executable(buffer) abort
|
||||
return ale#Var(a:buffer, 'java_javalsp_executable')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#java#javalsp#Config(buffer) abort
|
||||
let l:defaults = { 'java': { 'classPath': [], 'externalDependencies': [] } }
|
||||
let l:config = ale#Var(a:buffer, 'java_javalsp_config')
|
||||
|
||||
" Ensure the config dictionary contains both classPath and
|
||||
" externalDependencies keys to avoid a NPE crash on Java Language Server.
|
||||
call extend(l:config, l:defaults, 'keep')
|
||||
call extend(l:config['java'], l:defaults['java'], 'keep')
|
||||
|
||||
return l:config
|
||||
endfunction
|
||||
|
||||
function! ale_linters#java#javalsp#Command(buffer) abort
|
||||
let l:executable = ale_linters#java#javalsp#Executable(a:buffer)
|
||||
|
||||
@@ -38,4 +51,5 @@ call ale#linter#Define('java', {
|
||||
\ 'command': function('ale_linters#java#javalsp#Command'),
|
||||
\ 'language': 'java',
|
||||
\ 'project_root': function('ale#java#FindProjectRoot'),
|
||||
\ 'lsp_config': function('ale_linters#java#javalsp#Config')
|
||||
\})
|
||||
|
||||
0
ale_linters/javascript/flow.vim
Executable file → Normal file
0
ale_linters/javascript/flow.vim
Executable file → Normal file
@@ -8,6 +8,7 @@ call ale#Set('javascript_standard_options', '')
|
||||
function! ale_linters#javascript#standard#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'javascript_standard', [
|
||||
\ 'node_modules/standard/bin/cmd.js',
|
||||
\ 'node_modules/semistandard/bin/cmd.js',
|
||||
\ 'node_modules/.bin/standard',
|
||||
\])
|
||||
endfunction
|
||||
|
||||
0
ale_linters/less/lessc.vim
Executable file → Normal file
0
ale_linters/less/lessc.vim
Executable file → Normal file
@@ -17,18 +17,17 @@ function! ale_linters#markdown#mdl#GetCommand(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'markdown_mdl_options')
|
||||
|
||||
return ale#Escape(l:executable) . l:exec_args
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' -j' . (!empty(l:options) ? ' ' . l:options : '')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#markdown#mdl#Handle(buffer, lines) abort
|
||||
" matches: '(stdin):173: MD004 Unordered list style'
|
||||
let l:pattern = ':\(\d*\): \(.*\)$'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'text': l:match[2],
|
||||
\ 'lnum': l:error['line'],
|
||||
\ 'code': l:error['rule'] . '/' . join(l:error['aliases'], '/'),
|
||||
\ 'text': l:error['description'],
|
||||
\ 'type': 'W',
|
||||
\})
|
||||
endfor
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
" Author: Matt Brown <https://github.com/muglug>
|
||||
" Description: plugin for Psalm, static analyzer for PHP
|
||||
|
||||
call ale#Set('psalm_langserver_executable', 'psalm-language-server')
|
||||
call ale#Set('psalm_langserver_executable', 'psalm')
|
||||
call ale#Set('psalm_langserver_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! ale_linters#php#psalm#GetProjectRoot(buffer) abort
|
||||
@@ -14,8 +14,8 @@ call ale#linter#Define('php', {
|
||||
\ 'name': 'psalm',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {b -> ale#node#FindExecutable(b, 'psalm_langserver', [
|
||||
\ 'vendor/bin/psalm-language-server',
|
||||
\ 'vendor/bin/psalm',
|
||||
\ ])},
|
||||
\ 'command': '%e',
|
||||
\ 'command': '%e --language-server',
|
||||
\ 'project_root': function('ale_linters#php#psalm#GetProjectRoot'),
|
||||
\})
|
||||
|
||||
12
ale_linters/powershell/powershell.vim
Executable file → Normal file
12
ale_linters/powershell/powershell.vim
Executable file → Normal file
@@ -49,11 +49,19 @@ function! ale_linters#powershell#powershell#Handle(buffer, lines) abort
|
||||
let l:matchcount = 1
|
||||
endif
|
||||
|
||||
" If the match is 0, it was a failed match
|
||||
" probably due to an unexpected token which
|
||||
" contained a newline. Reset matchcount. to
|
||||
" continue to the next match
|
||||
if !empty(l:match[1])
|
||||
let l:item = {
|
||||
\ 'lnum': str2nr(l:match[1]),
|
||||
\ 'col': str2nr(l:match[2]),
|
||||
\ 'type': 'E',
|
||||
\}
|
||||
else
|
||||
let l:matchcount = 0
|
||||
endif
|
||||
elseif l:matchcount == 2
|
||||
" Second match[0] grabs the full line in order
|
||||
" to handles the text
|
||||
@@ -84,8 +92,8 @@ endfunction
|
||||
|
||||
call ale#linter#Define('powershell', {
|
||||
\ 'name': 'powershell',
|
||||
\ 'executable_callback': 'ale_linters#powershell#powershell#GetExecutable',
|
||||
\ 'command_callback': 'ale_linters#powershell#powershell#GetCommand',
|
||||
\ 'executable': function('ale_linters#powershell#powershell#GetExecutable'),
|
||||
\ 'command': function('ale_linters#powershell#powershell#GetCommand'),
|
||||
\ 'output_stream': 'stdout',
|
||||
\ 'callback': 'ale_linters#powershell#powershell#Handle',
|
||||
\})
|
||||
|
||||
49
ale_linters/purescript/ls.vim
Normal file
49
ale_linters/purescript/ls.vim
Normal file
@@ -0,0 +1,49 @@
|
||||
" Author: Drew Olson <drew@drewolson.org>
|
||||
" Description: Integrate ALE with purescript-language-server.
|
||||
|
||||
call ale#Set('purescript_ls_executable', 'purescript-language-server')
|
||||
call ale#Set('purescript_ls_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('purescript_ls_config', {})
|
||||
|
||||
function! ale_linters#purescript#ls#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'purescript_ls', [
|
||||
\ 'node_modules/.bin/purescript-language-server',
|
||||
\])
|
||||
endfunction
|
||||
|
||||
function! ale_linters#purescript#ls#GetCommand(buffer) abort
|
||||
let l:executable = ale_linters#purescript#ls#GetExecutable(a:buffer)
|
||||
|
||||
return ale#Escape(l:executable) . ' --stdio'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#purescript#ls#FindProjectRoot(buffer) abort
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, 'bower.json')
|
||||
|
||||
if !empty(l:config)
|
||||
return fnamemodify(l:config, ':h')
|
||||
endif
|
||||
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, 'psc-package.json')
|
||||
|
||||
if !empty(l:config)
|
||||
return fnamemodify(l:config, ':h')
|
||||
endif
|
||||
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, 'spago.dhall')
|
||||
|
||||
if !empty(l:config)
|
||||
return fnamemodify(l:config, ':h')
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('purescript', {
|
||||
\ 'name': 'purescript-language-server',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': function('ale_linters#purescript#ls#GetExecutable'),
|
||||
\ 'command': function('ale_linters#purescript#ls#GetCommand'),
|
||||
\ 'project_root': function('ale_linters#purescript#ls#FindProjectRoot'),
|
||||
\ 'lsp_config': {b -> ale#Var(b, 'purescript_ls_config')},
|
||||
\})
|
||||
@@ -78,4 +78,5 @@ call ale#linter#Define('python', {
|
||||
\ 'executable': function('ale_linters#python#mypy#GetExecutable'),
|
||||
\ 'command': function('ale_linters#python#mypy#GetCommand'),
|
||||
\ 'callback': 'ale_linters#python#mypy#Handle',
|
||||
\ 'output_stream': 'both'
|
||||
\})
|
||||
|
||||
@@ -36,7 +36,7 @@ function! ale_linters#ruby#brakeman#GetCommand(buffer) abort
|
||||
|
||||
let l:executable = ale#Var(a:buffer, 'ruby_brakeman_executable')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'brakeman')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'brakeman')
|
||||
\ . ' -f json -q '
|
||||
\ . ale#Var(a:buffer, 'ruby_brakeman_options')
|
||||
\ . ' -p ' . ale#Escape(l:rails_root)
|
||||
|
||||
42
ale_linters/ruby/debride.vim
Normal file
42
ale_linters/ruby/debride.vim
Normal file
@@ -0,0 +1,42 @@
|
||||
" Author: Eddie Lebow https://github.com/elebow
|
||||
" Description: debride, a dead method detector for Ruby files
|
||||
|
||||
call ale#Set('ruby_debride_executable', 'debride')
|
||||
call ale#Set('ruby_debride_options', '')
|
||||
|
||||
function! ale_linters#ruby#debride#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ruby_debride_executable')
|
||||
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'debride')
|
||||
\ . ale#Var(a:buffer, 'ruby_debride_options')
|
||||
\ . ' %s'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#ruby#debride#HandleOutput(buffer, lines) abort
|
||||
let l:output = []
|
||||
|
||||
for l:line in a:lines
|
||||
if l:line !~# '^ '
|
||||
continue
|
||||
endif
|
||||
|
||||
let l:elements = split(l:line)
|
||||
let l:method_name = l:elements[0]
|
||||
let l:lnum = split(l:elements[1], ':')[1]
|
||||
|
||||
call add(l:output, {
|
||||
\ 'lnum': 0 + l:lnum,
|
||||
\ 'text': 'Possible unused method: ' . l:method_name,
|
||||
\ 'type': 'W',
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('ruby', {
|
||||
\ 'name': 'debride',
|
||||
\ 'executable': {b -> ale#Var(b, 'ruby_debride_executable')},
|
||||
\ 'command': function('ale_linters#ruby#debride#GetCommand'),
|
||||
\ 'callback': 'ale_linters#ruby#debride#HandleOutput',
|
||||
\})
|
||||
@@ -33,7 +33,7 @@ function! ale_linters#ruby#rails_best_practices#GetCommand(buffer) abort
|
||||
let l:output_file = has('win32') ? '%t ' : '/dev/stdout '
|
||||
let l:cat_file = has('win32') ? '; type %t' : ''
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rails_best_practices')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'rails_best_practices')
|
||||
\ . ' --silent -f json --output-file ' . l:output_file
|
||||
\ . ale#Var(a:buffer, 'ruby_rails_best_practices_options')
|
||||
\ . ale#Escape(l:rails_root)
|
||||
|
||||
@@ -14,7 +14,7 @@ function! ale_linters#ruby#reek#GetCommand(buffer, version) abort
|
||||
\ ? ' --stdin-filename %s'
|
||||
\ : ''
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'reek')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'reek')
|
||||
\ . ' -f json --no-progress --no-color --force-exclusion'
|
||||
\ . l:display_name_args
|
||||
endfunction
|
||||
|
||||
@@ -7,7 +7,7 @@ call ale#Set('ruby_rubocop_options', '')
|
||||
function! ale_linters#ruby#rubocop#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ruby_rubocop_executable')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'rubocop')
|
||||
\ . ' --format json --force-exclusion '
|
||||
\ . ale#Var(a:buffer, 'ruby_rubocop_options')
|
||||
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))
|
||||
|
||||
23
ale_linters/ruby/sorbet.vim
Normal file
23
ale_linters/ruby/sorbet.vim
Normal file
@@ -0,0 +1,23 @@
|
||||
call ale#Set('ruby_sorbet_executable', 'srb')
|
||||
call ale#Set('ruby_sorbet_options', '')
|
||||
|
||||
function! ale_linters#ruby#sorbet#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable')
|
||||
let l:options = ale#Var(a:buffer, 'ruby_sorbet_options')
|
||||
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'srb')
|
||||
\ . ' tc'
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --lsp --disable-watchman'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('ruby', {
|
||||
\ 'name': 'sorbet',
|
||||
\ 'aliases': ['srb'],
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'language': 'ruby',
|
||||
\ 'executable': {b -> ale#Var(b, 'ruby_sorbet_executable')},
|
||||
\ 'command': function('ale_linters#ruby#sorbet#GetCommand'),
|
||||
\ 'project_root': function('ale#ruby#FindProjectRoot')
|
||||
\})
|
||||
|
||||
@@ -8,7 +8,7 @@ call ale#Set('ruby_standardrb_options', '')
|
||||
function! ale_linters#ruby#standardrb#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ruby_standardrb_executable')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'standardrb')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'standardrb')
|
||||
\ . ' --format json --force-exclusion '
|
||||
\ . ale#Var(a:buffer, 'ruby_standardrb_options')
|
||||
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))
|
||||
|
||||
@@ -25,14 +25,11 @@ endfunction
|
||||
function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
|
||||
let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check')
|
||||
\ && ale#semver#GTE(a:version, [0, 17, 0])
|
||||
let l:use_all_targets = l:use_check
|
||||
\ && ale#Var(a:buffer, 'rust_cargo_check_all_targets')
|
||||
let l:use_all_targets = ale#Var(a:buffer, 'rust_cargo_check_all_targets')
|
||||
\ && ale#semver#GTE(a:version, [0, 22, 0])
|
||||
let l:use_examples = l:use_check
|
||||
\ && ale#Var(a:buffer, 'rust_cargo_check_examples')
|
||||
let l:use_examples = ale#Var(a:buffer, 'rust_cargo_check_examples')
|
||||
\ && ale#semver#GTE(a:version, [0, 22, 0])
|
||||
let l:use_tests = l:use_check
|
||||
\ && ale#Var(a:buffer, 'rust_cargo_check_tests')
|
||||
let l:use_tests = ale#Var(a:buffer, 'rust_cargo_check_tests')
|
||||
\ && ale#semver#GTE(a:version, [0, 22, 0])
|
||||
|
||||
let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features')
|
||||
@@ -69,7 +66,15 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
|
||||
|
||||
if ale#Var(a:buffer, 'rust_cargo_use_clippy')
|
||||
let l:subcommand = 'clippy'
|
||||
let l:clippy_options = ' ' . ale#Var(a:buffer, 'rust_cargo_clippy_options')
|
||||
let l:clippy_options = ale#Var(a:buffer, 'rust_cargo_clippy_options')
|
||||
|
||||
if l:clippy_options =~# '^-- '
|
||||
let l:clippy_options = join(split(l:clippy_options, '-- '))
|
||||
endif
|
||||
|
||||
if l:clippy_options isnot# ''
|
||||
let l:clippy_options = ' -- ' . l:clippy_options
|
||||
endif
|
||||
endif
|
||||
|
||||
return l:nearest_cargo_prefix . 'cargo '
|
||||
|
||||
48
ale_linters/scala/metals.vim
Normal file
48
ale_linters/scala/metals.vim
Normal file
@@ -0,0 +1,48 @@
|
||||
" Author: Jeffrey Lau - https://github.com/zoonfafer
|
||||
" Description: Metals Language Server for Scala https://scalameta.org/metals/
|
||||
|
||||
call ale#Set('scala_metals_executable', 'metals-vim')
|
||||
call ale#Set('scala_metals_project_root', '')
|
||||
|
||||
function! ale_linters#scala#metals#GetProjectRoot(buffer) abort
|
||||
let l:project_root = ale#Var(a:buffer, 'scala_metals_project_root')
|
||||
|
||||
if !empty(l:project_root)
|
||||
return l:project_root
|
||||
endif
|
||||
|
||||
let l:potential_roots = [
|
||||
\ 'build.sc',
|
||||
\ 'build.sbt',
|
||||
\ '.bloop',
|
||||
\ '.metals',
|
||||
\]
|
||||
|
||||
for l:root in l:potential_roots
|
||||
let l:project_root = ale#path#ResolveLocalPath(
|
||||
\ a:buffer,
|
||||
\ l:root,
|
||||
\ ''
|
||||
\)
|
||||
|
||||
if !empty(l:project_root)
|
||||
return fnamemodify(
|
||||
\ l:project_root,
|
||||
\ ':h',
|
||||
\)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale_linters#scala#metals#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad('stdio')
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('scala', {
|
||||
\ 'name': 'metals',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'language': 'scala',
|
||||
\ 'executable': {b -> ale#Var(b, 'scala_metals_executable')},
|
||||
\ 'command': function('ale_linters#scala#metals#GetCommand'),
|
||||
\ 'project_root': function('ale_linters#scala#metals#GetProjectRoot'),
|
||||
\})
|
||||
@@ -34,8 +34,10 @@ function! ale_linters#sh#shell#Handle(buffer, lines) abort
|
||||
" Matches patterns line the following:
|
||||
"
|
||||
" bash: line 13: syntax error near unexpected token `d'
|
||||
" bash:行0: 未预期的符号“done”附近有语法错误
|
||||
" bash: 列 90: 尋找匹配的「"」時遇到了未預期的檔案結束符
|
||||
" sh: 11: Syntax error: "(" unexpected
|
||||
let l:pattern = '\v(line |: ?)(\d+): (.+)$'
|
||||
let l:pattern = '\v([^:]+:\D*)(\d+): (.+)$'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
|
||||
35
ale_linters/solidity/solc.vim
Normal file
35
ale_linters/solidity/solc.vim
Normal file
@@ -0,0 +1,35 @@
|
||||
" Author: Karl Bartel <karl42@gmail.com> - http://karl.berlin/
|
||||
" Description: Report solc compiler errors in Solidity code
|
||||
|
||||
call ale#Set('solidity_solc_options', '')
|
||||
|
||||
function! ale_linters#solidity#solc#Handle(buffer, lines) abort
|
||||
" Matches patterns like the following:
|
||||
" /path/to/file/file.sol:1:10: Error: Identifier not found or not unique.
|
||||
let l:pattern = '\v^[^:]+:(\d+):(\d+): (Error|Warning): (.*)$'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
let l:isError = l:match[3] is? 'error'
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'col': l:match[2] + 0,
|
||||
\ 'text': l:match[4],
|
||||
\ 'type': l:isError ? 'E' : 'W',
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
function! ale_linters#solidity#solc#GetCommand(buffer) abort
|
||||
return 'solc' . ale#Pad(ale#Var(a:buffer, 'solidity_solc_options')) . ' %s'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('solidity', {
|
||||
\ 'name': 'solc',
|
||||
\ 'executable': 'solc',
|
||||
\ 'command': function('ale_linters#solidity#solc#GetCommand'),
|
||||
\ 'callback': 'ale_linters#solidity#solc#Handle',
|
||||
\ 'output_stream': 'stderr',
|
||||
\})
|
||||
0
ale_linters/terraform/terraform.vim
Executable file → Normal file
0
ale_linters/terraform/terraform.vim
Executable file → Normal file
@@ -9,8 +9,13 @@ call ale#Set('terraform_tflint_executable', 'tflint')
|
||||
|
||||
function! ale_linters#terraform#tflint#Handle(buffer, lines) abort
|
||||
let l:output = []
|
||||
let l:pattern = '\v^(.*):(\d+),(\d+)-(\d+)?,?(\d+): (.{-1,}); (.+)$'
|
||||
let l:json = ale#util#FuzzyJSONDecode(a:lines, {})
|
||||
|
||||
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
|
||||
" This is a rough test for tflint's output format
|
||||
" On versions prior to 0.11 it outputs all errors as a single level list
|
||||
if type(l:json) is v:t_list
|
||||
for l:error in l:json
|
||||
if l:error.type is# 'ERROR'
|
||||
let l:type = 'E'
|
||||
elseif l:error.type is# 'NOTICE'
|
||||
@@ -26,6 +31,47 @@ function! ale_linters#terraform#tflint#Handle(buffer, lines) abort
|
||||
\ 'code': l:error.detector,
|
||||
\})
|
||||
endfor
|
||||
else
|
||||
for l:error in get(l:json, 'errors', [])
|
||||
for l:match in ale#util#GetMatches(l:error.message, [l:pattern])
|
||||
if l:match[4] is# ''
|
||||
let l:match[4] = l:match[2]
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'filename': l:match[1],
|
||||
\ 'lnum': str2nr(l:match[2]),
|
||||
\ 'col': str2nr(l:match[3]),
|
||||
\ 'end_lnum': str2nr(l:match[4]),
|
||||
\ 'end_col': str2nr(l:match[5]),
|
||||
\ 'text': l:match[7],
|
||||
\ 'code': l:match[6],
|
||||
\ 'type': 'E',
|
||||
\})
|
||||
endfor
|
||||
endfor
|
||||
|
||||
for l:error in get(l:json, 'issues', [])
|
||||
if l:error.rule.severity is# 'ERROR'
|
||||
let l:type = 'E'
|
||||
elseif l:error.rule.severity is# 'NOTICE'
|
||||
let l:type = 'I'
|
||||
else
|
||||
let l:type = 'W'
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'filename': l:error.range.filename,
|
||||
\ 'lnum': l:error.range.start.line,
|
||||
\ 'col': l:error.range.start.column,
|
||||
\ 'end_lnum': l:error.range.end.line,
|
||||
\ 'end_col': l:error.range.end.column,
|
||||
\ 'text': l:error.message,
|
||||
\ 'code': l:error.rule.name,
|
||||
\ 'type': l:type,
|
||||
\})
|
||||
endfor
|
||||
endif
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
@@ -24,6 +24,20 @@ function! ale_linters#verilog#vlog#Handle(buffer, lines) abort
|
||||
\})
|
||||
endfor
|
||||
|
||||
"Matches patterns like the following:
|
||||
"** Warning: (vlog-2623) add.v(7): Undefined variable: C.
|
||||
"** Error: (vlog-13294) file.v(1): Identifier must be declared with a port mode: C.
|
||||
" let l:pattern = '^**\s\(\w*\):[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)'
|
||||
let l:pattern = '^**\s\(\w*\):\s\([^)]*)\)[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)'
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[3] + 0,
|
||||
\ 'type': l:match[1] is? 'Error' ? 'E' : 'W',
|
||||
\ 'text': l:match[2] . ' ' . l:match[4],
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
|
||||
@@ -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, 6, 0]
|
||||
|
||||
" A function used to check for ALE features in files outside of the project.
|
||||
function! ale#Has(feature) abort
|
||||
|
||||
@@ -28,76 +28,107 @@ function! ale#c#GetBuildDirectory(buffer) abort
|
||||
return ale#path#Dirname(l:json_file)
|
||||
endfunction
|
||||
|
||||
function! ale#c#AreSpecialCharsBalanced(option) abort
|
||||
" Escape \"
|
||||
let l:option_escaped = substitute(a:option, '\\"', '', 'g')
|
||||
|
||||
" Retain special chars only
|
||||
let l:special_chars = substitute(l:option_escaped, '[^"''()`]', '', 'g')
|
||||
let l:special_chars = split(l:special_chars, '\zs')
|
||||
|
||||
" Check if they are balanced
|
||||
function! ale#c#ShellSplit(line) abort
|
||||
let l:stack = []
|
||||
let l:args = ['']
|
||||
let l:prev = ''
|
||||
|
||||
for l:char in l:special_chars
|
||||
if l:char is# ')'
|
||||
if len(l:stack) == 0 || get(l:stack, -1) isnot# '('
|
||||
return 0
|
||||
endif
|
||||
|
||||
for l:char in split(a:line, '\zs')
|
||||
if l:char is# ''''
|
||||
if len(l:stack) > 0 && get(l:stack, -1) is# ''''
|
||||
call remove(l:stack, -1)
|
||||
elseif l:char is# '('
|
||||
elseif (len(l:stack) == 0 || get(l:stack, -1) isnot# '"') && l:prev isnot# '\'
|
||||
call add(l:stack, l:char)
|
||||
else
|
||||
endif
|
||||
elseif (l:char is# '"' || l:char is# '`') && l:prev isnot# '\'
|
||||
if len(l:stack) > 0 && get(l:stack, -1) is# l:char
|
||||
call remove(l:stack, -1)
|
||||
else
|
||||
elseif len(l:stack) == 0 || get(l:stack, -1) isnot# ''''
|
||||
call add(l:stack, l:char)
|
||||
endif
|
||||
elseif (l:char is# '(' || l:char is# '[' || l:char is# '{') && l:prev isnot# '\'
|
||||
if len(l:stack) == 0 || get(l:stack, -1) isnot# ''''
|
||||
call add(l:stack, l:char)
|
||||
endif
|
||||
elseif (l:char is# ')' || l:char is# ']' || l:char is# '}') && l:prev isnot# '\'
|
||||
if len(l:stack) > 0 && get(l:stack, -1) is# {')': '(', ']': '[', '}': '{'}[l:char]
|
||||
call remove(l:stack, -1)
|
||||
endif
|
||||
elseif l:char is# ' ' && len(l:stack) == 0
|
||||
if len(get(l:args, -1)) > 0
|
||||
call add(l:args, '')
|
||||
endif
|
||||
|
||||
continue
|
||||
endif
|
||||
|
||||
let l:args[-1] = get(l:args, -1) . l:char
|
||||
endfor
|
||||
|
||||
return len(l:stack) == 0
|
||||
return l:args
|
||||
endfunction
|
||||
|
||||
function! ale#c#ParseCFlags(path_prefix, cflag_line) abort
|
||||
let l:split_lines = split(a:cflag_line)
|
||||
let l:cflags_list = []
|
||||
|
||||
let l:split_lines = ale#c#ShellSplit(a:cflag_line)
|
||||
let l:option_index = 0
|
||||
|
||||
while l:option_index < len(l:split_lines)
|
||||
let l:next_option_index = l:option_index + 1
|
||||
|
||||
" Join space-separated option
|
||||
while l:next_option_index < len(l:split_lines)
|
||||
\&& stridx(l:split_lines[l:next_option_index], '-') != 0
|
||||
let l:next_option_index += 1
|
||||
endwhile
|
||||
|
||||
let l:option = join(l:split_lines[l:option_index : l:next_option_index-1], ' ')
|
||||
call remove(l:split_lines, l:option_index, l:next_option_index-1)
|
||||
call insert(l:split_lines, l:option, l:option_index)
|
||||
|
||||
" Ignore invalid or conflicting options
|
||||
if stridx(l:option, '-') != 0
|
||||
\|| stridx(l:option, '-o') == 0
|
||||
\|| stridx(l:option, '-c') == 0
|
||||
call remove(l:split_lines, l:option_index)
|
||||
let l:option_index = l:option_index - 1
|
||||
" Fix relative path
|
||||
elseif stridx(l:option, '-I') == 0
|
||||
if !(stridx(l:option, ':') == 2+1 || stridx(l:option, '/') == 2+0)
|
||||
let l:option = '-I' . a:path_prefix . s:sep . l:option[2:]
|
||||
call remove(l:split_lines, l:option_index)
|
||||
call insert(l:split_lines, l:option, l:option_index)
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:option = l:split_lines[l:option_index]
|
||||
let l:option_index = l:option_index + 1
|
||||
|
||||
" Include options, that may need relative path fix
|
||||
if stridx(l:option, '-I') == 0
|
||||
\ || stridx(l:option, '-iquote') == 0
|
||||
\ || stridx(l:option, '-isystem') == 0
|
||||
\ || stridx(l:option, '-idirafter') == 0
|
||||
if stridx(l:option, '-I') == 0 && l:option isnot# '-I'
|
||||
let l:arg = join(split(l:option, '\zs')[2:], '')
|
||||
let l:option = '-I'
|
||||
else
|
||||
let l:arg = l:split_lines[l:option_index]
|
||||
let l:option_index = l:option_index + 1
|
||||
endif
|
||||
|
||||
" Fix relative paths if needed
|
||||
if stridx(l:arg, s:sep) != 0 && stridx(l:arg, '/') != 0
|
||||
let l:rel_path = substitute(l:arg, '"', '', 'g')
|
||||
let l:rel_path = substitute(l:rel_path, '''', '', 'g')
|
||||
let l:arg = ale#Escape(a:path_prefix . s:sep . l:rel_path)
|
||||
endif
|
||||
|
||||
call add(l:cflags_list, l:option)
|
||||
call add(l:cflags_list, l:arg)
|
||||
" Options with arg that can be grouped with the option or separate
|
||||
elseif stridx(l:option, '-D') == 0 || stridx(l:option, '-B') == 0
|
||||
call add(l:cflags_list, l:option)
|
||||
|
||||
if l:option is# '-D' || l:option is# '-B'
|
||||
call add(l:cflags_list, l:split_lines[l:option_index])
|
||||
let l:option_index = l:option_index + 1
|
||||
endif
|
||||
" Options that have an argument (always separate)
|
||||
elseif l:option is# '-iprefix' || stridx(l:option, '-iwithprefix') == 0
|
||||
\ || l:option is# '-isysroot' || l:option is# '-imultilib'
|
||||
call add(l:cflags_list, l:option)
|
||||
call add(l:cflags_list, l:split_lines[l:option_index])
|
||||
let l:option_index = l:option_index + 1
|
||||
" Options without argument
|
||||
elseif (stridx(l:option, '-W') == 0 && stridx(l:option, '-Wa,') != 0 && stridx(l:option, '-Wl,') != 0 && stridx(l:option, '-Wp,') != 0)
|
||||
\ || l:option is# '-w' || stridx(l:option, '-pedantic') == 0
|
||||
\ || l:option is# '-ansi' || stridx(l:option, '-std=') == 0
|
||||
\ || (stridx(l:option, '-f') == 0 && stridx(l:option, '-fdump') != 0 && stridx(l:option, '-fdiagnostics') != 0 && stridx(l:option, '-fno-show-column') != 0)
|
||||
\ || stridx(l:option, '-O') == 0
|
||||
\ || l:option is# '-C' || l:option is# '-CC' || l:option is# '-trigraphs'
|
||||
\ || stridx(l:option, '-nostdinc') == 0 || stridx(l:option, '-iplugindir=') == 0
|
||||
\ || stridx(l:option, '--sysroot=') == 0 || l:option is# '--no-sysroot-suffix'
|
||||
\ || stridx(l:option, '-m') == 0
|
||||
call add(l:cflags_list, l:option)
|
||||
endif
|
||||
endwhile
|
||||
|
||||
call uniq(l:split_lines)
|
||||
|
||||
return join(l:split_lines, ' ')
|
||||
return join(l:cflags_list, ' ')
|
||||
endfunction
|
||||
|
||||
function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
|
||||
@@ -234,6 +265,16 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
|
||||
return l:empty
|
||||
endfunction
|
||||
|
||||
function! ale#c#GetCompileCommand(json_item) abort
|
||||
if has_key(a:json_item, 'command')
|
||||
return a:json_item.command
|
||||
elseif has_key(a:json_item, 'arguments')
|
||||
return join(a:json_item.arguments, ' ')
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
||||
" Search for an exact file match first.
|
||||
let l:basename = tolower(expand('#' . a:buffer . ':t'))
|
||||
@@ -256,15 +297,14 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
||||
for l:item in l:file_list
|
||||
" Load the flags for this file, or for a source file matching the
|
||||
" header file.
|
||||
if has_key(l:item, 'command')
|
||||
\&& (
|
||||
if (
|
||||
\ bufnr(l:item.file) is a:buffer
|
||||
\ || (
|
||||
\ !empty(l:source_file)
|
||||
\ && l:item.file[-len(l:source_file):] is? l:source_file
|
||||
\ )
|
||||
\)
|
||||
return ale#c#ParseCFlags(l:item.directory, l:item.command)
|
||||
return ale#c#ParseCFlags(l:item.directory, ale#c#GetCompileCommand(l:item))
|
||||
endif
|
||||
endfor
|
||||
|
||||
@@ -276,8 +316,7 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
||||
|
||||
for l:item in l:dir_list
|
||||
if ale#path#Simplify(fnamemodify(l:item.file, ':h')) is? l:dir
|
||||
\&& has_key(l:item, 'command')
|
||||
return ale#c#ParseCFlags(l:item.directory, l:item.command)
|
||||
return ale#c#ParseCFlags(l:item.directory, ale#c#GetCompileCommand(l:item))
|
||||
endif
|
||||
endfor
|
||||
|
||||
|
||||
163
autoload/ale/code_action.vim
Normal file
163
autoload/ale/code_action.vim
Normal file
@@ -0,0 +1,163 @@
|
||||
" Author: Jerko Steiner <jerko.steiner@gmail.com>
|
||||
" Description: Code action support for LSP / tsserver
|
||||
|
||||
function! ale#code_action#HandleCodeAction(code_action) abort
|
||||
let l:current_buffer = bufnr('')
|
||||
let l:changes = a:code_action.changes
|
||||
|
||||
for l:file_code_edit in l:changes
|
||||
let l:buf = bufnr(l:file_code_edit.fileName)
|
||||
|
||||
if l:buf != -1 && l:buf != l:current_buffer && getbufvar(l:buf, '&mod')
|
||||
call ale#util#Execute('echom ''Aborting action, file is unsaved''')
|
||||
|
||||
return
|
||||
endif
|
||||
endfor
|
||||
|
||||
for l:file_code_edit in l:changes
|
||||
call ale#code_action#ApplyChanges(
|
||||
\ l:file_code_edit.fileName, l:file_code_edit.textChanges)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#code_action#ApplyChanges(filename, changes) abort
|
||||
let l:current_buffer = bufnr('')
|
||||
" The buffer is used to determine the fileformat, if available.
|
||||
let l:buffer = bufnr(a:filename)
|
||||
let l:is_current_buffer = l:buffer > 0 && l:buffer == l:current_buffer
|
||||
|
||||
if l:buffer > 0
|
||||
let l:lines = getbufline(l:buffer, 1, '$')
|
||||
else
|
||||
let l:lines = readfile(a:filename, 'b')
|
||||
endif
|
||||
|
||||
if l:is_current_buffer
|
||||
let l:pos = getpos('.')[1:2]
|
||||
else
|
||||
let l:pos = [1, 1]
|
||||
endif
|
||||
|
||||
" We have to keep track of how many lines we have added, and offset
|
||||
" changes accordingly.
|
||||
let l:line_offset = 0
|
||||
let l:column_offset = 0
|
||||
let l:last_end_line = 0
|
||||
|
||||
for l:code_edit in a:changes
|
||||
if l:code_edit.start.line isnot l:last_end_line
|
||||
let l:column_offset = 0
|
||||
endif
|
||||
|
||||
let l:line = l:code_edit.start.line + l:line_offset
|
||||
let l:column = l:code_edit.start.offset + l:column_offset
|
||||
let l:end_line = l:code_edit.end.line + l:line_offset
|
||||
let l:end_column = l:code_edit.end.offset + l:column_offset
|
||||
let l:text = l:code_edit.newText
|
||||
|
||||
let l:cur_line = l:pos[0]
|
||||
let l:cur_column = l:pos[1]
|
||||
|
||||
let l:last_end_line = l:end_line
|
||||
|
||||
" Adjust the ends according to previous edits.
|
||||
if l:end_line > len(l:lines)
|
||||
let l:end_line_len = 0
|
||||
else
|
||||
let l:end_line_len = len(l:lines[l:end_line - 1])
|
||||
endif
|
||||
|
||||
let l:insertions = split(l:text, '\n', 1)
|
||||
|
||||
if l:line is 1
|
||||
" Same logic as for column below. Vimscript's slice [:-1] will not
|
||||
" be an empty list.
|
||||
let l:start = []
|
||||
else
|
||||
let l:start = l:lines[: l:line - 2]
|
||||
endif
|
||||
|
||||
if l:column is 1
|
||||
" We need to handle column 1 specially, because we can't slice an
|
||||
" empty string ending on index 0.
|
||||
let l:middle = [l:insertions[0]]
|
||||
else
|
||||
let l:middle = [l:lines[l:line - 1][: l:column - 2] . l:insertions[0]]
|
||||
endif
|
||||
|
||||
call extend(l:middle, l:insertions[1:])
|
||||
let l:middle[-1] .= l:lines[l:end_line - 1][l:end_column - 1 :]
|
||||
|
||||
let l:lines_before_change = len(l:lines)
|
||||
let l:lines = l:start + l:middle + l:lines[l:end_line :]
|
||||
|
||||
let l:current_line_offset = len(l:lines) - l:lines_before_change
|
||||
let l:line_offset += l:current_line_offset
|
||||
let l:column_offset = len(l:middle[-1]) - l:end_line_len
|
||||
|
||||
let l:pos = s:UpdateCursor(l:pos,
|
||||
\ [l:line, l:column],
|
||||
\ [l:end_line, l:end_column],
|
||||
\ [l:current_line_offset, l:column_offset])
|
||||
endfor
|
||||
|
||||
if l:lines[-1] is# ''
|
||||
call remove(l:lines, -1)
|
||||
endif
|
||||
|
||||
call ale#util#Writefile(l:buffer, l:lines, a:filename)
|
||||
|
||||
if l:is_current_buffer
|
||||
call ale#util#Execute(':e!')
|
||||
call setpos('.', [0, l:pos[0], l:pos[1], 0])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:UpdateCursor(cursor, start, end, offset) abort
|
||||
let l:cur_line = a:cursor[0]
|
||||
let l:cur_column = a:cursor[1]
|
||||
let l:line = a:start[0]
|
||||
let l:column = a:start[1]
|
||||
let l:end_line = a:end[0]
|
||||
let l:end_column = a:end[1]
|
||||
let l:line_offset = a:offset[0]
|
||||
let l:column_offset = a:offset[1]
|
||||
|
||||
if l:end_line < l:cur_line
|
||||
" both start and end lines are before the cursor. only line offset
|
||||
" needs to be updated
|
||||
let l:cur_line += l:line_offset
|
||||
elseif l:end_line == l:cur_line
|
||||
" end line is at the same location as cursor, which means
|
||||
" l:line <= l:cur_line
|
||||
if l:line < l:cur_line || l:column <= l:cur_column
|
||||
" updates are happening either before or around the cursor
|
||||
if l:end_column < l:cur_column
|
||||
" updates are happening before the cursor, update the
|
||||
" column offset for cursor
|
||||
let l:cur_line += l:line_offset
|
||||
let l:cur_column += l:column_offset
|
||||
else
|
||||
" updates are happening around the cursor, move the cursor
|
||||
" to the end of the changes
|
||||
let l:cur_line += l:line_offset
|
||||
let l:cur_column = l:end_column + l:column_offset
|
||||
endif
|
||||
" else is not necessary, it means modifications are happening
|
||||
" after the cursor so no cursor updates need to be done
|
||||
endif
|
||||
else
|
||||
" end line is after the cursor
|
||||
if l:line < l:cur_line || l:line == l:cur_line && l:column <= l:cur_column
|
||||
" changes are happening around the cursor, move the cursor
|
||||
" to the end of the changes
|
||||
let l:cur_line = l:end_line + l:line_offset
|
||||
let l:cur_column = l:end_column + l:column_offset
|
||||
" else is not necesary, it means modifications are happening
|
||||
" after the cursor so no cursor updates need to be done
|
||||
endif
|
||||
endif
|
||||
|
||||
return [l:cur_line, l:cur_column]
|
||||
endfunction
|
||||
@@ -15,6 +15,7 @@ onoremap <silent> <Plug>(ale_show_completion_menu) <Nop>
|
||||
let g:ale_completion_delay = get(g:, 'ale_completion_delay', 100)
|
||||
let g:ale_completion_excluded_words = get(g:, 'ale_completion_excluded_words', [])
|
||||
let g:ale_completion_max_suggestions = get(g:, 'ale_completion_max_suggestions', 50)
|
||||
let g:ale_completion_tsserver_autoimport = get(g:, 'ale_completion_tsserver_autoimport', 0)
|
||||
|
||||
let s:timer_id = -1
|
||||
let s:last_done_pos = []
|
||||
@@ -52,6 +53,7 @@ let s:should_complete_map = {
|
||||
\ 'lisp': s:lisp_regex,
|
||||
\ 'typescript': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|''$|"$',
|
||||
\ 'rust': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$',
|
||||
\ 'cpp': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$|\.$|::$|-\>$',
|
||||
\}
|
||||
|
||||
" Regular expressions for finding the start column to replace with completion.
|
||||
@@ -59,11 +61,13 @@ let s:omni_start_map = {
|
||||
\ '<default>': '\v[a-zA-Z$_][a-zA-Z$_0-9]*$',
|
||||
\}
|
||||
|
||||
" A map of exact characters for triggering LSP completions.
|
||||
" A map of exact characters for triggering LSP completions. Do not forget to
|
||||
" update self.input_patterns in ale.py in updating entries in this map.
|
||||
let s:trigger_character_map = {
|
||||
\ '<default>': ['.'],
|
||||
\ 'typescript': ['.', '''', '"'],
|
||||
\ 'rust': ['.', '::'],
|
||||
\ 'cpp': ['.', '::', '->'],
|
||||
\}
|
||||
|
||||
function! s:GetFiletypeValue(map, filetype) abort
|
||||
@@ -215,6 +219,10 @@ function! ale#completion#GetCompletionPosition() abort
|
||||
return l:column - len(l:match) - 1
|
||||
endfunction
|
||||
|
||||
function! ale#completion#GetCompletionPositionForDeoplete(input) abort
|
||||
return match(a:input, '\k*$')
|
||||
endfunction
|
||||
|
||||
function! ale#completion#GetCompletionResult() abort
|
||||
if exists('b:ale_completion_result')
|
||||
return b:ale_completion_result
|
||||
@@ -260,6 +268,14 @@ function! ale#completion#Show(result) abort
|
||||
\ {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")}
|
||||
\)
|
||||
endif
|
||||
|
||||
if l:source is# 'ale-callback'
|
||||
call b:CompleteCallback(b:ale_completion_result)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#completion#GetAllTriggers() abort
|
||||
return deepcopy(s:trigger_character_map)
|
||||
endfunction
|
||||
|
||||
function! s:CompletionStillValid(request_id) abort
|
||||
@@ -273,6 +289,7 @@ function! s:CompletionStillValid(request_id) abort
|
||||
\ 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.source is# 'ale-callback'
|
||||
\)
|
||||
endfunction
|
||||
|
||||
@@ -280,7 +297,10 @@ function! ale#completion#ParseTSServerCompletions(response) abort
|
||||
let l:names = []
|
||||
|
||||
for l:suggestion in a:response.body
|
||||
call add(l:names, l:suggestion.name)
|
||||
call add(l:names, {
|
||||
\ 'word': l:suggestion.name,
|
||||
\ 'source': get(l:suggestion, 'source', ''),
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:names
|
||||
@@ -294,6 +314,10 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
||||
for l:suggestion in a:response.body
|
||||
let l:displayParts = []
|
||||
|
||||
for l:action in get(l:suggestion, 'codeActions', [])
|
||||
call add(l:displayParts, l:action.description . ' ')
|
||||
endfor
|
||||
|
||||
for l:part in l:suggestion.displayParts
|
||||
call add(l:displayParts, l:part.text)
|
||||
endfor
|
||||
@@ -314,13 +338,22 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
||||
endif
|
||||
|
||||
" See :help complete-items
|
||||
call add(l:results, {
|
||||
let l:result = {
|
||||
\ 'word': l:suggestion.name,
|
||||
\ 'kind': l:kind,
|
||||
\ 'icase': 1,
|
||||
\ 'menu': join(l:displayParts, ''),
|
||||
\ 'dup': g:ale_completion_tsserver_autoimport,
|
||||
\ 'info': join(l:documentationParts, ''),
|
||||
\}
|
||||
|
||||
if has_key(l:suggestion, 'codeActions')
|
||||
let l:result.user_data = json_encode({
|
||||
\ 'codeActions': l:suggestion.codeActions,
|
||||
\ })
|
||||
endif
|
||||
|
||||
call add(l:results, l:result)
|
||||
endfor
|
||||
|
||||
let l:names = getbufvar(l:buffer, 'ale_tsserver_completion_names', [])
|
||||
@@ -329,12 +362,12 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
||||
let l:names_with_details = map(copy(l:results), 'v:val.word')
|
||||
let l:missing_names = filter(
|
||||
\ copy(l:names),
|
||||
\ 'index(l:names_with_details, v:val) < 0',
|
||||
\ 'index(l:names_with_details, v:val.word) < 0',
|
||||
\)
|
||||
|
||||
for l:name in l:missing_names
|
||||
call add(l:results, {
|
||||
\ 'word': l:name,
|
||||
\ 'word': l:name.word,
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'menu': '',
|
||||
@@ -456,13 +489,22 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
|
||||
call setbufvar(l:buffer, 'ale_tsserver_completion_names', l:names)
|
||||
|
||||
if !empty(l:names)
|
||||
let l:identifiers = []
|
||||
|
||||
for l:name in l:names
|
||||
call add(l:identifiers, {
|
||||
\ 'name': l:name.word,
|
||||
\ 'source': get(l:name, 'source', ''),
|
||||
\})
|
||||
endfor
|
||||
|
||||
let b:ale_completion_info.request_id = ale#lsp#Send(
|
||||
\ b:ale_completion_info.conn_id,
|
||||
\ ale#lsp#tsserver_message#CompletionEntryDetails(
|
||||
\ l:buffer,
|
||||
\ b:ale_completion_info.line,
|
||||
\ b:ale_completion_info.column,
|
||||
\ l:names,
|
||||
\ l:identifiers,
|
||||
\ ),
|
||||
\)
|
||||
endif
|
||||
@@ -509,6 +551,7 @@ function! s:OnReady(linter, lsp_details) abort
|
||||
\ b:ale_completion_info.line,
|
||||
\ b:ale_completion_info.column,
|
||||
\ b:ale_completion_info.prefix,
|
||||
\ g:ale_completion_tsserver_autoimport,
|
||||
\)
|
||||
else
|
||||
" Send a message saying the buffer has changed first, otherwise
|
||||
@@ -553,12 +596,25 @@ 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(...) abort
|
||||
let l:source = get(a:000, 0, '')
|
||||
let l:options = get(a:000, 1, {})
|
||||
|
||||
if len(a:000) > 2
|
||||
throw 'Too many arguments!'
|
||||
endif
|
||||
|
||||
let l:CompleteCallback = get(l:options, 'callback', v:null)
|
||||
|
||||
if l:CompleteCallback isnot v:null
|
||||
let b:CompleteCallback = l:CompleteCallback
|
||||
endif
|
||||
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
|
||||
let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
|
||||
|
||||
if a:source is# 'ale-automatic' && empty(l:prefix)
|
||||
if l:source is# 'ale-automatic' && empty(l:prefix)
|
||||
return 0
|
||||
endif
|
||||
|
||||
@@ -571,7 +627,7 @@ function! ale#completion#GetCompletions(source) abort
|
||||
\ 'prefix': l:prefix,
|
||||
\ 'conn_id': 0,
|
||||
\ 'request_id': 0,
|
||||
\ 'source': a:source,
|
||||
\ 'source': l:source,
|
||||
\}
|
||||
unlet! b:ale_completion_result
|
||||
|
||||
@@ -663,6 +719,30 @@ function! ale#completion#Queue() abort
|
||||
let s:timer_id = timer_start(g:ale_completion_delay, function('s:TimerHandler'))
|
||||
endfunction
|
||||
|
||||
function! ale#completion#HandleUserData(completed_item) abort
|
||||
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
|
||||
|
||||
if l:source isnot# 'ale-automatic' && l:source isnot# 'ale-manual'
|
||||
return
|
||||
endif
|
||||
|
||||
let l:user_data_json = get(a:completed_item, 'user_data', '')
|
||||
|
||||
if empty(l:user_data_json)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:user_data = json_decode(l:user_data_json)
|
||||
|
||||
if type(l:user_data) isnot v:t_dict
|
||||
return
|
||||
endif
|
||||
|
||||
for l:code_action in get(l:user_data, 'codeActions', [])
|
||||
call ale#code_action#HandleCodeAction(l:code_action)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#completion#Done() abort
|
||||
silent! pclose
|
||||
|
||||
@@ -671,6 +751,10 @@ function! ale#completion#Done() abort
|
||||
let s:last_done_pos = getpos('.')[1:2]
|
||||
endfunction
|
||||
|
||||
augroup ALECompletionActions
|
||||
autocmd CompleteDone * call ale#completion#HandleUserData(v:completed_item)
|
||||
augroup END
|
||||
|
||||
function! s:Setup(enabled) abort
|
||||
augroup ALECompletionGroup
|
||||
autocmd!
|
||||
|
||||
@@ -50,6 +50,7 @@ let s:global_variable_list = [
|
||||
\ 'ale_sign_style_error',
|
||||
\ 'ale_sign_style_warning',
|
||||
\ 'ale_sign_warning',
|
||||
\ 'ale_sign_highlight_linenrs',
|
||||
\ 'ale_statusline_format',
|
||||
\ 'ale_type_map',
|
||||
\ 'ale_use_global_executables',
|
||||
@@ -62,7 +63,7 @@ function! s:Echo(message) abort
|
||||
execute 'echo a:message'
|
||||
endfunction
|
||||
|
||||
function! s:GetLinterVariables(filetype, linter_names) abort
|
||||
function! s:GetLinterVariables(filetype, exclude_linter_names) abort
|
||||
let l:variable_list = []
|
||||
let l:filetype_parts = split(a:filetype, '\.')
|
||||
|
||||
@@ -73,7 +74,7 @@ function! s:GetLinterVariables(filetype, linter_names) abort
|
||||
" Include matching variables.
|
||||
if !empty(l:match)
|
||||
\&& index(l:filetype_parts, l:match[1]) >= 0
|
||||
\&& index(a:linter_names, l:match[2]) >= 0
|
||||
\&& index(a:exclude_linter_names, l:match[2]) == -1
|
||||
call add(l:variable_list, l:key)
|
||||
endif
|
||||
endfor
|
||||
@@ -211,10 +212,11 @@ function! ale#debugging#Info() abort
|
||||
|
||||
let l:all_names = map(copy(l:all_linters), 'v:val[''name'']')
|
||||
let l:enabled_names = map(copy(l:enabled_linters), 'v:val[''name'']')
|
||||
let l:exclude_names = filter(copy(l:all_names), 'index(l:enabled_names, v:val) == -1')
|
||||
|
||||
" Load linter variables to display
|
||||
" This must be done after linters are loaded.
|
||||
let l:variable_list = s:GetLinterVariables(l:filetype, l:enabled_names)
|
||||
let l:variable_list = s:GetLinterVariables(l:filetype, l:exclude_names)
|
||||
|
||||
let l:fixers = ale#fix#registry#SuggestedFixers(l:filetype)
|
||||
let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1]))
|
||||
|
||||
@@ -47,7 +47,7 @@ function! ale#fix#ApplyQueuedFixes(buffer) abort
|
||||
set nomodified
|
||||
endif
|
||||
else
|
||||
call writefile(l:new_lines, expand(a:buffer . ':p')) " no-custom-checks
|
||||
call writefile(l:new_lines, expand('#' . a:buffer . ':p')) " no-custom-checks
|
||||
call setbufvar(a:buffer, '&modified', 0)
|
||||
endif
|
||||
endif
|
||||
@@ -74,7 +74,7 @@ endfunction
|
||||
function! ale#fix#ApplyFixes(buffer, output) abort
|
||||
let l:data = g:ale_fix_buffer_data[a:buffer]
|
||||
let l:data.output = a:output
|
||||
let l:data.changes_made = l:data.lines_before != l:data.output
|
||||
let l:data.changes_made = l:data.lines_before !=# l:data.output " no-custom-checks
|
||||
let l:data.done = 1
|
||||
|
||||
call ale#command#RemoveManagedFiles(a:buffer)
|
||||
|
||||
@@ -27,6 +27,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix PEP8 issues with black.',
|
||||
\ },
|
||||
\ 'dfmt': {
|
||||
\ 'function': 'ale#fixers#dfmt#Fix',
|
||||
\ 'suggested_filetypes': ['d'],
|
||||
\ 'description': 'Fix D files with dfmt.',
|
||||
\ },
|
||||
\ 'fecs': {
|
||||
\ 'function': 'ale#fixers#fecs#Fix',
|
||||
\ 'suggested_filetypes': ['javascript', 'css', 'html'],
|
||||
@@ -115,6 +120,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['scala'],
|
||||
\ 'description': 'Fix Scala files using scalafmt',
|
||||
\ },
|
||||
\ 'sorbet': {
|
||||
\ 'function': 'ale#fixers#sorbet#Fix',
|
||||
\ 'suggested_filetypes': ['ruby'],
|
||||
\ 'description': 'Fix ruby files with srb tc --autocorrect.',
|
||||
\ },
|
||||
\ 'standard': {
|
||||
\ 'function': 'ale#fixers#standard#Fix',
|
||||
\ 'suggested_filetypes': ['javascript'],
|
||||
@@ -145,6 +155,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['php'],
|
||||
\ 'description': 'Fix PHP files with php-cs-fixer.',
|
||||
\ },
|
||||
\ 'clangtidy': {
|
||||
\ 'function': 'ale#fixers#clangtidy#Fix',
|
||||
\ 'suggested_filetypes': ['c', 'cpp', 'objc'],
|
||||
\ 'description': 'Fix C/C++ and ObjectiveC files with clang-tidy.',
|
||||
\ },
|
||||
\ 'clang-format': {
|
||||
\ 'function': 'ale#fixers#clangformat#Fix',
|
||||
\ 'suggested_filetypes': ['c', 'cpp', 'cuda'],
|
||||
@@ -205,6 +220,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
\ 'description': 'Fix Haskell files with brittany.',
|
||||
\ },
|
||||
\ 'hindent': {
|
||||
\ 'function': 'ale#fixers#hindent#Fix',
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
\ 'description': 'Fix Haskell files with hindent.',
|
||||
\ },
|
||||
\ 'hlint': {
|
||||
\ 'function': 'ale#fixers#hlint#Fix',
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
@@ -240,6 +260,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['sql'],
|
||||
\ 'description': 'Fix SQL files with sqlfmt.',
|
||||
\ },
|
||||
\ 'sqlformat': {
|
||||
\ 'function': 'ale#fixers#sqlformat#Fix',
|
||||
\ 'suggested_filetypes': ['sql'],
|
||||
\ 'description': 'Fix SQL files with sqlformat.',
|
||||
\ },
|
||||
\ 'google_java_format': {
|
||||
\ 'function': 'ale#fixers#google_java_format#Fix',
|
||||
\ 'suggested_filetypes': ['java'],
|
||||
@@ -297,7 +322,7 @@ let s:default_registry = {
|
||||
\ },
|
||||
\ 'styler': {
|
||||
\ 'function': 'ale#fixers#styler#Fix',
|
||||
\ 'suggested_filetypes': ['r', 'rmarkdown'],
|
||||
\ 'suggested_filetypes': ['r', 'rmarkdown', 'rmd'],
|
||||
\ 'description': 'Fix R files with styler.',
|
||||
\ },
|
||||
\ 'latexindent': {
|
||||
@@ -315,6 +340,16 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Sort Python imports with reorder-python-imports.',
|
||||
\ },
|
||||
\ 'gnatpp': {
|
||||
\ 'function': 'ale#fixers#gnatpp#Fix',
|
||||
\ 'suggested_filetypes': ['ada'],
|
||||
\ 'description': 'Format Ada files with gnatpp.',
|
||||
\ },
|
||||
\ 'nixpkgs-fmt': {
|
||||
\ 'function': 'ale#fixers#nixpkgsfmt#Fix',
|
||||
\ 'suggested_filetypes': ['nix'],
|
||||
\ 'description': 'A formatter for Nix code',
|
||||
\ },
|
||||
\}
|
||||
|
||||
" Reset the function registry to the default entries.
|
||||
|
||||
@@ -29,6 +29,10 @@ function! ale#fixers#black#Fix(buffer) abort
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'python_black_options')
|
||||
|
||||
if expand('#' . a:buffer . ':e') is? 'pyi'
|
||||
let l:options .= '--pyi'
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'command': l:cd_string . ale#Escape(l:executable) . l:exec_args
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
|
||||
@@ -13,10 +13,15 @@ function! ale#fixers#clangformat#GetExecutable(buffer) abort
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#clangformat#Fix(buffer) abort
|
||||
let l:executable = ale#Escape(ale#fixers#clangformat#GetExecutable(a:buffer))
|
||||
let l:filename = ale#Escape(bufname(a:buffer))
|
||||
let l:options = ale#Var(a:buffer, 'c_clangformat_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(ale#fixers#clangformat#GetExecutable(a:buffer))
|
||||
\ . ' ' . l:options,
|
||||
\}
|
||||
let l:command = l:executable . ' --assume-filename=' . l:filename
|
||||
|
||||
if l:options isnot# ''
|
||||
let l:command .= ' ' . l:options
|
||||
endif
|
||||
|
||||
return {'command': l:command}
|
||||
endfunction
|
||||
|
||||
52
autoload/ale/fixers/clangtidy.vim
Normal file
52
autoload/ale/fixers/clangtidy.vim
Normal file
@@ -0,0 +1,52 @@
|
||||
scriptencoding utf-8
|
||||
" Author: ObserverOfTime <chronobserver@disroot.org>
|
||||
" Description: Fixing C/C++ files with clang-tidy.
|
||||
|
||||
function! s:set_variables() abort
|
||||
let l:use_global = get(g:, 'ale_use_global_executables', 0)
|
||||
|
||||
for l:ft in ['c', 'cpp']
|
||||
call ale#Set(l:ft . '_clangtidy_executable', 'clang-tidy')
|
||||
call ale#Set(l:ft . '_clangtidy_use_global', l:use_global)
|
||||
call ale#Set(l:ft . '_clangtidy_checks', [])
|
||||
call ale#Set(l:ft . '_clangtidy_options', '')
|
||||
call ale#Set(l:ft . '_clangtidy_extra_options', '')
|
||||
call ale#Set(l:ft . '_clangtidy_fix_errors', 1)
|
||||
endfor
|
||||
|
||||
call ale#Set('c_build_dir', '')
|
||||
endfunction
|
||||
|
||||
call s:set_variables()
|
||||
|
||||
function! ale#fixers#clangtidy#Var(buffer, name) abort
|
||||
let l:ft = getbufvar(str2nr(a:buffer), '&filetype')
|
||||
let l:ft = l:ft =~# 'cpp' ? 'cpp' : 'c'
|
||||
|
||||
return ale#Var(a:buffer, l:ft . '_clangtidy_' . a:name)
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#clangtidy#GetCommand(buffer) abort
|
||||
let l:checks = join(ale#fixers#clangtidy#Var(a:buffer, 'checks'), ',')
|
||||
let l:extra_options = ale#fixers#clangtidy#Var(a:buffer, 'extra_options')
|
||||
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
|
||||
let l:options = empty(l:build_dir)
|
||||
\ ? ale#fixers#clangtidy#Var(a:buffer, 'options') : ''
|
||||
let l:fix_errors = ale#fixers#clangtidy#Var(a:buffer, 'fix_errors')
|
||||
|
||||
return ' -fix' . (l:fix_errors ? ' -fix-errors' : '')
|
||||
\ . (empty(l:checks) ? '' : ' -checks=' . ale#Escape(l:checks))
|
||||
\ . (empty(l:extra_options) ? '' : ' ' . l:extra_options)
|
||||
\ . (empty(l:build_dir) ? '' : ' -p ' . ale#Escape(l:build_dir))
|
||||
\ . ' %t' . (empty(l:options) ? '' : ' -- ' . l:options)
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#clangtidy#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#clangtidy#Var(a:buffer, 'executable')
|
||||
let l:command = ale#fixers#clangtidy#GetCommand(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . l:command,
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
18
autoload/ale/fixers/dfmt.vim
Normal file
18
autoload/ale/fixers/dfmt.vim
Normal file
@@ -0,0 +1,18 @@
|
||||
" Author: theoldmoon0602
|
||||
" Description: Integration of dfmt with ALE.
|
||||
|
||||
call ale#Set('d_dfmt_executable', 'dfmt')
|
||||
call ale#Set('d_dfmt_options', '')
|
||||
|
||||
function! ale#fixers#dfmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'd_dfmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'd_dfmt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' -i'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
17
autoload/ale/fixers/gnatpp.vim
Normal file
17
autoload/ale/fixers/gnatpp.vim
Normal file
@@ -0,0 +1,17 @@
|
||||
" Author: tim <tim@inept.tech>
|
||||
" Description: Fix files with gnatpp.
|
||||
|
||||
call ale#Set('ada_gnatpp_executable', 'gnatpp')
|
||||
call ale#Set('ada_gnatpp_options', '')
|
||||
|
||||
function! ale#fixers#gnatpp#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ada_gnatpp_executable')
|
||||
let l:options = ale#Var(a:buffer, 'ada_gnatpp_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
@@ -7,9 +7,10 @@ call ale#Set('go_gofmt_options', '')
|
||||
function! ale#fixers#gofmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'go_gofmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'go_gofmt_options')
|
||||
let l:env = ale#go#EnvString(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ 'command': l:env . ale#Escape(l:executable)
|
||||
\ . ' -l -w'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t',
|
||||
|
||||
@@ -7,13 +7,14 @@ call ale#Set('go_goimports_options', '')
|
||||
function! ale#fixers#goimports#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'go_goimports_executable')
|
||||
let l:options = ale#Var(a:buffer, 'go_goimports_options')
|
||||
let l:env = ale#go#EnvString(a:buffer)
|
||||
|
||||
if !executable(l:executable)
|
||||
return 0
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ 'command': l:env . ale#Escape(l:executable)
|
||||
\ . ' -l -w -srcdir %s'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t',
|
||||
|
||||
@@ -2,9 +2,10 @@ call ale#Set('go_go_executable', 'go')
|
||||
|
||||
function! ale#fixers#gomod#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'go_go_executable')
|
||||
let l:env = ale#go#EnvString(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . ' mod edit -fmt %t',
|
||||
\ 'command': l:env . ale#Escape(l:executable) . ' mod edit -fmt %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
20
autoload/ale/fixers/hindent.vim
Normal file
20
autoload/ale/fixers/hindent.vim
Normal file
@@ -0,0 +1,20 @@
|
||||
" Author: AlexeiDrake <drake.alexei@gmail.com>
|
||||
" Description: Integration of hindent formatting with ALE.
|
||||
"
|
||||
call ale#Set('haskell_hindent_executable', 'hindent')
|
||||
|
||||
function! ale#fixers#hindent#GetExecutable(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'haskell_hindent_executable')
|
||||
|
||||
return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'hindent')
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#hindent#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#hindent#GetExecutable(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:executable
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
12
autoload/ale/fixers/nixpkgsfmt.vim
Normal file
12
autoload/ale/fixers/nixpkgsfmt.vim
Normal file
@@ -0,0 +1,12 @@
|
||||
call ale#Set('nix_nixpkgsfmt_executable', 'nixpkgs-fmt')
|
||||
call ale#Set('nix_nixpkgsfmt_options', '')
|
||||
|
||||
function! ale#fixers#nixpkgsfmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'nix_nixpkgsfmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'nix_nixpkgsfmt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options),
|
||||
\}
|
||||
endfunction
|
||||
@@ -39,9 +39,15 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
|
||||
let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
|
||||
let l:parser = ''
|
||||
|
||||
let l:filetypes = split(getbufvar(a:buffer, '&filetype'), '\.')
|
||||
|
||||
if index(l:filetypes, 'handlebars') > -1
|
||||
let l:parser = 'glimmer'
|
||||
endif
|
||||
|
||||
" Append the --parser flag depending on the current filetype (unless it's
|
||||
" already set in g:javascript_prettier_options).
|
||||
if empty(expand('#' . a:buffer . ':e')) && match(l:options, '--parser') == -1
|
||||
if empty(expand('#' . a:buffer . ':e')) && l:parser is# '' && match(l:options, '--parser') == -1
|
||||
" Mimic Prettier's defaults. In cases without a file extension or
|
||||
" filetype (scratch buffer), Prettier needs `parser` set to know how
|
||||
" to process the buffer.
|
||||
@@ -65,7 +71,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
|
||||
\ 'html': 'html',
|
||||
\}
|
||||
|
||||
for l:filetype in split(getbufvar(a:buffer, '&filetype'), '\.')
|
||||
for l:filetype in l:filetypes
|
||||
if has_key(l:prettier_parsers, l:filetype)
|
||||
let l:parser = l:prettier_parsers[l:filetype]
|
||||
break
|
||||
|
||||
@@ -6,7 +6,7 @@ function! ale#fixers#rubocop#GetCommand(buffer) abort
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.rubocop.yml')
|
||||
let l:options = ale#Var(a:buffer, 'ruby_rubocop_options')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'rubocop')
|
||||
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --auto-correct --force-exclusion %t'
|
||||
|
||||
19
autoload/ale/fixers/sorbet.vim
Normal file
19
autoload/ale/fixers/sorbet.vim
Normal file
@@ -0,0 +1,19 @@
|
||||
call ale#Set('ruby_sorbet_executable', 'srb')
|
||||
call ale#Set('ruby_sorbet_options', '')
|
||||
|
||||
function! ale#fixers#sorbet#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable')
|
||||
let l:options = ale#Var(a:buffer, 'ruby_sorbet_options')
|
||||
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'srb')
|
||||
\ . ' tc'
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --autocorrect --file %t'
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#sorbet#Fix(buffer) abort
|
||||
return {
|
||||
\ 'command': ale#fixers#sorbet#GetCommand(a:buffer),
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
16
autoload/ale/fixers/sqlformat.vim
Normal file
16
autoload/ale/fixers/sqlformat.vim
Normal file
@@ -0,0 +1,16 @@
|
||||
" Author: Cluas <Cluas@live.cn>
|
||||
" Description: Fixing files with sqlformat.
|
||||
|
||||
call ale#Set('sql_sqlformat_executable', 'sqlformat')
|
||||
call ale#Set('sql_sqlformat_options', '')
|
||||
|
||||
function! ale#fixers#sqlformat#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'sql_sqlformat_executable')
|
||||
let l:options = ale#Var(a:buffer, 'sql_sqlformat_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' -'
|
||||
\}
|
||||
endfunction
|
||||
@@ -9,7 +9,7 @@ function! ale#fixers#standardrb#GetCommand(buffer) abort
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.standard.yml')
|
||||
let l:options = ale#Var(a:buffer, 'ruby_standardrb_options')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'standardrb')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'standardrb')
|
||||
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --fix --force-exclusion %t'
|
||||
|
||||
@@ -25,3 +25,20 @@ function! ale#go#FindProjectRoot(buffer) abort
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
|
||||
call ale#Set('go_go111module', '')
|
||||
|
||||
" Return a string setting Go-specific environment variables
|
||||
function! ale#go#EnvString(buffer) abort
|
||||
let l:env = ''
|
||||
|
||||
" GO111MODULE - turn go modules behavior on/off
|
||||
let l:go111module = ale#Var(a:buffer, 'go_go111module')
|
||||
|
||||
if !empty(l:go111module)
|
||||
let l:env = ale#Env('GO111MODULE', l:go111module) . l:env
|
||||
endif
|
||||
|
||||
return l:env
|
||||
endfunction
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
" Description: languagetool for markdown files
|
||||
"
|
||||
call ale#Set('languagetool_executable', 'languagetool')
|
||||
call ale#Set('languagetool_options', '--autoDetect')
|
||||
|
||||
function! ale#handlers#languagetool#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'languagetool_executable')
|
||||
@@ -9,8 +10,10 @@ endfunction
|
||||
|
||||
function! ale#handlers#languagetool#GetCommand(buffer) abort
|
||||
let l:executable = ale#handlers#languagetool#GetExecutable(a:buffer)
|
||||
let l:options = ale#Var(a:buffer, 'languagetool_options')
|
||||
|
||||
return ale#Escape(l:executable) . ' --autoDetect %s'
|
||||
return ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options) . ' %s'
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#languagetool#HandleOutput(buffer, lines) abort
|
||||
|
||||
@@ -36,11 +36,3 @@ endfunction
|
||||
function! ale#handlers#ruby#HandleSyntaxErrors(buffer, lines) abort
|
||||
return s:HandleSyntaxError(a:buffer, a:lines)
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#ruby#EscapeExecutable(executable, bundle_exec) abort
|
||||
let l:exec_args = a:executable =~? 'bundle'
|
||||
\ ? ' exec ' . a:bundle_exec
|
||||
\ : ''
|
||||
|
||||
return ale#Escape(a:executable) . l:exec_args
|
||||
endfunction
|
||||
|
||||
@@ -26,6 +26,25 @@ endif
|
||||
let s:MAX_POS_VALUES = 8
|
||||
let s:MAX_COL_SIZE = 1073741824 " pow(2, 30)
|
||||
|
||||
let s:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
|
||||
|
||||
if s:has_nvim_highlight
|
||||
let s:ns_id = nvim_create_namespace('ale_highlight')
|
||||
endif
|
||||
|
||||
" Wrappers are necessary to test this functionality by faking the calls in tests.
|
||||
function! ale#highlight#nvim_buf_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end) abort
|
||||
" Ignore all errors for adding highlights.
|
||||
try
|
||||
call nvim_buf_add_highlight(a:buffer, a:ns_id, a:hl_group, a:line, a:col_start, a:col_end)
|
||||
catch
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! ale#highlight#nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end) abort
|
||||
call nvim_buf_clear_namespace(a:buffer, a:ns_id, a:line_start, a:line_end)
|
||||
endfunction
|
||||
|
||||
function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort
|
||||
if a:line >= a:end_line
|
||||
" For single lines, just return the one position.
|
||||
@@ -51,15 +70,53 @@ endfunction
|
||||
" except these which have matching loclist item entries.
|
||||
|
||||
function! ale#highlight#RemoveHighlights() abort
|
||||
if s:has_nvim_highlight
|
||||
call ale#highlight#nvim_buf_clear_namespace(bufnr(''), s:ns_id, 0, -1)
|
||||
else
|
||||
for l:match in getmatches()
|
||||
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
|
||||
call matchdelete(l:match.id)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Same semantics of matchaddpos but will use nvim_buf_add_highlight if
|
||||
" available. This involves iterating over the position list, switching from
|
||||
" 1-based indexing to 0-based indexing, and translating the multiple ways
|
||||
" that position can be specified for matchaddpos into line + col_start +
|
||||
" col_end.
|
||||
function! s:matchaddpos(group, pos_list) abort
|
||||
if s:has_nvim_highlight
|
||||
for l:pos in a:pos_list
|
||||
let l:line = type(l:pos) == v:t_number
|
||||
\ ? l:pos - 1
|
||||
\ : l:pos[0] - 1
|
||||
|
||||
if type(l:pos) == v:t_number || len(l:pos) == 1
|
||||
let l:col_start = 0
|
||||
let l:col_end = s:MAX_COL_SIZE
|
||||
else
|
||||
let l:col_start = l:pos[1] - 1
|
||||
let l:col_end = l:col_start + get(l:pos, 2, 1)
|
||||
endif
|
||||
|
||||
call ale#highlight#nvim_buf_add_highlight(
|
||||
\ bufnr(''),
|
||||
\ s:ns_id,
|
||||
\ a:group,
|
||||
\ l:line,
|
||||
\ l:col_start,
|
||||
\ l:col_end,
|
||||
\)
|
||||
endfor
|
||||
else
|
||||
call matchaddpos(a:group, a:pos_list)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:highlight_line(bufnr, lnum, group) abort
|
||||
call matchaddpos(a:group, [a:lnum])
|
||||
call s:matchaddpos(a:group, [a:lnum])
|
||||
endfunction
|
||||
|
||||
function! s:highlight_range(bufnr, range, group) abort
|
||||
@@ -72,7 +129,7 @@ function! s:highlight_range(bufnr, range, group) abort
|
||||
\ a:range.end_lnum,
|
||||
\ a:range.end_col
|
||||
\ ),
|
||||
\ 'matchaddpos(a:group, v:val)'
|
||||
\ 's:matchaddpos(a:group, v:val)'
|
||||
\)
|
||||
endfunction
|
||||
|
||||
|
||||
@@ -12,9 +12,12 @@ let s:linters = {}
|
||||
let s:default_ale_linter_aliases = {
|
||||
\ 'Dockerfile': 'dockerfile',
|
||||
\ 'csh': 'sh',
|
||||
\ 'javascriptreact': ['javascript', 'jsx'],
|
||||
\ 'plaintex': 'tex',
|
||||
\ 'rmarkdown': 'r',
|
||||
\ 'rmd': 'r',
|
||||
\ 'systemverilog': 'verilog',
|
||||
\ 'typescriptreact': ['typescript', 'tsx'],
|
||||
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
|
||||
\ 'vimwiki': 'markdown',
|
||||
\ 'vue': ['vue', 'javascript'],
|
||||
|
||||
@@ -103,6 +103,9 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||
endfor
|
||||
endif
|
||||
|
||||
" Save the current view before opening/closing any window
|
||||
call setbufvar(a:buffer, 'ale_winview', winsaveview())
|
||||
|
||||
" Open a window to show the problems if we need to.
|
||||
"
|
||||
" We'll check if the current buffer's List is not empty here, so the
|
||||
@@ -110,8 +113,6 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||
if s:ShouldOpen(a:buffer) && !empty(a:loclist)
|
||||
let l:winnr = winnr()
|
||||
let l:mode = mode()
|
||||
let l:reset_visual_selection = l:mode is? 'v' || l:mode is# "\<c-v>"
|
||||
let l:reset_character_selection = l:mode is? 's' || l:mode is# "\<c-s>"
|
||||
|
||||
" open windows vertically instead of default horizontally
|
||||
let l:open_type = ''
|
||||
@@ -133,15 +134,18 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||
wincmd p
|
||||
endif
|
||||
|
||||
if l:reset_visual_selection || l:reset_character_selection
|
||||
" If we were in a selection mode before, select the last selection.
|
||||
" Return to original mode when applicable
|
||||
if mode() != l:mode
|
||||
if l:mode is? 'v' || l:mode is# "\<c-v>"
|
||||
" Reset our last visual selection
|
||||
normal! gv
|
||||
|
||||
if l:reset_character_selection
|
||||
" Switch back to Select mode, if we were in that.
|
||||
elseif l:mode is? 's' || l:mode is# "\<c-s>"
|
||||
" Reset our last character selection
|
||||
normal! "\<c-g>"
|
||||
endif
|
||||
endif
|
||||
|
||||
call s:RestoreViewIfNeeded(a:buffer)
|
||||
endif
|
||||
|
||||
" If ALE isn't currently checking for more problems, close the window if
|
||||
@@ -152,6 +156,30 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Try to restore the window view after closing any of the lists to avoid making
|
||||
" the it moving around, especially useful when on insert mode
|
||||
function! s:RestoreViewIfNeeded(buffer) abort
|
||||
let l:saved_view = getbufvar(a:buffer, 'ale_winview', {})
|
||||
|
||||
" Saved view is empty, can't do anything
|
||||
if empty(l:saved_view)
|
||||
return
|
||||
endif
|
||||
|
||||
" Check wether the cursor has moved since linting was actually requested. If
|
||||
" the user has indeed moved lines, do nothing
|
||||
let l:current_view = winsaveview()
|
||||
|
||||
if l:current_view['lnum'] != l:saved_view['lnum']
|
||||
return
|
||||
endif
|
||||
|
||||
" Anchor view by topline if the list is set to open horizontally
|
||||
if ale#Var(a:buffer, 'list_vertical') == 0
|
||||
call winrestview({'topline': l:saved_view['topline']})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#list#SetLists(buffer, loclist) abort
|
||||
if get(g:, 'ale_set_lists_synchronously') == 1
|
||||
\|| getbufvar(a:buffer, 'ale_save_event_fired', 0)
|
||||
@@ -175,12 +203,15 @@ function! s:CloseWindowIfNeeded(buffer) abort
|
||||
return
|
||||
endif
|
||||
|
||||
let l:did_close_any_list = 0
|
||||
|
||||
try
|
||||
" Only close windows if the quickfix list or loclist is completely empty,
|
||||
" including errors set through other means.
|
||||
if g:ale_set_quickfix
|
||||
if empty(getqflist())
|
||||
cclose
|
||||
let l:did_close_any_list = 1
|
||||
endif
|
||||
else
|
||||
let l:win_ids = s:WinFindBuf(a:buffer)
|
||||
@@ -188,10 +219,15 @@ function! s:CloseWindowIfNeeded(buffer) abort
|
||||
for l:win_id in l:win_ids
|
||||
if g:ale_set_loclist && empty(getloclist(l:win_id))
|
||||
lclose
|
||||
let l:did_close_any_list = 1
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
" Ignore 'Cannot close last window' errors.
|
||||
catch /E444/
|
||||
endtry
|
||||
|
||||
if l:did_close_any_list
|
||||
call s:RestoreViewIfNeeded(a:buffer)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@@ -37,6 +37,7 @@ function! ale#lsp#Register(executable_or_address, project, init_options) abort
|
||||
\ 'init_queue': [],
|
||||
\ 'capabilities': {
|
||||
\ 'hover': 0,
|
||||
\ 'rename': 0,
|
||||
\ 'references': 0,
|
||||
\ 'completion': 0,
|
||||
\ 'completion_trigger_characters': [],
|
||||
@@ -199,6 +200,10 @@ function! s:UpdateCapabilities(conn, capabilities) abort
|
||||
let a:conn.capabilities.references = 1
|
||||
endif
|
||||
|
||||
if get(a:capabilities, 'renameProvider') is v:true
|
||||
let a:conn.capabilities.rename = 1
|
||||
endif
|
||||
|
||||
if !empty(get(a:capabilities, 'completionProvider'))
|
||||
let a:conn.capabilities.completion = 1
|
||||
endif
|
||||
@@ -317,6 +322,7 @@ function! ale#lsp#MarkConnectionAsTsserver(conn_id) abort
|
||||
let l:conn.capabilities.completion_trigger_characters = ['.']
|
||||
let l:conn.capabilities.definition = 1
|
||||
let l:conn.capabilities.symbol_search = 1
|
||||
let l:conn.capabilities.rename = 1
|
||||
endfunction
|
||||
|
||||
function! s:SendInitMessage(conn) abort
|
||||
|
||||
@@ -162,3 +162,13 @@ function! ale#lsp#message#DidChangeConfiguration(buffer, config) abort
|
||||
\ 'settings': a:config,
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#message#Rename(buffer, line, column, new_name) abort
|
||||
return [0, 'textDocument/rename', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
|
||||
\ },
|
||||
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
|
||||
\ 'newName': a:new_name,
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
@@ -36,12 +36,14 @@ function! ale#lsp#tsserver_message#Geterr(buffer) abort
|
||||
return [1, 'ts@geterr', {'files': [expand('#' . a:buffer . ':p')]}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#tsserver_message#Completions(buffer, line, column, prefix) abort
|
||||
function! ale#lsp#tsserver_message#Completions(
|
||||
\ buffer, line, column, prefix, include_external) abort
|
||||
return [0, 'ts@completions', {
|
||||
\ 'line': a:line,
|
||||
\ 'offset': a:column,
|
||||
\ 'file': expand('#' . a:buffer . ':p'),
|
||||
\ 'prefix': a:prefix,
|
||||
\ 'includeExternalModuleExports': a:include_external,
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
@@ -77,3 +79,27 @@ function! ale#lsp#tsserver_message#Quickinfo(buffer, line, column) abort
|
||||
\ 'file': expand('#' . a:buffer . ':p'),
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#tsserver_message#Rename(
|
||||
\ buffer, line, column, find_in_comments, find_in_strings) abort
|
||||
return [0, 'ts@rename', {
|
||||
\ 'line': a:line,
|
||||
\ 'offset': a:column,
|
||||
\ 'file': expand('#' . a:buffer . ':p'),
|
||||
\ 'arguments': {
|
||||
\ 'findInComments': a:find_in_comments,
|
||||
\ 'findInStrings': a:find_in_strings,
|
||||
\ }
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#tsserver_message#OrganizeImports(buffer) abort
|
||||
return [0, 'ts@organizeImports', {
|
||||
\ 'scope': {
|
||||
\ 'type': 'file',
|
||||
\ 'args': {
|
||||
\ 'file': expand('#' . a:buffer . ':p'),
|
||||
\ },
|
||||
\ },
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
59
autoload/ale/organize_imports.vim
Normal file
59
autoload/ale/organize_imports.vim
Normal file
@@ -0,0 +1,59 @@
|
||||
" Author: Jerko Steiner <jerko.steiner@gmail.com>
|
||||
" Description: Organize imports support for tsserver
|
||||
"
|
||||
function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort
|
||||
if get(a:response, 'command', '') isnot# 'organizeImports'
|
||||
return
|
||||
endif
|
||||
|
||||
if get(a:response, 'success', v:false) isnot v:true
|
||||
return
|
||||
endif
|
||||
|
||||
let l:file_code_edits = a:response.body
|
||||
|
||||
call ale#code_action#HandleCodeAction({
|
||||
\ 'description': 'Organize Imports',
|
||||
\ 'changes': l:file_code_edits,
|
||||
\})
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if a:linter.lsp isnot# 'tsserver'
|
||||
call ale#util#Execute('echom ''OrganizeImports currently only works with tsserver''')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
let l:Callback = function('ale#organize_imports#HandleTSServerResponse')
|
||||
|
||||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
|
||||
let l:message = ale#lsp#tsserver_message#OrganizeImports(l:buffer)
|
||||
|
||||
let l:request_id = ale#lsp#Send(l:id, l:message)
|
||||
endfunction
|
||||
|
||||
function! s:OrganizeImports(linter) abort
|
||||
let l:buffer = bufnr('')
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
|
||||
if a:linter.lsp isnot# 'tsserver'
|
||||
let l:column = min([l:column, len(getline(l:line))])
|
||||
endif
|
||||
|
||||
let l:Callback = function('s:OnReady')
|
||||
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||
endfunction
|
||||
|
||||
function! ale#organize_imports#Execute() abort
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call s:OrganizeImports(l:linter)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
@@ -54,14 +54,14 @@ function! ale#path#FindNearestDirectory(buffer, directory_name) abort
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" Given a buffer, a string to search for, an a global fallback for when
|
||||
" Given a buffer, a string to search for, and a global fallback for when
|
||||
" the search fails, look for a file in parent paths, and if that fails,
|
||||
" use the global fallback path instead.
|
||||
function! ale#path#ResolveLocalPath(buffer, search_string, global_fallback) abort
|
||||
" Search for a locally installed file first.
|
||||
let l:path = ale#path#FindNearestFile(a:buffer, a:search_string)
|
||||
|
||||
" If the serach fails, try the global executable instead.
|
||||
" If the search fails, try the global executable instead.
|
||||
if empty(l:path)
|
||||
let l:path = a:global_fallback
|
||||
endif
|
||||
|
||||
225
autoload/ale/rename.vim
Normal file
225
autoload/ale/rename.vim
Normal file
@@ -0,0 +1,225 @@
|
||||
" Author: Jerko Steiner <jerko.steiner@gmail.com>
|
||||
" Description: Rename symbol support for LSP / tsserver
|
||||
|
||||
let s:rename_map = {}
|
||||
|
||||
" Used to get the rename map in tests.
|
||||
function! ale#rename#GetMap() abort
|
||||
return deepcopy(s:rename_map)
|
||||
endfunction
|
||||
|
||||
" Used to set the rename map in tests.
|
||||
function! ale#rename#SetMap(map) abort
|
||||
let s:rename_map = a:map
|
||||
endfunction
|
||||
|
||||
function! ale#rename#ClearLSPData() abort
|
||||
let s:rename_map = {}
|
||||
endfunction
|
||||
|
||||
let g:ale_rename_tsserver_find_in_comments = get(g:, 'ale_rename_tsserver_find_in_comments')
|
||||
let g:ale_rename_tsserver_find_in_strings = get(g:, 'ale_rename_tsserver_find_in_strings')
|
||||
|
||||
function! s:message(message) abort
|
||||
call ale#util#Execute('echom ' . string(a:message))
|
||||
endfunction
|
||||
|
||||
function! ale#rename#HandleTSServerResponse(conn_id, response) abort
|
||||
if get(a:response, 'command', '') isnot# 'rename'
|
||||
return
|
||||
endif
|
||||
|
||||
if !has_key(s:rename_map, a:response.request_seq)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:old_name = s:rename_map[a:response.request_seq].old_name
|
||||
let l:new_name = s:rename_map[a:response.request_seq].new_name
|
||||
call remove(s:rename_map, a:response.request_seq)
|
||||
|
||||
if get(a:response, 'success', v:false) is v:false
|
||||
let l:message = get(a:response, 'message', 'unknown')
|
||||
call s:message('Error renaming "' . l:old_name . '" to: "' . l:new_name
|
||||
\ . '". Reason: ' . l:message)
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:changes = []
|
||||
|
||||
for l:response_item in a:response.body.locs
|
||||
let l:filename = l:response_item.file
|
||||
let l:text_changes = []
|
||||
|
||||
for l:loc in l:response_item.locs
|
||||
call add(l:text_changes, {
|
||||
\ 'start': {
|
||||
\ 'line': l:loc.start.line,
|
||||
\ 'offset': l:loc.start.offset,
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line': l:loc.end.line,
|
||||
\ 'offset': l:loc.end.offset,
|
||||
\ },
|
||||
\ 'newText': l:new_name,
|
||||
\})
|
||||
endfor
|
||||
|
||||
call add(l:changes, {
|
||||
\ 'fileName': l:filename,
|
||||
\ 'textChanges': l:text_changes,
|
||||
\})
|
||||
endfor
|
||||
|
||||
if empty(l:changes)
|
||||
call s:message('Error renaming "' . l:old_name . '" to: "' . l:new_name . '"')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
call ale#code_action#HandleCodeAction({
|
||||
\ 'description': 'rename',
|
||||
\ 'changes': l:changes,
|
||||
\})
|
||||
endfunction
|
||||
|
||||
function! ale#rename#HandleLSPResponse(conn_id, response) abort
|
||||
if has_key(a:response, 'id')
|
||||
\&& has_key(s:rename_map, a:response.id)
|
||||
call remove(s:rename_map, a:response.id)
|
||||
|
||||
if !has_key(a:response, 'result')
|
||||
call s:message('No rename result received from server')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:workspace_edit = a:response.result
|
||||
|
||||
if !has_key(l:workspace_edit, 'changes') || empty(l:workspace_edit.changes)
|
||||
call s:message('No changes received from server')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:changes = []
|
||||
|
||||
for l:file_name in keys(l:workspace_edit.changes)
|
||||
let l:text_edits = l:workspace_edit.changes[l:file_name]
|
||||
let l:text_changes = []
|
||||
|
||||
for l:edit in l:text_edits
|
||||
let l:range = l:edit.range
|
||||
let l:new_text = l:edit.newText
|
||||
|
||||
call add(l:text_changes, {
|
||||
\ 'start': {
|
||||
\ 'line': l:range.start.line + 1,
|
||||
\ 'offset': l:range.start.character + 1,
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line': l:range.end.line + 1,
|
||||
\ 'offset': l:range.end.character + 1,
|
||||
\ },
|
||||
\ 'newText': l:new_text,
|
||||
\})
|
||||
endfor
|
||||
|
||||
call add(l:changes, {
|
||||
\ 'fileName': ale#path#FromURI(l:file_name),
|
||||
\ 'textChanges': l:text_changes,
|
||||
\})
|
||||
endfor
|
||||
|
||||
call ale#code_action#HandleCodeAction({
|
||||
\ 'description': 'rename',
|
||||
\ 'changes': l:changes,
|
||||
\})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(line, column, old_name, new_name, linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if !ale#lsp#HasCapability(l:id, 'rename')
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
let l:Callback = a:linter.lsp is# 'tsserver'
|
||||
\ ? function('ale#rename#HandleTSServerResponse')
|
||||
\ : function('ale#rename#HandleLSPResponse')
|
||||
|
||||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
|
||||
if a:linter.lsp is# 'tsserver'
|
||||
let l:message = ale#lsp#tsserver_message#Rename(
|
||||
\ l:buffer,
|
||||
\ a:line,
|
||||
\ a:column,
|
||||
\ g:ale_rename_tsserver_find_in_comments,
|
||||
\ g:ale_rename_tsserver_find_in_strings,
|
||||
\)
|
||||
else
|
||||
" Send a message saying the buffer has changed first, or the
|
||||
" rename position probably won't make sense.
|
||||
call ale#lsp#NotifyForChanges(l:id, l:buffer)
|
||||
|
||||
let l:message = ale#lsp#message#Rename(
|
||||
\ l:buffer,
|
||||
\ a:line,
|
||||
\ a:column,
|
||||
\ a:new_name
|
||||
\)
|
||||
endif
|
||||
|
||||
let l:request_id = ale#lsp#Send(l:id, l:message)
|
||||
|
||||
let s:rename_map[l:request_id] = {
|
||||
\ 'new_name': a:new_name,
|
||||
\ 'old_name': a:old_name,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! s:ExecuteRename(linter, old_name, new_name) abort
|
||||
let l:buffer = bufnr('')
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
|
||||
if a:linter.lsp isnot# 'tsserver'
|
||||
let l:column = min([l:column, len(getline(l:line))])
|
||||
endif
|
||||
|
||||
let l:Callback = function(
|
||||
\ 's:OnReady', [l:line, l:column, a:old_name, a:new_name])
|
||||
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||
endfunction
|
||||
|
||||
function! ale#rename#Execute() abort
|
||||
let l:lsp_linters = []
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call add(l:lsp_linters, l:linter)
|
||||
endif
|
||||
endfor
|
||||
|
||||
if empty(l:lsp_linters)
|
||||
call s:message('No active LSPs')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:old_name = expand('<cword>')
|
||||
let l:new_name = ale#util#Input('New name: ', l:old_name)
|
||||
|
||||
if empty(l:new_name)
|
||||
call s:message('New name cannot be empty!')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
for l:lsp_linter in l:lsp_linters
|
||||
call s:ExecuteRename(l:lsp_linter, l:old_name, l:new_name)
|
||||
endfor
|
||||
endfunction
|
||||
@@ -74,3 +74,10 @@ function! ale#ruby#HandleRubocopOutput(buffer, lines) abort
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
function! ale#ruby#EscapeExecutable(executable, bundle_exec) abort
|
||||
let l:exec_args = a:executable =~? 'bundle'
|
||||
\ ? ' exec ' . a:bundle_exec
|
||||
\ : ''
|
||||
|
||||
return ale#Escape(a:executable) . l:exec_args
|
||||
endfunction
|
||||
|
||||
@@ -14,12 +14,14 @@ let g:ale_sign_style_error = get(g:, 'ale_sign_style_error', g:ale_sign_error)
|
||||
let g:ale_sign_warning = get(g:, 'ale_sign_warning', '--')
|
||||
let g:ale_sign_style_warning = get(g:, 'ale_sign_style_warning', g:ale_sign_warning)
|
||||
let g:ale_sign_info = get(g:, 'ale_sign_info', g:ale_sign_warning)
|
||||
let g:ale_sign_priority = get(g:, 'ale_sign_priority', 30)
|
||||
" This variable sets an offset which can be set for sign IDs.
|
||||
" This ID can be changed depending on what IDs are set for other plugins.
|
||||
" The dummy sign will use the ID exactly equal to the offset.
|
||||
let g:ale_sign_offset = get(g:, 'ale_sign_offset', 1000000)
|
||||
" This flag can be set to 1 to keep sign gutter always open
|
||||
let g:ale_sign_column_always = get(g:, 'ale_sign_column_always', 0)
|
||||
let g:ale_sign_highlight_linenrs = get(g:, 'ale_sign_highlight_linenrs', 0)
|
||||
|
||||
if !hlexists('ALEErrorSign')
|
||||
highlight link ALEErrorSign error
|
||||
@@ -82,6 +84,34 @@ execute 'sign define ALEInfoSign text=' . s:EscapeSignText(g:ale_sign_info)
|
||||
\ . ' texthl=ALEInfoSign linehl=ALEInfoLine'
|
||||
sign define ALEDummySign
|
||||
|
||||
if g:ale_sign_highlight_linenrs && has('nvim-0.3.2')
|
||||
if !hlexists('ALEErrorSignLineNr')
|
||||
highlight link ALEErrorSignLineNr CursorLineNr
|
||||
endif
|
||||
|
||||
if !hlexists('ALEStyleErrorSignLineNr')
|
||||
highlight link ALEStyleErrorSignLineNr CursorLineNr
|
||||
endif
|
||||
|
||||
if !hlexists('ALEWarningSignLineNr')
|
||||
highlight link ALEWarningSignLineNr CursorLineNr
|
||||
endif
|
||||
|
||||
if !hlexists('ALEStyleWarningSignLineNr')
|
||||
highlight link ALEStyleWarningSignLineNr CursorLineNr
|
||||
endif
|
||||
|
||||
if !hlexists('ALEInfoSignLineNr')
|
||||
highlight link ALEInfoSignLineNr CursorLineNr
|
||||
endif
|
||||
|
||||
sign define ALEErrorSign numhl=ALEErrorSignLineNr
|
||||
sign define ALEStyleErrorSign numhl=ALEStyleErrorSignLineNr
|
||||
sign define ALEWarningSign numhl=ALEWarningSignLineNr
|
||||
sign define ALEStyleWarningSign numhl=ALEStyleWarningSignLineNr
|
||||
sign define ALEInfoSign numhl=ALEInfoSignLineNr
|
||||
endif
|
||||
|
||||
function! ale#sign#GetSignName(sublist) abort
|
||||
let l:priority = g:ale#util#style_warning_priority
|
||||
|
||||
@@ -118,24 +148,59 @@ function! ale#sign#GetSignName(sublist) abort
|
||||
return 'ALEErrorSign'
|
||||
endfunction
|
||||
|
||||
function! s:PriorityCmd() abort
|
||||
if has('nvim-0.4.0') || (v:version >= 801 && has('patch614'))
|
||||
return ' priority=' . g:ale_sign_priority . ' '
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:GroupCmd() abort
|
||||
if has('nvim-0.4.0') || (v:version >= 801 && has('patch614'))
|
||||
return ' group=ale '
|
||||
else
|
||||
return ' '
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Read sign data for a buffer to a list of lines.
|
||||
function! ale#sign#ReadSigns(buffer) abort
|
||||
redir => l:output
|
||||
silent execute 'sign place buffer=' . a:buffer
|
||||
silent execute 'sign place ' . s:GroupCmd() . s:PriorityCmd()
|
||||
\ . ' buffer=' . a:buffer
|
||||
redir end
|
||||
|
||||
return split(l:output, "\n")
|
||||
endfunction
|
||||
|
||||
" Given a list of lines for sign output, return a List of [line, id, group]
|
||||
function! ale#sign#ParseSigns(line_list) abort
|
||||
function! ale#sign#ParsePattern() abort
|
||||
if has('nvim-0.4.0') || (v:version >= 801 && has('patch614'))
|
||||
" Matches output like :
|
||||
" line=4 id=1 group=ale name=ALEErrorSign
|
||||
" строка=1 id=1000001 группа=ale имя=ALEErrorSign
|
||||
" 行=1 識別子=1000001 グループ=ale 名前=ALEWarningSign
|
||||
" línea=12 id=1000001 grupo=ale nombre=ALEWarningSign
|
||||
" riga=1 id=1000001 gruppo=ale nome=ALEWarningSign
|
||||
" Zeile=235 id=1000001 Gruppe=ale Name=ALEErrorSign
|
||||
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=ale>.*\=(ALE[a-zA-Z]+Sign)'
|
||||
else
|
||||
" Matches output like :
|
||||
" line=4 id=1 name=ALEErrorSign
|
||||
" строка=1 id=1000001 имя=ALEErrorSign
|
||||
" 行=1 識別子=1000001 名前=ALEWarningSign
|
||||
" línea=12 id=1000001 nombre=ALEWarningSign
|
||||
" riga=1 id=1000001, nome=ALEWarningSign
|
||||
" riga=1 id=1000001 nome=ALEWarningSign
|
||||
" Zeile=235 id=1000001 Name=ALEErrorSign
|
||||
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=(ALE[a-zA-Z]+Sign)'
|
||||
endif
|
||||
|
||||
return l:pattern
|
||||
endfunction
|
||||
|
||||
" Given a list of lines for sign output, return a List of [line, id, group]
|
||||
function! ale#sign#ParseSigns(line_list) abort
|
||||
let l:pattern =ale#sign#ParsePattern()
|
||||
let l:result = []
|
||||
let l:is_dummy_sign_set = 0
|
||||
|
||||
@@ -290,8 +355,10 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
|
||||
if !l:is_dummy_sign_set && (!empty(a:sign_map) || g:ale_sign_column_always)
|
||||
call add(l:command_list, 'sign place '
|
||||
\ . g:ale_sign_offset
|
||||
\ . ' line=1 name=ALEDummySign buffer='
|
||||
\ . a:buffer
|
||||
\ . s:GroupCmd()
|
||||
\ . s:PriorityCmd()
|
||||
\ . ' line=1 name=ALEDummySign '
|
||||
\ . ' buffer=' . a:buffer
|
||||
\)
|
||||
let l:is_dummy_sign_set = 1
|
||||
endif
|
||||
@@ -308,6 +375,8 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
|
||||
if index(l:info.current_id_list, l:info.new_id) < 0
|
||||
call add(l:command_list, 'sign place '
|
||||
\ . (l:info.new_id)
|
||||
\ . s:GroupCmd()
|
||||
\ . s:PriorityCmd()
|
||||
\ . ' line=' . l:line_str
|
||||
\ . ' name=' . (l:info.new_name)
|
||||
\ . ' buffer=' . a:buffer
|
||||
@@ -322,6 +391,7 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
|
||||
if l:current_id isnot l:info.new_id
|
||||
call add(l:command_list, 'sign unplace '
|
||||
\ . l:current_id
|
||||
\ . s:GroupCmd()
|
||||
\ . ' buffer=' . a:buffer
|
||||
\)
|
||||
endif
|
||||
@@ -332,6 +402,7 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
|
||||
if l:is_dummy_sign_set && !g:ale_sign_column_always
|
||||
call add(l:command_list, 'sign unplace '
|
||||
\ . g:ale_sign_offset
|
||||
\ . s:GroupCmd()
|
||||
\ . ' buffer=' . a:buffer
|
||||
\)
|
||||
endif
|
||||
@@ -386,3 +457,12 @@ function! ale#sign#SetSigns(buffer, loclist) abort
|
||||
highlight link SignColumn ALESignColumnWithoutErrors
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Remove all signs.
|
||||
function! ale#sign#Clear() abort
|
||||
if has('nvim-0.4.0') || (v:version >= 801 && has('patch614'))
|
||||
sign unplace group=ale *
|
||||
else
|
||||
sign unplace *
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@@ -477,3 +477,6 @@ function! ale#util#FindItemAtCursor(buffer) abort
|
||||
return [l:info, l:loc]
|
||||
endfunction
|
||||
|
||||
function! ale#util#Input(message, value) abort
|
||||
return input(a:message, a:value)
|
||||
endfunction
|
||||
|
||||
26
autoload/asyncomplete/sources/ale.vim
Normal file
26
autoload/asyncomplete/sources/ale.vim
Normal file
@@ -0,0 +1,26 @@
|
||||
function! asyncomplete#sources#ale#get_source_options(...) abort
|
||||
let l:default = extend({
|
||||
\ 'name': 'ale',
|
||||
\ 'completor': function('asyncomplete#sources#ale#completor'),
|
||||
\ 'whitelist': ['*'],
|
||||
\ 'triggers': asyncomplete#sources#ale#get_triggers(),
|
||||
\ }, a:0 >= 1 ? a:1 : {})
|
||||
|
||||
return extend(l:default, {'refresh_pattern': '\k\+$'})
|
||||
endfunction
|
||||
|
||||
function! asyncomplete#sources#ale#get_triggers() abort
|
||||
let l:triggers = ale#completion#GetAllTriggers()
|
||||
let l:triggers['*'] = l:triggers['<default>']
|
||||
|
||||
return l:triggers
|
||||
endfunction
|
||||
|
||||
function! asyncomplete#sources#ale#completor(options, context) abort
|
||||
let l:keyword = matchstr(a:context.typed, '\w\+$')
|
||||
let l:startcol = a:context.col - len(l:keyword)
|
||||
|
||||
call ale#completion#GetCompletions('ale-callback', { 'callback': {completions ->
|
||||
\ asyncomplete#complete(a:options.name, a:context, l:startcol, completions)
|
||||
\ }})
|
||||
endfunction
|
||||
@@ -21,5 +21,16 @@ g:ale_ada_gcc_options *g:ale_ada_gcc_options*
|
||||
This variable can be set to pass additional options to gcc.
|
||||
|
||||
|
||||
===============================================================================
|
||||
gnatpp *ale-ada-gnatpp*
|
||||
|
||||
g:ale_ada_gnatpp_options *g:ale_ada_gnatpp_options*
|
||||
*b:ale_ada_gnatpp_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable can be set to pass extra options to the gnatpp fixer.
|
||||
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||
|
||||
@@ -177,6 +177,15 @@ g:ale_c_clangtidy_extra_options *g:ale_c_clangtidy_extra_options*
|
||||
This variable can be changed to modify flags given to clang-tidy.
|
||||
|
||||
|
||||
g:ale_c_clangtidy_fix_errors *g:ale_c_clangtidy_fix_errors*
|
||||
*b:ale_c_clangtidy_fix_errors*
|
||||
Type: |Number|
|
||||
Default: `1`
|
||||
|
||||
This variable can be changed to disable the `-fix-errors` option for the
|
||||
|clangtidy| fixer.
|
||||
|
||||
|
||||
===============================================================================
|
||||
cppcheck *ale-c-cppcheck*
|
||||
|
||||
|
||||
@@ -146,6 +146,15 @@ g:ale_cpp_clangtidy_extra_options *g:ale_cpp_clangtidy_extra_options*
|
||||
This variable can be changed to modify flags given to clang-tidy.
|
||||
|
||||
|
||||
g:ale_cpp_clangtidy_fix_errors *g:ale_cpp_clangtidy_fix_errors*
|
||||
*b:ale_cpp_clangtidy_fix_errors*
|
||||
Type: |Number|
|
||||
Default: `1`
|
||||
|
||||
This variable can be changed to disable the `-fix-errors` option for the
|
||||
|clangtidy| fixer.
|
||||
|
||||
|
||||
===============================================================================
|
||||
clazy *ale-cpp-clazy*
|
||||
|
||||
|
||||
@@ -6,11 +6,96 @@ In addition to the linters that are provided with ALE, C# code can be checked
|
||||
with the OmniSharp plugin. See here: https://github.com/OmniSharp/omnisharp-vim
|
||||
|
||||
|
||||
===============================================================================
|
||||
csc *ale-cs-csc*
|
||||
|
||||
The |ale-cs-csc| linter checks for semantic errors when files are opened or
|
||||
saved.
|
||||
|
||||
See |ale-lint-file-linters| for more information on linters which do not
|
||||
check for problems while you type.
|
||||
|
||||
The csc linter uses the mono csc compiler, providing full C# 7 and newer
|
||||
support, to generate a temporary module target file (/t:module). The module
|
||||
includes all '*.cs' files contained in the directory tree rooted at the path
|
||||
defined by the |g:ale_cs_csc_source| or |b:ale_cs_csc_source| variable and
|
||||
all sub directories.
|
||||
|
||||
It will in future replace the |ale-cs-mcs| and |ale-cs-mcsc| linters as both
|
||||
utilize the mcsc compiler which, according to the mono project, is no longer
|
||||
actively developed, and only receives maintenance updates. However, because
|
||||
the csc compiler does not support the -syntax option, this linter does not
|
||||
offer any as-you-type syntax checking, similar to the |ale-cs-mcsc| linter.
|
||||
|
||||
The paths to search for additional assembly files can be specified using the
|
||||
|g:ale_cs_csc_assembly_path| or |b:ale_cs_csc_assembly_path| variables.
|
||||
|
||||
NOTE: ALE will not find any errors in files apart from syntax errors if any
|
||||
one of the source files contains a syntax error. Syntax errors must be fixed
|
||||
first before other errors will be shown.
|
||||
|
||||
|
||||
g:ale_cs_csc_options *g:ale_cs_csc_options*
|
||||
*b:ale_cs_csc_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This option can be set to pass additional arguments to the `csc` compiler.
|
||||
|
||||
For example, to add the dotnet package which is not added per default: >
|
||||
|
||||
let g:ale_cs_mcs_options = ' /warn:4 /langversion:7.2'
|
||||
<
|
||||
NOTE: the `/unsafe` option is always passed to `csc`.
|
||||
|
||||
|
||||
g:ale_cs_csc_source *g:ale_cs_csc_source*
|
||||
*b:ale_cs_csc_source*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable defines the root path of the directory tree searched for the
|
||||
'*.cs' files to be linted. If this option is empty, the source file's
|
||||
directory will be used.
|
||||
|
||||
NOTE: Currently it is not possible to specify sub directories and
|
||||
directory sub trees which shall not be searched for *.cs files.
|
||||
|
||||
|
||||
g:ale_cs_csc_assembly_path *g:ale_cs_csc_assembly_path*
|
||||
*b:ale_cs_csc_assembly_path*
|
||||
Type: |List|
|
||||
Default: `[]`
|
||||
|
||||
This variable defines a list of path strings to be searched for external
|
||||
assembly files. The list is passed to the csc compiler using the `/lib:`
|
||||
flag.
|
||||
|
||||
|
||||
g:ale_cs_csc_assemblies *g:ale_cs_csc_assemblies*
|
||||
*b:ale_cs_csc_assemblies*
|
||||
Type: |List|
|
||||
Default: `[]`
|
||||
|
||||
This variable defines a list of external assembly (*.dll) files required
|
||||
by the mono mcs compiler to generate a valid module target. The list is
|
||||
passed the csc compiler using the `/r:` flag.
|
||||
|
||||
For example: >
|
||||
|
||||
" Compile C# programs with the Unity engine DLL file on Mac.
|
||||
let g:ale_cs_mcsc_assemblies = [
|
||||
\ '/Applications/Unity/Unity.app/Contents/Frameworks/Managed/UnityEngine.dll',
|
||||
\ 'path-to-unityproject/obj/Debug',
|
||||
\]
|
||||
<
|
||||
|
||||
===============================================================================
|
||||
mcs *ale-cs-mcs*
|
||||
|
||||
The `mcs` linter looks only for syntax errors while you type. See |ale-cs-mcsc|
|
||||
for the separately configured linter for checking for semantic errors.
|
||||
The `mcs` linter looks only for syntax errors while you type. See
|
||||
|ale-cs-mcsc| for the separately configured linter for checking for semantic
|
||||
errors.
|
||||
|
||||
|
||||
g:ale_cs_mcs_options *g:ale_cs_mcs_options*
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
===============================================================================
|
||||
ALE D Integration *ale-d-options*
|
||||
|
||||
===============================================================================
|
||||
dfmt *ale-d-dfmt*
|
||||
|
||||
g:ale_d_dfmt_options *g:ale_d_dfmt_options*
|
||||
*b:ale_d_dfmt_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable can be set to pass additional options to the dfmt fixer.
|
||||
|
||||
===============================================================================
|
||||
dls *ale-d-dls*
|
||||
|
||||
@@ -184,13 +184,12 @@ tests: https://github.com/junegunn/vader.vim
|
||||
See |ale-development-linter-tests| for more information on how to write linter
|
||||
tests.
|
||||
|
||||
When you add new linters or fixers, make sure to add them into the table in
|
||||
the README, and also into the |ale-support| list in the main help file. If you
|
||||
forget to keep them both in sync, you should see an error like the following
|
||||
in Travis CI. >
|
||||
|
||||
When you add new linters or fixers, make sure to add them into the tables in
|
||||
supported-tools.md and |ale-supported-languages-and-tools.txt|. If you forget to
|
||||
keep them both in sync, you should see an error like the following in Travis CI.
|
||||
>
|
||||
========================================
|
||||
diff README.md and doc/ale.txt tables
|
||||
diff supported-tools.md and doc/ale-supported-languages-and-tools.txt tables
|
||||
========================================
|
||||
Differences follow:
|
||||
|
||||
|
||||
@@ -29,23 +29,55 @@ g:ale_elm_format_options *g:ale_elm_format_options*
|
||||
This variable can be set to pass additional options to elm-format.
|
||||
|
||||
===============================================================================
|
||||
elm-lsp *ale-elm-elm-lsp*
|
||||
elm-ls *ale-elm-elm-ls*
|
||||
|
||||
g:ale_elm_lsp_executable *g:ale_elm_lsp_executable*
|
||||
*b:ale_elm_lsp_executable*
|
||||
g:ale_elm_ls_executable *g:ale_elm_ls_executable*
|
||||
*b:ale_elm_ls_executable*
|
||||
Type: |String|
|
||||
Default: `'elm-lsp'`
|
||||
Default: `'elm-language-server'`
|
||||
|
||||
See |ale-integrations-local-executables|
|
||||
|
||||
|
||||
g:ale_elm_lsp_use_global *g:ale_elm_lsp_use_global*
|
||||
*b:ale_elm_lsp_use_global*
|
||||
g:ale_elm_ls_use_global *g:ale_elm_ls_use_global*
|
||||
*b:ale_elm_ls_use_global*
|
||||
Type: |Number|
|
||||
Default: `get(g:, 'ale_use_global_executables', 0)`
|
||||
Default: `get(g:, 'ale_use_global_executables', 1)`
|
||||
|
||||
See |ale-integrations-local-executables|
|
||||
|
||||
|
||||
g:ale_elm_ls_elm_path *g:ale_elm_ls_elm_path*
|
||||
*b:ale_elm_ls_elm_path*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
See |ale-integrations-local-executables|
|
||||
|
||||
|
||||
g:ale_elm_ls_elm_format_path *g:ale_elm_ls_elm_format_path*
|
||||
*b:ale_elm_ls_elm_format_path*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
See |ale-integrations-local-executables|
|
||||
|
||||
|
||||
g:ale_elm_ls_elm_test_path *g:ale_elm_ls_elm_test_path*
|
||||
*b:ale_elm_ls_elm_test_path*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
See |ale-integrations-local-executables|
|
||||
|
||||
|
||||
g:ale_elm_ls_elm_analyse_trigger *g:ale_elm_ls_elm_analyse_trigger*
|
||||
*b:ale_elm_ls_elm_analyse_trigger*
|
||||
Type: |String|
|
||||
Default: `'change'`
|
||||
|
||||
One of 'change', 'save' or 'never'
|
||||
|
||||
===============================================================================
|
||||
elm-make *ale-elm-elm-make*
|
||||
|
||||
|
||||
@@ -30,6 +30,16 @@ g:ale_go_go_executable *g:ale_go_go_options*
|
||||
the `gomod` fixer.
|
||||
|
||||
|
||||
g:ale_go_go111module *g:ale_go_go111module*
|
||||
*b:ale_go_go111module*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
Override the value of the `$GO111MODULE` environment variable for
|
||||
golang tools.
|
||||
|
||||
|
||||
|
||||
===============================================================================
|
||||
bingo *ale-go-bingo*
|
||||
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
ALE Handlebars Integration *ale-handlebars-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
prettier *ale-handlebars-prettier*
|
||||
|
||||
See |ale-javascript-prettier| for information about the available options.
|
||||
Uses glimmer parser by default.
|
||||
|
||||
|
||||
===============================================================================
|
||||
ember-template-lint *ale-handlebars-embertemplatelint*
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ 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*
|
||||
|
||||
@@ -22,6 +23,7 @@ g:ale_haskell_floskell_executable *g:ale_haskell_floskell_executable*
|
||||
|
||||
This variable can be changed to use a different executable for floskell.
|
||||
|
||||
|
||||
===============================================================================
|
||||
ghc *ale-haskell-ghc*
|
||||
|
||||
@@ -32,6 +34,7 @@ g:ale_haskell_ghc_options *g:ale_haskell_ghc_options*
|
||||
|
||||
This variable can be changed to modify flags given to ghc.
|
||||
|
||||
|
||||
===============================================================================
|
||||
ghc-mod *ale-haskell-ghc-mod*
|
||||
|
||||
@@ -42,6 +45,7 @@ g:ale_haskell_ghc_mod_executable *g:ale_haskell_ghc_mod_executable*
|
||||
|
||||
This variable can be changed to use a different executable for ghc-mod.
|
||||
|
||||
|
||||
===============================================================================
|
||||
cabal-ghc *ale-haskell-cabal-ghc*
|
||||
|
||||
@@ -53,6 +57,7 @@ g:ale_haskell_cabal_ghc_options *g:ale_haskell_cabal_ghc_options*
|
||||
This variable can be changed to modify flags given to ghc through cabal
|
||||
exec.
|
||||
|
||||
|
||||
===============================================================================
|
||||
hdevtools *ale-haskell-hdevtools*
|
||||
|
||||
@@ -87,6 +92,18 @@ g:ale_haskell_hfmt_executable *g:ale_haskell_hfmt_executable*
|
||||
|
||||
This variable can be changed to use a different executable for hfmt.
|
||||
|
||||
|
||||
===============================================================================
|
||||
hindent *ale-haskell-hindent*
|
||||
|
||||
g:ale_haskell_hindent_executable *g:ale_haskell_hindent_executable*
|
||||
*b:ale_haskell_hindent_executable*
|
||||
Type: |String|
|
||||
Default: `'hindent'`
|
||||
|
||||
This variable can be changed to use a different executable for hindent.
|
||||
|
||||
|
||||
===============================================================================
|
||||
hlint *ale-haskell-hlint*
|
||||
|
||||
@@ -106,6 +123,7 @@ g:ale_haskell_hlint_options g:ale_haskell_hlint_options
|
||||
This variable can be used to pass extra options to the underlying hlint
|
||||
executable.
|
||||
|
||||
|
||||
===============================================================================
|
||||
stack-build *ale-haskell-stack-build*
|
||||
|
||||
@@ -117,6 +135,7 @@ g:ale_haskell_stack_build_options *g:ale_haskell_stack_build_options*
|
||||
We default to using `'--fast'`. Since Stack generates binaries, your
|
||||
programs will be slower unless you separately rebuild them outside of ALE.
|
||||
|
||||
|
||||
===============================================================================
|
||||
stack-ghc *ale-haskell-stack-ghc*
|
||||
|
||||
@@ -128,6 +147,7 @@ g:ale_haskell_stack_ghc_options *g:ale_haskell_stack_ghc_options*
|
||||
This variable can be changed to modify flags given to ghc through `stack
|
||||
ghc`
|
||||
|
||||
|
||||
===============================================================================
|
||||
stylish-haskell *ale-haskell-stylish-haskell*
|
||||
|
||||
@@ -139,6 +159,7 @@ g:ale_haskell_stylish_haskell_executable
|
||||
|
||||
This variable can be changed to use a different executable for stylish-haskell.
|
||||
|
||||
|
||||
===============================================================================
|
||||
hie *ale-haskell-hie*
|
||||
|
||||
@@ -150,5 +171,6 @@ g:ale_haskell_hie_executable *g:ale_haskell_hie_executable*
|
||||
This variable can be changed to use a different executable for the haskell
|
||||
ide engine. i.e. `'hie-wrapper'`
|
||||
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||
|
||||
40
doc/ale-ink.txt
Normal file
40
doc/ale-ink.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
===============================================================================
|
||||
ALE Ink Integration *ale-ink-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
ink-language-server *ale-ink-language-server*
|
||||
|
||||
Ink Language Server
|
||||
(https://github.com/ephraim/ink-language-server)
|
||||
|
||||
g:ale_ink_ls_executable g:ale_ink_ls_executable
|
||||
b:ale_ink_ls_executable
|
||||
Type: |String|
|
||||
Default: `'ink-language-server'`
|
||||
|
||||
Ink language server executable.
|
||||
|
||||
g:ale_ink_ls_initialization_options
|
||||
g:ale_ink_ls_initialization_options
|
||||
b:ale_ink_ls_initialization_options
|
||||
Type: |Dictionary|
|
||||
Default: `{}`
|
||||
|
||||
Dictionary containing configuration settings that will be passed to the
|
||||
language server at startup. For certain platforms and certain story
|
||||
structures, the defaults will suffice. However, many projects will need to
|
||||
change these settings - see the ink-language-server website for more
|
||||
information.
|
||||
|
||||
An example of setting non-default options:
|
||||
{
|
||||
\ 'ink': {
|
||||
\ 'mainStoryPath': 'init.ink',
|
||||
\ 'inklecateExecutablePath': '/usr/local/bin/inklecate',
|
||||
\ 'runThroughMono': v:false
|
||||
\ }
|
||||
\}
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||
@@ -9,7 +9,7 @@ g:ale_java_checkstyle_config *g:ale_java_checkstyle_config*
|
||||
*b:ale_java_checkstyle_config*
|
||||
|
||||
Type: |String|
|
||||
Default: `'google_checks.xml'`
|
||||
Default: `'/google_checks.xml'`
|
||||
|
||||
A path to a checkstyle configuration file.
|
||||
|
||||
@@ -123,7 +123,7 @@ executable in this directory.
|
||||
g:ale_java_javalsp_executable *g:ale_java_javalsp_executable*
|
||||
*b:ale_java_javalsp_executable*
|
||||
Type: |String|
|
||||
Default: `'launcher'`
|
||||
Default: `''`
|
||||
|
||||
This variable must be set to the absolute path of the language server launcher
|
||||
executable. For example:
|
||||
@@ -131,6 +131,33 @@ executable. For example:
|
||||
let g:ale_java_javalsp_executable=/java-language-server/dist/mac/bin/launcher
|
||||
<
|
||||
|
||||
g:ale_java_javalsp_config *g:ale_java_javalsp_config*
|
||||
*b:ale_java_javalsp_config*
|
||||
Type: |Dictionary|
|
||||
Default: `{}`
|
||||
|
||||
The javalsp linter automatically detects external depenencies for Maven and
|
||||
Gradle projects. In case the javalsp fails to detect some of them, you can
|
||||
specify them setting a dictionary to |g:ale_java_javalsp_config| variable.
|
||||
>
|
||||
let g:ale_java_javalsp_executable =
|
||||
\ {
|
||||
\ 'java': {
|
||||
\ 'externalDependencies': [
|
||||
\ 'junit:junit:jar:4.12:test', " Maven format
|
||||
\ 'junit:junit:4.1' " Gradle format
|
||||
\ ],
|
||||
\ 'classPath': [
|
||||
\ 'lib/some-dependency.jar',
|
||||
\ '/android-sdk/platforms/android-28.jar'
|
||||
\ ]
|
||||
\ }
|
||||
\ }
|
||||
|
||||
The Java language server will look for the dependencies you specify in
|
||||
`externalDependencies` array in your Maven and Gradle caches ~/.m2 and
|
||||
~/.gradle.
|
||||
|
||||
===============================================================================
|
||||
eclipselsp *ale-java-eclipselsp*
|
||||
|
||||
|
||||
24
doc/ale-nix.txt
Normal file
24
doc/ale-nix.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
===============================================================================
|
||||
ALE Nix Integration *ale-nix-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
nixpkgs-fmt *ale-nix-nixpkgs-fmt*
|
||||
|
||||
g:ale_nix_nixpkgsfmt_executable *g:ale_nix_nixpkgsfmt_executable*
|
||||
*b:ale_nix_nixpkgsfmt_executable*
|
||||
Type: |String|
|
||||
Default: `'nixpkgs-fmt'`
|
||||
|
||||
This variable sets executable used for nixpkgs-fmt.
|
||||
|
||||
g:ale_nix_nixpkgsfmt_options *g:ale_nix_nixpkgsfmt_options*
|
||||
*b:ale_nix_nixpkgsfmt_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable can be set to pass additional options to the nixpkgs-fmt fixer.
|
||||
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||
@@ -157,9 +157,9 @@ g:ale_php_phpstan_level *g:ale_php_phpstan_level*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable controls the rule levels. 0 is the loosest and 4 is the
|
||||
This variable controls the rule levels. 0 is the loosest and 7 is the
|
||||
strictest. If this option isn't set, the rule level will be controlled by
|
||||
the configuration file. If no configuration file can be detected, `'4'` will
|
||||
the configuration file. If no configuration file can be detected, `'7'` will
|
||||
be used instead.
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user