Compare commits

..

9 Commits

Author SHA1 Message Date
w0rp
d837169f1d Ignore compiled files from newer versions 2019-05-08 09:52:43 +01:00
w0rp
9778a6e5b5 Merge pull request #2134 from oaue/master
javac linter: fix handling of error messages containing ':' character
2019-05-08 09:51:46 +01:00
w0rp
0927634916 Fix #2452 - Strip trailing spaces off sign text automatically 2019-04-23 15:59:05 +01:00
w0rp
711de2c1be Fix #2415 - Mark tsserver and LSP linters inactive again 2019-04-17 18:13:22 +01:00
w0rp
fa18195e34 Fix #2440 - Fix the kotlinc command when Maven and Gradle are missing 2019-04-15 13:36:28 +01:00
w0rp
0059bcd1d0 Merge pull request #2433 from belka-ew/bugfix/remove-otherproject-util-double
Remove otherproject#util#Double from d.vim
2019-04-13 12:30:04 +01:00
w0rp
9d0a55edec Do not complain about generated _callback settings 2019-04-10 19:53:22 +01:00
w0rp
950204b133 Fix #2399 - Do not check buffers used for displaying diffs 2019-04-10 18:43:21 +01:00
w0rp
bbb6e70377 #2417 - Silence errors for shortmess+=T 2019-04-10 15:40:16 +01:00
241 changed files with 680 additions and 6257 deletions

View File

@@ -1,9 +1,9 @@
FROM tweekmonster/vim-testbed:latest FROM tweekmonster/vim-testbed:latest
RUN install_vim -tag v8.0.0027 -build \ RUN install_vim -tag v8.0.0027 -build \
-tag v8.1.0519 -build \ -tag v8.1.0204 -build \
-tag neovim:v0.2.0 -build \ -tag neovim:v0.2.0 -build \
-tag neovim:v0.3.5 -build -tag neovim:v0.3.0 -build
ENV PACKAGES="\ ENV PACKAGES="\
bash \ bash \

View File

@@ -1,4 +1,4 @@
Copyright (c) 2016-2019, w0rp <devw0rp@gmail.com> Copyright (c) 2016-2018, w0rp <devw0rp@gmail.com>
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,13 +1,13 @@
# Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.com/w0rp/ale.svg?branch=master)](https://travis-ci.com/w0rp/ale) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/w0rp/ale) [![Join the chat at https://gitter.im/vim-ale/Lobby](https://badges.gitter.im/vim-ale/Lobby.svg)](https://gitter.im/vim-ale/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) # Asynchronous Lint Engine [![Travis CI Build Status](https://travis-ci.org/w0rp/ale.svg?branch=master)](https://travis-ci.org/w0rp/ale) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/r0ef1xu8xjmik58d/branch/master?svg=true)](https://ci.appveyor.com/project/w0rp/ale) [![Join the chat at https://gitter.im/vim-ale/Lobby](https://badges.gitter.im/vim-ale/Lobby.svg)](https://gitter.im/vim-ale/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
![ALE Logo by Mark Grealish - https://www.bhalash.com/](https://user-images.githubusercontent.com/3518142/59195920-2c339500-8b85-11e9-9c22-f6b7f69637b8.jpg) ![ALE Logo by Mark Grealish - https://www.bhalash.com/](img/logo.jpg?raw=true)
ALE (Asynchronous Lint Engine) is a plugin providing linting (syntax checking ALE (Asynchronous Lint Engine) is a plugin for providing linting (checking
and semantic errors) in NeoVim 0.2.0+ and Vim 8 while you edit your text files, syntax and semantics) in NeoVim 0.2.0+ and Vim 8 while you edit your text files,
and acts as a Vim [Language Server Protocol](https://langserver.org/) client. and acts as a Vim [Language Server Protocol](https://langserver.org/) client.
<img src="https://user-images.githubusercontent.com/3518142/59195938-3a81b100-8b85-11e9-8e8d-6a601b1db908.gif" alt="A linting example with the darkspectrum color scheme in GVim." title="A linting example with the darkspectrum color scheme in GVim."> <img src="img/example.gif?raw=true" alt="A linting example with the darkspectrum color scheme in GVim." title="A linting example with the darkspectrum color scheme in GVim.">
ALE makes use of NeoVim and Vim 8 job control functions and timers to ALE makes use of NeoVim and Vim 8 job control functions and timers to
run linters on the contents of text buffers and return errors as run linters on the contents of text buffers and return errors as
@@ -26,7 +26,7 @@ features, including:
* Diagnostics (via Language Server Protocol linters) * Diagnostics (via Language Server Protocol linters)
* Go To Definition (`:ALEGoToDefinition`) * Go To Definition (`:ALEGoToDefinition`)
* Completion (Built in completion support, or with Deoplete) * Completion (`let g:ale_completion_enabled = 1` before ALE is loaded)
* Finding references (`:ALEFindReferences`) * Finding references (`:ALEFindReferences`)
* Hover information (`:ALEHover`) * Hover information (`:ALEHover`)
* Symbol search (`:ALESymbolSearch`) * Symbol search (`:ALESymbolSearch`)
@@ -159,36 +159,12 @@ ALE offers some support for completion via hijacking of omnicompletion while you
type. All of ALE's completion information must come from Language Server type. All of ALE's completion information must come from Language Server
Protocol linters, or from `tsserver` for TypeScript. Protocol linters, or from `tsserver` for TypeScript.
ALE integrates with [Deoplete](https://github.com/Shougo/deoplete.nvim) as a
completion source, named `'ale'`. You can configure Deoplete to only use ALE as
the source of completion information, or mix it with other sources.
```vim
" Use ALE and also some plugin 'foobar' as completion sources for all code.
call deoplete#custom#option('sources', {
\ '_': ['ale', 'foobar'],
\})
```
ALE also offers its own automatic completion support, which does not require any
other plugins, and can be enabled by changing a setting before ALE is loaded.
```vim ```vim
" Enable completion where available. " Enable completion where available.
" This setting must be set before ALE is loaded. " This setting must be set before ALE is loaded.
"
" You should not turn this setting on if you wish to use ALE as a completion
" source for other completion plugins, like Deoplete.
let g:ale_completion_enabled = 1 let g:ale_completion_enabled = 1
``` ```
ALE provides an omni-completion function you can use for triggering
completion manually with `<C-x><C-o>`.
```vim
set omnifunc=ale#completion#OmniFunc
```
See `:help ale-completion` for more information. See `:help ale-completion` for more information.
<a name="usage-go-to-definition"></a> <a name="usage-go-to-definition"></a>
@@ -258,14 +234,14 @@ any other tools. Simply clone the plugin into your `pack` directory.
```bash ```bash
mkdir -p ~/.vim/pack/git-plugins/start mkdir -p ~/.vim/pack/git-plugins/start
git clone --depth 1 https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale git clone https://github.com/w0rp/ale.git ~/.vim/pack/git-plugins/start/ale
``` ```
#### NeoVim on Unix #### NeoVim on Unix
```bash ```bash
mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start
git clone --depth 1 https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale git clone https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pack/git-plugins/start/ale
``` ```
#### Vim 8 on Windows #### Vim 8 on Windows
@@ -273,7 +249,7 @@ git clone --depth 1 https://github.com/w0rp/ale.git ~/.local/share/nvim/site/pac
```bash ```bash
# Run these commands in the "Git for Windows" Bash terminal # Run these commands in the "Git for Windows" Bash terminal
mkdir -p ~/vimfiles/pack/git-plugins/start mkdir -p ~/vimfiles/pack/git-plugins/start
git clone --depth 1 https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale git clone https://github.com/w0rp/ale.git ~/vimfiles/pack/git-plugins/start/ale
``` ```
#### Generating Vim help files #### Generating Vim help files
@@ -541,7 +517,7 @@ let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
Will give you: Will give you:
![Echoed message](https://user-images.githubusercontent.com/3518142/59195927-348bd000-8b85-11e9-88b6-508a094f1548.png) ![Echoed message](img/echo.png)
See `:help g:ale_echo_msg_format` for more information. See `:help g:ale_echo_msg_format` for more information.
@@ -722,10 +698,11 @@ while you type. ALE uses a timeout which is cancelled and reset every time you
type, and this delay can be increased so linters are run less often. See type, and this delay can be increased so linters are run less often. See
`:help g:ale_lint_delay` for more information. `:help g:ale_lint_delay` for more information.
If you don't wish to run linters while you type, you can disable that behaviour. If you don't wish to run linters while you type, you can disable that
Set `g:ale_lint_on_text_changed` to `never`. You won't get as frequent error behaviour. Set `g:ale_lint_on_text_changed` to `never` or `normal`. You won't
checking, but ALE shouldn't block your ability to edit a document after you save get as frequent error checking, but ALE shouldn't block your ability to edit a
a file, so the asynchronous nature of the plugin will still be an advantage. document after you save a file, so the asynchronous nature of the plugin will
still be an advantage.
If you are still concerned, you can turn the automatic linting off altogether, If you are still concerned, you can turn the automatic linting off altogether,
including the option `g:ale_lint_on_enter`, and you can run ALE manually with including the option `g:ale_lint_on_enter`, and you can run ALE manually with

View File

@@ -5,10 +5,7 @@ call ale#Set('asm_gcc_executable', 'gcc')
call ale#Set('asm_gcc_options', '-Wall') call ale#Set('asm_gcc_options', '-Wall')
function! ale_linters#asm#gcc#GetCommand(buffer) abort function! ale_linters#asm#gcc#GetCommand(buffer) abort
" `-o /dev/null` or `-o null` is needed to catch all errors, return '%e -x assembler -fsyntax-only '
" -fsyntax-only doesn't catch everything.
return '%e -x assembler'
\ . ' -o ' . g:ale#util#nul_file
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) \ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -' \ . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -'
endfunction endfunction

View File

@@ -4,6 +4,12 @@
call ale#Set('c_clangd_executable', 'clangd') call ale#Set('c_clangd_executable', 'clangd')
call ale#Set('c_clangd_options', '') call ale#Set('c_clangd_options', '')
function! ale_linters#c#clangd#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
endfunction
function! ale_linters#c#clangd#GetCommand(buffer) abort function! ale_linters#c#clangd#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options')) return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options'))
endfunction endfunction
@@ -13,5 +19,5 @@ call ale#linter#Define('c', {
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'c_clangd_executable')}, \ 'executable': {b -> ale#Var(b, 'c_clangd_executable')},
\ 'command': function('ale_linters#c#clangd#GetCommand'), \ 'command': function('ale_linters#c#clangd#GetCommand'),
\ 'project_root': function('ale#c#FindProjectRoot'), \ 'project_root': function('ale_linters#c#clangd#GetProjectRoot'),
\}) \})

View File

@@ -11,12 +11,9 @@ call ale#Set('c_clangtidy_executable', 'clang-tidy')
" http://clang.llvm.org/extra/clang-tidy/checks/list.html " http://clang.llvm.org/extra/clang-tidy/checks/list.html
call ale#Set('c_clangtidy_checks', []) call ale#Set('c_clangtidy_checks', [])
" Set this option to manually set some options for clang-tidy to use as compile " Set this option to manually set some options for clang-tidy.
" flags.
" This will disable compile_commands.json detection. " This will disable compile_commands.json detection.
call ale#Set('c_clangtidy_options', '') call ale#Set('c_clangtidy_options', '')
" Set this option to manually set options for clang-tidy directly.
call ale#Set('c_clangtidy_extra_options', '')
call ale#Set('c_build_dir', '') call ale#Set('c_build_dir', '')
function! ale_linters#c#clangtidy#GetCommand(buffer) abort function! ale_linters#c#clangtidy#GetCommand(buffer) abort
@@ -28,12 +25,8 @@ function! ale_linters#c#clangtidy#GetCommand(buffer) abort
\ ? ale#Var(a:buffer, 'c_clangtidy_options') \ ? ale#Var(a:buffer, 'c_clangtidy_options')
\ : '' \ : ''
" Get the options to pass directly to clang-tidy
let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options')
return '%e' return '%e'
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '') \ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
\ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '')
\ . ' %s' \ . ' %s'
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '') \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
\ . (!empty(l:options) ? ' -- ' . l:options : '') \ . (!empty(l:options) ? ' -- ' . l:options : '')

View File

@@ -5,17 +5,23 @@ call ale#Set('c_cppcheck_executable', 'cppcheck')
call ale#Set('c_cppcheck_options', '--enable=style') call ale#Set('c_cppcheck_options', '--enable=style')
function! ale_linters#c#cppcheck#GetCommand(buffer) abort function! ale_linters#c#cppcheck#GetCommand(buffer) abort
let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer) " Search upwards from the file for compile_commands.json.
let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer) "
let l:buffer_path_include = empty(l:compile_commands_option) " If we find it, we'll `cd` to where the compile_commands.json file is,
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) " then use the file to set up import paths, etc.
let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
let l:cd_command = !empty(l:compile_commmands_path)
\ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
\ : ''
let l:compile_commands_option = !empty(l:compile_commmands_path)
\ ? '--project=compile_commands.json '
\ : '' \ : ''
return l:cd_command return l:cd_command
\ . '%e -q --language=c' \ . '%e -q --language=c '
\ . ale#Pad(l:compile_commands_option) \ . l:compile_commands_option
\ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options')) \ . ale#Var(a:buffer, 'c_cppcheck_options')
\ . l:buffer_path_include
\ . ' %t' \ . ' %t'
endfunction endfunction

View File

@@ -5,15 +5,13 @@ call ale#Set('c_cquery_executable', 'cquery')
call ale#Set('c_cquery_cache_directory', expand('~/.cache/cquery')) call ale#Set('c_cquery_cache_directory', expand('~/.cache/cquery'))
function! ale_linters#c#cquery#GetProjectRoot(buffer) abort function! ale_linters#c#cquery#GetProjectRoot(buffer) abort
" Try to find cquery configuration files first. let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
let l:config = ale#path#FindNearestFile(a:buffer, '.cquery')
if !empty(l:config) if empty(l:project_root)
return fnamemodify(l:config, ':h') let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery')
endif endif
" Fall back on default project root detection. return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
return ale#c#FindProjectRoot(a:buffer)
endfunction endfunction
function! ale_linters#c#cquery#GetInitializationOptions(buffer) abort function! ale_linters#c#cquery#GetInitializationOptions(buffer) abort

View File

@@ -9,11 +9,7 @@ function! ale_linters#c#gcc#GetCommand(buffer, output) abort
" -iquote with the directory the file is in makes #include work for " -iquote with the directory the file is in makes #include work for
" headers in the same directory. " headers in the same directory.
" return '%e -S -x c -fsyntax-only'
" `-o /dev/null` or `-o null` is needed to catch all errors,
" -fsyntax-only doesn't catch everything.
return '%e -S -x c'
\ . ' -o ' . g:ale#util#nul_file
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ale#Pad(l:cflags) \ . ale#Pad(l:cflags)
\ . ale#Pad(ale#Var(a:buffer, 'c_gcc_options')) . ' -' \ . ale#Pad(ale#Var(a:buffer, 'c_gcc_options')) . ' -'

View File

@@ -1,54 +0,0 @@
" Author: Raphael Hoegger - https://github.com/pfuender
" Description: Cookstyle (RuboCop based), a code style analyzer for Ruby files
call ale#Set('chef_cookstyle_executable', 'cookstyle')
call ale#Set('chef_cookstyle_options', '')
function! ale_linters#chef#cookstyle#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'chef_cookstyle_options')
return '%e' . ale#Pad(escape(l:options, '~')) . ' --force-exclusion --format json --stdin ' . ' %s'
endfunction
function! ale_linters#chef#cookstyle#Handle(buffer, lines) abort
if len(a:lines) == 0
return []
endif
let l:errors = ale#util#FuzzyJSONDecode(a:lines[0], {})
if !has_key(l:errors, 'summary')
\|| l:errors['summary']['offense_count'] == 0
\|| empty(l:errors['files'])
return []
endif
let l:output = []
for l:error in l:errors['files'][0]['offenses']
let l:start_col = str2nr(l:error['location']['start_column'])
let l:end_col = str2nr(l:error['location']['last_column'])
if !l:end_col
let l:end_col = l:start_col + 1
endif
call add(l:output, {
\ 'lnum': str2nr(l:error['location']['line']),
\ 'col': l:start_col,
\ 'end_col': l:end_col,
\ 'code': l:error['cop_name'],
\ 'text': l:error['message'],
\ 'type': l:error['severity'] is? 'convention' ? 'W' : 'E',
\})
endfor
return l:output
endfunction
call ale#linter#Define('chef', {
\ 'name': 'cookstyle',
\ 'executable': {b -> ale#Var(b, 'chef_cookstyle_executable')},
\ 'command': function('ale_linters#chef#cookstyle#GetCommand'),
\ 'callback': 'ale_linters#chef#cookstyle#Handle',
\})

View File

@@ -1,34 +0,0 @@
" Author: Masashi Iizuka <liquidz.uo@gmail.com>
" Description: linter for clojure using clj-kondo https://github.com/borkdude/clj-kondo
function! ale_linters#clojure#clj_kondo#HandleCljKondoFormat(buffer, lines) abort
" output format
" <filename>:<line>:<column>: <issue type>: <message>
let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\d+):(\d+):? ((Exception|error|warning): ?(.+))$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:type = 'E'
if l:match[4] is? 'warning'
let l:type = 'W'
endif
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3],
\ 'type': l:type,
\})
endfor
return l:output
endfunction
call ale#linter#Define('clojure', {
\ 'name': 'clj-kondo',
\ 'output_stream': 'stdout',
\ 'executable': 'clj-kondo',
\ 'command': 'clj-kondo --lint %t',
\ 'callback': 'ale_linters#clojure#clj_kondo#HandleCljKondoFormat',
\})

View File

@@ -12,8 +12,7 @@ function! ale_linters#cpp#clangcheck#GetCommand(buffer) abort
let l:build_dir = ale#Var(a:buffer, 'c_build_dir') let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
if empty(l:build_dir) if empty(l:build_dir)
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer) let l:build_dir = ale#path#Dirname(ale#c#FindCompileCommands(a:buffer))
let l:build_dir = ale#path#Dirname(l:json_file)
endif endif
" The extra arguments in the command are used to prevent .plist files from " The extra arguments in the command are used to prevent .plist files from

View File

@@ -4,6 +4,12 @@
call ale#Set('cpp_clangd_executable', 'clangd') call ale#Set('cpp_clangd_executable', 'clangd')
call ale#Set('cpp_clangd_options', '') call ale#Set('cpp_clangd_options', '')
function! ale_linters#cpp#clangd#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
endfunction
function! ale_linters#cpp#clangd#GetCommand(buffer) abort function! ale_linters#cpp#clangd#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options')) return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options'))
endfunction endfunction
@@ -13,5 +19,5 @@ call ale#linter#Define('cpp', {
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'cpp_clangd_executable')}, \ 'executable': {b -> ale#Var(b, 'cpp_clangd_executable')},
\ 'command': function('ale_linters#cpp#clangd#GetCommand'), \ 'command': function('ale_linters#cpp#clangd#GetCommand'),
\ 'project_root': function('ale#c#FindProjectRoot'), \ 'project_root': function('ale_linters#cpp#clangd#GetProjectRoot'),
\}) \})

View File

@@ -5,12 +5,9 @@
call ale#Set('cpp_clangtidy_executable', 'clang-tidy') call ale#Set('cpp_clangtidy_executable', 'clang-tidy')
" Set this option to check the checks clang-tidy will apply. " Set this option to check the checks clang-tidy will apply.
call ale#Set('cpp_clangtidy_checks', []) call ale#Set('cpp_clangtidy_checks', [])
" Set this option to manually set some options for clang-tidy to use as compile " Set this option to manually set some options for clang-tidy.
" flags.
" This will disable compile_commands.json detection. " This will disable compile_commands.json detection.
call ale#Set('cpp_clangtidy_options', '') call ale#Set('cpp_clangtidy_options', '')
" Set this option to manually set options for clang-tidy directly.
call ale#Set('cpp_clangtidy_extra_options', '')
call ale#Set('c_build_dir', '') call ale#Set('c_build_dir', '')
function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
@@ -22,12 +19,8 @@ function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort
\ ? ale#Var(a:buffer, 'cpp_clangtidy_options') \ ? ale#Var(a:buffer, 'cpp_clangtidy_options')
\ : '' \ : ''
" Get the options to pass directly to clang-tidy
let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options')
return '%e' return '%e'
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '') \ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
\ . (!empty(l:extra_options) ? ' ' . ale#Escape(l:extra_options) : '')
\ . ' %s' \ . ' %s'
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '') \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
\ . (!empty(l:options) ? ' -- ' . l:options : '') \ . (!empty(l:options) ? ' -- ' . l:options : '')

