Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
04bd84e914
36 changed files with 998 additions and 193 deletions
16
.github/stale.yml
vendored
Normal file
16
.github/stale.yml
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
# This configuration closes stale PRs after 30 days.
|
||||
# Issues in ALE are never, ever stale. They are either resolved or not.
|
||||
only: pulls
|
||||
daysUntilStale: 28
|
||||
daysUntilClose: 2
|
||||
exemptLabels: []
|
||||
staleLabel: stale
|
||||
markComment: >
|
||||
This pull request has been automatically marked as stale because it has not
|
||||
been updated recently. Make sure to write tests and document your changes.
|
||||
See `:help ale-dev` for information on writing tests.
|
||||
|
||||
If your pull request is good to merge, bother w0rp or another maintainer
|
||||
again, and get them to merge it.
|
||||
closeComment: false
|
142
README.md
142
README.md
|
@ -61,23 +61,24 @@ other content at [w0rp.com](https://w0rp.com).
|
|||
4. [Contributing](#contributing)
|
||||
5. [FAQ](#faq)
|
||||
1. [How do I disable particular linters?](#faq-disable-linters)
|
||||
2. [How can I keep the sign gutter open?](#faq-keep-signs)
|
||||
3. [How can I change the signs ALE uses?](#faq-change-signs)
|
||||
4. [How can I change or disable the highlights ALE uses?](#faq-change-highlights)
|
||||
5. [How can I show errors or warnings in my statusline?](#faq-statusline)
|
||||
6. [How can I show errors or warnings in my lightline?](#faq-lightline)
|
||||
7. [How can I change the format for echo messages?](#faq-echo-format)
|
||||
8. [How can I execute some code when ALE starts or stops linting?](#faq-autocmd)
|
||||
9. [How can I navigate between errors quickly?](#faq-navigation)
|
||||
10. [How can I run linters only when I save files?](#faq-lint-on-save)
|
||||
11. [How can I use the quickfix list instead of the loclist?](#faq-quickfix)
|
||||
12. [How can I check JSX files with both stylelint and eslint?](#faq-jsx-stylelint-eslint)
|
||||
13. [How can I check Vue files with ESLint?](#faq-vue-eslint)
|
||||
14. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad)
|
||||
15. [How can I configure my C or C++ project?](#faq-c-configuration)
|
||||
16. [How can I configure ALE differently for different buffers?](#faq-buffer-configuration)
|
||||
17. [How can I configure the height of the list in which ALE displays errors?](#faq-list-window-height)
|
||||
18. [How can I see what ALE has configured for the current file?](#faq-get-info)
|
||||
2. [How can I see what ALE has configured for the current file?](#faq-get-info)
|
||||
3. [How can I use ALE and coc.nvim together?](#faq-coc-nvim)
|
||||
4. [How can I keep the sign gutter open?](#faq-keep-signs)
|
||||
5. [How can I change the signs ALE uses?](#faq-change-signs)
|
||||
6. [How can I change or disable the highlights ALE uses?](#faq-change-highlights)
|
||||
7. [How can I show errors or warnings in my statusline?](#faq-statusline)
|
||||
8. [How can I show errors or warnings in my lightline?](#faq-lightline)
|
||||
9. [How can I change the format for echo messages?](#faq-echo-format)
|
||||
10. [How can I execute some code when ALE starts or stops linting?](#faq-autocmd)
|
||||
11. [How can I navigate between errors quickly?](#faq-navigation)
|
||||
12. [How can I run linters only when I save files?](#faq-lint-on-save)
|
||||
13. [How can I use the quickfix list instead of the loclist?](#faq-quickfix)
|
||||
14. [How can I check JSX files with both stylelint and eslint?](#faq-jsx-stylelint-eslint)
|
||||
15. [How can I check Vue files with ESLint?](#faq-vue-eslint)
|
||||
16. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad)
|
||||
17. [How can I configure my C or C++ project?](#faq-c-configuration)
|
||||
18. [How can I configure ALE differently for different buffers?](#faq-buffer-configuration)
|
||||
19. [How can I configure the height of the list in which ALE displays errors?](#faq-list-window-height)
|
||||
|
||||
<a name="supported-languages"></a>
|
||||
|
||||
|
@ -193,12 +194,11 @@ completion manually with `<C-x><C-o>`.
|
|||
set omnifunc=ale#completion#OmniFunc
|
||||
```
|
||||
|
||||
When working with TypeScript files, ALE supports automatic imports from
|
||||
external modules. This behavior is disabled by default and can be enabled by
|
||||
setting:
|
||||
ALE supports automatic imports from external modules. This behavior is disabled
|
||||
by default and can be enabled by setting:
|
||||
|
||||
```vim
|
||||
let g:ale_completion_tsserver_autoimport = 1
|
||||
let g:ale_completion_autoimport = 1
|
||||
```
|
||||
|
||||
See `:help ale-completion` for more information.
|
||||
|
@ -416,9 +416,56 @@ This plugin will look for linters in the [`ale_linters`](ale_linters) directory.
|
|||
Each directory within corresponds to a particular filetype in Vim, and each file
|
||||
in each directory corresponds to the name of a particular linter.
|
||||
|
||||
<a name="faq-get-info"></a>
|
||||
|
||||
### 5.ii. How can I see what ALE has configured for the current file?
|
||||
|
||||
Run the following to see what is currently configured:
|
||||
|
||||
```vim
|
||||
:ALEInfo
|
||||
```
|
||||
|
||||
<a name="faq-coc-nvim"></a>
|
||||
|
||||
### 5.iii. How can I use ALE and coc.nvim together?
|
||||
|
||||
[coc.nvim](https://github.com/neoclide/coc.nvim) is a popular Vim plugin written
|
||||
in TypeScript and dependent on the [npm](https://www.npmjs.com/) ecosystem for
|
||||
providing full IDE features to Vim. Both ALE and coc.nvim implement
|
||||
[Language Server Protocol](https://microsoft.github.io/language-server-protocol/)
|
||||
(LSP) clients for supporting diagnostics (linting with a live server), and other
|
||||
features like auto-completion, and others listed above.
|
||||
|
||||
ALE is primarily focused on integrating with external programs through virtually
|
||||
any means, provided the plugin remains almost entirely written in Vim script.
|
||||
coc.nvim is primarily focused on bringing IDE features to Vim. If you want to
|
||||
run external programs on your files to check for errors, and also use the most
|
||||
advanced IDE features, you might want to use both plugins at the same time.
|
||||
|
||||
The easiest way to get both plugins to work together is to configure coc.nvim to
|
||||
send diagnostics to ALE, so ALE controls how all problems are presented to you,
|
||||
and to disable all LSP features in ALE, so ALE doesn't try to provide LSP
|
||||
features already provided by coc.nvim, such as auto-completion.
|
||||
|
||||
1. Open your coc.nvim configuration file with `:CocConfig` and add
|
||||
`"diagnostic.displayByAle": true` to your settings.
|
||||
2. Add `let g:ale_disable_lsp = 1` to your vimrc file, before plugins are
|
||||
loaded.
|
||||
|
||||
You can also use `b:ale_disable_lsp` in your ftplugin files to enable or disable
|
||||
LSP features in ALE for different filetypes. After you configure coc.nvim and
|
||||
ALE this way, you can further configure how problems appear to you by using all
|
||||
of the settings mentioned in ALE's help file, including how often diagnostics
|
||||
are requested. See `:help ale-lint`.
|
||||
|
||||
The integration between ALE and coc.nvim works using an API ALE offers for
|
||||
letting any other plugin integrate with ALE. If you are interested in writing a
|
||||
similar integration, see `:help ale-lint-other-sources`.
|
||||
|
||||
<a name="faq-keep-signs"></a>
|
||||
|
||||
### 5.ii. How can I keep the sign gutter open?
|
||||
### 5.iv. How can I keep the sign gutter open?
|
||||
|
||||
You can keep the sign gutter open at all times by setting the
|
||||
`g:ale_sign_column_always` to 1
|
||||
|
@ -429,7 +476,7 @@ let g:ale_sign_column_always = 1
|
|||
|
||||
<a name="faq-change-signs"></a>
|
||||
|
||||
### 5.iii. How can I change the signs ALE uses?
|
||||
### 5.v. How can I change the signs ALE uses?
|
||||
|
||||
Use these options to specify what text should be used for signs:
|
||||
|
||||
|
@ -449,7 +496,7 @@ highlight clear ALEWarningSign
|
|||
|
||||
<a name="faq-change-highlights"></a>
|
||||
|
||||
### 5.iv. How can I change or disable the highlights ALE uses?
|
||||
### 5.vi. How can I change or disable the highlights ALE uses?
|
||||
|
||||
ALE's highlights problems with highlight groups which link to `SpellBad`,
|
||||
`SpellCap`, `error`, and `todo` groups by default. The characters that are
|
||||
|
@ -475,7 +522,7 @@ See `:help ale-highlights` for more information.
|
|||
|
||||
<a name="faq-statusline"></a>
|
||||
|
||||
### 5.v. How can I show errors or warnings in my statusline?
|
||||
### 5.vii. How can I show errors or warnings in my statusline?
|
||||
|
||||
[vim-airline](https://github.com/vim-airline/vim-airline) integrates with ALE
|
||||
for displaying error information in the status bar. If you want to see the
|
||||
|
@ -524,7 +571,7 @@ for more information.
|
|||
|
||||
<a name="faq-lightline"></a>
|
||||
|
||||
### 5.vi. How can I show errors or warnings in my lightline?
|
||||
### 5.viii. How can I show errors or warnings in my lightline?
|
||||
|
||||
[lightline](https://github.com/itchyny/lightline.vim) does not have built-in
|
||||
support for ALE, nevertheless there is a plugin that adds this functionality: [maximbaz/lightline-ale](https://github.com/maximbaz/lightline-ale).
|
||||
|
@ -533,7 +580,7 @@ For more information, check out the sources of that plugin, `:help ale#statuslin
|
|||
|
||||
<a name="faq-echo-format"></a>
|
||||
|
||||
### 5.vii. How can I change the format for echo messages?
|
||||
### 5.ix. How can I change the format for echo messages?
|
||||
|
||||
There are 3 global options that allow customizing the echoed message.
|
||||
|
||||
|
@ -562,7 +609,7 @@ See `:help g:ale_echo_msg_format` for more information.
|
|||
|
||||
<a name="faq-autocmd"></a>
|
||||
|
||||
### 5.viii. How can I execute some code when ALE starts or stops linting?
|
||||
### 5.x. How can I execute some code when ALE starts or stops linting?
|
||||
|
||||
ALE runs its own [autocmd](http://vimdoc.sourceforge.net/htmldoc/autocmd.html)
|
||||
events when a lint or fix cycle are started and stopped. There is also an event
|
||||
|
@ -585,7 +632,7 @@ augroup END
|
|||
|
||||
<a name="faq-navigation"></a>
|
||||
|
||||
### 5.ix. How can I navigate between errors quickly?
|
||||
### 5.xi. How can I navigate between errors quickly?
|
||||
|
||||
ALE offers some commands with `<Plug>` keybinds for moving between warnings and
|
||||
errors quickly. You can map the keys Ctrl+j and Ctrl+k to moving between errors
|
||||
|
@ -601,7 +648,7 @@ For more information, consult the online documentation with
|
|||
|
||||
<a name="faq-lint-on-save"></a>
|
||||
|
||||
### 5.x. How can I run linters only when I save files?
|
||||
### 5.xii. How can I run linters only when I save files?
|
||||
|
||||
ALE offers an option `g:ale_lint_on_save` for enabling running the linters
|
||||
when files are saved. This option is enabled by default. If you only
|
||||
|
@ -622,7 +669,7 @@ files, you can set `g:ale_lint_on_save` to `0`.
|
|||
|
||||
<a name="faq-quickfix"></a>
|
||||
|
||||
### 5.xi. How can I use the quickfix list instead of the loclist?
|
||||
### 5.xiii. How can I use the quickfix list instead of the loclist?
|
||||
|
||||
The quickfix list can be enabled by turning the `g:ale_set_quickfix`
|
||||
option on. If you wish to also disable the loclist, you can disable
|
||||
|
@ -652,7 +699,7 @@ instead of the default horizontally.
|
|||
|
||||
<a name="faq-jsx-stylelint-eslint"></a>
|
||||
|
||||
### 5.xii. How can I check JSX files with both stylelint and eslint?
|
||||
### 5.xiv. How can I check JSX files with both stylelint and eslint?
|
||||
|
||||
If you configure ALE options correctly in your vimrc file, and install
|
||||
the right tools, you can check JSX files with stylelint and eslint.
|
||||
|
@ -694,7 +741,7 @@ no linter will be run twice for the same file.
|
|||
|
||||
<a name="faq-vue-eslint"></a>
|
||||
|
||||
### 5.xiii. How can I check Vue files with ESLint?
|
||||
### 5.xv. How can I check Vue files with ESLint?
|
||||
|
||||
To check Vue files with ESLint, your ESLint project configuration file must be
|
||||
configured to use the [Vue plugin](https://github.com/vuejs/eslint-plugin-vue).
|
||||
|
@ -725,7 +772,7 @@ let g:ale_linters = {'vue': ['eslint', 'vls']}
|
|||
|
||||
<a name="faq-my-battery-is-sad"></a>
|
||||
|
||||
### 5.xiv. Will this plugin eat all of my laptop battery power?
|
||||
### 5.xvi. Will this plugin eat all of my laptop battery power?
|
||||
|
||||
ALE takes advantage of the power of various tools to check your code. This of
|
||||
course means that CPU time will be used to continuously check your code. If you
|
||||
|
@ -749,7 +796,7 @@ including the option `g:ale_lint_on_enter`, and you can run ALE manually with
|
|||
|
||||
<a name="faq-c-configuration"></a>
|
||||
|
||||
### 5.xv. How can I configure my C or C++ project?
|
||||
### 5.xvii. How can I configure my C or C++ project?
|
||||
|
||||
The structure of C and C++ projects varies wildly from project to project, with
|
||||
many different build tools being used for building them, and many different
|
||||
|
@ -769,13 +816,24 @@ setting. Consult the documentation for that setting for more information.
|
|||
`b:ale_linters` can be used to select which tools you want to run, say if you
|
||||
want to use only `gcc` for one project, and only `clang` for another.
|
||||
|
||||
ALE will attempt to parse `compile_commands.json` files to discover compiler
|
||||
flags to use when linting code. See `:help g:ale_c_parse_compile_commands` for
|
||||
more information. See Clang's documentation for
|
||||
[compile_commands.json files](https://clang.llvm.org/docs/JSONCompilationDatabase.html).
|
||||
You should strongly consider generating them in your builds, which is easy to do
|
||||
with CMake.
|
||||
|
||||
You can also configure ALE to automatically run `make -n` to run dry runs on
|
||||
`Makefile`s to discover compiler flags. This can execute arbitrary code, so the
|
||||
option is disabled by default. See `:help g:ale_c_parse_makefile`.
|
||||
|
||||
You may also configure buffer-local settings for linters with project-specific
|
||||
vimrc files. [local_vimrc](https://github.com/LucHermitte/local_vimrc) can be
|
||||
used for executing local vimrc files which can be shared in your project.
|
||||
|
||||
<a name="faq-buffer-configuration"></a>
|
||||
|
||||
### 5.xvi. How can I configure ALE differently for different buffers?
|
||||
### 5.xviii. How can I configure ALE differently for different buffers?
|
||||
|
||||
ALE offers various ways to configure which linters or fixers are run, and
|
||||
other settings. For the majority of ALE's settings, they can either be
|
||||
|
@ -811,7 +869,7 @@ Buffer-local variables for settings always override the global settings.
|
|||
|
||||
<a name="faq-list-window-height"></a>
|
||||
|
||||
### 5.xvii. How can I configure the height of the list in which ALE displays errors?
|
||||
### 5.xix. How can I configure the height of the list in which ALE displays errors?
|
||||
|
||||
To set a default height for the error list, use the `g:ale_list_window_size` variable.
|
||||
|
||||
|
@ -819,13 +877,3 @@ To set a default height for the error list, use the `g:ale_list_window_size` var
|
|||
" Show 5 lines of errors (default: 10)
|
||||
let g:ale_list_window_size = 5
|
||||
```
|
||||
|
||||
<a name="faq-get-info"></a>
|
||||
|
||||
### 5.xviii. How can I see what ALE has configured for the current file?
|
||||
|
||||
Run the following to see what is currently configured:
|
||||
|
||||
```vim
|
||||
:ALEInfo
|
||||
```
|
||||
|
|
|
@ -25,6 +25,11 @@ function! ale_linters#cpp#clangtidy#GetCommand(buffer, output) abort
|
|||
let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags
|
||||
endif
|
||||
|
||||
" Tell clang-tidy a .h header with a C++ filetype in Vim is a C++ file.
|
||||
if expand('#' . a:buffer) =~# '\.h$'
|
||||
let l:options .= !empty(l:options) ? ' -x c++' : '-x c++'
|
||||
endif
|
||||
|
||||
" Get the options to pass directly to clang-tidy
|
||||
let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options')
|
||||
|
||||
|
|
|
@ -31,21 +31,28 @@ function! ale_linters#java#eclipselsp#JarPath(buffer) abort
|
|||
" Search jar file within repository path when manually built using mvn
|
||||
let l:files = globpath(l:path, '**/'.l:platform.'/**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
|
||||
|
||||
if len(l:files) > 1
|
||||
if len(l:files) >= 1
|
||||
return l:files[0]
|
||||
endif
|
||||
|
||||
" Search jar file within VSCode extensions folder.
|
||||
let l:files = globpath(l:path, '**/'.l:platform.'/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
|
||||
|
||||
if len(l:files) > 1
|
||||
if len(l:files) >= 1
|
||||
return l:files[0]
|
||||
endif
|
||||
|
||||
" Search jar file within unzipped tar.gz file
|
||||
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
|
||||
if len(l:files) >= 1
|
||||
return l:files[0]
|
||||
endif
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ call ale#Set('rust_cargo_default_feature_behavior', 'default')
|
|||
call ale#Set('rust_cargo_include_features', '')
|
||||
call ale#Set('rust_cargo_use_clippy', 0)
|
||||
call ale#Set('rust_cargo_clippy_options', '')
|
||||
call ale#Set('rust_cargo_target_dir', '')
|
||||
|
||||
function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort
|
||||
if ale#path#FindNearestFile(a:bufnr, 'Cargo.toml') isnot# ''
|
||||
|
@ -31,6 +32,9 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
|
|||
\ && ale#semver#GTE(a:version, [0, 22, 0])
|
||||
let l:use_tests = ale#Var(a:buffer, 'rust_cargo_check_tests')
|
||||
\ && ale#semver#GTE(a:version, [0, 22, 0])
|
||||
let l:target_dir = ale#Var(a:buffer, 'rust_cargo_target_dir')
|
||||
let l:use_target_dir = !empty(l:target_dir)
|
||||
\ && ale#semver#GTE(a:version, [0, 17, 0])
|
||||
|
||||
let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features')
|
||||
|
||||
|
@ -82,6 +86,7 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
|
|||
\ . (l:use_all_targets ? ' --all-targets' : '')
|
||||
\ . (l:use_examples ? ' --examples' : '')
|
||||
\ . (l:use_tests ? ' --tests' : '')
|
||||
\ . (l:use_target_dir ? (' --target-dir ' . ale#Escape(l:target_dir)) : '')
|
||||
\ . ' --frozen --message-format=json -q'
|
||||
\ . l:default_feature
|
||||
\ . l:include_features
|
||||
|
|
|
@ -13,14 +13,15 @@ function! ale_linters#verilog#vlog#Handle(buffer, lines) abort
|
|||
"Matches patterns like the following:
|
||||
"** Warning: add.v(7): (vlog-2623) Undefined variable: C.
|
||||
"** Error: file.v(1): (vlog-13294) Identifier must be declared with a port mode: C.
|
||||
let l:pattern = '^**\s\(\w*\):[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)'
|
||||
let l:pattern = '^**\s\(\w*\): \([a-zA-Z0-9\-\.\_\/ ]\+\)(\(\d\+\)):\s\+\(.*\)'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[2] + 0,
|
||||
\ 'lnum': l:match[3] + 0,
|
||||
\ 'type': l:match[1] is? 'Error' ? 'E' : 'W',
|
||||
\ 'text': l:match[3],
|
||||
\ 'text': l:match[4],
|
||||
\ 'filename': l:match[2],
|
||||
\})
|
||||
endfor
|
||||
|
||||
|
@ -28,13 +29,14 @@ function! ale_linters#verilog#vlog#Handle(buffer, lines) abort
|
|||
"** Warning: (vlog-2623) add.v(7): Undefined variable: C.
|
||||
"** Error: (vlog-13294) file.v(1): Identifier must be declared with a port mode: C.
|
||||
" let l:pattern = '^**\s\(\w*\):[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)'
|
||||
let l:pattern = '^**\s\(\w*\):\s\([^)]*)\)[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)'
|
||||
let l:pattern = '^**\s\(\w*\):\s\([^)]*)\) \([a-zA-Z0-9\-\.\_\/ ]\+\)(\(\d\+\)):\s\+\(.*\)'
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[3] + 0,
|
||||
\ 'lnum': l:match[4] + 0,
|
||||
\ 'type': l:match[1] is? 'Error' ? 'E' : 'W',
|
||||
\ 'text': l:match[2] . ' ' . l:match[4],
|
||||
\ 'text': l:match[2] . ' ' . l:match[5],
|
||||
\ 'filename': l:match[3],
|
||||
\})
|
||||
endfor
|
||||
|
||||
|
|
|
@ -2,20 +2,13 @@
|
|||
" Description: Functions for integrating with C-family linters.
|
||||
|
||||
call ale#Set('c_parse_makefile', 0)
|
||||
call ale#Set('c_parse_compile_commands', 0)
|
||||
call ale#Set('c_parse_compile_commands', 1)
|
||||
let s:sep = has('win32') ? '\' : '/'
|
||||
|
||||
" Set just so tests can override it.
|
||||
let g:__ale_c_project_filenames = ['.git/HEAD', 'configure', 'Makefile', 'CMakeLists.txt']
|
||||
|
||||
function! ale#c#GetBuildDirectory(buffer) abort
|
||||
" Don't include build directory for header files, as compile_commands.json
|
||||
" files don't consider headers to be translation units, and provide no
|
||||
" commands for compiling header files.
|
||||
if expand('#' . a:buffer) =~# '\v\.(h|hpp)$'
|
||||
return ''
|
||||
endif
|
||||
|
||||
let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
|
||||
|
||||
" c_build_dir has the priority if defined
|
||||
|
@ -334,10 +327,6 @@ endfunction
|
|||
function! ale#c#GetCFlags(buffer, output) abort
|
||||
let l:cflags = v:null
|
||||
|
||||
if ale#Var(a:buffer, 'c_parse_makefile') && !empty(a:output)
|
||||
let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output)
|
||||
endif
|
||||
|
||||
if ale#Var(a:buffer, 'c_parse_compile_commands')
|
||||
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||
|
||||
|
@ -346,6 +335,12 @@ function! ale#c#GetCFlags(buffer, output) abort
|
|||
endif
|
||||
endif
|
||||
|
||||
if ale#Var(a:buffer, 'c_parse_makefile')
|
||||
\&& !empty(a:output)
|
||||
\&& !empty(l:cflags)
|
||||
let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output)
|
||||
endif
|
||||
|
||||
if l:cflags is v:null
|
||||
let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))
|
||||
endif
|
||||
|
|
|
@ -16,7 +16,8 @@ onoremap <silent> <Plug>(ale_show_completion_menu) <Nop>
|
|||
let g:ale_completion_delay = get(g:, 'ale_completion_delay', 100)
|
||||
let g:ale_completion_excluded_words = get(g:, 'ale_completion_excluded_words', [])
|
||||
let g:ale_completion_max_suggestions = get(g:, 'ale_completion_max_suggestions', 50)
|
||||
let g:ale_completion_tsserver_autoimport = get(g:, 'ale_completion_tsserver_autoimport', 0)
|
||||
let g:ale_completion_autoimport = get(g:, 'ale_completion_autoimport', 0)
|
||||
let g:ale_completion_tsserver_remove_warnings = get(g:, 'ale_completion_tsserver_remove_warnings', 0)
|
||||
|
||||
let s:timer_id = -1
|
||||
let s:last_done_pos = []
|
||||
|
@ -397,10 +398,14 @@ function! ale#completion#ParseTSServerCompletions(response) abort
|
|||
let l:names = []
|
||||
|
||||
for l:suggestion in a:response.body
|
||||
call add(l:names, {
|
||||
\ 'word': l:suggestion.name,
|
||||
\ 'source': get(l:suggestion, 'source', ''),
|
||||
\})
|
||||
let l:kind = get(l:suggestion, 'kind', '')
|
||||
|
||||
if g:ale_completion_tsserver_remove_warnings == 0 || l:kind isnot# 'warning'
|
||||
call add(l:names, {
|
||||
\ 'word': l:suggestion.name,
|
||||
\ 'source': get(l:suggestion, 'source', ''),
|
||||
\})
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:names
|
||||
|
@ -413,12 +418,22 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
|||
|
||||
for l:suggestion in a:response.body
|
||||
let l:displayParts = []
|
||||
let l:local_name = v:null
|
||||
|
||||
for l:action in get(l:suggestion, 'codeActions', [])
|
||||
call add(l:displayParts, l:action.description . ' ')
|
||||
endfor
|
||||
|
||||
for l:part in l:suggestion.displayParts
|
||||
" Stop on stop on line breaks for the menu.
|
||||
if get(l:part, 'kind') is# 'lineBreak'
|
||||
break
|
||||
endif
|
||||
|
||||
if get(l:part, 'kind') is# 'localName'
|
||||
let l:local_name = l:part.text
|
||||
endif
|
||||
|
||||
call add(l:displayParts, l:part.text)
|
||||
endfor
|
||||
|
||||
|
@ -431,11 +446,17 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
|||
|
||||
" See :help complete-items
|
||||
let l:result = {
|
||||
\ 'word': l:suggestion.name,
|
||||
\ 'word': (
|
||||
\ l:suggestion.name is# 'default'
|
||||
\ && l:suggestion.kind is# 'alias'
|
||||
\ && !empty(l:local_name)
|
||||
\ ? l:local_name
|
||||
\ : l:suggestion.name
|
||||
\ ),
|
||||
\ 'kind': ale#completion#GetCompletionSymbols(l:suggestion.kind),
|
||||
\ 'icase': 1,
|
||||
\ 'menu': join(l:displayParts, ''),
|
||||
\ 'dup': g:ale_completion_tsserver_autoimport,
|
||||
\ 'dup': g:ale_completion_autoimport,
|
||||
\ 'info': join(l:documentationParts, ''),
|
||||
\}
|
||||
|
||||
|
@ -517,6 +538,12 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
|||
continue
|
||||
endif
|
||||
|
||||
" Don't use LSP items with additional text edits when autoimport for
|
||||
" completions is turned off.
|
||||
if has_key(l:item, 'additionalTextEdits') && !g:ale_completion_autoimport
|
||||
continue
|
||||
endif
|
||||
|
||||
let l:doc = get(l:item, 'documentation', '')
|
||||
|
||||
if type(l:doc) is v:t_dict && has_key(l:doc, 'value')
|
||||
|
@ -661,12 +688,16 @@ function! s:OnReady(linter, lsp_details) abort
|
|||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
|
||||
if a:linter.lsp is# 'tsserver'
|
||||
if get(g:, 'ale_completion_tsserver_autoimport') is 1
|
||||
execute 'echom `g:ale_completion_tsserver_autoimport` is deprecated. Use `g:ale_completion_autoimport` instead.'''
|
||||
endif
|
||||
|
||||
let l:message = ale#lsp#tsserver_message#Completions(
|
||||
\ l:buffer,
|
||||
\ b:ale_completion_info.line,
|
||||
\ b:ale_completion_info.column,
|
||||
\ b:ale_completion_info.prefix,
|
||||
\ g:ale_completion_tsserver_autoimport,
|
||||
\ g:ale_completion_autoimport,
|
||||
\)
|
||||
else
|
||||
" Send a message saying the buffer has changed first, otherwise
|
||||
|
|
|
@ -17,8 +17,8 @@ function! ale#fixers#prettier_standard#Fix(buffer) abort
|
|||
|
||||
return {
|
||||
\ 'command': ale#Escape(ale#fixers#prettier_standard#GetExecutable(a:buffer))
|
||||
\ . ' %t'
|
||||
\ . ' --stdin'
|
||||
\ . ' --stdin-filepath=%s'
|
||||
\ . ' ' . l:options,
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
|
|
|
@ -1,20 +1,41 @@
|
|||
call ale#Set('ruby_rubocop_options', '')
|
||||
call ale#Set('ruby_rubocop_auto_correct_all', 0)
|
||||
call ale#Set('ruby_rubocop_executable', 'rubocop')
|
||||
|
||||
" Rubocop fixer outputs diagnostics first and then the fixed
|
||||
" output. These are delimited by a "=======" string that we
|
||||
" look for to remove everything before it.
|
||||
function! ale#fixers#rubocop#PostProcess(buffer, output) abort
|
||||
let l:line = 0
|
||||
|
||||
for l:output in a:output
|
||||
let l:line = l:line + 1
|
||||
|
||||
if l:output =~# "^=\\+$"
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
return a:output[l:line :]
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#rubocop#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ruby_rubocop_executable')
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.rubocop.yml')
|
||||
let l:options = ale#Var(a:buffer, 'ruby_rubocop_options')
|
||||
let l:auto_correct_all = ale#Var(a:buffer, 'ruby_rubocop_auto_correct_all')
|
||||
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'rubocop')
|
||||
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --auto-correct --force-exclusion %t'
|
||||
\ . (l:auto_correct_all ? ' --auto-correct-all' : ' --auto-correct')
|
||||
\ . ' --force-exclusion --stdin '
|
||||
\ . ale#Escape(expand('#' . a:buffer . ':p'))
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#rubocop#Fix(buffer) abort
|
||||
return {
|
||||
\ 'command': ale#fixers#rubocop#GetCommand(a:buffer),
|
||||
\ 'read_temporary_file': 1,
|
||||
\ 'process_with': 'ale#fixers#rubocop#PostProcess'
|
||||
\}
|
||||
endfunction
|
||||
|
|
|
@ -16,7 +16,7 @@ function! ale#fixers#tslint#Fix(buffer) abort
|
|||
return {
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . l:tslint_config_option
|
||||
\ . ' --fix %t',
|
||||
\ . ' --outputAbsolutePaths --fix %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
|
|
|
@ -56,6 +56,137 @@ function! ale#hover#HandleTSServerResponse(conn_id, response) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
" Convert a language name to another one.
|
||||
" The language name could be an empty string or v:null
|
||||
function! s:ConvertLanguageName(language) abort
|
||||
return a:language
|
||||
endfunction
|
||||
|
||||
function! ale#hover#ParseLSPResult(contents) abort
|
||||
let l:includes = {}
|
||||
let l:highlights = []
|
||||
let l:lines = []
|
||||
let l:list = type(a:contents) is v:t_list ? a:contents : [a:contents]
|
||||
let l:region_index = 0
|
||||
|
||||
for l:item in l:list
|
||||
if !empty(l:lines)
|
||||
call add(l:lines, '')
|
||||
endif
|
||||
|
||||
if type(l:item) is v:t_dict && has_key(l:item, 'kind')
|
||||
if l:item.kind is# 'markdown'
|
||||
" Handle markdown values as we handle strings below.
|
||||
let l:item = get(l:item, 'value', '')
|
||||
elseif l:item.kind is# 'plaintext'
|
||||
" We shouldn't try to parse plaintext as markdown.
|
||||
" Pass the lines on and skip parsing them.
|
||||
call extend(l:lines, split(get(l:item, 'value', ''), "\n"))
|
||||
|
||||
continue
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:marked_list = []
|
||||
|
||||
" If the item is a string, then we should parse it as Markdown text.
|
||||
if type(l:item) is v:t_string
|
||||
let l:fence_language = v:null
|
||||
let l:fence_lines = []
|
||||
|
||||
for l:line in split(l:item, "\n")
|
||||
if l:fence_language is v:null
|
||||
" Look for the start of a code fence. (```python, etc.)
|
||||
let l:match = matchlist(l:line, '^```\(.*\)$')
|
||||
|
||||
if !empty(l:match)
|
||||
let l:fence_language = l:match[1]
|
||||
|
||||
if !empty(l:marked_list)
|
||||
call add(l:fence_lines, '')
|
||||
endif
|
||||
else
|
||||
if !empty(l:marked_list)
|
||||
\&& l:marked_list[-1][0] isnot v:null
|
||||
call add(l:marked_list, [v:null, ['']])
|
||||
endif
|
||||
|
||||
call add(l:marked_list, [v:null, [l:line]])
|
||||
endif
|
||||
elseif l:line =~# '^```$'
|
||||
" When we hit the end of a code fence, pass the fenced
|
||||
" lines on to the next steps below.
|
||||
call add(l:marked_list, [l:fence_language, l:fence_lines])
|
||||
let l:fence_language = v:null
|
||||
let l:fence_lines = []
|
||||
else
|
||||
" Gather lines inside of a code fence.
|
||||
call add(l:fence_lines, l:line)
|
||||
endif
|
||||
endfor
|
||||
" If the result from the LSP server is a {language: ..., value: ...}
|
||||
" Dictionary, then that should be interpreted as if it was:
|
||||
"
|
||||
" ```${language}
|
||||
" ${value}
|
||||
" ```
|
||||
elseif type(l:item) is v:t_dict
|
||||
\&& has_key(l:item, 'language')
|
||||
\&& type(l:item.language) is v:t_string
|
||||
\&& has_key(l:item, 'value')
|
||||
\&& type(l:item.value) is v:t_string
|
||||
call add(
|
||||
\ l:marked_list,
|
||||
\ [l:item.language, split(l:item.value, "\n")],
|
||||
\)
|
||||
endif
|
||||
|
||||
for [l:language, l:marked_lines] in l:marked_list
|
||||
if l:language is v:null
|
||||
" NOTE: We could handle other Markdown formatting here.
|
||||
call map(
|
||||
\ l:marked_lines,
|
||||
\ 'substitute(v:val, ''\\_'', ''_'', ''g'')',
|
||||
\)
|
||||
else
|
||||
let l:language = s:ConvertLanguageName(l:language)
|
||||
|
||||
if !empty(l:language)
|
||||
let l:includes[l:language] = printf(
|
||||
\ 'syntax/%s.vim',
|
||||
\ l:language,
|
||||
\)
|
||||
|
||||
let l:start = len(l:lines) + 1
|
||||
let l:end = l:start + len(l:marked_lines)
|
||||
let l:region_index += 1
|
||||
|
||||
call add(l:highlights, 'syntax region'
|
||||
\ . ' ALE_hover_' . l:region_index
|
||||
\ . ' start=/\%' . l:start . 'l/'
|
||||
\ . ' end=/\%' . l:end . 'l/'
|
||||
\ . ' contains=@ALE_hover_' . l:language
|
||||
\)
|
||||
endif
|
||||
endif
|
||||
|
||||
call extend(l:lines, l:marked_lines)
|
||||
endfor
|
||||
endfor
|
||||
|
||||
let l:include_commands = []
|
||||
|
||||
for [l:language, l:lang_path] in sort(items(l:includes))
|
||||
call add(l:include_commands, 'unlet! b:current_syntax')
|
||||
call add(
|
||||
\ l:include_commands,
|
||||
\ printf('syntax include @ALE_hover_%s %s', l:language, l:lang_path),
|
||||
\)
|
||||
endfor
|
||||
|
||||
return [l:include_commands + l:highlights, l:lines]
|
||||
endfunction
|
||||
|
||||
function! ale#hover#HandleLSPResponse(conn_id, response) abort
|
||||
if has_key(a:response, 'id')
|
||||
\&& has_key(s:hover_map, a:response.id)
|
||||
|
@ -82,40 +213,25 @@ function! ale#hover#HandleLSPResponse(conn_id, response) abort
|
|||
return
|
||||
endif
|
||||
|
||||
let l:result = l:result.contents
|
||||
let [l:commands, l:lines] = ale#hover#ParseLSPResult(l:result.contents)
|
||||
|
||||
if type(l:result) is v:t_string
|
||||
" The result can be just a string.
|
||||
let l:result = [l:result]
|
||||
endif
|
||||
|
||||
if type(l:result) is v:t_dict
|
||||
" If the result is an object, then it's markup content.
|
||||
let l:result = has_key(l:result, 'value') ? [l:result.value] : []
|
||||
endif
|
||||
|
||||
if type(l:result) is v:t_list
|
||||
" Replace objects with text values.
|
||||
call filter(l:result, '!(type(v:val) is v:t_dict && !has_key(v:val, ''value''))')
|
||||
call map(l:result, 'type(v:val) is v:t_string ? v:val : v:val.value')
|
||||
let l:str = join(l:result, "\n")
|
||||
let l:str = substitute(l:str, '^\s*\(.\{-}\)\s*$', '\1', '')
|
||||
|
||||
if !empty(l:str)
|
||||
if get(l:options, 'hover_from_balloonexpr', 0)
|
||||
\&& exists('*balloon_show')
|
||||
\&& ale#Var(l:options.buffer, 'set_balloons')
|
||||
call balloon_show(l:str)
|
||||
elseif get(l:options, 'truncated_echo', 0)
|
||||
call ale#cursor#TruncatedEcho(split(l:str, "\n")[0])
|
||||
elseif g:ale_hover_to_preview
|
||||
call ale#preview#Show(split(l:str, "\n"), {
|
||||
\ 'filetype': 'ale-preview.message',
|
||||
\ 'stay_here': 1,
|
||||
\})
|
||||
else
|
||||
call ale#util#ShowMessage(l:str)
|
||||
endif
|
||||
if !empty(l:lines)
|
||||
if get(l:options, 'hover_from_balloonexpr', 0)
|
||||
\&& exists('*balloon_show')
|
||||
\&& ale#Var(l:options.buffer, 'set_balloons')
|
||||
call balloon_show(join(l:lines, "\n"))
|
||||
elseif get(l:options, 'truncated_echo', 0)
|
||||
call ale#cursor#TruncatedEcho(l:lines[0])
|
||||
elseif g:ale_hover_to_preview
|
||||
call ale#preview#Show(l:lines, {
|
||||
\ 'filetype': 'ale-preview.message',
|
||||
\ 'stay_here': 1,
|
||||
\ 'commands': l:commands,
|
||||
\})
|
||||
else
|
||||
call ale#util#ShowMessage(join(l:lines, "\n"), {
|
||||
\ 'commands': l:commands,
|
||||
\})
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -187,6 +303,8 @@ function! ale#hover#Show(buffer, line, col, opt) abort
|
|||
endfor
|
||||
endfunction
|
||||
|
||||
let s:last_pos = [0, 0, 0]
|
||||
|
||||
" This function implements the :ALEHover command.
|
||||
function! ale#hover#ShowAtCursor() abort
|
||||
let l:buffer = bufnr('')
|
||||
|
@ -197,11 +315,20 @@ endfunction
|
|||
|
||||
function! ale#hover#ShowTruncatedMessageAtCursor() abort
|
||||
let l:buffer = bufnr('')
|
||||
let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer)
|
||||
let l:pos = getpos('.')[0:2]
|
||||
|
||||
if empty(l:loc)
|
||||
let l:pos = getpos('.')
|
||||
call ale#hover#Show(l:buffer, l:pos[1], l:pos[2], {'truncated_echo': 1})
|
||||
if l:pos != s:last_pos
|
||||
let s:last_pos = l:pos
|
||||
let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer)
|
||||
|
||||
if empty(l:loc)
|
||||
call ale#hover#Show(
|
||||
\ l:buffer,
|
||||
\ l:pos[1],
|
||||
\ l:pos[2],
|
||||
\ {'truncated_echo': 1},
|
||||
\)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ let s:default_ale_linter_aliases = {
|
|||
\ 'csh': 'sh',
|
||||
\ 'javascriptreact': ['javascript', 'jsx'],
|
||||
\ 'plaintex': 'tex',
|
||||
\ 'ps1': 'powershell',
|
||||
\ 'rmarkdown': 'r',
|
||||
\ 'rmd': 'r',
|
||||
\ 'systemverilog': 'verilog',
|
||||
|
|
|
@ -31,6 +31,10 @@ function! ale#preview#Show(lines, ...) abort
|
|||
setlocal readonly
|
||||
let &l:filetype = get(l:options, 'filetype', 'ale-preview')
|
||||
|
||||
for l:command in get(l:options, 'commands', [])
|
||||
call execute(l:command)
|
||||
endfor
|
||||
|
||||
if get(l:options, 'stay_here')
|
||||
wincmd p
|
||||
endif
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
" This probably doesn't handle Unicode characters well.
|
||||
function! s:EncodeChar(char) abort
|
||||
let l:result = ''
|
||||
|
||||
for l:index in range(strlen(a:char))
|
||||
let l:result .= printf('%%%02x', char2nr(a:char[l:index]))
|
||||
endfor
|
||||
|
||||
return l:result
|
||||
endfunction
|
||||
|
||||
function! ale#uri#Encode(value) abort
|
||||
return substitute(
|
||||
\ a:value,
|
||||
\ '\([^a-zA-Z0-9\\/$\-_.!*''(),]\)',
|
||||
\ '\=printf(''%%%02x'', char2nr(submatch(1)))',
|
||||
\ '\=s:EncodeChar(submatch(1))',
|
||||
\ 'g'
|
||||
\)
|
||||
endfunction
|
||||
|
@ -12,7 +21,7 @@ function! ale#uri#Decode(value) abort
|
|||
return substitute(
|
||||
\ a:value,
|
||||
\ '%\(\x\x\)',
|
||||
\ '\=nr2char(''0x'' . submatch(1))',
|
||||
\ '\=printf("%c", str2nr(submatch(1), 16))',
|
||||
\ 'g'
|
||||
\)
|
||||
endfunction
|
||||
|
|
|
@ -16,7 +16,9 @@ endfunction
|
|||
" Vim 8 does not support echoing long messages from asynchronous callbacks,
|
||||
" but NeoVim does. Small messages can be echoed in Vim 8, and larger messages
|
||||
" have to be shown in preview windows.
|
||||
function! ale#util#ShowMessage(string) abort
|
||||
function! ale#util#ShowMessage(string, ...) abort
|
||||
let l:options = get(a:000, 0, {})
|
||||
|
||||
if !has('nvim')
|
||||
call ale#preview#CloseIfTypeMatches('ale-preview.message')
|
||||
endif
|
||||
|
@ -25,10 +27,13 @@ function! ale#util#ShowMessage(string) abort
|
|||
if has('nvim') || (a:string !~? "\n" && len(a:string) < &columns)
|
||||
execute 'echo a:string'
|
||||
else
|
||||
call ale#preview#Show(split(a:string, "\n"), {
|
||||
\ 'filetype': 'ale-preview.message',
|
||||
\ 'stay_here': 1,
|
||||
\})
|
||||
call ale#preview#Show(split(a:string, "\n"), extend(
|
||||
\ {
|
||||
\ 'filetype': 'ale-preview.message',
|
||||
\ 'stay_here': 1,
|
||||
\ },
|
||||
\ l:options,
|
||||
\))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
@ -418,7 +423,10 @@ function! ale#util#Writefile(buffer, lines, filename) abort
|
|||
\ ? map(copy(a:lines), 'substitute(v:val, ''\r*$'', ''\r'', '''')')
|
||||
\ : a:lines
|
||||
|
||||
call writefile(l:corrected_lines, a:filename, 'S') " no-custom-checks
|
||||
" Set binary flag if buffer doesn't have eol and nofixeol to avoid appending newline
|
||||
let l:flags = !getbufvar(a:buffer, '&eol') && exists('+fixeol') && !&fixeol ? 'bS' : 'S'
|
||||
|
||||
call writefile(l:corrected_lines, a:filename, l:flags) " no-custom-checks
|
||||
endfunction
|
||||
|
||||
if !exists('s:patial_timers')
|
||||
|
|
|
@ -37,7 +37,7 @@ g:ale_c_build_dir *g:ale_c_build_dir*
|
|||
g:ale_c_parse_compile_commands *g:ale_c_parse_compile_commands*
|
||||
*b:ale_c_parse_compile_commands*
|
||||
Type: |Number|
|
||||
Default: `0`
|
||||
Default: `1`
|
||||
|
||||
If set to `1`, ALE will parse `compile_commands.json` files to automatically
|
||||
determine flags for C or C++ compilers. ALE will first search for the
|
||||
|
@ -45,9 +45,6 @@ g:ale_c_parse_compile_commands *g:ale_c_parse_compile_commands*
|
|||
`compile_commands.json` files in the directories for
|
||||
|g:ale_c_build_dir_names|.
|
||||
|
||||
If |g:ale_c_parse_makefile| or |b:ale_c_parse_makefile| is set to `1`, the
|
||||
output of `make -n` will be preferred over `compile_commands.json` files.
|
||||
|
||||
|
||||
g:ale_c_parse_makefile *g:ale_c_parse_makefile*
|
||||
*b:ale_c_parse_makefile*
|
||||
|
@ -58,6 +55,19 @@ g:ale_c_parse_makefile *g:ale_c_parse_makefile*
|
|||
set for C or C++ compilers. This can make it easier to determine the correct
|
||||
build flags to use for different files.
|
||||
|
||||
WARNING: Running `make -n` automatically can execute arbitrary code, even
|
||||
though it's supposed to be a dry run, so enable this option with care. You
|
||||
might prefer to use the buffer-local version of the option instead with
|
||||
|g:ale_pattern_options|, or you own code for checking which project you're
|
||||
in.
|
||||
|
||||
You might want to disable this option if `make -n` takes too long to run for
|
||||
projects you work on.
|
||||
|
||||
If |g:ale_c_parse_compile_commands| or |b:ale_c_parse_compile_commands| is
|
||||
set to `1`, flags taken from `compile_commands.json` will be preferred over
|
||||
`make -n` output.
|
||||
|
||||
|
||||
===============================================================================
|
||||
astyle *ale-c-astyle*
|
||||
|
|
|
@ -25,13 +25,6 @@ Installation
|
|||
|
||||
Install PSScriptAnalyzer by any means, so long as it can be automatically
|
||||
imported in PowerShell.
|
||||
Some PowerShell plugins set the filetype of files to `ps1`. To continue using
|
||||
these plugins, use the ale_linter_aliases global to alias `ps1` to `powershell`
|
||||
|
||||
>
|
||||
" Allow ps1 filetype to work with powershell linters
|
||||
let g:ale_linter_aliases = {'ps1': 'powershell'}
|
||||
<
|
||||
|
||||
g:ale_powershell_psscriptanalyzer_executable
|
||||
*g:ale_powershell_psscriptanalyzer_executable*
|
||||
|
|
|
@ -114,6 +114,14 @@ g:ale_ruby_rubocop_options *g:ale_ruby_rubocop_options*
|
|||
This variable can be changed to modify flags given to rubocop.
|
||||
|
||||
|
||||
g:ale_ruby_rubocop_auto_correct_all *g:ale_ruby_rubocop_auto_correct_all*
|
||||
*b:ale_ruby_rubocop_auto_correct_all*
|
||||
Type: Number
|
||||
Default: `0`
|
||||
|
||||
This variable can be changed to make rubocop to correct all offenses (unsafe).
|
||||
|
||||
|
||||
===============================================================================
|
||||
ruby *ale-ruby-ruby*
|
||||
|
||||
|
@ -172,8 +180,8 @@ g:ale_ruby_sorbet_options *g:ale_ruby_sorbet_options*
|
|||
===============================================================================
|
||||
standardrb *ale-ruby-standardrb*
|
||||
|
||||
g:ale_ruby_standardrb_executable *g:ale_ruby_standardrb_executable*
|
||||
*b:ale_ruby_standardrb_executable*
|
||||
g:ale_ruby_standardrb_executable *g:ale_ruby_standardrb_executable*
|
||||
*b:ale_ruby_standardrb_executable*
|
||||
Type: String
|
||||
Default: `'standardrb'`
|
||||
|
||||
|
|
|
@ -174,6 +174,18 @@ g:ale_rust_cargo_clippy_options
|
|||
only `cargo clippy` supports (e.g. `--deny`).
|
||||
|
||||
|
||||
g:ale_rust_cargo_target_dir
|
||||
*g:ale_rust_cargo_target_dir*
|
||||
*b:ale_rust_cargo_target_dir*
|
||||
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
Use a custom target directory when running the commands for ALE. This can
|
||||
help to avoid "waiting for file lock on build directory" messages when
|
||||
running `cargo` commands manually while ALE is performing its checks.
|
||||
|
||||
|
||||
===============================================================================
|
||||
rls *ale-rust-rls*
|
||||
|
||||
|
|
22
doc/ale.txt
22
doc/ale.txt
|
@ -246,7 +246,7 @@ A plugin might integrate its own checks with ALE like so: >
|
|||
|
||||
function! WorkDone(buffer, results) abort
|
||||
" Send results to ALE after they have been collected.
|
||||
call ale#other_source#ShowResults(buffer, 'some-name', a:results)
|
||||
call ale#other_source#ShowResults(a:buffer, 'some-name', a:results)
|
||||
endfunction
|
||||
<
|
||||
|
||||
|
@ -418,9 +418,12 @@ The |ALEComplete| command can be used to show completion suggestions manually,
|
|||
even when |g:ale_completion_enabled| is set to `0`. For manually requesting
|
||||
completion information with Deoplete, consult Deoplete's documentation.
|
||||
|
||||
When working with TypeScript files, ALE by can support automatic imports
|
||||
from external modules. This behavior can be enabled by setting the
|
||||
|g:ale_completion_tsserver_autoimport| variable to `1`.
|
||||
ALE by can support automatic imports from external modules. This behavior can
|
||||
be enabled by setting the |g:ale_completion_autoimport| variable to `1`.
|
||||
|
||||
When working with TypeScript files, ALE can remove warnings from your
|
||||
completions by setting the |g:ale_completion_tsserver_remove_warnings|
|
||||
variable to 1.
|
||||
|
||||
*ale-completion-completeopt-bug*
|
||||
|
||||
|
@ -681,8 +684,16 @@ g:ale_completion_enabled *g:ale_completion_enabled*
|
|||
|
||||
See |ale-completion|
|
||||
|
||||
g:ale_completion_tsserver_remove_warnings *g:ale_completion_tsserver_remove_warnings*
|
||||
|
||||
g:ale_completion_tsserver_autoimport *g:ale_completion_tsserver_autoimport*
|
||||
Type: Number
|
||||
Default: `0`
|
||||
|
||||
When this option is set to `0`, ALE will return all completion items,
|
||||
including those that are a warning. Warnings can be excluded from completed
|
||||
items by setting it to `1`.
|
||||
|
||||
g:ale_completion_autoimport *g:ale_completion_autoimport*
|
||||
|
||||
Type: Number
|
||||
Default: `0`
|
||||
|
@ -1227,6 +1238,7 @@ g:ale_linter_aliases *g:ale_linter_aliases*
|
|||
\ 'csh': 'sh',
|
||||
\ 'javascriptreact': ['javascript', 'jsx'],
|
||||
\ 'plaintex': 'tex',
|
||||
\ 'ps1': 'powershell',
|
||||
\ 'rmarkdown': 'r',
|
||||
\ 'rmd': 'r',
|
||||
\ 'systemverilog': 'verilog',
|
||||
|
|
|
@ -57,7 +57,7 @@ Execute(The build directory setting should override the options):
|
|||
\ . ' -checks=' . ale#Escape('*') . ' %s'
|
||||
\ . ' -p ' . ale#Escape('/foo/bar')
|
||||
|
||||
Execute(The build directory should be ignored for header files):
|
||||
Execute(The build directory should be used for header files):
|
||||
call ale#test#SetFilename('test.h')
|
||||
|
||||
let b:ale_c_clangtidy_checks = ['*']
|
||||
|
@ -66,12 +66,8 @@ Execute(The build directory should be ignored for header files):
|
|||
|
||||
AssertLinter 'clang-tidy',
|
||||
\ ale#Escape('clang-tidy')
|
||||
\ . ' -checks=' . ale#Escape('*') . ' %s -- -Wall'
|
||||
|
||||
call ale#test#SetFilename('test.h')
|
||||
|
||||
AssertLinter 'clang-tidy',
|
||||
\ ale#Escape('clang-tidy') . ' -checks=' . ale#Escape('*') . ' %s -- -Wall'
|
||||
\ . ' -checks=' . ale#Escape('*') . ' %s'
|
||||
\ . ' -p ' . ale#Escape('/foo/bar')
|
||||
|
||||
Execute(The executable should be configurable):
|
||||
let b:ale_c_clangtidy_checks = ['*']
|
||||
|
|
|
@ -169,10 +169,11 @@ Execute(Build supports all cargo flags):
|
|||
let g:ale_rust_cargo_check_tests = 1
|
||||
let g:ale_rust_cargo_check_examples = 1
|
||||
let b:ale_rust_cargo_default_feature_behavior = 'all'
|
||||
let b:ale_rust_cargo_target_dir = 'target/ale'
|
||||
|
||||
AssertLinter 'cargo', [
|
||||
\ ale#Escape('cargo') . ' --version',
|
||||
\ 'cargo build --all-targets --examples --tests --frozen --message-format=json -q --all-features',
|
||||
\ 'cargo build --all-targets --examples --tests --target-dir ' . ale#Escape('target/ale') . ' --frozen --message-format=json -q --all-features',
|
||||
\]
|
||||
|
||||
Execute(Clippy supports all cargo flags):
|
||||
|
@ -182,10 +183,11 @@ Execute(Clippy supports all cargo flags):
|
|||
let g:ale_rust_cargo_check_examples = 1
|
||||
let b:ale_rust_cargo_default_feature_behavior = 'all'
|
||||
let b:ale_rust_cargo_clippy_options = '-D warnings'
|
||||
let b:ale_rust_cargo_target_dir = 'target/ale'
|
||||
|
||||
AssertLinter 'cargo', [
|
||||
\ ale#Escape('cargo') . ' --version',
|
||||
\ 'cargo clippy --all-targets --examples --tests --frozen --message-format=json -q --all-features -- -D warnings',
|
||||
\ 'cargo clippy --all-targets --examples --tests --target-dir ' . ale#Escape('target/ale') . ' --frozen --message-format=json -q --all-features -- -D warnings',
|
||||
\]
|
||||
|
||||
Execute(cargo-check does not refer ale_rust_cargo_clippy_options):
|
||||
|
@ -197,3 +199,21 @@ Execute(cargo-check does not refer ale_rust_cargo_clippy_options):
|
|||
\ ale#Escape('cargo') . ' --version',
|
||||
\ 'cargo check --frozen --message-format=json -q',
|
||||
\]
|
||||
|
||||
Execute(`cargo --target-dir` should be used when the version is new enough and it is set):
|
||||
let b:ale_rust_cargo_target_dir = 'target/ale'
|
||||
|
||||
GivenCommandOutput ['cargo 0.17.0 (3423351a5 2017-10-06)']
|
||||
AssertLinter 'cargo', [
|
||||
\ ale#Escape('cargo') . ' --version',
|
||||
\ 'cargo check --target-dir ' . ale#Escape('target/ale') . g:suffix,
|
||||
\]
|
||||
|
||||
Execute(`cargo --target-dir` should not be used when the version is not new enough and it is set):
|
||||
let b:ale_rust_cargo_target_dir = 'target/ale'
|
||||
|
||||
GivenCommandOutput ['cargo 0.16.0 (3423351a5 2017-10-06)']
|
||||
AssertLinter 'cargo', [
|
||||
\ ale#Escape('cargo') . ' --version',
|
||||
\ 'cargo build' . g:suffix,
|
||||
\]
|
||||
|
|
|
@ -57,7 +57,7 @@ Execute(The build directory setting should override the options):
|
|||
\ . ' -checks=' . ale#Escape('*') . ' %s'
|
||||
\ . ' -p ' . ale#Escape('/foo/bar')
|
||||
|
||||
Execute(The build directory should be ignored for header files):
|
||||
Execute(The build directory should be used for header files):
|
||||
call ale#test#SetFilename('test.h')
|
||||
|
||||
let b:ale_cpp_clangtidy_checks = ['*']
|
||||
|
@ -66,12 +66,16 @@ Execute(The build directory should be ignored for header files):
|
|||
|
||||
AssertLinter 'clang-tidy',
|
||||
\ ale#Escape('clang-tidy')
|
||||
\ . ' -checks=' . ale#Escape('*') . ' %s -- -Wall'
|
||||
\ . ' -checks=' . ale#Escape('*') . ' %s'
|
||||
\ . ' -p ' . ale#Escape('/foo/bar')
|
||||
\ . ' -- -x c++'
|
||||
|
||||
call ale#test#SetFilename('test.hpp')
|
||||
|
||||
AssertLinter 'clang-tidy',
|
||||
\ ale#Escape('clang-tidy') . ' -checks=' . ale#Escape('*') . ' %s -- -Wall'
|
||||
\ ale#Escape('clang-tidy')
|
||||
\ . ' -checks=' . ale#Escape('*') . ' %s'
|
||||
\ . ' -p ' . ale#Escape('/foo/bar')
|
||||
|
||||
Execute(The executable should be configurable):
|
||||
let b:ale_cpp_clangtidy_checks = ['*']
|
||||
|
|
|
@ -34,18 +34,20 @@ Execute(The build directory should be configurable):
|
|||
\ ale#Escape('clazy-standalone')
|
||||
\ . ' -checks=' . ale#Escape('level1') . ' -p ' . ale#Escape('/foo/bar') . ' %s'
|
||||
|
||||
Execute(The build directory should be ignored for header files):
|
||||
Execute(The build directory should be used for header files):
|
||||
call ale#test#SetFilename('test.h')
|
||||
|
||||
let b:ale_c_build_dir = '/foo/bar'
|
||||
|
||||
AssertLinter 'clazy-standalone',
|
||||
\ ale#Escape('clazy-standalone') . ' -checks=' . ale#Escape('level1') . ' %s'
|
||||
\ ale#Escape('clazy-standalone')
|
||||
\ . ' -checks=' . ale#Escape('level1') . ' -p ' . ale#Escape('/foo/bar') . ' %s'
|
||||
|
||||
call ale#test#SetFilename('test.hpp')
|
||||
|
||||
AssertLinter 'clazy-standalone',
|
||||
\ ale#Escape('clazy-standalone') . ' -checks=' . ale#Escape('level1') . ' %s'
|
||||
\ ale#Escape('clazy-standalone')
|
||||
\ . ' -checks=' . ale#Escape('level1') . ' -p ' . ale#Escape('/foo/bar') . ' %s'
|
||||
|
||||
Execute(The executable should be configurable):
|
||||
let b:ale_cpp_clazy_executable = 'foobar'
|
||||
|
|
|
@ -121,7 +121,7 @@ Execute(The right message should be sent for the initial tsserver request):
|
|||
\ 'line': 1,
|
||||
\ 'offset': 3,
|
||||
\ 'prefix': 'fo',
|
||||
\ 'includeExternalModuleExports': g:ale_completion_tsserver_autoimport,
|
||||
\ 'includeExternalModuleExports': g:ale_completion_autoimport,
|
||||
\ }]],
|
||||
\ g:message_list
|
||||
" We should set up the completion info correctly.
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
Before:
|
||||
Save g:ale_completion_autoimport
|
||||
Save g:ale_completion_max_suggestions
|
||||
|
||||
let g:ale_completion_max_suggestions = 50
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
unlet! b:ale_completion_info
|
||||
|
||||
Execute(Should handle Rust completion results correctly):
|
||||
|
@ -527,7 +535,9 @@ Execute(Should handle completion messages with the deprecated insertText attribu
|
|||
\ },
|
||||
\ })
|
||||
|
||||
Execute(Should handle completion messages with additionalTextEdits):
|
||||
Execute(Should handle completion messages with additionalTextEdits when ale_completion_autoimport is turned on):
|
||||
let g:ale_completion_autoimport = 1
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
|
@ -596,3 +606,42 @@ Execute(Should handle completion messages with additionalTextEdits):
|
|||
\ ],
|
||||
\ },
|
||||
\ })
|
||||
|
||||
Execute(Should not handle completion messages with additionalTextEdits when ale_completion_autoimport is turned off):
|
||||
let g:ale_completion_autoimport = 0
|
||||
|
||||
AssertEqual
|
||||
\ [],
|
||||
\ ale#completion#ParseLSPCompletions({
|
||||
\ 'id': 226,
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'result': {
|
||||
\ 'isIncomplete': v:false,
|
||||
\ 'items': [
|
||||
\ {
|
||||
\ 'detail': 'PlayTimeCallback',
|
||||
\ 'filterText': 'next_callback',
|
||||
\ 'insertText': 'next_callback',
|
||||
\ 'insertTextFormat': 1,
|
||||
\ 'kind': 6,
|
||||
\ 'label': ' next_callback',
|
||||
\ 'sortText': '3ee19999next_callback',
|
||||
\ 'additionalTextEdits': [
|
||||
\ {
|
||||
\ 'range': {
|
||||
\ 'start': {
|
||||
\ 'line': 10,
|
||||
\ 'character': 1,
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line': 12,
|
||||
\ 'character': 3,
|
||||
\ },
|
||||
\ },
|
||||
\ 'newText': 'from "module" import next_callback',
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ })
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
Before:
|
||||
Save g:ale_completion_tsserver_remove_warnings
|
||||
|
||||
let g:ale_completion_tsserver_remove_warnings = 0
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
unlet! b:ale_tsserver_completion_names
|
||||
|
||||
Execute(TypeScript completions responses should be parsed correctly):
|
||||
|
@ -29,6 +36,51 @@ Execute(TypeScript completions responses should be parsed correctly):
|
|||
\ ],
|
||||
\})
|
||||
|
||||
Execute(TypeScript completions responses should include warnings):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'word': 'foo',
|
||||
\ 'source': '/path/to/foo.ts',
|
||||
\ },
|
||||
\ {
|
||||
\ 'word': 'bar',
|
||||
\ 'source': '',
|
||||
\ },
|
||||
\ {
|
||||
\ 'word': 'baz',
|
||||
\ 'source': '',
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#completion#ParseTSServerCompletions({
|
||||
\ 'body': [
|
||||
\ {'name': 'foo', 'source': '/path/to/foo.ts'},
|
||||
\ {'name': 'bar', 'kind': 'warning'},
|
||||
\ {'name': 'baz'},
|
||||
\ ],
|
||||
\})
|
||||
|
||||
Execute(TypeScript completions responses should not include warnings if excluded):
|
||||
let g:ale_completion_tsserver_remove_warnings = 1
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'word': 'foo',
|
||||
\ 'source': '/path/to/foo.ts',
|
||||
\ },
|
||||
\ {
|
||||
\ 'word': 'baz',
|
||||
\ 'source': '',
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#completion#ParseTSServerCompletions({
|
||||
\ 'body': [
|
||||
\ {'name': 'foo', 'source': '/path/to/foo.ts'},
|
||||
\ {'name': 'bar', 'kind': 'warning'},
|
||||
\ {'name': 'baz'},
|
||||
\ ],
|
||||
\})
|
||||
|
||||
Execute(TypeScript completion details responses should be parsed correctly):
|
||||
AssertEqual
|
||||
\ [
|
||||
|
@ -38,7 +90,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
|
|||
\ 'info': '',
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'dup': g:ale_completion_tsserver_autoimport,
|
||||
\ 'dup': g:ale_completion_autoimport,
|
||||
\ },
|
||||
\ {
|
||||
\ 'word': 'def',
|
||||
|
@ -46,7 +98,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
|
|||
\ 'info': 'foo bar baz',
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'dup': g:ale_completion_tsserver_autoimport,
|
||||
\ 'dup': g:ale_completion_autoimport,
|
||||
\ },
|
||||
\ {
|
||||
\ 'word': 'ghi',
|
||||
|
@ -54,7 +106,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
|
|||
\ 'info': '',
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'dup': g:ale_completion_tsserver_autoimport,
|
||||
\ 'dup': g:ale_completion_autoimport,
|
||||
\ },
|
||||
\ ],
|
||||
\ ale#completion#ParseTSServerCompletionEntryDetails({
|
||||
|
@ -132,7 +184,7 @@ Execute(Entries without details should be included in the responses):
|
|||
\ 'changes': [],
|
||||
\ }],
|
||||
\ }),
|
||||
\ 'dup': g:ale_completion_tsserver_autoimport,
|
||||
\ 'dup': g:ale_completion_autoimport,
|
||||
\ },
|
||||
\ {
|
||||
\ 'word': 'def',
|
||||
|
@ -140,7 +192,7 @@ Execute(Entries without details should be included in the responses):
|
|||
\ 'info': 'foo bar baz',
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'dup': g:ale_completion_tsserver_autoimport,
|
||||
\ 'dup': g:ale_completion_autoimport,
|
||||
\ },
|
||||
\ {
|
||||
\ 'word': 'xyz',
|
||||
|
@ -197,3 +249,54 @@ Execute(Entries without details should be included in the responses):
|
|||
\ },
|
||||
\ ],
|
||||
\})
|
||||
|
||||
Execute(Default imports should be handled correctly):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'word': 'abcd',
|
||||
\ 'menu': 'Import default ''abcd'' from module "./foo" (alias) const abcd: 3',
|
||||
\ 'info': '',
|
||||
\ 'kind': 't',
|
||||
\ 'icase': 1,
|
||||
\ 'user_data': json_encode({
|
||||
\ 'codeActions': [{
|
||||
\ 'description': 'Import default ''abcd'' from module "./foo"',
|
||||
\ 'changes': [],
|
||||
\ }],
|
||||
\ }),
|
||||
\ 'dup': g:ale_completion_autoimport,
|
||||
\ },
|
||||
\ ],
|
||||
\ ale#completion#ParseTSServerCompletionEntryDetails({
|
||||
\ 'body': [
|
||||
\ {
|
||||
\ 'name': 'default',
|
||||
\ 'kind': 'alias',
|
||||
\ 'displayParts': [
|
||||
\ {'kind': 'punctuation', 'text': '('},
|
||||
\ {'kind': 'text', 'text': 'alias'},
|
||||
\ {'kind': 'punctuation', 'text': ')'},
|
||||
\ {'kind': 'space', 'text': ' '},
|
||||
\ {'kind': 'keyword', 'text': 'const'},
|
||||
\ {'kind': 'space', 'text': ' '},
|
||||
\ {'kind': 'localName', 'text': 'abcd'},
|
||||
\ {'kind': 'punctuation', 'text': ':'},
|
||||
\ {'kind': 'space', 'text': ' '},
|
||||
\ {'kind': 'stringLiteral', 'text': '3'},
|
||||
\ {'kind': 'lineBreak', 'text': '^@'},
|
||||
\ {'kind': 'keyword', 'text': 'export'},
|
||||
\ {'kind': 'space', 'text': ' '},
|
||||
\ {'kind': 'keyword', 'text': 'default'},
|
||||
\ {'kind': 'space', 'text': ' '},
|
||||
\ {'kind': 'aliasName', 'text': 'abcd'}
|
||||
\ ],
|
||||
\ 'codeActions': [
|
||||
\ {
|
||||
\ 'description': 'Import default ''abcd'' from module "./foo"',
|
||||
\ 'changes': [],
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ ],
|
||||
\ })
|
||||
|
|
19
test/fixers/test_prettier_standard_callback.vader
Normal file
19
test/fixers/test_prettier_standard_callback.vader
Normal file
|
@ -0,0 +1,19 @@
|
|||
Before:
|
||||
call ale#assert#SetUpFixerTest('javascript', 'prettier_standard')
|
||||
|
||||
silent cd ..
|
||||
silent cd command_callback
|
||||
let g:dir = getcwd()
|
||||
|
||||
After:
|
||||
call ale#assert#TearDownFixerTest()
|
||||
|
||||
Execute(The prettier callback should return the correct default values):
|
||||
call ale#test#SetFilename('../prettier-test-files/testfile.js')
|
||||
|
||||
AssertFixer
|
||||
\ {
|
||||
\ 'command': ale#Escape(g:ale_javascript_prettier_standard_executable)
|
||||
\ . ' --stdin'
|
||||
\ . ' --stdin-filepath=%s ',
|
||||
\ }
|
|
@ -21,9 +21,10 @@ Execute(The rubocop callback should return the correct default values):
|
|||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'read_temporary_file': 1,
|
||||
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
|
||||
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
|
||||
\ . ' --auto-correct --force-exclusion %t',
|
||||
\ . ' --auto-correct --force-exclusion --stdin '
|
||||
\ . ale#Escape(expand('#' . bufnr('') . ':p')),
|
||||
\ },
|
||||
\ ale#fixers#rubocop#Fix(bufnr(''))
|
||||
|
||||
|
@ -32,10 +33,11 @@ Execute(The rubocop callback should include configuration files):
|
|||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'read_temporary_file': 1,
|
||||
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
|
||||
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
|
||||
\ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.rubocop.yml'))
|
||||
\ . ' --auto-correct --force-exclusion %t',
|
||||
\ . ' --auto-correct --force-exclusion --stdin '
|
||||
\ . ale#Escape(expand('#' . bufnr('') . ':p')),
|
||||
\ },
|
||||
\ ale#fixers#rubocop#Fix(bufnr(''))
|
||||
|
||||
|
@ -45,10 +47,64 @@ Execute(The rubocop callback should include custom rubocop options):
|
|||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'read_temporary_file': 1,
|
||||
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
|
||||
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
|
||||
\ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.rubocop.yml'))
|
||||
\ . ' --except Lint/Debugger'
|
||||
\ . ' --auto-correct --force-exclusion %t',
|
||||
\ . ' --auto-correct --force-exclusion --stdin '
|
||||
\ . ale#Escape(expand('#' . bufnr('') . ':p')),
|
||||
\ },
|
||||
\ ale#fixers#rubocop#Fix(bufnr(''))
|
||||
|
||||
Execute(The rubocop callback should use auto-correct-all option when set):
|
||||
let g:ale_ruby_rubocop_auto_correct_all = 1
|
||||
call ale#test#SetFilename('ruby_paths/with_config/dummy.rb')
|
||||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
|
||||
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
|
||||
\ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.rubocop.yml'))
|
||||
\ . ' --auto-correct-all --force-exclusion --stdin '
|
||||
\ . ale#Escape(expand('#' . bufnr('') . ':p')),
|
||||
\ },
|
||||
\ ale#fixers#rubocop#Fix(bufnr(''))
|
||||
|
||||
Execute(The rubocop post-processor should remove diagnostics content):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 'class MyModel < ApplicationRecord',
|
||||
\ ' # rubocop:disable Rails/InverseOf',
|
||||
\ ' has_one :something',
|
||||
\ ' # rubocop:enable Rails/InverseOf',
|
||||
\ 'end',
|
||||
\ '',
|
||||
\ 'array = [1, 2, 3,',
|
||||
\ ' 4, 5, 6]',
|
||||
\ 'array = [''run'',',
|
||||
\ ' ''forrest'',',
|
||||
\ ' ''run'']',
|
||||
\ ],
|
||||
\ ale#fixers#rubocop#PostProcess(bufnr(''), [
|
||||
\ 'Inspecting 1 file',
|
||||
\ 'C',
|
||||
\ '',
|
||||
\ 'Offenses:',
|
||||
\ 'app/models/my_model.rb:8:3: C: [Corrected] Layout/ArrayAlignment: ',
|
||||
\ '4, 5, 6]',
|
||||
\ '^',
|
||||
\ '',
|
||||
\ '1 file inspected, 3 offenses detected, 3 offenses corrected',
|
||||
\ '====================',
|
||||
\ 'class MyModel < ApplicationRecord',
|
||||
\ ' # rubocop:disable Rails/InverseOf',
|
||||
\ ' has_one :something',
|
||||
\ ' # rubocop:enable Rails/InverseOf',
|
||||
\ 'end',
|
||||
\ '',
|
||||
\ 'array = [1, 2, 3,',
|
||||
\ ' 4, 5, 6]',
|
||||
\ 'array = [''run'',',
|
||||
\ ' ''forrest'',',
|
||||
\ ' ''run'']',
|
||||
\ ])
|
||||
|
|
|
@ -27,7 +27,7 @@ Execute(The tslint callback should return the correct default values):
|
|||
\ 'read_temporary_file': 1,
|
||||
\ 'command': ale#Escape('tslint')
|
||||
\ . ' -c ' . ale#Escape('tslint.json')
|
||||
\ . ' --fix %t',
|
||||
\ . ' --outputAbsolutePaths --fix %t',
|
||||
\ },
|
||||
\ ale#fixers#tslint#Fix(bufnr(''))
|
||||
|
||||
|
@ -40,6 +40,6 @@ Execute(The tslint callback should include custom tslint config option):
|
|||
\ 'read_temporary_file': 1,
|
||||
\ 'command': ale#Escape('tslint')
|
||||
\ . ' -c ' . ale#Escape('.tslintrc')
|
||||
\ . ' --fix %t',
|
||||
\ . ' --outputAbsolutePaths --fix %t',
|
||||
\ },
|
||||
\ ale#fixers#tslint#Fix(bufnr(''))
|
||||
|
|
|
@ -10,12 +10,14 @@ Execute(The vlog handler should parse old-style lines correctly):
|
|||
\ {
|
||||
\ 'lnum': 7,
|
||||
\ 'type': 'W',
|
||||
\ 'text': '(vlog-2623) Undefined variable: C.'
|
||||
\ 'text': '(vlog-2623) Undefined variable: C.',
|
||||
\ 'filename': 'add.v'
|
||||
\ },
|
||||
\ {
|
||||
\ 'lnum': 1,
|
||||
\ 'type': 'E',
|
||||
\ 'text': '(vlog-13294) Identifier must be declared with a port mode: C.'
|
||||
\ 'text': '(vlog-13294) Identifier must be declared with a port mode: C.',
|
||||
\ 'filename': 'file.v'
|
||||
\ },
|
||||
\ ],
|
||||
\ ale_linters#verilog#vlog#Handle(bufnr(''), [
|
||||
|
@ -29,12 +31,14 @@ Execute(The vlog handler should parse new-style lines correctly):
|
|||
\ {
|
||||
\ 'lnum': 7,
|
||||
\ 'type': 'W',
|
||||
\ 'text': '(vlog-2623) Undefined variable: C.'
|
||||
\ 'text': '(vlog-2623) Undefined variable: C.',
|
||||
\ 'filename': 'add.v'
|
||||
\ },
|
||||
\ {
|
||||
\ 'lnum': 1,
|
||||
\ 'type': 'E',
|
||||
\ 'text': '(vlog-13294) Identifier must be declared with a port mode: C.'
|
||||
\ 'text': '(vlog-13294) Identifier must be declared with a port mode: C.',
|
||||
\ 'filename': 'file.v'
|
||||
\ },
|
||||
\ ],
|
||||
\ ale_linters#verilog#vlog#Handle(bufnr(''), [
|
||||
|
|
|
@ -5,7 +5,7 @@ Before:
|
|||
let g:Callback = 0
|
||||
let g:message_list = []
|
||||
let g:item_list = []
|
||||
let g:echo_list = []
|
||||
let g:show_message_arg_list = []
|
||||
|
||||
runtime autoload/ale/linter.vim
|
||||
runtime autoload/ale/lsp.vim
|
||||
|
@ -27,8 +27,8 @@ Before:
|
|||
return 42
|
||||
endfunction
|
||||
|
||||
function! ale#util#ShowMessage(string) abort
|
||||
call add(g:echo_list, a:string)
|
||||
function! ale#util#ShowMessage(string, ...) abort
|
||||
call add(g:show_message_arg_list, [a:string] + a:000)
|
||||
endfunction
|
||||
|
||||
function! HandleValidLSPResult(result) abort
|
||||
|
@ -58,7 +58,7 @@ After:
|
|||
unlet! g:Callback
|
||||
unlet! g:message_list
|
||||
unlet! b:ale_linters
|
||||
unlet! g:echo_list
|
||||
unlet! g:show_message_arg_list
|
||||
|
||||
delfunction HandleValidLSPResult
|
||||
|
||||
|
@ -112,31 +112,31 @@ Execute(tsserver quickinfo displayString values should be displayed):
|
|||
\ }
|
||||
\)
|
||||
|
||||
AssertEqual ['foo bar'], g:echo_list
|
||||
AssertEqual [['foo bar']], g:show_message_arg_list
|
||||
AssertEqual {}, ale#hover#GetMap()
|
||||
|
||||
Execute(LSP hover responses with just a string should be handled):
|
||||
call HandleValidLSPResult({'contents': 'foobar'})
|
||||
|
||||
AssertEqual ['foobar'], g:echo_list
|
||||
AssertEqual [['foobar', {'commands': []}]], g:show_message_arg_list
|
||||
AssertEqual {}, ale#hover#GetMap()
|
||||
|
||||
Execute(LSP hover null responses should be handled):
|
||||
call HandleValidLSPResult(v:null)
|
||||
|
||||
AssertEqual [], g:echo_list
|
||||
AssertEqual [], g:show_message_arg_list
|
||||
AssertEqual {}, ale#hover#GetMap()
|
||||
|
||||
Execute(LSP hover responses with markup content should be handled):
|
||||
call HandleValidLSPResult({'contents': {'kind': 'something', 'value': 'markup'}})
|
||||
call HandleValidLSPResult({'contents': {'kind': 'markdown', 'value': 'markup'}})
|
||||
|
||||
AssertEqual ['markup'], g:echo_list
|
||||
AssertEqual [['markup', {'commands': []}]], g:show_message_arg_list
|
||||
AssertEqual {}, ale#hover#GetMap()
|
||||
|
||||
Execute(LSP hover responses with markup content missing values should be handled):
|
||||
call HandleValidLSPResult({'contents': {'kind': 'something'}})
|
||||
call HandleValidLSPResult({'contents': {'kind': 'markdown'}})
|
||||
|
||||
AssertEqual [], g:echo_list
|
||||
AssertEqual [], g:show_message_arg_list
|
||||
AssertEqual {}, ale#hover#GetMap()
|
||||
|
||||
Execute(LSP hover response with lists of strings should be handled):
|
||||
|
@ -145,17 +145,27 @@ Execute(LSP hover response with lists of strings should be handled):
|
|||
\ "bar\n",
|
||||
\]})
|
||||
|
||||
AssertEqual ["foo\n\nbar\n"], g:echo_list
|
||||
AssertEqual [["foo\n\nbar", {'commands': []}]], g:show_message_arg_list
|
||||
AssertEqual {}, ale#hover#GetMap()
|
||||
|
||||
Execute(LSP hover response with lists of strings and marked strings should be handled):
|
||||
call HandleValidLSPResult({'contents': [
|
||||
\ {'language': 'rust', 'value': 'foo'},
|
||||
\ {'language': 'foobar'},
|
||||
\ "bar\n",
|
||||
\]})
|
||||
|
||||
AssertEqual ["foo\nbar\n"], g:echo_list
|
||||
AssertEqual [
|
||||
\ [
|
||||
\ "foo\n\nbar",
|
||||
\ {
|
||||
\ 'commands': [
|
||||
\ 'unlet! b:current_syntax',
|
||||
\ 'syntax include @ALE_hover_rust syntax/rust.vim',
|
||||
\ 'syntax region ALE_hover_1 start=/\%1l/ end=/\%2l/ contains=@ALE_hover_rust',
|
||||
\ ],
|
||||
\ },
|
||||
\ ],
|
||||
\], g:show_message_arg_list
|
||||
AssertEqual {}, ale#hover#GetMap()
|
||||
|
||||
Execute(tsserver responses for documentation requests should be handled):
|
||||
|
|
173
test/test_hover_parsing.vader
Normal file
173
test/test_hover_parsing.vader
Normal file
|
@ -0,0 +1,173 @@
|
|||
Execute(Invalid results should be handled):
|
||||
AssertEqual [[], []], ale#hover#ParseLSPResult(0)
|
||||
AssertEqual [[], []], ale#hover#ParseLSPResult([0])
|
||||
AssertEqual [[], []], ale#hover#ParseLSPResult('')
|
||||
AssertEqual [[], []], ale#hover#ParseLSPResult({})
|
||||
AssertEqual [[], []], ale#hover#ParseLSPResult([{}])
|
||||
AssertEqual [[], []], ale#hover#ParseLSPResult([''])
|
||||
AssertEqual [[], []], ale#hover#ParseLSPResult({'value': ''})
|
||||
AssertEqual [[], []], ale#hover#ParseLSPResult([{'value': ''}])
|
||||
AssertEqual [[], []], ale#hover#ParseLSPResult({'kind': 'markdown'})
|
||||
AssertEqual [[], []], ale#hover#ParseLSPResult({'kind': 'plaintext'})
|
||||
AssertEqual [[], []], ale#hover#ParseLSPResult({'kind': 'x', 'value': 'xxx'})
|
||||
|
||||
Execute(A string with a code fence should be handled):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ [
|
||||
\ 'unlet! b:current_syntax',
|
||||
\ 'syntax include @ALE_hover_python syntax/python.vim',
|
||||
\ 'syntax region ALE_hover_1 start=/\%1l/ end=/\%3l/ contains=@ALE_hover_python',
|
||||
\ ],
|
||||
\ [
|
||||
\ 'def foo():',
|
||||
\ ' pass',
|
||||
\ ],
|
||||
\ ],
|
||||
\ ale#hover#ParseLSPResult(join([
|
||||
\ '```python',
|
||||
\ 'def foo():',
|
||||
\ ' pass',
|
||||
\ '```',
|
||||
\ ], "\n"))
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ [
|
||||
\ 'unlet! b:current_syntax',
|
||||
\ 'syntax include @ALE_hover_python syntax/python.vim',
|
||||
\ 'unlet! b:current_syntax',
|
||||
\ 'syntax include @ALE_hover_typescript syntax/typescript.vim',
|
||||
\ 'syntax region ALE_hover_1 start=/\%1l/ end=/\%3l/ contains=@ALE_hover_python',
|
||||
\ 'syntax region ALE_hover_2 start=/\%5l/ end=/\%8l/ contains=@ALE_hover_python',
|
||||
\ 'syntax region ALE_hover_3 start=/\%8l/ end=/\%10l/ contains=@ALE_hover_typescript',
|
||||
\ ],
|
||||
\ [
|
||||
\ 'def foo():',
|
||||
\ ' pass',
|
||||
\ '',
|
||||
\ 'middle line',
|
||||
\ '',
|
||||
\ 'def bar():',
|
||||
\ ' pass',
|
||||
\ '',
|
||||
\ 'const baz = () => undefined',
|
||||
\ ],
|
||||
\ ],
|
||||
\ ale#hover#ParseLSPResult(join([
|
||||
\ '```python',
|
||||
\ 'def foo():',
|
||||
\ ' pass',
|
||||
\ '```',
|
||||
\ 'middle line',
|
||||
\ '```python',
|
||||
\ 'def bar():',
|
||||
\ ' pass',
|
||||
\ '```',
|
||||
\ '```typescript',
|
||||
\ 'const baz = () => undefined',
|
||||
\ '```',
|
||||
\ ], "\n"))
|
||||
|
||||
Execute(Multiple strings with fences should be handled):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ [
|
||||
\ 'unlet! b:current_syntax',
|
||||
\ 'syntax include @ALE_hover_python syntax/python.vim',
|
||||
\ 'unlet! b:current_syntax',
|
||||
\ 'syntax include @ALE_hover_typescript syntax/typescript.vim',
|
||||
\ 'syntax region ALE_hover_1 start=/\%1l/ end=/\%3l/ contains=@ALE_hover_python',
|
||||
\ 'syntax region ALE_hover_2 start=/\%5l/ end=/\%8l/ contains=@ALE_hover_python',
|
||||
\ 'syntax region ALE_hover_3 start=/\%8l/ end=/\%10l/ contains=@ALE_hover_typescript',
|
||||
\ ],
|
||||
\ [
|
||||
\ 'def foo():',
|
||||
\ ' pass',
|
||||
\ '',
|
||||
\ 'middle line',
|
||||
\ '',
|
||||
\ 'def bar():',
|
||||
\ ' pass',
|
||||
\ '',
|
||||
\ 'const baz = () => undefined',
|
||||
\ ],
|
||||
\ ],
|
||||
\ ale#hover#ParseLSPResult([
|
||||
\ join([
|
||||
\ '```python',
|
||||
\ 'def foo():',
|
||||
\ ' pass',
|
||||
\ '```',
|
||||
\ ], "\n"),
|
||||
\ join([
|
||||
\ 'middle line',
|
||||
\ '```python',
|
||||
\ 'def bar():',
|
||||
\ ' pass',
|
||||
\ '```',
|
||||
\ '```typescript',
|
||||
\ 'const baz = () => undefined',
|
||||
\ '```',
|
||||
\ ], "\n"),
|
||||
\ ])
|
||||
|
||||
Execute(Objects with kinds should be handled):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ [
|
||||
\ 'unlet! b:current_syntax',
|
||||
\ 'syntax include @ALE_hover_python syntax/python.vim',
|
||||
\ 'syntax region ALE_hover_1 start=/\%1l/ end=/\%3l/ contains=@ALE_hover_python',
|
||||
\ ],
|
||||
\ [
|
||||
\ 'def foo():',
|
||||
\ ' pass',
|
||||
\ '',
|
||||
\ '```typescript',
|
||||
\ 'const baz = () => undefined',
|
||||
\ '```',
|
||||
\ ],
|
||||
\ ],
|
||||
\ ale#hover#ParseLSPResult([
|
||||
\ {
|
||||
\ 'kind': 'markdown',
|
||||
\ 'value': join([
|
||||
\ '```python',
|
||||
\ 'def foo():',
|
||||
\ ' pass',
|
||||
\ '```',
|
||||
\ ], "\n"),
|
||||
\ },
|
||||
\ {
|
||||
\ 'kind': 'plaintext',
|
||||
\ 'value': join([
|
||||
\ '```typescript',
|
||||
\ 'const baz = () => undefined',
|
||||
\ '```',
|
||||
\ ], "\n"),
|
||||
\ },
|
||||
\ ])
|
||||
|
||||
Execute(Simple markdown formatting should be handled):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ [
|
||||
\ 'unlet! b:current_syntax',
|
||||
\ 'syntax include @ALE_hover_python syntax/python.vim',
|
||||
\ 'syntax region ALE_hover_1 start=/\%1l/ end=/\%3l/ contains=@ALE_hover_python',
|
||||
\ ],
|
||||
\ [
|
||||
\ 'def foo():',
|
||||
\ ' pass',
|
||||
\ '',
|
||||
\ 'formatted _ line _',
|
||||
\ ],
|
||||
\ ],
|
||||
\ ale#hover#ParseLSPResult(join([
|
||||
\ '```python',
|
||||
\ 'def foo():',
|
||||
\ ' pass',
|
||||
\ '```',
|
||||
\ 'formatted \_ line \_',
|
||||
\ ], "\n"))
|
|
@ -1,3 +1,6 @@
|
|||
Before:
|
||||
scriptencoding utf-8
|
||||
|
||||
Execute(ale#path#ToURI should work for Windows paths):
|
||||
AssertEqual 'file:///C:/foo/bar/baz.tst', ale#path#ToURI('C:\foo\bar\baz.tst')
|
||||
AssertEqual 'foo/bar/baz.tst', ale#path#ToURI('foo\bar\baz.tst')
|
||||
|
@ -62,3 +65,9 @@ Execute(ale#path#ToURI should percent encode unsafe characters):
|
|||
|
||||
Execute(ale#path#FromURI should decode percent encodings):
|
||||
AssertEqual ' +:?&=', ale#path#FromURI('%20%2b%3a%3f%26%3d')
|
||||
|
||||
Execute(ale#path#ToURI should handle UTF-8):
|
||||
AssertEqual 'file:///T%c3%a9l%c3%a9chargement', ale#path#ToURI('/Téléchargement')
|
||||
|
||||
Execute(ale#path#FromURI should handle UTF-8):
|
||||
AssertEqual '/Téléchargement', ale#path#FromURI('file:///T%C3%A9l%C3%A9chargement')
|
||||
|
|
|
@ -69,3 +69,49 @@ Execute(Unix file lines should be written as normal):
|
|||
AssertEqual
|
||||
\ ['first', 'second', 'third', ''],
|
||||
\ readfile(g:new_line_test_file, 'b')
|
||||
|
||||
Execute(Newline at end of file should be preserved even when nofixeol):
|
||||
call ale#test#SetFilename(g:new_line_test_file)
|
||||
|
||||
setlocal buftype=
|
||||
noautocmd :w
|
||||
noautocmd :e! ++ff=unix
|
||||
set eol
|
||||
set nofixeol
|
||||
|
||||
call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file)
|
||||
|
||||
AssertEqual
|
||||
\ ['first', 'second', 'third', ''],
|
||||
\ readfile(g:new_line_test_file, 'b')
|
||||
|
||||
Execute(Newline should not be appended on write when noeol and nofixeol):
|
||||
call ale#test#SetFilename(g:new_line_test_file)
|
||||
|
||||
setlocal buftype=
|
||||
noautocmd :w
|
||||
noautocmd :e! ++ff=unix
|
||||
set noeol
|
||||
set nofixeol
|
||||
|
||||
call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file)
|
||||
|
||||
AssertEqual
|
||||
\ ['first', 'second', 'third'],
|
||||
\ readfile(g:new_line_test_file, 'b')
|
||||
|
||||
Execute(Newline should be appended on write when noeol and fixeol):
|
||||
call ale#test#SetFilename(g:new_line_test_file)
|
||||
|
||||
setlocal buftype=
|
||||
noautocmd :w
|
||||
noautocmd :e! ++ff=unix
|
||||
set noeol
|
||||
set fixeol
|
||||
|
||||
call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file)
|
||||
|
||||
AssertEqual
|
||||
\ ['first', 'second', 'third', ''],
|
||||
\ readfile(g:new_line_test_file, 'b')
|
||||
|
||||
|
|
Reference in a new issue