From 41c0b837aec7770612274df1078ceddb6accd3f7 Mon Sep 17 00:00:00 2001 From: w0rp Date: Tue, 24 Apr 2018 21:48:33 +0100 Subject: [PATCH] #1278 Allow linters to be defined pretty much anywhere --- autoload/ale/linter.vim | 18 ++++++++++-------- doc/ale.txt | 22 ++++++++++++++++++++++ test/test_ale_info.vader | 1 + test/test_linter_retrieval.vader | 4 ++++ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim index 7e32b7bc..8aec2598 100644 --- a/autoload/ale/linter.vim +++ b/autoload/ale/linter.vim @@ -3,6 +3,7 @@ call ale#Set('wrap_command_as_one_argument', 0) " Description: Linter registration and lazy-loading " Retrieves linters as requested by the engine, loading them if needed. +let s:runtime_loaded_map = {} let s:linters = {} " Default filetype aliases. @@ -38,6 +39,7 @@ let s:default_ale_linters = { " Testing/debugging helper to unload all linters. function! ale#linter#Reset() abort + let s:runtime_loaded_map = {} let s:linters = {} endfunction @@ -250,20 +252,20 @@ function! ale#linter#Define(filetype, linter) abort call add(s:linters[a:filetype], l:new_linter) endfunction +" Prevent any linters from being loaded for a given filetype. +function! ale#linter#PreventLoading(filetype) abort + let s:runtime_loaded_map[a:filetype] = 1 +endfunction + function! ale#linter#GetAll(filetypes) abort let l:combined_linters = [] for l:filetype in a:filetypes - " Load linter defintions from files if we haven't loaded them yet. - if !has_key(s:linters, l:filetype) + " Load linters from runtimepath if we haven't done that yet. + if !has_key(s:runtime_loaded_map, l:filetype) execute 'silent! runtime! ale_linters/' . l:filetype . '/*.vim' - " Always set an empty List for the loaded linters if we don't find - " any. This will prevent us from executing the runtime command - " many times, redundantly. - if !has_key(s:linters, l:filetype) - let s:linters[l:filetype] = [] - endif + let s:runtime_loaded_map[l:filetype] = 1 endif call extend(l:combined_linters, get(s:linters, l:filetype, [])) diff --git a/doc/ale.txt b/doc/ale.txt index 45d7ba1a..a20e9133 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2359,6 +2359,21 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* containing `.` characters will be split into individual parts, and files will be loaded for each filetype between the `.` characters. + Linters can be defined from vimrc and other files as long as this function + is loaded first. For example, the following code will define a Hello World + linter in vimrc in Vim 8: > + + " Plugins have to be loaded first. + " If you are using a plugin manager, run that first. + packloadall + + call ale#linter#Define('vim', { + \ 'name': 'echo-test', + \ 'executable': 'echo', + \ 'command': 'echo hello world', + \ 'callback': {buffer, lines -> map(lines, '{"text": v:val, "lnum": 1}')}, + \}) +< ale#linter#Get(filetype) *ale#linter#Get()* @@ -2374,6 +2389,13 @@ ale#linter#Get(filetype) *ale#linter#Get()* components. +ale#linter#PreventLoading(filetype) *ale#linter#PreventLoading()* + + Given a `filetype`, prevent any more linters from being loaded from + |runtimepath| for that filetype. This function can be called from vimrc or + similar to prevent ALE from loading linters. + + ale#statusline#Count(buffer) *ale#statusline#Count()* Given the number of a buffer which may have problems, return a |Dictionary| diff --git a/test/test_ale_info.vader b/test/test_ale_info.vader index acf1bfdf..c1ae5a7d 100644 --- a/test/test_ale_info.vader +++ b/test/test_ale_info.vader @@ -32,6 +32,7 @@ Before: call ale#engine#ResetExecutableCache() call ale#linter#Reset() + call ale#linter#PreventLoading('testft') let g:ale_linters = {} let g:ale_fixers = {} let g:ale_linter_aliases = {} diff --git a/test/test_linter_retrieval.vader b/test/test_linter_retrieval.vader index 5d1ee451..6c402d54 100644 --- a/test/test_linter_retrieval.vader +++ b/test/test_linter_retrieval.vader @@ -5,6 +5,9 @@ Before: let g:testlinter1 = {'name': 'testlinter1', 'executable': 'testlinter1', 'command': 'testlinter1', 'callback': 'testCB1', 'output_stream': 'stdout', 'read_buffer': 1, 'lint_file': 0, 'aliases': [], 'lsp': '', 'add_newline': 0} let g:testlinter2 = {'name': 'testlinter2', 'executable': 'testlinter2', 'command': 'testlinter2', 'callback': 'testCB2', 'output_stream': 'stdout', 'read_buffer': 0, 'lint_file': 1, 'aliases': [], 'lsp': '', 'add_newline': 0} call ale#linter#Reset() + call ale#linter#PreventLoading('testft') + call ale#linter#PreventLoading('javascript') + call ale#linter#PreventLoading('typescript') After: Restore @@ -145,6 +148,7 @@ Execute (Buffer-local overrides for aliases should be used): AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft1') Execute (Linters should be loaded from disk appropriately): + call ale#linter#Reset() AssertEqual [{'name': 'testlinter', 'output_stream': 'stdout', 'executable': 'testlinter', 'command': 'testlinter', 'callback': 'testCB', 'read_buffer': 1, 'lint_file': 0, 'aliases': [], 'lsp': '', 'add_newline': 0}], ale#linter#Get('testft')