View File

@@ -5,17 +5,23 @@ call ale#Set('cpp_cppcheck_executable', 'cppcheck')
call ale#Set('cpp_cppcheck_options', '--enable=style') call ale#Set('cpp_cppcheck_options', '--enable=style')
function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort
let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer) " Search upwards from the file for compile_commands.json.
let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer) "
let l:buffer_path_include = empty(l:compile_commands_option) " If we find it, we'll `cd` to where the compile_commands.json file is,
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) " then use the file to set up import paths, etc.
let l:compile_commmands_path = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
let l:cd_command = !empty(l:compile_commmands_path)
\ ? ale#path#CdString(fnamemodify(l:compile_commmands_path, ':h'))
\ : ''
let l:compile_commands_option = !empty(l:compile_commmands_path)
\ ? '--project=compile_commands.json '
\ : '' \ : ''
return l:cd_command return l:cd_command
\ . '%e -q --language=c++' \ . '%e -q --language=c++ '
\ . ale#Pad(l:compile_commands_option) \ . l:compile_commands_option
\ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options')) \ . ale#Var(a:buffer, 'cpp_cppcheck_options')
\ . l:buffer_path_include
\ . ' %t' \ . ' %t'
endfunction endfunction

View File

@@ -5,15 +5,13 @@ call ale#Set('cpp_cquery_executable', 'cquery')
call ale#Set('cpp_cquery_cache_directory', expand('~/.cache/cquery')) call ale#Set('cpp_cquery_cache_directory', expand('~/.cache/cquery'))
function! ale_linters#cpp#cquery#GetProjectRoot(buffer) abort function! ale_linters#cpp#cquery#GetProjectRoot(buffer) abort
" Try to find cquery configuration files first. let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
let l:config = ale#path#FindNearestFile(a:buffer, '.cquery')
if !empty(l:config) if empty(l:project_root)
return fnamemodify(l:config, ':h') let l:project_root = ale#path#FindNearestFile(a:buffer, '.cquery')
endif endif
" Fall back on default project root detection. return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
return ale#c#FindProjectRoot(a:buffer)
endfunction endfunction
function! ale_linters#cpp#cquery#GetInitializationOptions(buffer) abort function! ale_linters#cpp#cquery#GetInitializationOptions(buffer) abort

View File

@@ -9,11 +9,7 @@ function! ale_linters#cpp#gcc#GetCommand(buffer, output) abort
" -iquote with the directory the file is in makes #include work for " -iquote with the directory the file is in makes #include work for
" headers in the same directory. " headers in the same directory.
" return '%e -S -x c++ -fsyntax-only'
" `-o /dev/null` or `-o null` is needed to catch all errors,
" -fsyntax-only doesn't catch everything.
return '%e -S -x c++'
\ . ' -o ' . g:ale#util#nul_file
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) \ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ale#Pad(l:cflags) \ . ale#Pad(l:cflags)
\ . ale#Pad(ale#Var(a:buffer, 'cpp_gcc_options')) . ' -' \ . ale#Pad(ale#Var(a:buffer, 'cpp_gcc_options')) . ' -'

View File

@@ -1,9 +0,0 @@
" Author: harttle <yangjvn@126.com>
" Description: fecs for CSS files
call ale#linter#Define('css', {
\ 'name': 'fecs',
\ 'executable': function('ale#handlers#fecs#GetExecutable'),
\ 'command': function('ale#handlers#fecs#GetCommand'),
\ 'callback': 'ale#handlers#fecs#Handle',
\})

View File

@@ -1,93 +0,0 @@
" Author: Autoine Gagne - https://github.com/AntoineGagne
" Description: Define a checker that runs dialyzer on Erlang files.
let g:ale_erlang_dialyzer_executable =
\ get(g:, 'ale_erlang_dialyzer_executable', 'dialyzer')
let g:ale_erlang_dialyzer_plt_file =
\ get(g:, 'ale_erlang_dialyzer_plt_file', '')
let g:ale_erlang_dialyzer_rebar3_profile =
\ get(g:, 'ale_erlang_dialyzer_rebar3_profile', 'default')
function! ale_linters#erlang#dialyzer#GetRebar3Profile(buffer) abort
return ale#Var(a:buffer, 'erlang_dialyzer_rebar3_profile')
endfunction
function! ale_linters#erlang#dialyzer#FindPlt(buffer) abort
let l:plt_file = ''
let l:rebar3_profile = ale_linters#erlang#dialyzer#GetRebar3Profile(a:buffer)
let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build' . l:rebar3_profile)
if !empty(l:plt_file_directory)
let l:plt_file = split(globpath(l:plt_file_directory, '/*_plt'), '\n')
endif
if !empty(l:plt_file)
return l:plt_file[0]
endif
if !empty($REBAR_PLT_DIR)
return expand('$REBAR_PLT_DIR/dialyzer/plt')
endif
return expand('$HOME/.dialyzer_plt')
endfunction
function! ale_linters#erlang#dialyzer#GetPlt(buffer) abort
let l:plt_file = ale#Var(a:buffer, 'erlang_dialyzer_plt_file')
if !empty(l:plt_file)
return l:plt_file
endif
return ale_linters#erlang#dialyzer#FindPlt(a:buffer)
endfunction
function! ale_linters#erlang#dialyzer#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'erlang_dialyzer_executable')
endfunction
function! ale_linters#erlang#dialyzer#GetCommand(buffer) abort
let l:command = ale#Escape(ale_linters#erlang#dialyzer#GetExecutable(a:buffer))
\ . ' -n'
\ . ' --plt ' . ale#Escape(ale_linters#erlang#dialyzer#GetPlt(a:buffer))
\ . ' -Wunmatched_returns'
\ . ' -Werror_handling'
\ . ' -Wrace_conditions'
\ . ' -Wunderspecs'
\ . ' %s'
return l:command
endfunction
function! ale_linters#erlang#dialyzer#Handle(buffer, lines) abort
" Match patterns like the following:
"
" erl_tidy_prv_fmt.erl:3: Callback info about the provider behaviour is not available
let l:pattern = '^\S\+:\(\d\+\): \(.\+\)$'
let l:output = []
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) != 0
let l:code = l:match[2]
call add(l:output, {
\ 'lnum': str2nr(l:match[1]),
\ 'lcol': 0,
\ 'text': l:code,
\ 'type': 'W'
\})
endif
endfor
return l:output
endfunction
call ale#linter#Define('erlang', {
\ 'name': 'dialyzer',
\ 'executable': function('ale_linters#erlang#dialyzer#GetExecutable'),
\ 'command': function('ale_linters#erlang#dialyzer#GetCommand'),
\ 'callback': function('ale_linters#erlang#dialyzer#Handle'),
\ 'lint_file': 1
\})

View File

@@ -1,30 +0,0 @@
" Author: w0rp <devw0rp@gmail.com>
" Author: Jerko Steiner <https://github.com/jeremija>
" Description: https://github.com/saibing/gopls
call ale#Set('go_gopls_executable', 'gopls')
call ale#Set('go_gopls_options', '--mode stdio')
function! ale_linters#go#gopls#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'go_gopls_options'))
endfunction
function! ale_linters#go#gopls#FindProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'go.mod')
let l:mods = ':h'
if empty(l:project_root)
let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git')
let l:mods = ':h:h'
endif
return !empty(l:project_root) ? fnamemodify(l:project_root, l:mods) : ''
endfunction
call ale#linter#Define('go', {
\ 'name': 'gopls',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'go_gopls_executable')},
\ 'command': function('ale_linters#go#gopls#GetCommand'),
\ 'project_root': function('ale_linters#go#gopls#FindProjectRoot'),
\})

View File

@@ -4,8 +4,7 @@
call ale#Set('haskell_cabal_ghc_options', '-fno-code -v0') call ale#Set('haskell_cabal_ghc_options', '-fno-code -v0')
function! ale_linters#haskell#cabal_ghc#GetCommand(buffer) abort function! ale_linters#haskell#cabal_ghc#GetCommand(buffer) abort
return ale#path#BufferCdString(a:buffer) return 'cabal exec -- ghc '
\ . 'cabal exec -- ghc '
\ . ale#Var(a:buffer, 'haskell_cabal_ghc_options') \ . ale#Var(a:buffer, 'haskell_cabal_ghc_options')
\ . ' %t' \ . ' %t'
endfunction endfunction

View File

@@ -4,8 +4,7 @@
call ale#Set('haskell_stack_ghc_options', '-fno-code -v0') call ale#Set('haskell_stack_ghc_options', '-fno-code -v0')
function! ale_linters#haskell#stack_ghc#GetCommand(buffer) abort function! ale_linters#haskell#stack_ghc#GetCommand(buffer) abort
return ale#path#BufferCdString(a:buffer) return ale#handlers#haskell#GetStackExecutable(a:buffer)
\ . ale#handlers#haskell#GetStackExecutable(a:buffer)
\ . ' ghc -- ' \ . ' ghc -- '
\ . ale#Var(a:buffer, 'haskell_stack_ghc_options') \ . ale#Var(a:buffer, 'haskell_stack_ghc_options')
\ . ' %t' \ . ' %t'

View File

@@ -1,9 +0,0 @@
" Author: harttle <yangjvn@126.com>
" Description: fecs for HTMl files
call ale#linter#Define('html', {
\ 'name': 'fecs',
\ 'executable': function('ale#handlers#fecs#GetExecutable'),
\ 'command': function('ale#handlers#fecs#GetCommand'),
\ 'callback': 'ale#handlers#fecs#Handle',
\})

View File

@@ -1,10 +1,6 @@
" Author: Devon Meunier <devon.meunier@gmail.com> " Author: Devon Meunier <devon.meunier@gmail.com>
" Description: checkstyle for Java files " Description: checkstyle for Java files
call ale#Set('java_checkstyle_executable', 'checkstyle')
call ale#Set('java_checkstyle_config', 'google_checks.xml')
call ale#Set('java_checkstyle_options', '')
function! ale_linters#java#checkstyle#Handle(buffer, lines) abort function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
let l:output = [] let l:output = []
@@ -21,10 +17,6 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
\}) \})
endfor endfor
if !empty(l:output)
return l:output
endif
" old checkstyle versions " old checkstyle versions
let l:pattern = '\v(.+):(\d+): ([^:]+): (.+)$' let l:pattern = '\v(.+):(\d+): ([^:]+): (.+)$'
@@ -40,21 +32,18 @@ function! ale_linters#java#checkstyle#Handle(buffer, lines) abort
endfunction endfunction
function! ale_linters#java#checkstyle#GetCommand(buffer) abort function! ale_linters#java#checkstyle#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'java_checkstyle_options') return 'checkstyle '
let l:config_option = ale#Var(a:buffer, 'java_checkstyle_config') \ . ale#Var(a:buffer, 'java_checkstyle_options')
let l:config = l:options !~# '\v(^| )-c' && !empty(l:config_option)
\ ? ale#path#FindNearestFile(a:buffer, l:config_option)
\ : ''
return '%e'
\ . ale#Pad(l:options)
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
\ . ' %s' \ . ' %s'
endfunction endfunction
if !exists('g:ale_java_checkstyle_options')
let g:ale_java_checkstyle_options = '-c /google_checks.xml'
endif
call ale#linter#Define('java', { call ale#linter#Define('java', {
\ 'name': 'checkstyle', \ 'name': 'checkstyle',
\ 'executable': {b -> ale#Var(b, 'java_checkstyle_executable')}, \ 'executable': 'checkstyle',
\ 'command': function('ale_linters#java#checkstyle#GetCommand'), \ 'command': function('ale_linters#java#checkstyle#GetCommand'),
\ 'callback': 'ale_linters#java#checkstyle#Handle', \ 'callback': 'ale_linters#java#checkstyle#Handle',
\ 'lint_file': 1, \ 'lint_file': 1,

View File

@@ -1,161 +0,0 @@
" Author: Horacio Sanson <https://github.com/hsanson>
" Description: Support for the Eclipse language server https://github.com/eclipse/eclipse.jdt.ls
let s:version_cache = {}
call ale#Set('java_eclipselsp_path', ale#path#Simplify($HOME . '/eclipse.jdt.ls'))
call ale#Set('java_eclipselsp_config_path', '')
call ale#Set('java_eclipselsp_workspace_path', '')
call ale#Set('java_eclipselsp_executable', 'java')
function! ale_linters#java#eclipselsp#Executable(buffer) abort
return ale#Var(a:buffer, 'java_eclipselsp_executable')
endfunction
function! ale_linters#java#eclipselsp#TargetPath(buffer) abort
return ale#Var(a:buffer, 'java_eclipselsp_path')
endfunction
function! ale_linters#java#eclipselsp#JarPath(buffer) abort
let l:path = ale_linters#java#eclipselsp#TargetPath(a:buffer)
" Search jar file within repository path when manually built using mvn
let l:repo_path = l:path . '/org.eclipse.jdt.ls.product/target/repository'
let l:files = globpath(l:repo_path, '**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
if len(l:files) == 1
return l:files[0]
endif
" Search jar file within VSCode extensions folder.
let l:files = globpath(l:path, '**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
if len(l:files) == 1
return l:files[0]
endif
" Search jar file within system package path
let l:files = globpath('/usr/share/java/jdtls/plugins', 'org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
if len(l:files) == 1
return l:files[0]
endif
return ''
endfunction
function! ale_linters#java#eclipselsp#ConfigurationPath(buffer) abort
let l:path = fnamemodify(ale_linters#java#eclipselsp#JarPath(a:buffer), ':p:h:h')
let l:config_path = ale#Var(a:buffer, 'java_eclipselsp_config_path')
if !empty(l:config_path)
return ale#path#Simplify(l:config_path)
endif
if has('win32')
let l:path = l:path . '/config_win'
elseif has('macunix')
let l:path = l:path . '/config_mac'
else
let l:path = l:path . '/config_linux'
endif
return ale#path#Simplify(l:path)
endfunction
function! ale_linters#java#eclipselsp#VersionCheck(version_lines) abort
return s:GetVersion('', a:version_lines)
endfunction
function! s:GetVersion(executable, version_lines) abort
let l:version = []
for l:line in a:version_lines
let l:match = matchlist(l:line, '\(\d\+\)\.\(\d\+\)\.\(\d\+\)')
if !empty(l:match)
let l:version = [l:match[1] + 0, l:match[2] + 0, l:match[3] + 0]
let s:version_cache[a:executable] = l:version
break
endif
endfor
return l:version
endfunction
function! ale_linters#java#eclipselsp#CommandWithVersion(buffer, version_lines, meta) abort
let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer)
let l:version = s:GetVersion(l:executable, a:version_lines)
return ale_linters#java#eclipselsp#Command(a:buffer, l:version)
endfunction
function! ale_linters#java#eclipselsp#WorkspacePath(buffer) abort
let l:wspath = ale#Var(a:buffer, 'java_eclipselsp_workspace_path')
if !empty(l:wspath)
return l:wspath
endif
return ale#path#Dirname(ale#java#FindProjectRoot(a:buffer))
endfunction
function! ale_linters#java#eclipselsp#Command(buffer, version) abort
let l:path = ale#Var(a:buffer, 'java_eclipselsp_path')
let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer)
let l:cmd = [ ale#Escape(l:executable),
\ '-Declipse.application=org.eclipse.jdt.ls.core.id1',
\ '-Dosgi.bundles.defaultStartLevel=4',
\ '-Declipse.product=org.eclipse.jdt.ls.core.product',
\ '-Dlog.level=ALL',
\ '-noverify',
\ '-Xmx1G',
\ '-jar',
\ ale#Escape(ale_linters#java#eclipselsp#JarPath(a:buffer)),
\ '-configuration',
\ ale#Escape(ale_linters#java#eclipselsp#ConfigurationPath(a:buffer)),
\ '-data',
\ ale#Escape(ale_linters#java#eclipselsp#WorkspacePath(a:buffer))
\ ]
if ale#semver#GTE(a:version, [1, 9])
call add(l:cmd, '--add-modules=ALL-SYSTEM')
call add(l:cmd, '--add-opens java.base/java.util=ALL-UNNAMED')
call add(l:cmd, '--add-opens java.base/java.lang=ALL-UNNAMED')
endif
return join(l:cmd, ' ')
endfunction
function! ale_linters#java#eclipselsp#RunWithVersionCheck(buffer) abort
let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer)
if empty(l:executable)
return ''
endif
let l:cache = s:version_cache
if has_key(s:version_cache, l:executable)
return ale_linters#java#eclipselsp#Command(a:buffer, s:version_cache[l:executable])
endif
let l:command = ale#Escape(l:executable) . ' -version'
return ale#command#Run(
\ a:buffer,
\ l:command,
\ function('ale_linters#java#eclipselsp#CommandWithVersion')
\)
endfunction
call ale#linter#Define('java', {
\ 'name': 'eclipselsp',
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#java#eclipselsp#Executable'),
\ 'command': function('ale_linters#java#eclipselsp#RunWithVersionCheck'),
\ 'language': 'java',
\ 'project_root': function('ale#java#FindProjectRoot'),
\})

View File

@@ -21,11 +21,6 @@ function! ale_linters#java#javac#RunWithImportPaths(buffer) abort
let l:command = ale#gradle#BuildClasspathCommand(a:buffer) let l:command = ale#gradle#BuildClasspathCommand(a:buffer)
endif endif
" Try to use Ant if Gradle and Maven aren't available
if empty(l:command)
let l:command = ale#ant#BuildClasspathCommand(a:buffer)
endif
if empty(l:command) if empty(l:command)
return ale_linters#java#javac#GetCommand(a:buffer, [], {}) return ale_linters#java#javac#GetCommand(a:buffer, [], {})
endif endif

View File

@@ -1,7 +1,7 @@
" Author: Horacio Sanson <https://github.com/hsanson> " Author: Horacio Sanson <https://github.com/hsanson>
" Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac " Description: Support for the Java language server https://github.com/georgewfraser/vscode-javac
call ale#Set('java_javalsp_executable', '') call ale#Set('java_javalsp_executable', 'java')
function! ale_linters#java#javalsp#Executable(buffer) abort function! ale_linters#java#javalsp#Executable(buffer) abort
return ale#Var(a:buffer, 'java_javalsp_executable') return ale#Var(a:buffer, 'java_javalsp_executable')
@@ -10,25 +10,7 @@ endfunction
function! ale_linters#java#javalsp#Command(buffer) abort function! ale_linters#java#javalsp#Command(buffer) abort
let l:executable = ale_linters#java#javalsp#Executable(a:buffer) let l:executable = ale_linters#java#javalsp#Executable(a:buffer)
if fnamemodify(l:executable, ':t') is# 'java' return ale#Escape(l:executable) . ' -Xverify:none -m javacs/org.javacs.Main'
" For backward compatibility.
let l:cmd = [
\ ale#Escape(l:executable),
\ '--add-exports jdk.compiler/com.sun.tools.javac.api=javacs',
\ '--add-exports jdk.compiler/com.sun.tools.javac.code=javacs',
\ '--add-exports jdk.compiler/com.sun.tools.javac.comp=javacs',
\ '--add-exports jdk.compiler/com.sun.tools.javac.main=javacs',
\ '--add-exports jdk.compiler/com.sun.tools.javac.tree=javacs',
\ '--add-exports jdk.compiler/com.sun.tools.javac.model=javacs',
\ '--add-exports jdk.compiler/com.sun.tools.javac.util=javacs',
\ '--add-opens jdk.compiler/com.sun.tools.javac.api=javacs',
\ '-m javacs/org.javacs.Main',
\]
return join(l:cmd, ' ')
else
return ale#Escape(l:executable)
endif
endfunction endfunction
call ale#linter#Define('java', { call ale#linter#Define('java', {

View File

@@ -6,5 +6,5 @@ call ale#linter#Define('javascript', {
\ 'output_stream': 'both', \ 'output_stream': 'both',
\ 'executable': function('ale#handlers#eslint#GetExecutable'), \ 'executable': function('ale#handlers#eslint#GetExecutable'),
\ 'command': function('ale#handlers#eslint#GetCommand'), \ 'command': function('ale#handlers#eslint#GetCommand'),
\ 'callback': 'ale#handlers#eslint#HandleJSON', \ 'callback': 'ale#handlers#eslint#Handle',
\}) \})

View File

@@ -1,10 +0,0 @@
" Author: harttle <yangjvn@126.com>
" Description: fecs for JavaScript files
call ale#linter#Define('javascript', {
\ 'name': 'fecs',
\ 'executable': function('ale#handlers#fecs#GetExecutable'),
\ 'command': function('ale#handlers#fecs#GetCommand'),
\ 'read_buffer': 0,
\ 'callback': 'ale#handlers#fecs#Handle',
\})

View File

@@ -14,7 +14,7 @@ endfunction
function! ale_linters#javascript#xo#GetCommand(buffer) abort function! ale_linters#javascript#xo#GetCommand(buffer) abort
return ale#Escape(ale_linters#javascript#xo#GetExecutable(a:buffer)) return ale#Escape(ale_linters#javascript#xo#GetExecutable(a:buffer))
\ . ' ' . ale#Var(a:buffer, 'javascript_xo_options') \ . ' ' . ale#Var(a:buffer, 'javascript_xo_options')
\ . ' --reporter json --stdin --stdin-filename %s' \ . ' --reporter unix --stdin --stdin-filename %s'
endfunction endfunction
" xo uses eslint and the output format is the same " xo uses eslint and the output format is the same
@@ -22,5 +22,5 @@ call ale#linter#Define('javascript', {
\ 'name': 'xo', \ 'name': 'xo',
\ 'executable': function('ale_linters#javascript#xo#GetExecutable'), \ 'executable': function('ale_linters#javascript#xo#GetExecutable'),
\ 'command': function('ale_linters#javascript#xo#GetCommand'), \ 'command': function('ale_linters#javascript#xo#GetCommand'),
\ 'callback': 'ale#handlers#eslint#HandleJSON', \ 'callback': 'ale#handlers#eslint#Handle',
\}) \})

View File

@@ -4,6 +4,12 @@
call ale#Set('objc_clangd_executable', 'clangd') call ale#Set('objc_clangd_executable', 'clangd')
call ale#Set('objc_clangd_options', '') call ale#Set('objc_clangd_options', '')
function! ale_linters#objc#clangd#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
endfunction
function! ale_linters#objc#clangd#GetCommand(buffer) abort function! ale_linters#objc#clangd#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'objc_clangd_options')) return '%e' . ale#Pad(ale#Var(a:buffer, 'objc_clangd_options'))
endfunction endfunction
@@ -13,5 +19,5 @@ call ale#linter#Define('objc', {
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'objc_clangd_executable')}, \ 'executable': {b -> ale#Var(b, 'objc_clangd_executable')},
\ 'command': function('ale_linters#objc#clangd#GetCommand'), \ 'command': function('ale_linters#objc#clangd#GetCommand'),
\ 'project_root': function('ale#c#FindProjectRoot'), \ 'project_root': function('ale_linters#objc#clangd#GetProjectRoot'),
\}) \})

View File

@@ -4,6 +4,12 @@
call ale#Set('objcpp_clangd_executable', 'clangd') call ale#Set('objcpp_clangd_executable', 'clangd')
call ale#Set('objcpp_clangd_options', '') call ale#Set('objcpp_clangd_options', '')
function! ale_linters#objcpp#clangd#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
endfunction
function! ale_linters#objcpp#clangd#GetCommand(buffer) abort function! ale_linters#objcpp#clangd#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'objcpp_clangd_options')) return '%e' . ale#Pad(ale#Var(a:buffer, 'objcpp_clangd_options'))
endfunction endfunction
@@ -13,5 +19,5 @@ call ale#linter#Define('objcpp', {
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'objcpp_clangd_executable')}, \ 'executable': {b -> ale#Var(b, 'objcpp_clangd_executable')},
\ 'command': function('ale_linters#objcpp#clangd#GetCommand'), \ 'command': function('ale_linters#objcpp#clangd#GetCommand'),
\ 'project_root': function('ale#c#FindProjectRoot'), \ 'project_root': function('ale_linters#objcpp#clangd#GetProjectRoot'),
\}) \})

View File

@@ -10,13 +10,13 @@ call ale#Set('php_phpcs_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale_linters#php#phpcs#GetCommand(buffer) abort function! ale_linters#php#phpcs#GetCommand(buffer) abort
let l:standard = ale#Var(a:buffer, 'php_phpcs_standard') let l:standard = ale#Var(a:buffer, 'php_phpcs_standard')
let l:standard_option = !empty(l:standard) let l:standard_option = !empty(l:standard)
\ ? '--standard=' . ale#Escape(l:standard) \ ? '--standard=' . l:standard
\ : '' \ : ''
let l:options = ale#Var(a:buffer, 'php_phpcs_options')
return ale#path#BufferCdString(a:buffer) return '%e -s --report=emacs --stdin-path=%s'
\ . '%e -s --report=emacs --stdin-path=%s' \ . ale#Pad(l:standard_option)
\ . ale#Pad(l:standard_option) \ . ale#Pad(l:options)
\ . ale#Pad(ale#Var(a:buffer, 'php_phpcs_options'))
endfunction endfunction
function! ale_linters#php#phpcs#Handle(buffer, lines) abort function! ale_linters#php#phpcs#Handle(buffer, lines) abort
@@ -36,7 +36,6 @@ function! ale_linters#php#phpcs#Handle(buffer, lines) abort
\ 'col': l:match[2] + 0, \ 'col': l:match[2] + 0,
\ 'text': l:text, \ 'text': l:text,
\ 'type': l:type is# 'error' ? 'E' : 'W', \ 'type': l:type is# 'error' ? 'E' : 'W',
\ 'sub_type': 'style',
\}) \})
endfor endfor

View File

@@ -3,42 +3,23 @@
" Set to change the ruleset " Set to change the ruleset
let g:ale_php_phpstan_executable = get(g:, 'ale_php_phpstan_executable', 'phpstan') let g:ale_php_phpstan_executable = get(g:, 'ale_php_phpstan_executable', 'phpstan')
let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '') let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '4')
let g:ale_php_phpstan_configuration = get(g:, 'ale_php_phpstan_configuration', '') let g:ale_php_phpstan_configuration = get(g:, 'ale_php_phpstan_configuration', '')
let g:ale_php_phpstan_autoload = get(g:, 'ale_php_phpstan_autoload', '')
function! ale_linters#php#phpstan#GetCommand(buffer, version) abort function! ale_linters#php#phpstan#GetCommand(buffer, version) abort
let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration') let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration')
let l:configuration_option = !empty(l:configuration) let l:configuration_option = !empty(l:configuration)
\ ? ' -c ' . ale#Escape(l:configuration) \ ? ' -c ' . l:configuration
\ : ''
let l:autoload = ale#Var(a:buffer, 'php_phpstan_autoload')
let l:autoload_option = !empty(l:autoload)
\ ? ' -a ' . ale#Escape(l:autoload)
\ : ''
let l:level = ale#Var(a:buffer, 'php_phpstan_level')
let l:config_file_exists = ale#path#FindNearestFile(a:buffer, 'phpstan.neon')
if empty(l:level) && empty(l:config_file_exists)
" if no configuration file is found, then use 4 as a default level
let l:level = '4'
endif
let l:level_option = !empty(l:level)
\ ? ' -l ' . ale#Escape(l:level)
\ : '' \ : ''
let l:error_format = ale#semver#GTE(a:version, [0, 10, 3]) let l:error_format = ale#semver#GTE(a:version, [0, 10, 3])
\ ? ' --error-format raw' \ ? ' --error-format raw'
\ : ' --errorFormat raw' \ : ' --errorFormat raw'
return '%e analyze --no-progress' return '%e analyze -l'
\ . ale#Var(a:buffer, 'php_phpstan_level')
\ . l:error_format \ . l:error_format
\ . l:configuration_option \ . l:configuration_option
\ . l:autoload_option
\ . l:level_option
\ . ' %s' \ . ' %s'
endfunction endfunction
@@ -54,7 +35,7 @@ function! ale_linters#php#phpstan#Handle(buffer, lines) abort
call add(l:output, { call add(l:output, {
\ 'lnum': l:match[2] + 0, \ 'lnum': l:match[2] + 0,
\ 'text': l:match[3], \ 'text': l:match[3],
\ 'type': 'E', \ 'type': 'W',
\}) \})
endfor endfor

View File

@@ -1,91 +0,0 @@
" Author: Jesse Harris - https://github.com/zigford
" Description: This file adds support for powershell scripts synatax errors
call ale#Set('powershell_powershell_executable', 'pwsh')
function! ale_linters#powershell#powershell#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'powershell_powershell_executable')
endfunction
" Some powershell magic to show syntax errors without executing the script
" thanks to keith hill:
" https://rkeithhill.wordpress.com/2007/10/30/powershell-quicktip-preparsing-scripts-to-check-for-syntax-errors/
function! ale_linters#powershell#powershell#GetCommand(buffer) abort
let l:script = ['Param($Script);
\ trap {$_;continue} & {
\ $Contents = Get-Content -Path $Script;
\ $Contents = [string]::Join([Environment]::NewLine, $Contents);
\ [void]$ExecutionContext.InvokeCommand.NewScriptBlock($Contents);
\ };']
return ale#powershell#RunPowerShell(
\ a:buffer, 'powershell_powershell', l:script)
endfunction
" Parse powershell error output using regex into a list of dicts
function! ale_linters#powershell#powershell#Handle(buffer, lines) abort
let l:output = []
" Our 3 patterns we need to scrape the data for the dicts
let l:patterns = [
\ '\v^At line:(\d+) char:(\d+)',
\ '\v^(At|\+| )@!.*',
\ '\vFullyQualifiedErrorId : (\w+)',
\]
let l:matchcount = 0
for l:match in ale#util#GetMatches(a:lines, l:patterns)
" We want to work with 3 matches per syntax error
let l:matchcount = l:matchcount + 1
if l:matchcount == 1 || str2nr(l:match[1])
" First match consists of 2 capture groups, and
" can capture the line and col
if exists('l:item')
" We may be here because the last syntax
" didn't emit a code, and so only had 2
" matches
call add(l:output, l:item)
let l:matchcount = 1
endif
let l:item = {
\ 'lnum': str2nr(l:match[1]),
\ 'col': str2nr(l:match[2]),
\ 'type': 'E',
\}
elseif l:matchcount == 2
" Second match[0] grabs the full line in order
" to handles the text
let l:item['text'] = l:match[0]
else
" Final match handles the code, however
" powershell only emits 1 code for all errors
" so, we get the final code on the last error
" and loop over the previously added items to
" append the code we now know
call add(l:output, l:item)
unlet l:item
if len(l:match[1]) > 0
for l:i in l:output
let l:i['code'] = l:match[1]
endfor
endif
" Reset the matchcount so we can begin gathering
" matches for the next syntax error
let l:matchcount = 0
endif
endfor
return l:output
endfunction
call ale#linter#Define('powershell', {
\ 'name': 'powershell',
\ 'executable_callback': 'ale_linters#powershell#powershell#GetExecutable',
\ 'command_callback': 'ale_linters#powershell#powershell#GetCommand',
\ 'output_stream': 'stdout',
\ 'callback': 'ale_linters#powershell#powershell#Handle',
\})

View File

@@ -13,6 +13,37 @@ function! ale_linters#powershell#psscriptanalyzer#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'powershell_psscriptanalyzer_executable') return ale#Var(a:buffer, 'powershell_psscriptanalyzer_executable')
endfunction endfunction
" Write a powershell script to a temp file for execution
" return the command used to execute it
function! s:TemporaryPSScript(buffer, input) abort
let l:filename = 'script.ps1'
" Create a temp dir to house our temp .ps1 script
" a temp dir is needed as powershell needs the .ps1
" extension
let l:tempdir = ale#util#Tempname() . (has('win32') ? '\' : '/')
let l:tempscript = l:tempdir . l:filename
" Create the temporary directory for the file, unreadable by 'other'
" users.
call mkdir(l:tempdir, '', 0750)
" Automatically delete the directory later.
call ale#command#ManageDirectory(a:buffer, l:tempdir)
" Write the script input out to a file.
call ale#util#Writefile(a:buffer, a:input, l:tempscript)
return l:tempscript
endfunction
function! ale_linters#powershell#psscriptanalyzer#RunPowerShell(buffer, command) abort
let l:executable = ale_linters#powershell#psscriptanalyzer#GetExecutable(
\ a:buffer)
let l:tempscript = s:TemporaryPSScript(a:buffer, a:command)
return ale#Escape(l:executable)
\ . ' -Exe Bypass -NoProfile -File '
\ . ale#Escape(l:tempscript)
\ . ' %t'
endfunction
" Run Invoke-ScriptAnalyzer and output each linting message as 4 seperate lines " Run Invoke-ScriptAnalyzer and output each linting message as 4 seperate lines
" for each parsing " for each parsing
function! ale_linters#powershell#psscriptanalyzer#GetCommand(buffer) abort function! ale_linters#powershell#psscriptanalyzer#GetCommand(buffer) abort
@@ -29,10 +60,8 @@ function! ale_linters#powershell#psscriptanalyzer#GetCommand(buffer) abort
\ $_.Message; \ $_.Message;
\ $_.RuleName}'] \ $_.RuleName}']
return ale#powershell#RunPowerShell( return ale_linters#powershell#psscriptanalyzer#RunPowerShell(
\ a:buffer, \ a:buffer, l:script)
\ 'powershell_psscriptanalyzer',
\ l:script)
endfunction endfunction
" add every 4 lines to an item(Dict) and every item to a list " add every 4 lines to an item(Dict) and every item to a list
@@ -69,8 +98,8 @@ endfunction
call ale#linter#Define('powershell', { call ale#linter#Define('powershell', {
\ 'name': 'psscriptanalyzer', \ 'name': 'psscriptanalyzer',
\ 'executable': function('ale_linters#powershell#psscriptanalyzer#GetExecutable'), \ 'executable_callback': 'ale_linters#powershell#psscriptanalyzer#GetExecutable',
\ 'command': function('ale_linters#powershell#psscriptanalyzer#GetCommand'), \ 'command_callback': 'ale_linters#powershell#psscriptanalyzer#GetCommand',
\ 'output_stream': 'stdout', \ 'output_stream': 'stdout',
\ 'callback': 'ale_linters#powershell#psscriptanalyzer#Handle', \ 'callback': 'ale_linters#powershell#psscriptanalyzer#Handle',
\}) \})

View File

@@ -31,20 +31,6 @@ function! ale_linters#pug#puglint#GetCommand(buffer) abort
\ . ' -r inline %t' \ . ' -r inline %t'
endfunction endfunction
function! ale_linters#pug#puglint#Handle(buffer, lines) abort
for l:line in a:lines[:10]
if l:line =~# '^SyntaxError: '
return [{
\ 'lnum': 1,
\ 'text': 'puglint configuration error (type :ALEDetail for more information)',
\ 'detail': join(a:lines, "\n"),
\}]
endif
endfor
return ale#handlers#unix#HandleAsError(a:buffer, a:lines)
endfunction
call ale#linter#Define('pug', { call ale#linter#Define('pug', {
\ 'name': 'puglint', \ 'name': 'puglint',
\ 'executable': {b -> ale#node#FindExecutable(b, 'pug_puglint', [ \ 'executable': {b -> ale#node#FindExecutable(b, 'pug_puglint', [
@@ -52,5 +38,5 @@ call ale#linter#Define('pug', {
\ ])}, \ ])},
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'command': function('ale_linters#pug#puglint#GetCommand'), \ 'command': function('ale_linters#pug#puglint#GetCommand'),
\ 'callback': 'ale_linters#pug#puglint#Handle', \ 'callback': 'ale#handlers#unix#HandleAsError',
\}) \})

View File

@@ -6,7 +6,6 @@ call ale#Set('python_pylint_options', '')
call ale#Set('python_pylint_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_pylint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pylint_change_directory', 1) call ale#Set('python_pylint_change_directory', 1)
call ale#Set('python_pylint_auto_pipenv', 0) call ale#Set('python_pylint_auto_pipenv', 0)
call ale#Set('python_pylint_use_msg_id', 0)
function! ale_linters#python#pylint#GetExecutable(buffer) abort function! ale_linters#python#pylint#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pylint_auto_pipenv')) if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pylint_auto_pipenv'))
@@ -65,17 +64,11 @@ function! ale_linters#python#pylint#Handle(buffer, lines) abort
continue continue
endif endif
if ale#Var(a:buffer, 'python_pylint_use_msg_id') is# 1
let l:code_out = l:code
else
let l:code_out = l:match[4]
endif
call add(l:output, { call add(l:output, {
\ 'lnum': l:match[1] + 0, \ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 1, \ 'col': l:match[2] + 1,
\ 'text': l:match[5], \ 'text': l:match[5],
\ 'code': l:code_out, \ 'code': l:match[4],
\ 'type': l:code[:0] is# 'E' ? 'E' : 'W', \ 'type': l:code[:0] is# 'E' ? 'E' : 'W',
\}) \})
endfor endfor

View File

@@ -1,23 +0,0 @@
" Author: David Buchan-Swanson <github@deecewan.com>
" Description: Integrate ALE with reason-language-server.
call ale#Set('reason_ls_executable', '')
function! ale_linters#reason#ls#FindProjectRoot(buffer) abort
let l:reason_config = ale#path#FindNearestFile(a:buffer, 'bsconfig.json')
if !empty(l:reason_config)
return fnamemodify(l:reason_config, ':h')
endif
return ''
endfunction
call ale#linter#Define('reason', {
\ 'name': 'reason-language-server',
\ 'lsp': 'stdio',
\ 'executable': {buffer -> ale#Var(buffer, 'reason_ls_executable')},
\ 'command': '%e',
\ 'project_root': function('ale_linters#reason#ls#FindProjectRoot'),
\ 'language': 'reason',
\})

View File

@@ -2,7 +2,7 @@
" Description: A language server for Rust " Description: A language server for Rust
call ale#Set('rust_rls_executable', 'rls') call ale#Set('rust_rls_executable', 'rls')
call ale#Set('rust_rls_toolchain', '') call ale#Set('rust_rls_toolchain', 'nightly')
call ale#Set('rust_rls_config', {}) call ale#Set('rust_rls_config', {})
function! ale_linters#rust#rls#GetCommand(buffer) abort function! ale_linters#rust#rls#GetCommand(buffer) abort

View File

@@ -10,7 +10,6 @@ call ale#Set('sh_shellcheck_exclusions', get(g:, 'ale_linters_sh_shellcheck_excl
call ale#Set('sh_shellcheck_executable', 'shellcheck') call ale#Set('sh_shellcheck_executable', 'shellcheck')
call ale#Set('sh_shellcheck_dialect', 'auto') call ale#Set('sh_shellcheck_dialect', 'auto')
call ale#Set('sh_shellcheck_options', '') call ale#Set('sh_shellcheck_options', '')
call ale#Set('sh_shellcheck_change_directory', 1)
function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
let l:shell_type = ale#handlers#sh#GetShellType(a:buffer) let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
@@ -41,15 +40,12 @@ function! ale_linters#sh#shellcheck#GetCommand(buffer, version) abort
let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions') let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions')
let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect') let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect')
let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : '' let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : ''
let l:cd_string = ale#Var(a:buffer, 'sh_shellcheck_change_directory')
\ ? ale#path#BufferCdString(a:buffer)
\ : ''
if l:dialect is# 'auto' if l:dialect is# 'auto'
let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer) let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer)
endif endif
return l:cd_string return ale#path#BufferCdString(a:buffer)
\ . '%e' \ . '%e'
\ . (!empty(l:dialect) ? ' -s ' . l:dialect : '') \ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')

View File

@@ -1,13 +0,0 @@
" Author: Dan Loman <https://github.com/namolnad>
" Description: Support for sourcekit-lsp https://github.com/apple/sourcekit-lsp
call ale#Set('sourcekit_lsp_executable', 'sourcekit-lsp')
call ale#linter#Define('swift', {
\ 'name': 'sourcekitlsp',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'sourcekit_lsp_executable')},
\ 'command': '%e',
\ 'project_root': function('ale#swift#FindProjectRoot'),
\ 'language': 'swift',
\})

View File

@@ -1,49 +0,0 @@
" Author: Keith Maxwell <keith.maxwell@gmail.com>
" Description: terraform fmt to check for errors
call ale#Set('terraform_terraform_executable', 'terraform')
function! ale_linters#terraform#terraform#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'terraform_terraform_executable')
endfunction
function! ale_linters#terraform#terraform#GetCommand(buffer) abort
return ale#Escape(ale_linters#terraform#terraform#GetExecutable(a:buffer))
\ . ' fmt -no-color --check=true -'
endfunction
function! ale_linters#terraform#terraform#Handle(buffer, lines) abort
let l:head = '^Error running fmt: In <standard input>: '
let l:output = []
let l:patterns = [
\ l:head.'At \(\d\+\):\(\d\+\): \(.*\)$',
\ l:head.'\(.*\)$'
\]
for l:match in ale#util#GetMatches(a:lines, l:patterns)
if len(l:match[2]) > 0
call add(l:output, {
\ 'lnum': str2nr(l:match[1]),
\ 'col': str2nr(l:match[2]),
\ 'text': l:match[3],
\ 'type': 'E',
\})
else
call add(l:output, {
\ 'lnum': line('$'),
\ 'text': l:match[1],
\ 'type': 'E',
\})
endif
endfor
return l:output
endfunction
call ale#linter#Define('terraform', {
\ 'name': 'terraform',
\ 'output_stream': 'stderr',
\ 'executable': function('ale_linters#terraform#terraform#GetExecutable'),
\ 'command': function('ale_linters#terraform#terraform#GetCommand'),
\ 'callback': 'ale_linters#terraform#terraform#Handle',
\})

View File

@@ -1,21 +0,0 @@
" Author: Ricardo Liang <ricardoliang@gmail.com>
" Description: Texlab language server (Rust rewrite)
call ale#Set('tex_texlab_executable', 'texlab')
call ale#Set('tex_texlab_options', '')
function! ale_linters#tex#texlab#GetProjectRoot(buffer) abort
return ''
endfunction
function! ale_linters#tex#texlab#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'tex_texlab_options'))
endfunction
call ale#linter#Define('tex', {
\ 'name': 'texlab',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'tex_texlab_executable')},
\ 'command': function('ale_linters#tex#texlab#GetCommand'),
\ 'project_root': function('ale_linters#tex#texlab#GetProjectRoot'),
\})

View File

@@ -5,5 +5,5 @@ call ale#linter#Define('typescript', {
\ 'name': 'eslint', \ 'name': 'eslint',
\ 'executable': function('ale#handlers#eslint#GetExecutable'), \ 'executable': function('ale#handlers#eslint#GetExecutable'),
\ 'command': function('ale#handlers#eslint#GetCommand'), \ 'command': function('ale#handlers#eslint#GetCommand'),
\ 'callback': 'ale#handlers#eslint#HandleJSON', \ 'callback': 'ale#handlers#eslint#Handle',
\}) \})

View File

@@ -1,23 +0,0 @@
call ale#Set('typescript_xo_executable', 'xo')
call ale#Set('typescript_xo_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('typescript_xo_options', '')
function! ale_linters#typescript#xo#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'typescript_xo', [
\ 'node_modules/.bin/xo',
\])
endfunction
function! ale_linters#typescript#xo#GetCommand(buffer) abort
return ale#Escape(ale_linters#typescript#xo#GetExecutable(a:buffer))
\ . ale#Pad(ale#Var(a:buffer, 'typescript_xo_options'))
\ . ' --reporter json --stdin --stdin-filename %s'
endfunction
" xo uses eslint and the output format is the same
call ale#linter#Define('typescript', {
\ 'name': 'xo',
\ 'executable': function('ale_linters#typescript#xo#GetExecutable'),
\ 'command': function('ale_linters#typescript#xo#GetCommand'),
\ 'callback': 'ale#handlers#eslint#HandleJSON',
\})

View File

@@ -97,7 +97,7 @@ function! s:Lint(buffer, should_lint_file, timer_id) abort
" Apply ignore lists for linters only if needed. " Apply ignore lists for linters only if needed.
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore') let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp') let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
let l:linters = !empty(l:ignore_config) || l:disable_lsp let l:linters = !empty(l:ignore_config)
\ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config, l:disable_lsp) \ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config, l:disable_lsp)
\ : l:linters \ : l:linters
@@ -156,7 +156,7 @@ function! ale#Queue(delay, ...) abort
endif endif
endfunction endfunction
let s:current_ale_version = [2, 5, 0] let s:current_ale_version = [2, 4, 0]
" A function used to check for ALE features in files outside of the project. " A function used to check for ALE features in files outside of the project.
function! ale#Has(feature) abort function! ale#Has(feature) abort

View File

@@ -1,41 +0,0 @@
" Author: Andrew Lee <andrewl@mbda.fun>.
" Inspired by ale/gradle.vim by Michael Pardo <michael@michaelpardo.com>
" Description: Functions for working with Ant projects.
" Given a buffer number, find an Ant project root
function! ale#ant#FindProjectRoot(buffer) abort
let l:build_xml_path = ale#path#FindNearestFile(a:buffer, 'build.xml')
if !empty(l:build_xml_path)
return fnamemodify(l:build_xml_path, ':h')
endif
return ''
endfunction
" Given a buffer number, find the path to the `ant` executable. Returns an empty
" string if cannot find the executable.
function! ale#ant#FindExecutable(buffer) abort
if executable('ant')
return 'ant'
endif
return ''
endfunction
" Given a buffer number, build a command to print the classpath of the root
" project. Returns an empty string if cannot build the command.
function! ale#ant#BuildClasspathCommand(buffer) abort
let l:executable = ale#ant#FindExecutable(a:buffer)
let l:project_root = ale#ant#FindProjectRoot(a:buffer)
if !empty(l:executable) && !empty(l:project_root)
return ale#path#CdString(l:project_root)
\ . ale#Escape(l:executable)
\ . ' classpath'
\ . ' -S'
\ . ' -q'
endif
return ''
endfunction

View File

@@ -96,13 +96,6 @@ function! ale#assert#Fixer(expected_result) abort
AssertEqual a:expected_result, l:result AssertEqual a:expected_result, l:result
endfunction endfunction
function! ale#assert#FixerNotExecuted() abort
let l:buffer = bufnr('')
let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))[-1]
Assert empty(l:result), "The fixer will be executed when it shouldn't be"
endfunction
function! ale#assert#LinterNotExecuted() abort function! ale#assert#LinterNotExecuted() abort
let l:buffer = bufnr('') let l:buffer = bufnr('')
let l:linter = s:GetLinter() let l:linter = s:GetLinter()
@@ -165,7 +158,6 @@ endfunction
function! ale#assert#SetUpFixerTestCommands() abort function! ale#assert#SetUpFixerTestCommands() abort
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>) command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>) command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>)
command! -nargs=0 AssertFixerNotExecuted :call ale#assert#FixerNotExecuted()
endfunction endfunction
" A dummy function for making sure this module is loaded. " A dummy function for making sure this module is loaded.
@@ -324,8 +316,4 @@ function! ale#assert#TearDownFixerTest() abort
if exists(':AssertFixer') if exists(':AssertFixer')
delcommand AssertFixer delcommand AssertFixer
endif endif
if exists(':AssertFixerNotExecuted')
delcommand AssertFixerNotExecuted
endif
endfunction endfunction

View File

@@ -23,9 +23,27 @@ function! ale#c#GetBuildDirectory(buffer) abort
return l:build_dir return l:build_dir
endif endif
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer) return ale#path#Dirname(ale#c#FindCompileCommands(a:buffer))
endfunction
return ale#path#Dirname(l:json_file)
function! ale#c#FindProjectRoot(buffer) abort
for l:project_filename in g:__ale_c_project_filenames
let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
if !empty(l:full_path)
let l:path = fnamemodify(l:full_path, ':h')
" Correct .git path detection.
if fnamemodify(l:path, ':t') is# '.git'
let l:path = fnamemodify(l:path, ':h')
endif
return l:path
endif
endfor
return ''
endfunction endfunction
function! ale#c#AreSpecialCharsBalanced(option) abort function! ale#c#AreSpecialCharsBalanced(option) abort
@@ -102,7 +120,7 @@ endfunction
function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
if !g:ale_c_parse_makefile if !g:ale_c_parse_makefile
return v:null return ''
endif endif
let l:buffer_filename = expand('#' . a:buffer . ':t') let l:buffer_filename = expand('#' . a:buffer . ':t')
@@ -122,17 +140,14 @@ function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
return ale#c#ParseCFlags(l:makefile_dir, l:cflag_line) return ale#c#ParseCFlags(l:makefile_dir, l:cflag_line)
endfunction endfunction
" Given a buffer number, find the project directory containing " Given a buffer number, find the build subdirectory with compile commands
" compile_commands.json, and the path to the compile_commands.json file. " The subdirectory is returned without the trailing /
"
" If compile_commands.json cannot be found, two empty strings will be
" returned.
function! ale#c#FindCompileCommands(buffer) abort function! ale#c#FindCompileCommands(buffer) abort
" Look above the current source file to find compile_commands.json " Look above the current source file to find compile_commands.json
let l:json_file = ale#path#FindNearestFile(a:buffer, 'compile_commands.json') let l:json_file = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
if !empty(l:json_file) if !empty(l:json_file)
return [fnamemodify(l:json_file, ':h'), l:json_file] return l:json_file
endif endif
" Search in build directories if we can't find it in the project. " Search in build directories if we can't find it in the project.
@@ -142,42 +157,12 @@ function! ale#c#FindCompileCommands(buffer) abort
let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json' let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json'
if filereadable(l:json_file) if filereadable(l:json_file)
return [l:path, l:json_file] return l:json_file
endif endif
endfor endfor
endfor endfor
return ['', ''] return ''
endfunction
" Find the project root for C/C++ projects.
"
" The location of compile_commands.json will be used to find project roots.
"
" If compile_commands.json cannot be found, other common configuration files
" will be used to detect the project root.
function! ale#c#FindProjectRoot(buffer) abort
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
" Fall back on detecting the project root based on other filenames.
if empty(l:root)
for l:project_filename in g:__ale_c_project_filenames
let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
if !empty(l:full_path)
let l:path = fnamemodify(l:full_path, ':h')
" Correct .git path detection.
if fnamemodify(l:path, ':t') is# '.git'
let l:path = fnamemodify(l:path, ':h')
endif
return l:path
endif
endfor
endif
return l:root
endfunction endfunction
" Cache compile_commands.json data in a Dictionary, so we don't need to read " Cache compile_commands.json data in a Dictionary, so we don't need to read
@@ -209,14 +194,10 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
let l:raw_data = [] let l:raw_data = []
silent! let l:raw_data = json_decode(join(readfile(a:compile_commands_file), '')) silent! let l:raw_data = json_decode(join(readfile(a:compile_commands_file), ''))
if type(l:raw_data) isnot v:t_list
let l:raw_data = []
endif
let l:file_lookup = {} let l:file_lookup = {}
let l:dir_lookup = {} let l:dir_lookup = {}
for l:entry in (type(l:raw_data) is v:t_list ? l:raw_data : []) for l:entry in l:raw_data
let l:basename = tolower(fnamemodify(l:entry.file, ':t')) let l:basename = tolower(fnamemodify(l:entry.file, ':t'))
let l:file_lookup[l:basename] = get(l:file_lookup, l:basename, []) + [l:entry] let l:file_lookup[l:basename] = get(l:file_lookup, l:basename, []) + [l:entry]
@@ -238,32 +219,9 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
" Search for an exact file match first. " Search for an exact file match first.
let l:basename = tolower(expand('#' . a:buffer . ':t')) let l:basename = tolower(expand('#' . a:buffer . ':t'))
let l:file_list = get(a:file_lookup, l:basename, []) let l:file_list = get(a:file_lookup, l:basename, [])
" A source file matching the header filename.
let l:source_file = ''
if empty(l:file_list) && l:basename =~? '\.h$\|\.hpp$'
for l:suffix in ['.c', '.cpp']
let l:key = fnamemodify(l:basename, ':r') . l:suffix
let l:file_list = get(a:file_lookup, l:key, [])
if !empty(l:file_list)
let l:source_file = l:key
break
endif
endfor
endif
for l:item in l:file_list for l:item in l:file_list
" Load the flags for this file, or for a source file matching the if bufnr(l:item.file) is a:buffer && has_key(l:item, 'command')
" header file.
if has_key(l:item, 'command')
\&& (
\ bufnr(l:item.file) is a:buffer
\ || (
\ !empty(l:source_file)
\ && l:item.file[-len(l:source_file):] is? l:source_file
\ )
\)
return ale#c#ParseCFlags(l:item.directory, l:item.command) return ale#c#ParseCFlags(l:item.directory, l:item.command)
endif endif
endfor endfor
@@ -293,25 +251,25 @@ function! ale#c#FlagsFromCompileCommands(buffer, compile_commands_file) abort
endfunction endfunction
function! ale#c#GetCFlags(buffer, output) abort function! ale#c#GetCFlags(buffer, output) abort
let l:cflags = v:null let l:cflags = ' '
if ale#Var(a:buffer, 'c_parse_makefile') && !empty(a:output) if ale#Var(a:buffer, 'c_parse_makefile') && !empty(a:output)
let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output) let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output)
endif endif
if ale#Var(a:buffer, 'c_parse_compile_commands') if ale#Var(a:buffer, 'c_parse_compile_commands')
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer) let l:json_file = ale#c#FindCompileCommands(a:buffer)
if !empty(l:json_file) if !empty(l:json_file)
let l:cflags = ale#c#FlagsFromCompileCommands(a:buffer, l:json_file) let l:cflags = ale#c#FlagsFromCompileCommands(a:buffer, l:json_file)
endif endif
endif endif
if l:cflags is v:null if l:cflags is# ' '
let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer)) let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))
endif endif
return l:cflags isnot v:null ? l:cflags : '' return l:cflags
endfunction endfunction
function! ale#c#GetMakeCommand(buffer) abort function! ale#c#GetMakeCommand(buffer) abort

View File

@@ -159,20 +159,18 @@ function! ale#completion#Filter(buffer, filetype, suggestions, prefix) abort
endfunction endfunction
function! s:ReplaceCompletionOptions() abort function! s:ReplaceCompletionOptions() abort
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '') " Remember the old omnifunc value, if there is one.
" If we don't store an old one, we'll just never reset the option.
if l:source is# 'ale-automatic' || l:source is# 'ale-manual' " This will stop some random exceptions from appearing.
" Remember the old omnifunc value, if there is one. if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc)
" If we don't store an old one, we'll just never reset the option. let b:ale_old_omnifunc = &l:omnifunc
" This will stop some random exceptions from appearing.
if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc)
let b:ale_old_omnifunc = &l:omnifunc
endif
let &l:omnifunc = 'ale#completion#AutomaticOmniFunc'
endif endif
if l:source is# 'ale-automatic' let &l:omnifunc = 'ale#completion#OmniFunc'
let l:info = get(b:, 'ale_completion_info', {})
if !get(l:info, 'manual')
if !exists('b:ale_old_completeopt') if !exists('b:ale_old_completeopt')
let b:ale_old_completeopt = &l:completeopt let b:ale_old_completeopt = &l:completeopt
endif endif
@@ -201,65 +199,47 @@ function! ale#completion#RestoreCompletionOptions() abort
endif endif
endfunction endfunction
function! ale#completion#GetCompletionPosition() abort function! ale#completion#OmniFunc(findstart, base) abort
if !exists('b:ale_completion_info')
return 0
endif
let l:line = b:ale_completion_info.line
let l:column = b:ale_completion_info.column
let l:regex = s:GetFiletypeValue(s:omni_start_map, &filetype)
let l:up_to_column = getline(l:line)[: l:column - 2]
let l:match = matchstr(l:up_to_column, l:regex)
return l:column - len(l:match) - 1
endfunction
function! ale#completion#GetCompletionResult() abort
if exists('b:ale_completion_result')
return b:ale_completion_result
endif
return v:null
endfunction
function! ale#completion#AutomaticOmniFunc(findstart, base) abort
if a:findstart if a:findstart
return ale#completion#GetCompletionPosition() let l:line = b:ale_completion_info.line
let l:column = b:ale_completion_info.column
let l:regex = s:GetFiletypeValue(s:omni_start_map, &filetype)
let l:up_to_column = getline(l:line)[: l:column - 2]
let l:match = matchstr(l:up_to_column, l:regex)
return l:column - len(l:match) - 1
else else
let l:result = ale#completion#GetCompletionResult() " Parse a new response if there is one.
if exists('b:ale_completion_response')
\&& exists('b:ale_completion_parser')
let l:response = b:ale_completion_response
let l:parser = b:ale_completion_parser
unlet b:ale_completion_response
unlet b:ale_completion_parser
let b:ale_completion_result = function(l:parser)(l:response)
endif
call s:ReplaceCompletionOptions() call s:ReplaceCompletionOptions()
return l:result isnot v:null ? l:result : [] return get(b:, 'ale_completion_result', [])
endif endif
endfunction endfunction
function! ale#completion#Show(result) abort function! ale#completion#Show(response, completion_parser) abort
if ale#util#Mode() isnot# 'i' if ale#util#Mode() isnot# 'i'
return return
endif endif
" Set the list in the buffer, temporarily replace omnifunc with our " Set the list in the buffer, temporarily replace omnifunc with our
" function, and then start omni-completion. " function, and then start omni-completion.
let b:ale_completion_result = a:result let b:ale_completion_response = a:response
let b:ale_completion_parser = a:completion_parser
" Don't try to open the completion menu if there's nothing to show.
if empty(b:ale_completion_result)
return
endif
" Replace completion options shortly before opening the menu. " Replace completion options shortly before opening the menu.
call s:ReplaceCompletionOptions() call s:ReplaceCompletionOptions()
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '') call timer_start(0, {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")})
if l:source is# 'ale-automatic' || l:source is# 'ale-manual'
call timer_start(
\ 0,
\ {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")}
\)
endif
endfunction endfunction
function! s:CompletionStillValid(request_id) abort function! s:CompletionStillValid(request_id) abort
@@ -269,11 +249,7 @@ function! s:CompletionStillValid(request_id) abort
\&& has_key(b:, 'ale_completion_info') \&& has_key(b:, 'ale_completion_info')
\&& b:ale_completion_info.request_id == a:request_id \&& b:ale_completion_info.request_id == a:request_id
\&& b:ale_completion_info.line == l:line \&& b:ale_completion_info.line == l:line
\&& ( \&& b:ale_completion_info.column == l:column
\ b:ale_completion_info.column == l:column
\ || b:ale_completion_info.source is# 'deoplete'
\ || b:ale_completion_info.source is# 'ale-omnifunc'
\)
endfunction endfunction
function! ale#completion#ParseTSServerCompletions(response) abort function! ale#completion#ParseTSServerCompletions(response) abort
@@ -380,8 +356,6 @@ function! ale#completion#ParseLSPCompletions(response) abort
if get(l:item, 'insertTextFormat') is s:LSP_INSERT_TEXT_FORMAT_PLAIN if get(l:item, 'insertTextFormat') is s:LSP_INSERT_TEXT_FORMAT_PLAIN
\&& type(get(l:item, 'textEdit')) is v:t_dict \&& type(get(l:item, 'textEdit')) is v:t_dict
let l:text = l:item.textEdit.newText let l:text = l:item.textEdit.newText
elseif type(get(l:item, 'insertText')) is v:t_string
let l:text = l:item.insertText
else else
let l:text = l:item.label let l:text = l:item.label
endif endif
@@ -468,7 +442,8 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
endif endif
elseif l:command is# 'completionEntryDetails' elseif l:command is# 'completionEntryDetails'
call ale#completion#Show( call ale#completion#Show(
\ ale#completion#ParseTSServerCompletionEntryDetails(a:response), \ a:response,
\ 'ale#completion#ParseTSServerCompletionEntryDetails',
\) \)
endif endif
endfunction endfunction
@@ -480,7 +455,8 @@ function! ale#completion#HandleLSPResponse(conn_id, response) abort
endif endif
call ale#completion#Show( call ale#completion#Show(
\ ale#completion#ParseLSPCompletions(a:response), \ a:response,
\ 'ale#completion#ParseLSPCompletions',
\) \)
endfunction endfunction
@@ -521,7 +497,10 @@ function! s:OnReady(linter, lsp_details) abort
let l:message = ale#lsp#message#Completion( let l:message = ale#lsp#message#Completion(
\ l:buffer, \ l:buffer,
\ b:ale_completion_info.line, \ b:ale_completion_info.line,
\ b:ale_completion_info.column, \ min([
\ b:ale_completion_info.line_length,
\ b:ale_completion_info.column,
\ ]) + 1,
\ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix), \ ale#completion#GetTriggerCharacter(&filetype, b:ale_completion_info.prefix),
\) \)
endif endif
@@ -538,28 +517,15 @@ function! s:OnReady(linter, lsp_details) abort
endif endif
endfunction endfunction
" This function can be called to check if ALE can provide completion data for
" the current buffer. 1 will be returned if there's a potential source of
" completion data ALE can use, and 0 will be returned otherwise.
function! ale#completion#CanProvideCompletions() abort
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
return 1
endif
endfor
return 0
endfunction
" This function can be used to manually trigger autocomplete, even when " This function can be used to manually trigger autocomplete, even when
" g:ale_completion_enabled is set to false " g:ale_completion_enabled is set to false
function! ale#completion#GetCompletions(source) abort function! ale#completion#GetCompletions(manual) abort
let [l:line, l:column] = getpos('.')[1:2] let [l:line, l:column] = getpos('.')[1:2]
let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column) let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
if a:source is# 'ale-automatic' && empty(l:prefix) if !a:manual && empty(l:prefix)
return 0 return
endif endif
let l:line_length = len(getline('.')) let l:line_length = len(getline('.'))
@@ -571,51 +537,21 @@ function! ale#completion#GetCompletions(source) abort
\ 'prefix': l:prefix, \ 'prefix': l:prefix,
\ 'conn_id': 0, \ 'conn_id': 0,
\ 'request_id': 0, \ 'request_id': 0,
\ 'source': a:source, \ 'manual': a:manual,
\} \}
unlet! b:ale_completion_result
let l:buffer = bufnr('') let l:buffer = bufnr('')
let l:Callback = function('s:OnReady') let l:Callback = function('s:OnReady')
let l:started = 0
for l:linter in ale#linter#Get(&filetype) for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp) if !empty(l:linter.lsp)
if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback) call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
let l:started = 1
endif
endif endif
endfor endfor
return l:started
endfunction
function! ale#completion#OmniFunc(findstart, base) abort
if a:findstart
let l:started = ale#completion#GetCompletions('ale-omnifunc')
if !l:started
" This is the special value for cancelling completions silently.
" See :help complete-functions
return -3
endif
return ale#completion#GetCompletionPosition()
else
let l:result = ale#completion#GetCompletionResult()
while l:result is v:null && !complete_check()
sleep 2ms
let l:result = ale#completion#GetCompletionResult()
endwhile
return l:result isnot v:null ? l:result : []
endif
endfunction endfunction
function! s:TimerHandler(...) abort function! s:TimerHandler(...) abort
if !get(b:, 'ale_completion_enabled', g:ale_completion_enabled) if !g:ale_completion_enabled
return return
endif endif
@@ -626,7 +562,7 @@ function! s:TimerHandler(...) abort
" When running the timer callback, we have to be sure that the cursor " When running the timer callback, we have to be sure that the cursor
" hasn't moved from where it was when we requested completions by typing. " hasn't moved from where it was when we requested completions by typing.
if s:timer_pos == [l:line, l:column] && ale#util#Mode() is# 'i' if s:timer_pos == [l:line, l:column] && ale#util#Mode() is# 'i'
call ale#completion#GetCompletions('ale-automatic') call ale#completion#GetCompletions(0)
endif endif
endfunction endfunction
@@ -640,7 +576,7 @@ function! ale#completion#StopTimer() abort
endfunction endfunction
function! ale#completion#Queue() abort function! ale#completion#Queue() abort
if !get(b:, 'ale_completion_enabled', g:ale_completion_enabled) if !g:ale_completion_enabled
return return
endif endif

View File

@@ -238,12 +238,6 @@ function! ale#debugging#Info() abort
endfunction endfunction
function! ale#debugging#InfoToClipboard() abort function! ale#debugging#InfoToClipboard() abort
if !has('clipboard')
call s:Echo('clipboard not available. Try :ALEInfoToFile instead.')
return
endif
redir => l:output redir => l:output
silent call ale#debugging#Info() silent call ale#debugging#Info()
redir END redir END

View File

@@ -3,9 +3,6 @@
let s:go_to_definition_map = {} let s:go_to_definition_map = {}
" Enable automatic updates of the tagstack
let g:ale_update_tagstack = get(g:, 'ale_update_tagstack', 1)
" Used to get the definition map in tests. " Used to get the definition map in tests.
function! ale#definition#GetMap() abort function! ale#definition#GetMap() abort
return deepcopy(s:go_to_definition_map) return deepcopy(s:go_to_definition_map)
@@ -20,20 +17,6 @@ function! ale#definition#ClearLSPData() abort
let s:go_to_definition_map = {} let s:go_to_definition_map = {}
endfunction endfunction
function! ale#definition#UpdateTagStack() abort
let l:should_update_tagstack = exists('*gettagstack') && exists('*settagstack') && g:ale_update_tagstack
if l:should_update_tagstack
" Grab the old location (to jump back to) and the word under the
" cursor (as a label for the tagstack)
let l:old_location = [bufnr('%'), line('.'), col('.'), 0]
let l:tagname = expand('<cword>')
let l:winid = win_getid()
call settagstack(l:winid, {'items': [{'from': l:old_location, 'tagname': l:tagname}]}, 'a')
call settagstack(l:winid, {'curidx': len(gettagstack(l:winid)['items']) + 1})
endif
endfunction
function! ale#definition#HandleTSServerResponse(conn_id, response) abort function! ale#definition#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') is# 'definition' if get(a:response, 'command', '') is# 'definition'
\&& has_key(s:go_to_definition_map, a:response.request_seq) \&& has_key(s:go_to_definition_map, a:response.request_seq)
@@ -44,7 +27,6 @@ function! ale#definition#HandleTSServerResponse(conn_id, response) abort
let l:line = a:response.body[0].start.line let l:line = a:response.body[0].start.line
let l:column = a:response.body[0].start.offset let l:column = a:response.body[0].start.offset
call ale#definition#UpdateTagStack()
call ale#util#Open(l:filename, l:line, l:column, l:options) call ale#util#Open(l:filename, l:line, l:column, l:options)
endif endif
endif endif
@@ -69,7 +51,6 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
let l:line = l:item.range.start.line + 1 let l:line = l:item.range.start.line + 1
let l:column = l:item.range.start.character + 1 let l:column = l:item.range.start.character + 1
call ale#definition#UpdateTagStack()
call ale#util#Open(l:filename, l:line, l:column, l:options) call ale#util#Open(l:filename, l:line, l:column, l:options)
break break
endfor endfor

View File

@@ -710,10 +710,6 @@ function! ale#engine#Cleanup(buffer) abort
return return
endif endif
if exists('*ale#lsp#CloseDocument')
call ale#lsp#CloseDocument(a:buffer)
endif
if !has_key(g:ale_buffer_info, a:buffer) if !has_key(g:ale_buffer_info, a:buffer)
return return
endif endif

View File

@@ -128,7 +128,7 @@ function! ale#events#Init() abort
endif endif
if g:ale_lint_on_insert_leave if g:ale_lint_on_insert_leave
autocmd InsertLeave * if ale#Var(str2nr(expand('<abuf>')), 'lint_on_insert_leave') | call ale#Queue(0) | endif autocmd InsertLeave * call ale#Queue(0)
endif endif
if g:ale_echo_cursor || g:ale_cursor_detail if g:ale_echo_cursor || g:ale_cursor_detail

View File

@@ -1,61 +1,45 @@
call ale#Set('fix_on_save_ignore', {})
" Apply fixes queued up for buffers which may be hidden. " Apply fixes queued up for buffers which may be hidden.
" Vim doesn't let you modify hidden buffers. " Vim doesn't let you modify hidden buffers.
function! ale#fix#ApplyQueuedFixes(buffer) abort function! ale#fix#ApplyQueuedFixes() abort
let l:data = get(g:ale_fix_buffer_data, a:buffer, {'done': 0}) let l:buffer = bufnr('')
let l:has_bufline_api = exists('*deletebufline') && exists('*setbufline') let l:data = get(g:ale_fix_buffer_data, l:buffer, {'done': 0})
if !l:data.done || (!l:has_bufline_api && a:buffer isnot bufnr('')) if !l:data.done
return return
endif endif
call remove(g:ale_fix_buffer_data, a:buffer) call remove(g:ale_fix_buffer_data, l:buffer)
if l:data.changes_made if l:data.changes_made
let l:start_line = len(l:data.output) + 1
let l:end_line = len(l:data.lines_before)
if l:end_line >= l:start_line
let l:save = winsaveview()
silent execute l:start_line . ',' . l:end_line . 'd_'
call winrestview(l:save)
endif
" If the file is in DOS mode, we have to remove carriage returns from " If the file is in DOS mode, we have to remove carriage returns from
" the ends of lines before calling setline(), or we will see them " the ends of lines before calling setline(), or we will see them
" twice. " twice.
let l:new_lines = getbufvar(a:buffer, '&fileformat') is# 'dos' let l:lines_to_set = getbufvar(l:buffer, '&fileformat') is# 'dos'
\ ? map(copy(l:data.output), 'substitute(v:val, ''\r\+$'', '''', '''')') \ ? map(copy(l:data.output), 'substitute(v:val, ''\r\+$'', '''', '''')')
\ : l:data.output \ : l:data.output
let l:first_line_to_remove = len(l:new_lines) + 1
" Use a Vim API for setting lines in other buffers, if available. call setline(1, l:lines_to_set)
if l:has_bufline_api
call setbufline(a:buffer, 1, l:new_lines)
call deletebufline(a:buffer, l:first_line_to_remove, '$')
" Fall back on setting lines the old way, for the current buffer.
else
let l:old_line_length = len(l:data.lines_before)
if l:old_line_length >= l:first_line_to_remove
let l:save = winsaveview()
silent execute
\ l:first_line_to_remove . ',' . l:old_line_length . 'd_'
call winrestview(l:save)
endif
call setline(1, l:new_lines)
endif
if l:data.should_save if l:data.should_save
if a:buffer is bufnr('') if empty(&buftype)
if empty(&buftype) noautocmd :w!
noautocmd :w!
else
set nomodified
endif
else else
call writefile(l:new_lines, expand(a:buffer . ':p')) " no-custom-checks set nomodified
call setbufvar(a:buffer, '&modified', 0)
endif endif
endif endif
endif endif
if l:data.should_save if l:data.should_save
let l:should_lint = ale#Var(a:buffer, 'fix_on_save') let l:should_lint = g:ale_fix_on_save
\ && ale#Var(a:buffer, 'lint_on_save')
else else
let l:should_lint = l:data.changes_made let l:should_lint = l:data.changes_made
endif endif
@@ -66,7 +50,7 @@ function! ale#fix#ApplyQueuedFixes(buffer) abort
" fixing problems. " fixing problems.
if g:ale_enabled if g:ale_enabled
\&& l:should_lint \&& l:should_lint
\&& !ale#events#QuitRecently(a:buffer) \&& !ale#events#QuitRecently(l:buffer)
call ale#Queue(0, l:data.should_save ? 'lint_file' : '') call ale#Queue(0, l:data.should_save ? 'lint_file' : '')
endif endif
endfunction endfunction
@@ -97,7 +81,7 @@ function! ale#fix#ApplyFixes(buffer, output) abort
" We can only change the lines of a buffer which is currently open, " We can only change the lines of a buffer which is currently open,
" so try and apply the fixes to the current buffer. " so try and apply the fixes to the current buffer.
call ale#fix#ApplyQueuedFixes(a:buffer) call ale#fix#ApplyQueuedFixes()
endfunction endfunction
function! s:HandleExit(job_info, buffer, job_output, data) abort function! s:HandleExit(job_info, buffer, job_output, data) abort
@@ -281,21 +265,7 @@ function! s:AddSubCallbacks(full_list, callbacks) abort
return 1 return 1
endfunction endfunction
function! s:IgnoreFixers(callback_list, filetype, config) abort function! s:GetCallbacks(buffer, fixers) abort
if type(a:config) is v:t_list
let l:ignore_list = a:config
else
let l:ignore_list = []
for l:part in split(a:filetype , '\.')
call extend(l:ignore_list, get(a:config, l:part, []))
endfor
endif
call filter(a:callback_list, 'index(l:ignore_list, v:val) < 0')
endfunction
function! s:GetCallbacks(buffer, fixing_flag, fixers) abort
if len(a:fixers) if len(a:fixers)
let l:callback_list = a:fixers let l:callback_list = a:fixers
elseif type(get(b:, 'ale_fixers')) is v:t_list elseif type(get(b:, 'ale_fixers')) is v:t_list
@@ -320,12 +290,8 @@ function! s:GetCallbacks(buffer, fixing_flag, fixers) abort
endif endif
endif endif
if a:fixing_flag is# 'save_file' if empty(l:callback_list)
let l:config = ale#Var(a:buffer, 'fix_on_save_ignore') return []
if !empty(l:config)
call s:IgnoreFixers(l:callback_list, &filetype, l:config)
endif
endif endif
let l:corrected_list = [] let l:corrected_list = []
@@ -373,7 +339,7 @@ function! ale#fix#Fix(buffer, fixing_flag, ...) abort
endif endif
try try
let l:callback_list = s:GetCallbacks(a:buffer, a:fixing_flag, a:000) let l:callback_list = s:GetCallbacks(a:buffer, a:000)
catch /E700\|BADNAME/ catch /E700\|BADNAME/
let l:function_name = join(split(split(v:exception, ':')[3])) let l:function_name = join(split(split(v:exception, ':')[3]))
let l:echo_message = printf( let l:echo_message = printf(
@@ -413,4 +379,5 @@ endfunction
" Set up an autocmd command to try and apply buffer fixes when available. " Set up an autocmd command to try and apply buffer fixes when available.
augroup ALEBufferFixGroup augroup ALEBufferFixGroup
autocmd! autocmd!
autocmd BufEnter * call ale#fix#ApplyQueuedFixes(str2nr(expand('<abuf>'))) autocmd BufEnter * call ale#fix#ApplyQueuedFixes()
augroup END

View File

@@ -27,11 +27,6 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'], \ 'suggested_filetypes': ['python'],
\ 'description': 'Fix PEP8 issues with black.', \ 'description': 'Fix PEP8 issues with black.',
\ }, \ },
\ 'fecs': {
\ 'function': 'ale#fixers#fecs#Fix',
\ 'suggested_filetypes': ['javascript', 'css', 'html'],
\ 'description': 'Apply fecs format to a file.',
\ },
\ 'tidy': { \ 'tidy': {
\ 'function': 'ale#fixers#tidy#Fix', \ 'function': 'ale#fixers#tidy#Fix',
\ 'suggested_filetypes': ['html'], \ 'suggested_filetypes': ['html'],
@@ -190,11 +185,6 @@ let s:default_registry = {
\ 'suggested_filetypes': ['hack'], \ 'suggested_filetypes': ['hack'],
\ 'description': 'Fix Hack files with hackfmt.', \ 'description': 'Fix Hack files with hackfmt.',
\ }, \ },
\ 'floskell': {
\ 'function': 'ale#fixers#floskell#Fix',
\ 'suggested_filetypes': ['haskell'],
\ 'description': 'Fix Haskell files with floskell.',
\ },
\ 'hfmt': { \ 'hfmt': {
\ 'function': 'ale#fixers#hfmt#Fix', \ 'function': 'ale#fixers#hfmt#Fix',
\ 'suggested_filetypes': ['haskell'], \ 'suggested_filetypes': ['haskell'],
@@ -220,11 +210,6 @@ let s:default_registry = {
\ 'suggested_filetypes': ['ocaml'], \ 'suggested_filetypes': ['ocaml'],
\ 'description': 'Fix OCaml files with ocamlformat.', \ 'description': 'Fix OCaml files with ocamlformat.',
\ }, \ },
\ 'ocp-indent': {
\ 'function': 'ale#fixers#ocp_indent#Fix',
\ 'suggested_filetypes': ['ocaml'],
\ 'description': 'Fix OCaml files with ocp-indent.',
\ },
\ 'refmt': { \ 'refmt': {
\ 'function': 'ale#fixers#refmt#Fix', \ 'function': 'ale#fixers#refmt#Fix',
\ 'suggested_filetypes': ['reason'], \ 'suggested_filetypes': ['reason'],
@@ -262,8 +247,8 @@ let s:default_registry = {
\ }, \ },
\ 'xo': { \ 'xo': {
\ 'function': 'ale#fixers#xo#Fix', \ 'function': 'ale#fixers#xo#Fix',
\ 'suggested_filetypes': ['javascript', 'typescript'], \ 'suggested_filetypes': ['javascript'],
\ 'description': 'Fix JavaScript/TypeScript files using xo --fix.', \ 'description': 'Fix JavaScript files using xo --fix.',
\ }, \ },
\ 'qmlfmt': { \ 'qmlfmt': {
\ 'function': 'ale#fixers#qmlfmt#Fix', \ 'function': 'ale#fixers#qmlfmt#Fix',
@@ -295,26 +280,6 @@ let s:default_registry = {
\ 'suggested_filetypes': ['kt'], \ 'suggested_filetypes': ['kt'],
\ 'description': 'Fix Kotlin files with ktlint.', \ 'description': 'Fix Kotlin files with ktlint.',
\ }, \ },
\ 'styler': {
\ 'function': 'ale#fixers#styler#Fix',
\ 'suggested_filetypes': ['r', 'rmarkdown'],
\ 'description': 'Fix R files with styler.',
\ },
\ 'latexindent': {
\ 'function': 'ale#fixers#latexindent#Fix',
\ 'suggested_filetypes': ['tex'],
\ 'description' : 'Indent code within environments, commands, after headings and within special code blocks.',
\ },
\ 'pgformatter': {
\ 'function': 'ale#fixers#pgformatter#Fix',
\ 'suggested_filetypes': ['sql'],
\ 'description': 'A PostgreSQL SQL syntax beautifier',
\ },
\ 'reorder-python-imports': {
\ 'function': 'ale#fixers#reorder_python_imports#Fix',
\ 'suggested_filetypes': ['python'],
\ 'description': 'Sort Python imports with reorder-python-imports.',
\ },
\} \}
" Reset the function registry to the default entries. " Reset the function registry to the default entries.

View File

@@ -35,18 +35,9 @@ endfunction
function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'javascript_eslint_options') let l:config = ale#handlers#eslint#FindConfig(a:buffer)
" Use the configuration file from the options, if configured. if empty(l:config)
if l:options =~# '\v(^| )-c|(^| )--config'
let l:config = ''
let l:has_config = 1
else
let l:config = ale#handlers#eslint#FindConfig(a:buffer)
let l:has_config = !empty(l:config)
endif
if !l:has_config
return 0 return 0
endif endif
@@ -54,7 +45,6 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0]) if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options)
\ . ' --stdin-filename %s --stdin --fix-to-stdout', \ . ' --stdin-filename %s --stdin --fix-to-stdout',
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
\} \}
@@ -64,7 +54,6 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
if ale#semver#GTE(a:version, [4, 9, 0]) if ale#semver#GTE(a:version, [4, 9, 0])
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options)
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
\} \}
@@ -72,8 +61,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . ' -c ' . ale#Escape(l:config)
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
\ . ' --fix %t', \ . ' --fix %t',
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\} \}

View File

@@ -1,17 +0,0 @@
" Author: harttle <yangjvn@126.com>
" Description: Apply fecs format to a file.
function! ale#fixers#fecs#Fix(buffer) abort
let l:executable = ale#handlers#fecs#GetExecutable(a:buffer)
if !executable(l:executable)
return 0
endif
let l:config_options = ' format --replace=true %t'
return {
\ 'command': ale#Escape(l:executable) . l:config_options,
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -1,20 +0,0 @@
" Author: robertjlooby <robertjlooby@gmail.com>
" Description: Integration of floskell with ALE.
call ale#Set('haskell_floskell_executable', 'floskell')
function! ale#fixers#floskell#GetExecutable(buffer) abort
let l:executable = ale#Var(a:buffer, 'haskell_floskell_executable')
return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'floskell')
endfunction
function! ale#fixers#floskell#Fix(buffer) abort
let l:executable = ale#fixers#floskell#GetExecutable(a:buffer)
return {
\ 'command': l:executable
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -1,18 +0,0 @@
" Author: riley-martine <riley.martine@protonmail.com>
" Description: Integration of latexindent with ALE.
call ale#Set('tex_latexindent_executable', 'latexindent')
call ale#Set('tex_latexindent_options', '')
function! ale#fixers#latexindent#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'tex_latexindent_executable')
let l:options = ale#Var(a:buffer, 'tex_latexindent_options')
return {
\ 'command': ale#Escape(l:executable)
\ . ' -l -w'
\ . (empty(l:options) ? '' : ' ' . l:options)
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -1,18 +0,0 @@
" Author: Kanenobu Mitsuru
" Description: Integration of ocp-indent with ALE.
call ale#Set('ocaml_ocp_indent_executable', 'ocp-indent')
call ale#Set('ocaml_ocp_indent_options', '')
call ale#Set('ocaml_ocp_indent_config', '')
function! ale#fixers#ocp_indent#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'ocaml_ocp_indent_executable')
let l:config = ale#Var(a:buffer, 'ocaml_ocp_indent_config')
let l:options = ale#Var(a:buffer, 'ocaml_ocp_indent_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (empty(l:config) ? '' : ' --config=' . ale#Escape(l:config))
\ . (empty(l:options) ? '': ' ' . l:options)
\}
endfunction

View File

@@ -1,12 +0,0 @@
call ale#Set('sql_pgformatter_executable', 'pg_format')
call ale#Set('sql_pgformatter_options', '')
function! ale#fixers#pgformatter#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'sql_pgformatter_executable')
let l:options = ale#Var(a:buffer, 'sql_pgformatter_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (empty(l:options) ? '' : ' ' . l:options),
\}
endfunction

View File

@@ -1,25 +0,0 @@
" Author: jake <me@jake.computer>
" Description: Fixing Python imports with reorder-python-imports.
call ale#Set('python_reorder_python_imports_executable', 'reorder-python-imports')
call ale#Set('python_reorder_python_imports_options', '')
call ale#Set('python_reorder_python_imports_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale#fixers#reorder_python_imports#Fix(buffer) abort
let l:executable = ale#python#FindExecutable(
\ a:buffer,
\ 'python_reorder_python_imports',
\ ['reorder-python-imports'],
\)
if !executable(l:executable)
return 0
endif
let l:options = ale#Var(a:buffer, 'python_reorder_python_imports_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '') . ' -',
\}
endfunction

View File

@@ -1,16 +0,0 @@
" Author: tvatter <thibault.vatter@gmail.com>
" Description: Fixing R files with styler.
call ale#Set('r_styler_executable', 'Rscript')
call ale#Set('r_styler_options', 'tidyverse_style')
function! ale#fixers#styler#Fix(buffer) abort
return {
\ 'command': 'Rscript --vanilla -e '
\ . '"suppressPackageStartupMessages(library(styler));'
\ . 'style_file(commandArgs(TRUE), style = '
\ . ale#Var(a:buffer, 'r_styler_options') . ')"'
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -3,17 +3,15 @@ scriptencoding utf-8
" Description: Utilities for ccls " Description: Utilities for ccls
function! ale#handlers#ccls#GetProjectRoot(buffer) abort function! ale#handlers#ccls#GetProjectRoot(buffer) abort
" Try to find ccls configuration files first. let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls-root')
let l:config = ale#path#FindNearestFile(a:buffer, '.ccls-root')
if empty(l:config) if empty(l:project_root)
let l:config = ale#path#FindNearestFile(a:buffer, '.ccls') let l:project_root = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
endif endif
if !empty(l:config) if empty(l:project_root)
return fnamemodify(l:config, ':h') let l:project_root = ale#path#FindNearestFile(a:buffer, '.ccls')
endif endif
" Fall back on default project root detection. return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : ''
return ale#c#FindProjectRoot(a:buffer)
endfunction endfunction

View File

@@ -1,46 +1,5 @@
" Description: Handle errors for cppcheck. " Description: Handle errors for cppcheck.
function! ale#handlers#cppcheck#GetCdCommand(buffer) abort
let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer)
let l:cd_command = !empty(l:dir) ? ale#path#CdString(l:dir) : ''
return l:cd_command
endfunction
function! ale#handlers#cppcheck#GetBufferPathIncludeOptions(buffer) abort
let l:buffer_path_include = ''
" Get path to this buffer so we can include it into cppcheck with -I
" This could be expanded to get more -I directives from the compile
" command in compile_commands.json, if it's found.
let l:buffer_path = fnamemodify(bufname(a:buffer), ':p:h')
let l:buffer_path_include = ' -I' . ale#Escape(l:buffer_path)
return l:buffer_path_include
endfunction
function! ale#handlers#cppcheck#GetCompileCommandsOptions(buffer) abort
" If the current buffer is modified, using compile_commands.json does no
" good, so include the file's directory instead. It's not quite as good as
" using --project, but is at least equivalent to running cppcheck on this
" file manually from the file's directory.
let l:modified = getbufvar(a:buffer, '&modified')
if l:modified
return ''
endif
" Search upwards from the file for compile_commands.json.
"
" If we find it, we'll `cd` to where the compile_commands.json file is,
" then use the file to set up import paths, etc.
let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer)
return !empty(l:json_path)
\ ? '--project=' . ale#Escape(l:json_path[len(l:dir) + 1: ])
\ : ''
endfunction
function! ale#handlers#cppcheck#HandleCppCheckFormat(buffer, lines) abort function! ale#handlers#cppcheck#HandleCppCheckFormat(buffer, lines) abort
" Look for lines like the following. " Look for lines like the following.
" "

View File

@@ -44,9 +44,16 @@ function! ale#handlers#eslint#GetCommand(buffer) abort
return ale#node#Executable(a:buffer, l:executable) return ale#node#Executable(a:buffer, l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -f json --stdin --stdin-filename %s' \ . ' -f unix --stdin --stdin-filename %s'
endfunction endfunction
let s:col_end_patterns = [
\ '\vParsing error: Unexpected token (.+) ?',
\ '\v''(.+)'' is not defined.',
\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]',
\ '\vUnexpected (console) statement',
\]
function! s:AddHintsForTypeScriptParsingErrors(output) abort function! s:AddHintsForTypeScriptParsingErrors(output) abort
for l:item in a:output for l:item in a:output
let l:item.text = substitute( let l:item.text = substitute(
@@ -83,71 +90,22 @@ function! s:CheckForBadConfig(buffer, lines) abort
return 0 return 0
endfunction endfunction
function! s:parseJSON(buffer, lines) abort function! ale#handlers#eslint#Handle(buffer, lines) abort
try if s:CheckForBadConfig(a:buffer, a:lines)
let l:parsed = json_decode(a:lines[-1]) return [{
catch \ 'lnum': 1,
return [] \ 'text': 'eslint configuration error (type :ALEDetail for more information)',
endtry \ 'detail': join(a:lines, "\n"),
\}]
if type(l:parsed) != v:t_list || empty(l:parsed)
return []
endif endif
let l:errors = l:parsed[0]['messages'] if a:lines == ['Could not connect']
return [{
if empty(l:errors) \ 'lnum': 1,
return [] \ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.',
\}]
endif endif
let l:output = []
for l:error in l:errors
let l:obj = ({
\ 'lnum': get(l:error, 'line', 0),
\ 'text': get(l:error, 'message', ''),
\ 'type': 'E',
\})
if get(l:error, 'severity', 0) is# 1
let l:obj.type = 'W'
endif
if has_key(l:error, 'ruleId')
let l:code = l:error['ruleId']
" Sometimes ESLint returns null here
if !empty(l:code)
let l:obj.code = l:code
endif
endif
if has_key(l:error, 'column')
let l:obj.col = l:error['column']
endif
if has_key(l:error, 'endColumn')
let l:obj.end_col = l:error['endColumn'] - 1
endif
if has_key(l:error, 'endLine')
let l:obj.end_lnum = l:error['endLine']
endif
call add(l:output, l:obj)
endfor
return l:output
endfunction
let s:col_end_patterns = [
\ '\vParsing error: Unexpected token (.+) ?',
\ '\v''(.+)'' is not defined.',
\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]',
\ '\vUnexpected (console) statement',
\]
function! s:parseLines(buffer, lines) abort
" Matches patterns line the following: " Matches patterns line the following:
" "
" /path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle] " /path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]
@@ -162,6 +120,12 @@ function! s:parseLines(buffer, lines) abort
for l:match in ale#util#GetMatches(a:lines, [l:pattern, l:parsing_pattern]) for l:match in ale#util#GetMatches(a:lines, [l:pattern, l:parsing_pattern])
let l:text = l:match[3] let l:text = l:match[3]
if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore')
if l:text =~# '^File ignored'
continue
endif
endif
let l:obj = { let l:obj = {
\ 'lnum': l:match[1] + 0, \ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0, \ 'col': l:match[2] + 0,
@@ -188,59 +152,9 @@ function! s:parseLines(buffer, lines) abort
call add(l:output, l:obj) call add(l:output, l:obj)
endfor endfor
return l:output
endfunction
function! s:FilterResult(buffer, obj) abort
if ale#Var(a:buffer, 'javascript_eslint_suppress_eslintignore')
if a:obj.text =~# '^File ignored'
return 0
endif
endif
if has_key(a:obj, 'code') && a:obj.code is# 'no-trailing-spaces'
\&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
return 0
endif
return 1
endfunction
function! s:HandleESLintOutput(buffer, lines, type) abort
if s:CheckForBadConfig(a:buffer, a:lines)
return [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(a:lines, "\n"),
\}]
endif
if a:lines == ['Could not connect']
return [{
\ 'lnum': 1,
\ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.',
\}]
endif
if a:type is# 'json'
let l:output = s:parseJSON(a:buffer, a:lines)
else
let l:output = s:parseLines(a:buffer, a:lines)
endif
call filter(l:output, {idx, obj -> s:FilterResult(a:buffer, obj)})
if expand('#' . a:buffer . ':t') =~? '\.tsx\?$' if expand('#' . a:buffer . ':t') =~? '\.tsx\?$'
call s:AddHintsForTypeScriptParsingErrors(l:output) call s:AddHintsForTypeScriptParsingErrors(l:output)
endif endif
return l:output return l:output
endfunction endfunction
function! ale#handlers#eslint#HandleJSON(buffer, lines) abort
return s:HandleESLintOutput(a:buffer, a:lines, 'json')
endfunction
function! ale#handlers#eslint#Handle(buffer, lines) abort
return s:HandleESLintOutput(a:buffer, a:lines, 'lines')
endfunction

View File

@@ -1,52 +0,0 @@
" Author: harttle <yangjvn@126.com>
" Description: fecs http://fecs.baidu.com/
call ale#Set('javascript_fecs_executable', 'fecs')
call ale#Set('javascript_fecs_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale#handlers#fecs#GetCommand(buffer) abort
return '%e check --colors=false --rule=true %t'
endfunction
function! ale#handlers#fecs#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_fecs', [
\ 'node_modules/.bin/fecs',
\ 'node_modules/fecs/bin/fecs',
\])
endfunction
function! ale#handlers#fecs#Handle(buffer, lines) abort
" Matches patterns looking like the following
"
" fecs WARN → line 20, col 25: Unexpected console statement. (no-console)
" fecs ERROR → line 24, col 36: Missing radix parameter. (radix)
"
let l:pattern = '\v^.*(WARN|ERROR)\s+→\s+line (\d+),\s+col\s+(\d+):\s+(.*)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:obj = {
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[4]
\}
let l:code_match = matchlist(l:match[4], '\v^(.{-})\s*\((.+)\)$')
if !empty(l:code_match)
let l:obj.code = l:code_match[2]
let l:obj.text = l:code_match[1]
endif
if l:match[1] is# 'WARN'
let l:obj.type = 'W'
elseif l:match[1] is# 'ERROR'
let l:obj.type = 'E'
endif
call add(l:output, l:obj)
endfor
return l:output
endfunction

View File

@@ -11,7 +11,6 @@ let s:pragma_error = '#pragma once in main file'
" <stdin>:10:27: error: invalid operands to binary - (have int and char *) " <stdin>:10:27: error: invalid operands to binary - (have int and char *)
" -:189:7: note: $/${} is unnecessary on arithmetic variables. [SC2004] " -:189:7: note: $/${} is unnecessary on arithmetic variables. [SC2004]
let s:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+)$' let s:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+)$'
let s:inline_pattern = '\v inlined from .* at \<stdin\>:(\d+):(\d+):$'
function! s:IsHeaderFile(filename) abort function! s:IsHeaderFile(filename) abort
return a:filename =~? '\v\.(h|hpp)$' return a:filename =~? '\v\.(h|hpp)$'
@@ -26,28 +25,6 @@ function! s:RemoveUnicodeQuotes(text) abort
return l:text return l:text
endfunction endfunction
function! s:ParseInlinedFunctionProblems(buffer, lines) abort
let l:output = []
let l:pos_match = []
for l:line in a:lines
let l:match = matchlist(l:line, s:pattern)
if !empty(l:match) && !empty(l:pos_match)
call add(l:output, {
\ 'lnum': str2nr(l:pos_match[1]),
\ 'col': str2nr(l:pos_match[2]),
\ 'type': (l:match[4] is# 'error' || l:match[4] is# 'fatal error') ? 'E' : 'W',
\ 'text': s:RemoveUnicodeQuotes(l:match[5]),
\})
endif
let l:pos_match = matchlist(l:line, s:inline_pattern)
endfor
return l:output
endfunction
" Report problems inside of header files just for gcc and clang " Report problems inside of header files just for gcc and clang
function! s:ParseProblemsInHeaders(buffer, lines) abort function! s:ParseProblemsInHeaders(buffer, lines) abort
let l:output = [] let l:output = []
@@ -152,7 +129,6 @@ endfunction
function! ale#handlers#gcc#HandleGCCFormatWithIncludes(buffer, lines) abort function! ale#handlers#gcc#HandleGCCFormatWithIncludes(buffer, lines) abort
let l:output = ale#handlers#gcc#HandleGCCFormat(a:buffer, a:lines) let l:output = ale#handlers#gcc#HandleGCCFormat(a:buffer, a:lines)
call extend(l:output, s:ParseInlinedFunctionProblems(a:buffer, a:lines))
call extend(l:output, s:ParseProblemsInHeaders(a:buffer, a:lines)) call extend(l:output, s:ParseProblemsInHeaders(a:buffer, a:lines))
return l:output return l:output

View File

@@ -56,20 +56,14 @@ function! ale#handlers#rust#HandleRustErrors(buffer, lines) abort
endif endif
if !empty(l:span) if !empty(l:span)
let l:output_line = { call add(l:output, {
\ 'lnum': l:span.line_start, \ 'lnum': l:span.line_start,
\ 'end_lnum': l:span.line_end, \ 'end_lnum': l:span.line_end,
\ 'col': l:span.column_start, \ 'col': l:span.column_start,
\ 'end_col': l:span.column_end-1, \ 'end_col': l:span.column_end-1,
\ 'text': empty(l:span.label) ? l:error.message : printf('%s: %s', l:error.message, l:span.label), \ 'text': empty(l:span.label) ? l:error.message : printf('%s: %s', l:error.message, l:span.label),
\ 'type': toupper(l:error.level[0]), \ 'type': toupper(l:error.level[0]),
\} \})
if has_key(l:error, 'rendered') && !empty(l:error.rendered)
let l:output_line.detail = l:error.rendered
endif
call add(l:output, l:output_line)
endif endif
endfor endfor
endfor endfor

View File

@@ -49,33 +49,14 @@ endfunction
" Given a loclist for current items to highlight, remove all highlights " Given a loclist for current items to highlight, remove all highlights
" except these which have matching loclist item entries. " except these which have matching loclist item entries.
function! ale#highlight#RemoveHighlights() abort function! ale#highlight#RemoveHighlights() abort
for l:match in getmatches() for l:match in getmatches()
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$' if l:match.group =~# '^ALE'
call matchdelete(l:match.id) call matchdelete(l:match.id)
endif endif
endfor endfor
endfunction endfunction
function! s:highlight_line(bufnr, lnum, group) abort
call matchaddpos(a:group, [a:lnum])
endfunction
function! s:highlight_range(bufnr, range, group) abort
" Set all of the positions, which are chunked into Lists which
" are as large as will be accepted by matchaddpos.
call map(
\ ale#highlight#CreatePositions(
\ a:range.lnum,
\ a:range.col,
\ a:range.end_lnum,
\ a:range.end_col
\ ),
\ 'matchaddpos(a:group, v:val)'
\)
endfunction
function! ale#highlight#UpdateHighlights() abort function! ale#highlight#UpdateHighlights() abort
let l:item_list = get(b:, 'ale_enabled', 1) && g:ale_enabled let l:item_list = get(b:, 'ale_enabled', 1) && g:ale_enabled
\ ? get(b:, 'ale_highlight_items', []) \ ? get(b:, 'ale_highlight_items', [])
@@ -98,14 +79,17 @@ function! ale#highlight#UpdateHighlights() abort
let l:group = 'ALEError' let l:group = 'ALEError'
endif endif
let l:range = { let l:line = l:item.lnum
\ 'lnum': l:item.lnum, let l:col = l:item.col
\ 'col': l:item.col, let l:end_line = get(l:item, 'end_lnum', l:line)
\ 'end_lnum': get(l:item, 'end_lnum', l:item.lnum), let l:end_col = get(l:item, 'end_col', l:col)
\ 'end_col': get(l:item, 'end_col', l:item.col)
\}
call s:highlight_range(l:item.bufnr, l:range, l:group) " Set all of the positions, which are chunked into Lists which
" are as large as will be accepted by matchaddpos.
call map(
\ ale#highlight#CreatePositions(l:line, l:col, l:end_line, l:end_col),
\ 'matchaddpos(l:group, v:val)'
\)
endfor endfor
" If highlights are enabled and signs are not enabled, we should still " If highlights are enabled and signs are not enabled, we should still
@@ -127,7 +111,7 @@ function! ale#highlight#UpdateHighlights() abort
endif endif
if l:available_groups[l:group] if l:available_groups[l:group]
call s:highlight_line(l:item.bufnr, l:item.lnum, l:group) call matchaddpos(l:group, [l:item.lnum])
endif endif
endfor endfor
endif endif

View File

@@ -16,11 +16,5 @@ function! ale#java#FindProjectRoot(buffer) abort
return fnamemodify(l:maven_pom_file, ':h') return fnamemodify(l:maven_pom_file, ':h')
endif endif
let l:ant_root = ale#ant#FindProjectRoot(a:buffer)
if !empty(l:ant_root)
return l:ant_root
endif
return '' return ''
endfunction endfunction

View File

@@ -13,13 +13,10 @@ let s:default_ale_linter_aliases = {
\ 'Dockerfile': 'dockerfile', \ 'Dockerfile': 'dockerfile',
\ 'csh': 'sh', \ 'csh': 'sh',
\ 'plaintex': 'tex', \ 'plaintex': 'tex',
\ 'rmarkdown': 'r',
\ 'systemverilog': 'verilog', \ 'systemverilog': 'verilog',
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'], \ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
\ 'vimwiki': 'markdown', \ 'vimwiki': 'markdown',
\ 'vue': ['vue', 'javascript'], \ 'vue': ['vue', 'javascript'],
\ 'xsd': ['xsd', 'xml'],
\ 'xslt': ['xslt', 'xml'],
\ 'zsh': 'sh', \ 'zsh': 'sh',
\} \}
@@ -358,14 +355,12 @@ function! ale#linter#Define(filetype, linter) abort
" This command will throw from the sandbox. " This command will throw from the sandbox.
let &l:equalprg=&l:equalprg let &l:equalprg=&l:equalprg
let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter)
if !has_key(s:linters, a:filetype) if !has_key(s:linters, a:filetype)
let s:linters[a:filetype] = [] let s:linters[a:filetype] = []
endif endif
" Remove previously defined linters with the same name. let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter)
call filter(s:linters[a:filetype], 'v:val.name isnot# a:linter.name')
call add(s:linters[a:filetype], l:new_linter) call add(s:linters[a:filetype], l:new_linter)
endfunction endfunction

View File

@@ -71,8 +71,8 @@ function! s:FixList(buffer, list) abort
return l:new_list return l:new_list
endfunction endfunction
function! s:WinFindBuf(buffer) abort function! s:BufWinId(buffer) abort
return exists('*win_findbuf') ? win_findbuf(str2nr(a:buffer)) : [0] return exists('*bufwinid') ? bufwinid(str2nr(a:buffer)) : 0
endfunction endfunction
function! s:SetListsImpl(timer_id, buffer, loclist) abort function! s:SetListsImpl(timer_id, buffer, loclist) abort
@@ -88,19 +88,17 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
call setqflist([], 'r', {'title': l:title}) call setqflist([], 'r', {'title': l:title})
endif endif
elseif g:ale_set_loclist elseif g:ale_set_loclist
" If windows support is off, win_findbuf() may not exist. " If windows support is off, bufwinid() may not exist.
" We'll set result in the current window, which might not be correct, " We'll set result in the current window, which might not be correct,
" but it's better than nothing. " but it's better than nothing.
let l:ids = s:WinFindBuf(a:buffer) let l:id = s:BufWinId(a:buffer)
for l:id in l:ids if has('nvim')
if has('nvim') call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title)
call setloclist(l:id, s:FixList(a:buffer, a:loclist), ' ', l:title) else
else call setloclist(l:id, s:FixList(a:buffer, a:loclist))
call setloclist(l:id, s:FixList(a:buffer, a:loclist)) call setloclist(l:id, [], 'r', {'title': l:title})
call setloclist(l:id, [], 'r', {'title': l:title}) endif
endif
endfor
endif endif
" Open a window to show the problems if we need to. " Open a window to show the problems if we need to.
@@ -183,13 +181,11 @@ function! s:CloseWindowIfNeeded(buffer) abort
cclose cclose
endif endif
else else
let l:win_ids = s:WinFindBuf(a:buffer) let l:win_id = s:BufWinId(a:buffer)
for l:win_id in l:win_ids if g:ale_set_loclist && empty(getloclist(l:win_id))
if g:ale_set_loclist && empty(getloclist(l:win_id)) lclose
lclose endif
endif
endfor
endif endif
" Ignore 'Cannot close last window' errors. " Ignore 'Cannot close last window' errors.
catch /E444/ catch /E444/

View File

@@ -111,7 +111,7 @@ function! ale#loclist_jumping#Jump(direction, ...) abort
if !empty(l:nearest) if !empty(l:nearest)
normal! m` normal! m`
call cursor([l:nearest[0], max([l:nearest[1], 1])]) call cursor(l:nearest)
endif endif
endfunction endfunction

View File

@@ -321,69 +321,7 @@ endfunction
function! s:SendInitMessage(conn) abort function! s:SendInitMessage(conn) abort
let [l:init_id, l:init_data] = ale#lsp#CreateMessageData( let [l:init_id, l:init_data] = ale#lsp#CreateMessageData(
\ ale#lsp#message#Initialize( \ ale#lsp#message#Initialize(a:conn.root, a:conn.init_options),
\ a:conn.root,
\ a:conn.init_options,
\ {
\ 'workspace': {
\ 'applyEdit': v:false,
\ 'didChangeConfiguration': {
\ 'dynamicRegistration': v:false,
\ },
\ 'symbol': {
\ 'dynamicRegistration': v:false,
\ },
\ 'workspaceFolders': v:false,
\ 'configuration': v:false,
\ },
\ 'textDocument': {
\ 'synchronization': {
\ 'dynamicRegistration': v:false,
\ 'willSave': v:false,
\ 'willSaveWaitUntil': v:false,
\ 'didSave': v:true,
\ },
\ 'completion': {
\ 'dynamicRegistration': v:false,
\ 'completionItem': {
\ 'snippetSupport': v:false,
\ 'commitCharactersSupport': v:false,
\ 'documentationFormat': ['plaintext'],
\ 'deprecatedSupport': v:false,
\ 'preselectSupport': v:false,
\ },
\ 'contextSupport': v:false,
\ },
\ 'hover': {
\ 'dynamicRegistration': v:false,
\ 'contentFormat': ['plaintext'],
\ },
\ 'references': {
\ 'dynamicRegistration': v:false,
\ },
\ 'documentSymbol': {
\ 'dynamicRegistration': v:false,
\ 'hierarchicalDocumentSymbolSupport': v:false,
\ },
\ 'definition': {
\ 'dynamicRegistration': v:false,
\ 'linkSupport': v:false,
\ },
\ 'typeDefinition': {
\ 'dynamicRegistration': v:false,
\ },
\ 'publishDiagnostics': {
\ 'relatedInformation': v:true,
\ },
\ 'codeAction': {
\ 'dynamicRegistration': v:false,
\ },
\ 'rename': {
\ 'dynamicRegistration': v:false,
\ },
\ },
\ },
\ ),
\) \)
let a:conn.init_request_id = l:init_id let a:conn.init_request_id = l:init_id
call s:SendMessageData(a:conn, l:init_data) call s:SendMessageData(a:conn, l:init_data)
@@ -546,35 +484,6 @@ function! ale#lsp#OpenDocument(conn_id, buffer, language_id) abort
return l:opened return l:opened
endfunction endfunction
" Notify LSP servers or tsserver that a document is closed, if opened before.
" If a document is closed, 1 will be returned, otherwise 0 will be returned.
"
" Only the buffer number is required here. A message will be sent to every
" language server that was notified previously of the document being opened.
function! ale#lsp#CloseDocument(buffer) abort
let l:closed = 0
" The connection keys are sorted so the messages are easier to test, and
" so messages are sent in a consistent order.
for l:conn_id in sort(keys(s:connections))
let l:conn = s:connections[l:conn_id]
if l:conn.initialized && has_key(l:conn.open_documents, a:buffer)
if l:conn.is_tsserver
let l:message = ale#lsp#tsserver_message#Close(a:buffer)
else
let l:message = ale#lsp#message#DidClose(a:buffer)
endif
call ale#lsp#Send(l:conn_id, l:message)
call remove(l:conn.open_documents, a:buffer)
let l:closed = 1
endif
endfor
return l:closed
endfunction
" Notify LSP servers or tsserver that a document has changed, if needed. " Notify LSP servers or tsserver that a document has changed, if needed.
" If a notification is sent, 1 will be returned, otherwise 0 will be returned. " If a notification is sent, 1 will be returned, otherwise 0 will be returned.
function! ale#lsp#NotifyForChanges(conn_id, buffer) abort function! ale#lsp#NotifyForChanges(conn_id, buffer) abort

View File

@@ -28,13 +28,14 @@ function! ale#lsp#message#GetNextVersionID() abort
return l:id return l:id
endfunction endfunction
function! ale#lsp#message#Initialize(root_path, options, capabilities) abort function! ale#lsp#message#Initialize(root_path, initialization_options) abort
" TODO: Define needed capabilities.
" NOTE: rootPath is deprecated in favour of rootUri " NOTE: rootPath is deprecated in favour of rootUri
return [0, 'initialize', { return [0, 'initialize', {
\ 'processId': getpid(), \ 'processId': getpid(),
\ 'rootPath': a:root_path, \ 'rootPath': a:root_path,
\ 'capabilities': a:capabilities, \ 'capabilities': {},
\ 'initializationOptions': a:options, \ 'initializationOptions': a:initialization_options,
\ 'rootUri': ale#path#ToURI(a:root_path), \ 'rootUri': ale#path#ToURI(a:root_path),
\}] \}]
endfunction endfunction

View File

@@ -28,7 +28,7 @@ function! ale#lsp#response#ReadDiagnostics(response) abort
for l:diagnostic in a:response.params.diagnostics for l:diagnostic in a:response.params.diagnostics
let l:severity = get(l:diagnostic, 'severity', 0) let l:severity = get(l:diagnostic, 'severity', 0)
let l:loclist_item = { let l:loclist_item = {
\ 'text': substitute(l:diagnostic.message, '\(\r\n\|\n\|\r\)', ' ', 'g'), \ 'text': l:diagnostic.message,
\ 'type': 'E', \ 'type': 'E',
\ 'lnum': l:diagnostic.range.start.line + 1, \ 'lnum': l:diagnostic.range.start.line + 1,
\ 'col': l:diagnostic.range.start.character + 1, \ 'col': l:diagnostic.range.start.character + 1,
@@ -90,7 +90,7 @@ function! ale#lsp#response#ReadTSServerDiagnostics(response) abort
\ 'lnum': l:diagnostic.start.line, \ 'lnum': l:diagnostic.start.line,
\ 'col': l:diagnostic.start.offset, \ 'col': l:diagnostic.start.offset,
\ 'end_lnum': l:diagnostic.end.line, \ 'end_lnum': l:diagnostic.end.line,
\ 'end_col': l:diagnostic.end.offset - 1, \ 'end_col': l:diagnostic.end.offset,
\} \}
if has_key(l:diagnostic, 'code') if has_key(l:diagnostic, 'code')

View File

@@ -8,16 +8,8 @@ if !has_key(s:, 'lsp_linter_map')
let s:lsp_linter_map = {} let s:lsp_linter_map = {}
endif endif
" A Dictionary to track one-shot handlers for custom LSP requests
let s:custom_handlers_map = get(s:, 'custom_handlers_map', {})
" Check if diagnostics for a particular linter should be ignored. " Check if diagnostics for a particular linter should be ignored.
function! s:ShouldIgnore(buffer, linter_name) abort function! s:ShouldIgnore(buffer, linter_name) abort
" Ignore all diagnostics if LSP integration is disabled.
if ale#Var(a:buffer, 'disable_lsp')
return 1
endif
let l:config = ale#Var(a:buffer, 'linters_ignore') let l:config = ale#Var(a:buffer, 'linters_ignore')
" Don't load code for ignoring diagnostics if there's nothing to ignore. " Don't load code for ignoring diagnostics if there's nothing to ignore.
@@ -34,13 +26,15 @@ endfunction
function! s:HandleLSPDiagnostics(conn_id, response) abort function! s:HandleLSPDiagnostics(conn_id, response) abort
let l:linter_name = s:lsp_linter_map[a:conn_id] let l:linter_name = s:lsp_linter_map[a:conn_id]
let l:filename = ale#path#FromURI(a:response.params.uri) let l:filename = ale#path#FromURI(a:response.params.uri)
let l:buffer = bufnr('^' . l:filename . '$') let l:buffer = bufnr(l:filename)
let l:info = get(g:ale_buffer_info, l:buffer, {}) let l:info = get(g:ale_buffer_info, l:buffer, {})
if empty(l:info) if empty(l:info)
return return
endif endif
call ale#engine#MarkLinterInactive(l:info, l:linter_name)
if s:ShouldIgnore(l:buffer, l:linter_name) if s:ShouldIgnore(l:buffer, l:linter_name)
return return
endif endif
@@ -52,7 +46,7 @@ endfunction
function! s:HandleTSServerDiagnostics(response, error_type) abort function! s:HandleTSServerDiagnostics(response, error_type) abort
let l:linter_name = 'tsserver' let l:linter_name = 'tsserver'
let l:buffer = bufnr('^' . a:response.body.file . '$') let l:buffer = bufnr(a:response.body.file)
let l:info = get(g:ale_buffer_info, l:buffer, {}) let l:info = get(g:ale_buffer_info, l:buffer, {})
if empty(l:info) if empty(l:info)
@@ -387,10 +381,6 @@ function! s:CheckWithLSP(linter, details) abort
if a:linter.lsp is# 'tsserver' if a:linter.lsp is# 'tsserver'
let l:message = ale#lsp#tsserver_message#Geterr(l:buffer) let l:message = ale#lsp#tsserver_message#Geterr(l:buffer)
let l:notified = ale#lsp#Send(l:id, l:message) != 0 let l:notified = ale#lsp#Send(l:id, l:message) != 0
if l:notified
call ale#engine#MarkLinterActive(l:info, a:linter)
endif
else else
let l:notified = ale#lsp#NotifyForChanges(l:id, l:buffer) let l:notified = ale#lsp#NotifyForChanges(l:id, l:buffer)
endif endif
@@ -401,6 +391,10 @@ function! s:CheckWithLSP(linter, details) abort
let l:save_message = ale#lsp#message#DidSave(l:buffer) let l:save_message = ale#lsp#message#DidSave(l:buffer)
let l:notified = ale#lsp#Send(l:id, l:save_message) != 0 let l:notified = ale#lsp#Send(l:id, l:save_message) != 0
endif endif
if l:notified
call ale#engine#MarkLinterActive(l:info, a:linter)
endif
endfunction endfunction
function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort
@@ -410,57 +404,9 @@ endfunction
" Clear LSP linter data for the linting engine. " Clear LSP linter data for the linting engine.
function! ale#lsp_linter#ClearLSPData() abort function! ale#lsp_linter#ClearLSPData() abort
let s:lsp_linter_map = {} let s:lsp_linter_map = {}
let s:custom_handlers_map = {}
endfunction endfunction
" Just for tests. " Just for tests.
function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
let s:lsp_linter_map = a:replacement_map let s:lsp_linter_map = a:replacement_map
endfunction endfunction
function! s:HandleLSPResponseToCustomRequests(conn_id, response) abort
if has_key(a:response, 'id')
\&& has_key(s:custom_handlers_map, a:response.id)
let l:Handler = remove(s:custom_handlers_map, a:response.id)
call l:Handler(a:response)
endif
endfunction
function! s:OnReadyForCustomRequests(args, linter, lsp_details) abort
let l:id = a:lsp_details.connection_id
let l:request_id = ale#lsp#Send(l:id, a:args.message)
if l:request_id > 0 && has_key(a:args, 'handler')
let l:Callback = function('s:HandleLSPResponseToCustomRequests')
call ale#lsp#RegisterCallback(l:id, l:Callback)
let s:custom_handlers_map[l:request_id] = a:args.handler
endif
endfunction
" Send a custom request to an LSP linter.
function! ale#lsp_linter#SendRequest(buffer, linter_name, message, ...) abort
let l:filetype = ale#linter#ResolveFiletype(getbufvar(a:buffer, '&filetype'))
let l:linter_list = ale#linter#GetAll(l:filetype)
let l:linter_list = filter(l:linter_list, {_, v -> v.name is# a:linter_name})
if len(l:linter_list) < 1
throw 'Linter "' . a:linter_name . '" not found!'
endif
let l:linter = l:linter_list[0]
if empty(l:linter.lsp)
throw 'Linter "' . a:linter_name . '" does not support LSP!'
endif
let l:is_notification = a:message[0]
let l:callback_args = {'message': a:message}
if !l:is_notification && a:0
let l:callback_args.handler = a:1
endif
let l:Callback = function('s:OnReadyForCustomRequests', [l:callback_args])
return ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback)
endfunction

View File

@@ -3,20 +3,13 @@
" simplify a path, and fix annoying issues with paths on Windows. " simplify a path, and fix annoying issues with paths on Windows.
" "
" Forward slashes are changed to back slashes so path equality works better " Forward slashes are changed to back slashes so path equality works better.
" on Windows. Back slashes are changed to forward slashes on Unix.
"
" Unix paths can technically contain back slashes, but in practice no path
" should, and replacing back slashes with forward slashes makes linters work
" in environments like MSYS.
" "
" Paths starting with more than one forward slash are changed to only one " Paths starting with more than one forward slash are changed to only one
" forward slash, to prevent the paths being treated as special MSYS paths. " forward slash, to prevent the paths being treated as special MSYS paths.
function! ale#path#Simplify(path) abort function! ale#path#Simplify(path) abort
if has('unix') if has('unix')
let l:unix_path = substitute(a:path, '\\', '/', 'g') return substitute(simplify(a:path), '^//\+', '/', 'g') " no-custom-checks
return substitute(simplify(l:unix_path), '^//\+', '/', 'g') " no-custom-checks
endif endif
let l:win_path = substitute(a:path, '/', '\\', 'g') let l:win_path = substitute(a:path, '/', '\\', 'g')

View File

@@ -1,32 +0,0 @@
" Author: zigford <zigford@gmail.com>
" Description: Functions for integrating with Powershell linters.
" Write a powershell script to a temp file for execution
" return the command used to execute it
function! s:TemporaryPSScript(buffer, input) abort
let l:filename = 'script.ps1'
" Create a temp dir to house our temp .ps1 script
" a temp dir is needed as powershell needs the .ps1
" extension
let l:tempdir = ale#util#Tempname() . (has('win32') ? '\' : '/')
let l:tempscript = l:tempdir . l:filename
" Create the temporary directory for the file, unreadable by 'other'
" users.
call mkdir(l:tempdir, '', 0750)
" Automatically delete the directory later.
call ale#command#ManageDirectory(a:buffer, l:tempdir)
" Write the script input out to a file.
call ale#util#Writefile(a:buffer, a:input, l:tempscript)
return l:tempscript
endfunction
function! ale#powershell#RunPowerShell(buffer, base_var_name, command) abort
let l:executable = ale#Var(a:buffer, a:base_var_name . '_executable')
let l:tempscript = s:TemporaryPSScript(a:buffer, a:command)
return ale#Escape(l:executable)
\ . ' -Exe Bypass -NoProfile -File '
\ . ale#Escape(l:tempscript)
\ . ' %t'
endfunction

View File

@@ -25,7 +25,7 @@ function! ale#python#FindProjectRootIni(buffer) abort
\|| filereadable(l:path . '/tox.ini') \|| filereadable(l:path . '/tox.ini')
\|| filereadable(l:path . '/mypy.ini') \|| filereadable(l:path . '/mypy.ini')
\|| filereadable(l:path . '/pycodestyle.cfg') \|| filereadable(l:path . '/pycodestyle.cfg')
\|| filereadable(l:path . '/.flake8') \|| filereadable(l:path . '/flake8.cfg')
\|| filereadable(l:path . '/.flake8rc') \|| filereadable(l:path . '/.flake8rc')
\|| filereadable(l:path . '/pylama.ini') \|| filereadable(l:path . '/pylama.ini')
\|| filereadable(l:path . '/pylintrc') \|| filereadable(l:path . '/pylintrc')

View File

@@ -1,7 +1,7 @@
" Author: Eddie Lebow https://github.com/elebow " Author: Eddie Lebow https://github.com/elebow
" Description: Functions for integrating with Ruby tools " Description: Functions for integrating with Ruby tools
" Find the nearest dir containing "app", "db", and "config", and assume it is " Find the nearest dir contining "app", "db", and "config", and assume it is
" the root of a Rails app. " the root of a Rails app.
function! ale#ruby#FindRailsRoot(buffer) abort function! ale#ruby#FindRailsRoot(buffer) abort
for l:name in ['app', 'config', 'db'] for l:name in ['app', 'config', 'db']

View File

@@ -1,13 +0,0 @@
" Author: Dan Loman <https://github.com/namolnad>
" Description: Functions for integrating with Swift tools
" Find the nearest dir containing a Package.swift file and assume it is the root of the Swift project.
function! ale#swift#FindProjectRoot(buffer) abort
let l:swift_config = ale#path#FindNearestFile(a:buffer, 'Package.swift')
if !empty(l:swift_config)
return fnamemodify(l:swift_config, ':h')
endif
return ''
endfunction

View File

@@ -422,7 +422,7 @@ function! ale#util#Writefile(buffer, lines, filename) abort
\ ? map(copy(a:lines), 'substitute(v:val, ''\r*$'', ''\r'', '''')') \ ? map(copy(a:lines), 'substitute(v:val, ''\r*$'', ''\r'', '''')')
\ : a:lines \ : a:lines
call writefile(l:corrected_lines, a:filename, 'S') " no-custom-checks call writefile(l:corrected_lines, a:filename) " no-custom-checks
endfunction endfunction
if !exists('s:patial_timers') if !exists('s:patial_timers')

View File

@@ -81,7 +81,7 @@ function! ale#virtualtext#ShowCursorWarning(...) abort
call ale#virtualtext#Clear() call ale#virtualtext#Clear()
if !empty(l:loc) if !empty(l:loc)
let l:msg = l:loc.text let l:msg = get(l:loc, 'detail', l:loc.text)
let l:hl_group = 'ALEVirtualTextInfo' let l:hl_group = 'ALEVirtualTextInfo'
let l:type = get(l:loc, 'type', 'E') let l:type = get(l:loc, 'type', 'E')

View File

@@ -156,7 +156,7 @@ g:ale_c_clangtidy_options *g:ale_c_clangtidy_options*
Type: |String| Type: |String|
Default: `''` Default: `''`
This variable can be changed to modify compiler flags given to clang-tidy. This variable can be changed to modify flags given to clang-tidy.
- Setting this variable to a non-empty string, - Setting this variable to a non-empty string,
- and working in a buffer where no compilation database is found using - and working in a buffer where no compilation database is found using
@@ -169,14 +169,6 @@ g:ale_c_clangtidy_options *g:ale_c_clangtidy_options*
of the |g:ale_c_build_dir_names| directories of the project tree. of the |g:ale_c_build_dir_names| directories of the project tree.
g:ale_c_clangtidy_extra_options *g:ale_c_clangtidy_extra_options*
*b:ale_c_clangtidy_extra_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to clang-tidy.
=============================================================================== ===============================================================================
cppcheck *ale-c-cppcheck* cppcheck *ale-c-cppcheck*

View File

@@ -2,26 +2,6 @@
ALE Chef Integration *ale-chef-options* ALE Chef Integration *ale-chef-options*
===============================================================================
cookstyle *ale-chef-cookstyle*
g:ale_chef_cookstyle_options *g:ale_chef_cookstyle_options*
*b:ale_chef_cookstyle_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to cookstyle.
g:ale_chef_cookstyle_executable *g:ale_chef_cookstyle_executable*
*b:ale_chef_cookstyle_executable*
Type: |String|
Default: `'cookstyle'`
This variable can be changed to point to the cookstyle binary in case it's
not on the $PATH or a specific version/path must be used.
=============================================================================== ===============================================================================
foodcritic *ale-chef-foodcritic* foodcritic *ale-chef-foodcritic*

View File

@@ -2,13 +2,6 @@
ALE Clojure Integration *ale-clojure-options* ALE Clojure Integration *ale-clojure-options*
===============================================================================
clj-kondo *ale-clojure-clj-kondo*
A minimal and opinionated linter for code that sparks joy.
https://github.com/borkdude/clj-kondo
=============================================================================== ===============================================================================
joker *ale-clojure-joker* joker *ale-clojure-joker*

View File

@@ -125,7 +125,7 @@ g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options*
Type: |String| Type: |String|
Default: `''` Default: `''`
This variable can be changed to modify compiler flags given to clang-tidy. This variable can be changed to modify flags given to clang-tidy.
- Setting this variable to a non-empty string, - Setting this variable to a non-empty string,
- and working in a buffer where no compilation database is found using - and working in a buffer where no compilation database is found using
@@ -138,14 +138,6 @@ g:ale_cpp_clangtidy_options *g:ale_cpp_clangtidy_options*
of the |g:ale_c_build_dir_names| directories of the project tree. of the |g:ale_c_build_dir_names| directories of the project tree.
g:ale_cpp_clangtidy_extra_options *g:ale_cpp_clangtidy_extra_options*
*b:ale_cpp_clangtidy_extra_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to clang-tidy.
=============================================================================== ===============================================================================
clazy *ale-cpp-clazy* clazy *ale-cpp-clazy*

View File

@@ -2,14 +2,6 @@
ALE CSS Integration *ale-css-options* ALE CSS Integration *ale-css-options*
===============================================================================
fecs *ale-css-fecs*
`fecs` options for CSS is the same as the options for JavaScript, and both of
them reads `./.fecsrc` as the default configuration file. See:
|ale-javascript-fecs|.
=============================================================================== ===============================================================================
prettier *ale-css-prettier* prettier *ale-css-prettier*

View File

@@ -151,9 +151,9 @@ ALE is tested with a suite of tests executed in Travis CI and AppVeyor. ALE
runs tests with the following versions of Vim in the following environments. runs tests with the following versions of Vim in the following environments.
1. Vim 8.0.0027 on Linux via Travis CI. 1. Vim 8.0.0027 on Linux via Travis CI.
2. Vim 8.1.0519 on Linux via Travis CI. 2. Vim 8.1.0204 on Linux via Travis CI.
3. NeoVim 0.2.0 on Linux via Travis CI. 3. NeoVim 0.2.0 on Linux via Travis CI.
4. NeoVim 0.3.5 on Linux via Travis CI. 4. NeoVim 0.3.0 on Linux via Travis CI.
5. Vim 8 (stable builds) on Windows via AppVeyor. 5. Vim 8 (stable builds) on Windows via AppVeyor.
If you are developing ALE code on Linux, Mac OSX, or BSD, you can run ALEs If you are developing ALE code on Linux, Mac OSX, or BSD, you can run ALEs
@@ -351,7 +351,6 @@ given the above setup are as follows.
`GivenCommandOutput [...]` - Define output for ale#command#Run. `GivenCommandOutput [...]` - Define output for ale#command#Run.
`AssertFixer results` - Check the fixer results `AssertFixer results` - Check the fixer results
`AssertFixerNotExecuted` - Check that fixers will not be executed.
=============================================================================== ===============================================================================

View File

@@ -3,35 +3,6 @@ ALE Erlang Integration *ale-erlang-options*
=============================================================================== ===============================================================================
dialyzer *ale-erlang-dialyzer*
g:ale_erlang_dialyzer_executable *g:ale_erlang_dialyzer_executable*
*b:ale_erlang_dialyzer_executable*
Type: |String|
Default: `'dialyzer'`
This variable can be changed to specify the dialyzer executable.
g:ale_erlang_dialyzer_plt_file *g:ale_erlang_dialyzer_plt_file*
*b:ale_erlang_dialyzer_plt_file*
Type: |String|
This variable can be changed to specify the path to the PLT file. By
default, it will search for the PLT file inside the `_build` directory. If
there isn't one, it will fallback to the path `$REBAR_PLT_DIR/dialyzer/plt`.
Otherwise, it will default to `$HOME/.dialyzer_plt`.
g:ale_erlang_dialyzer_rebar3_profile *g:ale_erlang_dialyzer_rebar3_profile*
*b:ale_erlang_dialyzer_rebar3_profile*
Type: |String|
Default: `'default'`
This variable can be changed to specify the profile that is used to
run dialyzer with rebar3.
-------------------------------------------------------------------------------
erlc *ale-erlang-erlc* erlc *ale-erlang-erlc*
g:ale_erlang_erlc_options *g:ale_erlang_erlc_options* g:ale_erlang_erlc_options *g:ale_erlang_erlc_options*

View File

@@ -30,23 +30,6 @@ g:ale_go_go_executable *g:ale_go_go_options*
the `gomod` fixer. the `gomod` fixer.
===============================================================================
bingo *ale-go-bingo*
g:ale_go_bingo_executable *g:ale_go_bingo_executable*
*b:ale_go_bingo_executable*
Type: |String|
Default: `'bingo'`
Location of the bingo binary file.
g:ale_go_bingo_options *g:ale_go_bingo_options*
*b:ale_go_bingo_options*
Type: |String|
Default: `''`
=============================================================================== ===============================================================================
gobuild *ale-go-gobuild* gobuild *ale-go-gobuild*
@@ -70,60 +53,6 @@ g:ale_go_gofmt_options *g:ale_go_gofmt_options*
This variable can be set to pass additional options to the gofmt fixer. This variable can be set to pass additional options to the gofmt fixer.
===============================================================================
golangci-lint *ale-go-golangci-lint*
`golangci-lint` is a `lint_file` linter, which only lints files that are
written to disk. This differs from the default behavior of linting the buffer.
See: |ale-lint-file|
g:ale_go_golangci_lint_executable *g:ale_go_golangci_lint_executable*
*b:ale_go_golangci_lint_executable*
Type: |String|
Default: `'golangci-lint'`
The executable that will be run for golangci-lint.
g:ale_go_golangci_lint_options *g:ale_go_golangci_lint_options*
*b:ale_go_golangci_lint_options*
Type: |String|
Default: `'--enable-all'`
This variable can be changed to alter the command-line arguments to the
golangci-lint invocation.
g:ale_go_golangci_lint_package *g:ale_go_golangci_lint_package*
*b:ale_go_golangci_lint_package*
Type: |Number|
Default: `0`
When set to `1`, the whole Go package will be checked instead of only the
current file.
===============================================================================
golangserver *ale-go-golangserver*
g:ale_go_langserver_executable *g:ale_go_langserver_executable*
*b:ale_go_langserver_executable*
Type: |String|
Default: `'go-langserver'`
Location of the go-langserver binary file.
g:ale_go_langserver_options *g:ale_go_langserver_options*
*b:ale_go_langserver_options*
Type: |String|
Default: `''`
Additional options passed to the go-langserver command. Note that the
`-gocodecompletion` option is ignored because it is handled automatically
by the |g:ale_completion_enabled| variable.
=============================================================================== ===============================================================================
golint *ale-go-golint* golint *ale-go-golint*
@@ -143,6 +72,17 @@ g:ale_go_golint_options *g:ale_go_golint_options*
This variable can be set to pass additional options to the golint linter. This variable can be set to pass additional options to the golint linter.
===============================================================================
govet *ale-go-govet*
g:ale_go_govet_options *g:ale_go_govet_options*
*b:ale_go_govet_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the go vet linter.
=============================================================================== ===============================================================================
gometalinter *ale-go-gometalinter* gometalinter *ale-go-gometalinter*
@@ -181,34 +121,6 @@ g:ale_go_gometalinter_lint_package *g:ale_go_gometalinter_lint_package*
current file. current file.
===============================================================================
gopls *ale-go-gopls*
g:ale_go_gopls_executable *g:ale_go_gopls_executable*
*b:ale_go_gopls_executable*
Type: |String|
Default: `'gopls'`
Location of the gopls binary file.
g:ale_go_gopls_options *g:ale_go_gopls_options*
*b:ale_go_gopls_options*
Type: |String|
Default: `''`
===============================================================================
govet *ale-go-govet*
g:ale_go_govet_options *g:ale_go_govet_options*
*b:ale_go_govet_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the go vet linter.
=============================================================================== ===============================================================================
staticcheck *ale-go-staticcheck* staticcheck *ale-go-staticcheck*
@@ -230,5 +142,74 @@ g:ale_go_staticcheck_lint_package *g:ale_go_staticcheck_lint_package*
current file. current file.
===============================================================================
golangserver *ale-go-golangserver*
g:ale_go_langserver_executable *g:ale_go_langserver_executable*
*b:ale_go_langserver_executable*
Type: |String|
Default: `'go-langserver'`
Location of the go-langserver binary file.
g:ale_go_langserver_options *g:ale_go_langserver_options*
*b:ale_go_langserver_options*
Type: |String|
Default: `''`
Additional options passed to the go-langserver command. Note that the
`-gocodecompletion` option is ignored because it is handled automatically
by the |g:ale_completion_enabled| variable.
===============================================================================
golangci-lint *ale-go-golangci-lint*
`golangci-lint` is a `lint_file` linter, which only lints files that are
written to disk. This differs from the default behavior of linting the buffer.
See: |ale-lint-file|
g:ale_go_golangci_lint_executable *g:ale_go_golangci_lint_executable*
*b:ale_go_golangci_lint_executable*
Type: |String|
Default: `'golangci-lint'`
The executable that will be run for golangci-lint.
g:ale_go_golangci_lint_options *g:ale_go_golangci_lint_options*
*b:ale_go_golangci_lint_options*
Type: |String|
Default: `'--enable-all'`
This variable can be changed to alter the command-line arguments to the
golangci-lint invocation.
g:ale_go_golangci_lint_package *g:ale_go_golangci_lint_package*
*b:ale_go_golangci_lint_package*
Type: |Number|
Default: `0`
When set to `1`, the whole Go package will be checked instead of only the
current file.
===============================================================================
bingo *ale-go-bingo*
g:ale_go_bingo_executable *g:ale_go_bingo_executable*
*b:ale_go_bingo_executable*
Type: |String|
Default: `'go-bingo'`
Location of the go-bingo binary file.
g:ale_go_bingo_options *g:ale_go_bingo_options*
*b:ale_go_bingo_options*
Type: |String|
Default: `''`
=============================================================================== ===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@@ -12,16 +12,6 @@ g:ale_haskell_brittany_executable *g:ale_haskell_brittany_executable*
This variable can be changed to use a different executable for brittany. This variable can be changed to use a different executable for brittany.
===============================================================================
floskell *ale-haskell-floskell*
g:ale_haskell_floskell_executable *g:ale_haskell_floskell_executable*
*b:ale_haskell_floskell_executable*
Type: |String|
Default: `'floskell'`
This variable can be changed to use a different executable for floskell.
=============================================================================== ===============================================================================
ghc *ale-haskell-ghc* ghc *ale-haskell-ghc*

View File

@@ -5,7 +5,7 @@ ALE HCL Integration *ale-hcl-options*
=============================================================================== ===============================================================================
terraform-fmt *ale-hcl-terraform-fmt* terraform-fmt *ale-hcl-terraform-fmt*
See |ale-terraform-fmt-fixer| for information about the available options. See |ale-terraform-fmt| for information about the available options.
=============================================================================== ===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@@ -2,14 +2,6 @@
ALE HTML Integration *ale-html-options* ALE HTML Integration *ale-html-options*
===============================================================================
fecs *ale-html-fecs*
`fecs` options for HTMl is the same as the options for JavaScript,
and both of them reads `./.fecsrc` as the default configuration file.
See: |ale-javascript-fecs|.
=============================================================================== ===============================================================================
htmlhint *ale-html-htmlhint* htmlhint *ale-html-htmlhint*

View File

@@ -5,41 +5,14 @@ ALE Java Integration *ale-java-options*
=============================================================================== ===============================================================================
checkstyle *ale-java-checkstyle* checkstyle *ale-java-checkstyle*
g:ale_java_checkstyle_config *g:ale_java_checkstyle_config*
*b:ale_java_checkstyle_config*
Type: |String|
Default: `'google_checks.xml'`
A path to a checkstyle configuration file.
If a configuration file is specified with |g:ale_java_checkstyle_options|,
it will be preferred over this setting.
The path to the configuration file can be an absolute path or a relative
path. ALE will search for the relative path in parent directories.
g:ale_java_checkstyle_executable *g:ale_java_checkstyle_executable*
*b:ale_java_checkstyle_executable*
Type: |String|
Default: 'checkstyle'
This variable can be changed to modify the executable used for checkstyle.
g:ale_java_checkstyle_options *g:ale_java_checkstyle_options* g:ale_java_checkstyle_options *g:ale_java_checkstyle_options*
*b:ale_java_checkstyle_options* *b:ale_java_checkstyle_options*
Type: |String| Type: String
Default: `''` Default: '-c /google_checks.xml'
This variable can be changed to modify flags given to checkstyle. This variable can be changed to modify flags given to checkstyle.
If a configuration file is specified with `-c`, it will be used instead of
configuration files set with |g:ale_java_checkstyle_config|.
=============================================================================== ===============================================================================
javac *ale-java-javac* javac *ale-java-javac*
@@ -117,83 +90,15 @@ or
This generates a dist/mac or dist/windows directory that contains the This generates a dist/mac or dist/windows directory that contains the
language server. To let ALE use this language server you need to set the language server. To let ALE use this language server you need to set the
g:ale_java_javalsp_executable variable to the absolute path of the launcher g:ale_java_javalsp_executable variable to the absolute path of the java
executable in this directory. executable in this directory.
g:ale_java_javalsp_executable *g:ale_java_javalsp_executable* g:ale_java_javalsp_executable *g:ale_java_javalsp_executable*
*b:ale_java_javalsp_executable* *b:ale_java_javalsp_executable*
Type: |String| Type: |String|
Default: `'launcher'`
This variable must be set to the absolute path of the language server launcher
executable. For example:
>
let g:ale_java_javalsp_executable=/java-language-server/dist/mac/bin/launcher
<
===============================================================================
eclipselsp *ale-java-eclipselsp*
To enable Eclipse LSP linter you need to clone and build the eclipse.jdt.ls
language server from https://github.com/eclipse/eclipse.jdt.ls. Simply
clone the source code repo and then build the plugin:
./mvnw clean verify
Note: currently, the build can only run when launched with JDK 8. JDK 9 or more
recent versions can be used to run the server though.
After build completes the files required to run the language server will be
located inside the repository folder `eclipse.jdt.ls`. Please ensure to set
|g:ale_java_eclipselsp_path| to the absolute path of that folder.
You could customize compiler options and code assists of the server.
Under your project folder, modify the file `.settings/org.eclipse.jdt.core.prefs`
with options presented at
https://help.eclipse.org/neon/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/JavaCore.html.
g:ale_java_eclipselsp_path *g:ale_java_eclipselsp_path*
*b:ale_java_eclipselsp_path*
Type: |String|
Default: `'$HOME/eclipse.jdt.ls'`
Absolute path to the location of the eclipse.jdt.ls repository folder. Or if
you have VSCode extension installed the absolute path to the VSCode extensions
folder (e.g. $HOME/.vscode/extensions/redhat.java-0.4x.0 in Linux).
g:ale_java_eclipselsp_executable *g:ale_java_eclipse_executable*
*b:ale_java_eclipse_executable*
Type: |String|
Default: `'java'` Default: `'java'`
This variable can be set to change the executable path used for java. This variable can be changed to use a different executable for java.
g:ale_java_eclipselsp_config_path *g:ale_java_eclipse_config_path*
*b:ale_java_eclipse_config_path*
Type: |String|
Default: `''`
Set this variable to change the configuration directory path used by
eclipselsp (e.g. `$HOME/.jdtls` in Linux).
By default ALE will attempt to use the configuration within the installation
directory.
This setting is particularly useful when eclipselsp is installed in a
non-writable directory like `/usr/share/java/jdtls`, as is the case when
installed via system package.
g:ale_java_eclipselsp_workspace_path *g:ale_java_eclipselsp_workspace_path*
*b:ale_java_eclipselsp_workspace_path*
Type: |String|
Default: `''`
If you have Eclipse installed is good idea to set this variable to the
absolute path of the Eclipse workspace. If not set this value will be set to
the parent folder of the project root.
=============================================================================== ===============================================================================

View File

@@ -73,33 +73,6 @@ g:ale_javascript_eslint_suppress_missing_config
configuration files are found. configuration files are found.
===============================================================================
fecs *ale-javascript-fecs*
`fecs` is a lint tool for HTML/CSS/JavaScript, can be installed via:
`$ npm install --save-dev fecs`
And the configuration file is located at `./fecsrc`, see http://fecs.baidu.com
for more options.
g:ale_javascript_fecs_executable *g:ale_javascript_fecs_executable*
*b:ale_javascript_fecs_executable*
Type: |String|
Default: `'fecs'`
See |ale-integrations-local-executables|
g:ale_javascript_fecs_use_global *g:ale_javascript_fecs_use_global*
*b:ale_javascript_fecs_use_global*
Type: |Number|
Default: `get(g:, 'ale_use_global_executables', 0)`
See |ale-integrations-local-executables|
=============================================================================== ===============================================================================
flow *ale-javascript-flow* flow *ale-javascript-flow*

Some files were not shown because too many files have changed in this diff Show More