First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
" Author: w0rp <devw0rp@gmail.com>
|
|
|
|
" Description: Linter registration and lazy-loading
|
|
|
|
" Retrieves linters as requested by the engine, loading them if needed.
|
|
|
|
|
2018-04-24 16:48:33 -04:00
|
|
|
let s:runtime_loaded_map = {}
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
let s:linters = {}
|
|
|
|
|
2017-05-27 18:51:27 -04:00
|
|
|
" Default filetype aliases.
|
2016-10-11 18:11:45 -04:00
|
|
|
" The user defined aliases will be merged with this Dictionary.
|
2018-05-26 06:41:52 -04:00
|
|
|
"
|
|
|
|
" NOTE: Update the g:ale_linter_aliases documentation when modifying this.
|
2016-10-11 18:11:45 -04:00
|
|
|
let s:default_ale_linter_aliases = {
|
2017-02-02 17:26:46 -05:00
|
|
|
\ 'Dockerfile': 'dockerfile',
|
2016-10-11 18:11:45 -04:00
|
|
|
\ 'csh': 'sh',
|
2016-12-04 18:13:57 -05:00
|
|
|
\ 'plaintex': 'tex',
|
|
|
|
\ 'systemverilog': 'verilog',
|
2018-06-23 13:20:39 -04:00
|
|
|
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
|
2018-05-26 06:41:52 -04:00
|
|
|
\ 'vimwiki': 'markdown',
|
2017-02-02 17:26:46 -05:00
|
|
|
\ 'zsh': 'sh',
|
2016-10-11 18:11:45 -04:00
|
|
|
\}
|
|
|
|
|
|
|
|
" Default linters to run for particular filetypes.
|
|
|
|
" The user defined linter selections will be merged with this Dictionary.
|
2016-12-22 06:32:20 -05:00
|
|
|
"
|
|
|
|
" No linters are used for plaintext files by default.
|
2017-02-15 17:59:26 -05:00
|
|
|
"
|
|
|
|
" Only cargo is enabled for Rust by default.
|
2017-04-20 11:55:20 -04:00
|
|
|
" rpmlint is disabled by default because it can result in code execution.
|
2018-08-02 16:09:51 -04:00
|
|
|
" hhast is disabled by default because it executes code in the project root.
|
2017-11-14 14:55:28 -05:00
|
|
|
"
|
|
|
|
" NOTE: Update the g:ale_linters documentation when modifying this.
|
2016-10-11 18:11:45 -04:00
|
|
|
let s:default_ale_linters = {
|
|
|
|
\ 'csh': ['shell'],
|
2017-05-30 08:39:22 -04:00
|
|
|
\ 'go': ['gofmt', 'golint', 'go vet'],
|
2018-08-02 16:09:51 -04:00
|
|
|
\ 'hack': ['hack'],
|
2017-03-01 19:06:09 -05:00
|
|
|
\ 'help': [],
|
2017-12-02 15:43:47 -05:00
|
|
|
\ 'perl': ['perlcritic'],
|
2018-09-28 19:18:40 -04:00
|
|
|
\ 'perl6': [],
|
2017-08-30 04:13:49 -04:00
|
|
|
\ 'python': ['flake8', 'mypy', 'pylint'],
|
2017-02-15 17:59:26 -05:00
|
|
|
\ 'rust': ['cargo'],
|
2017-04-20 11:55:20 -04:00
|
|
|
\ 'spec': [],
|
2016-12-22 06:32:20 -05:00
|
|
|
\ 'text': [],
|
2017-02-15 17:59:26 -05:00
|
|
|
\ 'zsh': ['shell'],
|
2016-10-11 18:11:45 -04:00
|
|
|
\}
|
|
|
|
|
2016-10-21 22:02:20 -04:00
|
|
|
" Testing/debugging helper to unload all linters.
|
|
|
|
function! ale#linter#Reset() abort
|
2018-04-24 16:48:33 -04:00
|
|
|
let s:runtime_loaded_map = {}
|
2016-10-21 22:02:20 -04:00
|
|
|
let s:linters = {}
|
|
|
|
endfunction
|
|
|
|
|
2018-07-06 17:46:36 -04:00
|
|
|
" Return a reference to the linters loaded.
|
|
|
|
" This is only for tests.
|
|
|
|
" Do not call this function.
|
|
|
|
function! ale#linter#GetLintersLoaded() abort
|
2018-07-17 16:39:50 -04:00
|
|
|
" This command will throw from the sandbox.
|
2018-08-17 05:10:49 -04:00
|
|
|
let &l:equalprg=&l:equalprg
|
2018-07-17 16:39:50 -04:00
|
|
|
|
2018-07-06 17:46:36 -04:00
|
|
|
return s:linters
|
|
|
|
endfunction
|
|
|
|
|
2016-10-25 15:25:23 -04:00
|
|
|
function! s:IsCallback(value) abort
|
2018-07-24 20:27:28 -04:00
|
|
|
return type(a:value) is v:t_string || type(a:value) is v:t_func
|
2016-10-25 15:25:23 -04:00
|
|
|
endfunction
|
|
|
|
|
2017-02-09 18:32:57 -05:00
|
|
|
function! s:IsBoolean(value) abort
|
2018-07-24 20:27:28 -04:00
|
|
|
return type(a:value) is v:t_number && (a:value == 0 || a:value == 1)
|
2017-02-09 18:32:57 -05:00
|
|
|
endfunction
|
|
|
|
|
2018-04-27 17:52:11 -04:00
|
|
|
function! s:LanguageGetter(buffer) dict abort
|
|
|
|
return l:self.language
|
|
|
|
endfunction
|
|
|
|
|
2018-07-04 08:12:58 -04:00
|
|
|
function! ale#linter#PreProcess(filetype, linter) abort
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(a:linter) isnot v:t_dict
|
2016-10-25 15:25:23 -04:00
|
|
|
throw 'The linter object must be a Dictionary'
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
endif
|
|
|
|
|
2016-10-25 15:25:23 -04:00
|
|
|
let l:obj = {
|
2017-07-07 05:47:09 -04:00
|
|
|
\ 'add_newline': get(a:linter, 'add_newline', 0),
|
2016-10-25 15:25:23 -04:00
|
|
|
\ 'name': get(a:linter, 'name'),
|
2017-06-08 08:52:29 -04:00
|
|
|
\ 'lsp': get(a:linter, 'lsp', ''),
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
\}
|
|
|
|
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(l:obj.name) isnot v:t_string
|
2016-10-25 15:25:23 -04:00
|
|
|
throw '`name` must be defined to name the linter'
|
|
|
|
endif
|
|
|
|
|
2017-08-08 03:39:13 -04:00
|
|
|
let l:needs_address = l:obj.lsp is# 'socket'
|
2017-08-10 19:31:42 -04:00
|
|
|
let l:needs_executable = l:obj.lsp isnot# 'socket'
|
|
|
|
let l:needs_command = l:obj.lsp isnot# 'socket'
|
2017-07-26 05:37:37 -04:00
|
|
|
let l:needs_lsp_details = !empty(l:obj.lsp)
|
2017-07-02 08:17:24 -04:00
|
|
|
|
2017-07-02 08:25:36 -04:00
|
|
|
if empty(l:obj.lsp)
|
|
|
|
let l:obj.callback = get(a:linter, 'callback')
|
|
|
|
|
|
|
|
if !s:IsCallback(l:obj.callback)
|
|
|
|
throw '`callback` must be defined with a callback to accept output'
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
2017-07-02 08:17:24 -04:00
|
|
|
if index(['', 'socket', 'stdio', 'tsserver'], l:obj.lsp) < 0
|
2018-09-01 20:59:36 -04:00
|
|
|
throw '`lsp` must be either `''lsp''`, `''stdio''`, `''socket''` or `''tsserver''` if defined'
|
2017-06-08 08:52:29 -04:00
|
|
|
endif
|
|
|
|
|
|
|
|
if !l:needs_executable
|
|
|
|
if has_key(a:linter, 'executable')
|
|
|
|
\|| has_key(a:linter, 'executable_callback')
|
2017-07-02 08:17:24 -04:00
|
|
|
throw '`executable` and `executable_callback` cannot be used when lsp == ''socket'''
|
2017-06-08 08:52:29 -04:00
|
|
|
endif
|
|
|
|
elseif has_key(a:linter, 'executable_callback')
|
2016-10-25 15:25:23 -04:00
|
|
|
let l:obj.executable_callback = a:linter.executable_callback
|
|
|
|
|
|
|
|
if !s:IsCallback(l:obj.executable_callback)
|
|
|
|
throw '`executable_callback` must be a callback if defined'
|
|
|
|
endif
|
|
|
|
elseif has_key(a:linter, 'executable')
|
|
|
|
let l:obj.executable = a:linter.executable
|
|
|
|
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(l:obj.executable) isnot v:t_string
|
2016-10-25 15:25:23 -04:00
|
|
|
throw '`executable` must be a string if defined'
|
|
|
|
endif
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
else
|
2016-10-25 15:25:23 -04:00
|
|
|
throw 'Either `executable` or `executable_callback` must be defined'
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
endif
|
|
|
|
|
2017-06-08 08:52:29 -04:00
|
|
|
if !l:needs_command
|
|
|
|
if has_key(a:linter, 'command')
|
|
|
|
\|| has_key(a:linter, 'command_callback')
|
|
|
|
\|| has_key(a:linter, 'command_chain')
|
2017-07-02 08:17:24 -04:00
|
|
|
throw '`command` and `command_callback` and `command_chain` cannot be used when lsp == ''socket'''
|
2017-06-08 08:52:29 -04:00
|
|
|
endif
|
|
|
|
elseif has_key(a:linter, 'command_chain')
|
2017-02-04 13:30:30 -05:00
|
|
|
let l:obj.command_chain = a:linter.command_chain
|
|
|
|
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(l:obj.command_chain) isnot v:t_list
|
2017-02-04 13:30:30 -05:00
|
|
|
throw '`command_chain` must be a List'
|
|
|
|
endif
|
|
|
|
|
|
|
|
if empty(l:obj.command_chain)
|
|
|
|
throw '`command_chain` must contain at least one item'
|
|
|
|
endif
|
|
|
|
|
|
|
|
let l:link_index = 0
|
|
|
|
|
|
|
|
for l:link in l:obj.command_chain
|
|
|
|
let l:err_prefix = 'The `command_chain` item ' . l:link_index . ' '
|
|
|
|
|
|
|
|
if !s:IsCallback(get(l:link, 'callback'))
|
|
|
|
throw l:err_prefix . 'must define a `callback` function'
|
|
|
|
endif
|
|
|
|
|
|
|
|
if has_key(l:link, 'output_stream')
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(l:link.output_stream) isnot v:t_string
|
2017-02-04 13:30:30 -05:00
|
|
|
\|| index(['stdout', 'stderr', 'both'], l:link.output_stream) < 0
|
|
|
|
throw l:err_prefix . '`output_stream` flag must be '
|
|
|
|
\ . "'stdout', 'stderr', or 'both'"
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
2017-02-09 18:32:57 -05:00
|
|
|
if has_key(l:link, 'read_buffer') && !s:IsBoolean(l:link.read_buffer)
|
|
|
|
throw l:err_prefix . 'value for `read_buffer` must be `0` or `1`'
|
|
|
|
endif
|
|
|
|
|
2017-02-04 13:30:30 -05:00
|
|
|
let l:link_index += 1
|
|
|
|
endfor
|
|
|
|
elseif has_key(a:linter, 'command_callback')
|
2016-10-25 15:25:23 -04:00
|
|
|
let l:obj.command_callback = a:linter.command_callback
|
|
|
|
|
|
|
|
if !s:IsCallback(l:obj.command_callback)
|
|
|
|
throw '`command_callback` must be a callback if defined'
|
|
|
|
endif
|
|
|
|
elseif has_key(a:linter, 'command')
|
|
|
|
let l:obj.command = a:linter.command
|
|
|
|
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(l:obj.command) isnot v:t_string
|
2016-10-25 15:25:23 -04:00
|
|
|
throw '`command` must be a string if defined'
|
|
|
|
endif
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
else
|
2016-10-25 15:25:23 -04:00
|
|
|
throw 'Either `command`, `executable_callback`, `command_chain` '
|
|
|
|
\ . 'must be defined'
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
endif
|
|
|
|
|
2017-02-09 15:44:13 -05:00
|
|
|
if (
|
|
|
|
\ has_key(a:linter, 'command')
|
|
|
|
\ + has_key(a:linter, 'command_chain')
|
|
|
|
\ + has_key(a:linter, 'command_callback')
|
|
|
|
\) > 1
|
|
|
|
throw 'Only one of `command`, `command_callback`, or `command_chain` '
|
|
|
|
\ . 'should be set'
|
|
|
|
endif
|
|
|
|
|
2017-06-08 08:52:29 -04:00
|
|
|
if !l:needs_address
|
|
|
|
if has_key(a:linter, 'address_callback')
|
2017-07-02 08:17:24 -04:00
|
|
|
throw '`address_callback` cannot be used when lsp != ''socket'''
|
2017-06-08 08:52:29 -04:00
|
|
|
endif
|
|
|
|
elseif has_key(a:linter, 'address_callback')
|
|
|
|
let l:obj.address_callback = a:linter.address_callback
|
|
|
|
|
|
|
|
if !s:IsCallback(l:obj.address_callback)
|
|
|
|
throw '`address_callback` must be a callback if defined'
|
|
|
|
endif
|
|
|
|
else
|
|
|
|
throw '`address_callback` must be defined for getting the LSP address'
|
|
|
|
endif
|
|
|
|
|
2017-07-26 05:37:37 -04:00
|
|
|
if l:needs_lsp_details
|
2018-07-04 08:12:58 -04:00
|
|
|
if has_key(a:linter, 'language_callback')
|
|
|
|
if has_key(a:linter, 'language')
|
2018-04-27 17:52:11 -04:00
|
|
|
throw 'Only one of `language` or `language_callback` '
|
|
|
|
\ . 'should be set'
|
|
|
|
endif
|
|
|
|
|
2018-07-04 08:12:58 -04:00
|
|
|
let l:obj.language_callback = get(a:linter, 'language_callback')
|
|
|
|
|
|
|
|
if !s:IsCallback(l:obj.language_callback)
|
|
|
|
throw '`language_callback` must be a callback for LSP linters'
|
|
|
|
endif
|
|
|
|
else
|
|
|
|
" Default to using the filetype as the language.
|
|
|
|
let l:obj.language = get(a:linter, 'language', a:filetype)
|
2017-07-26 05:37:37 -04:00
|
|
|
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(l:obj.language) isnot v:t_string
|
2018-04-27 17:52:11 -04:00
|
|
|
throw '`language` must be a string'
|
|
|
|
endif
|
|
|
|
|
|
|
|
" Make 'language_callback' return the 'language' value.
|
|
|
|
let l:obj.language_callback = function('s:LanguageGetter')
|
2017-07-26 05:37:37 -04:00
|
|
|
endif
|
|
|
|
|
|
|
|
let l:obj.project_root_callback = get(a:linter, 'project_root_callback')
|
|
|
|
|
|
|
|
if !s:IsCallback(l:obj.project_root_callback)
|
|
|
|
throw '`project_root_callback` must be a callback for LSP linters'
|
|
|
|
endif
|
2018-04-22 07:28:12 -04:00
|
|
|
|
|
|
|
if has_key(a:linter, 'completion_filter')
|
|
|
|
let l:obj.completion_filter = a:linter.completion_filter
|
|
|
|
|
|
|
|
if !s:IsCallback(l:obj.completion_filter)
|
|
|
|
throw '`completion_filter` must be a callback'
|
|
|
|
endif
|
|
|
|
endif
|
2018-06-06 11:58:49 -04:00
|
|
|
|
|
|
|
if has_key(a:linter, 'initialization_options_callback')
|
|
|
|
if has_key(a:linter, 'initialization_options')
|
|
|
|
throw 'Only one of `initialization_options` or '
|
|
|
|
\ . '`initialization_options_callback` should be set'
|
|
|
|
endif
|
|
|
|
|
|
|
|
let l:obj.initialization_options_callback = a:linter.initialization_options_callback
|
|
|
|
|
|
|
|
if !s:IsCallback(l:obj.initialization_options_callback)
|
|
|
|
throw '`initialization_options_callback` must be a callback if defined'
|
|
|
|
endif
|
|
|
|
elseif has_key(a:linter, 'initialization_options')
|
|
|
|
let l:obj.initialization_options = a:linter.initialization_options
|
|
|
|
endif
|
2018-10-22 08:24:46 -04:00
|
|
|
|
|
|
|
if has_key(a:linter, 'lsp_config')
|
|
|
|
if type(a:linter.lsp_config) isnot v:t_dict
|
|
|
|
throw '`lsp_config` must be a Dictionary'
|
|
|
|
endif
|
|
|
|
|
|
|
|
let l:obj.lsp_config = a:linter.lsp_config
|
|
|
|
endif
|
2017-07-26 05:37:37 -04:00
|
|
|
endif
|
|
|
|
|
2016-10-25 15:25:23 -04:00
|
|
|
let l:obj.output_stream = get(a:linter, 'output_stream', 'stdout')
|
|
|
|
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(l:obj.output_stream) isnot v:t_string
|
2016-10-25 15:25:23 -04:00
|
|
|
\|| index(['stdout', 'stderr', 'both'], l:obj.output_stream) < 0
|
|
|
|
throw "`output_stream` must be 'stdout', 'stderr', or 'both'"
|
|
|
|
endif
|
|
|
|
|
2017-03-07 19:23:14 -05:00
|
|
|
" An option indicating that this linter should only be run against the
|
|
|
|
" file on disk.
|
|
|
|
let l:obj.lint_file = get(a:linter, 'lint_file', 0)
|
|
|
|
|
|
|
|
if !s:IsBoolean(l:obj.lint_file)
|
|
|
|
throw '`lint_file` must be `0` or `1`'
|
|
|
|
endif
|
|
|
|
|
2017-02-09 18:32:57 -05:00
|
|
|
" An option indicating that the buffer should be read.
|
2017-03-07 19:23:14 -05:00
|
|
|
let l:obj.read_buffer = get(a:linter, 'read_buffer', !l:obj.lint_file)
|
2017-02-09 18:32:57 -05:00
|
|
|
|
|
|
|
if !s:IsBoolean(l:obj.read_buffer)
|
|
|
|
throw '`read_buffer` must be `0` or `1`'
|
|
|
|
endif
|
|
|
|
|
2017-03-07 19:23:14 -05:00
|
|
|
if l:obj.lint_file && l:obj.read_buffer
|
|
|
|
throw 'Only one of `lint_file` or `read_buffer` can be `1`'
|
|
|
|
endif
|
|
|
|
|
2017-05-27 16:27:42 -04:00
|
|
|
let l:obj.aliases = get(a:linter, 'aliases', [])
|
|
|
|
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(l:obj.aliases) isnot v:t_list
|
|
|
|
\|| len(filter(copy(l:obj.aliases), 'type(v:val) isnot v:t_string')) > 0
|
2017-05-27 16:27:42 -04:00
|
|
|
throw '`aliases` must be a List of String values'
|
|
|
|
endif
|
|
|
|
|
2016-10-25 15:25:23 -04:00
|
|
|
return l:obj
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! ale#linter#Define(filetype, linter) abort
|
2018-07-17 16:39:50 -04:00
|
|
|
" This command will throw from the sandbox.
|
2018-08-17 05:10:49 -04:00
|
|
|
let &l:equalprg=&l:equalprg
|
2018-07-17 16:39:50 -04:00
|
|
|
|
2016-10-25 15:25:23 -04:00
|
|
|
if !has_key(s:linters, a:filetype)
|
|
|
|
let s:linters[a:filetype] = []
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
endif
|
|
|
|
|
2018-07-04 08:12:58 -04:00
|
|
|
let l:new_linter = ale#linter#PreProcess(a:filetype, a:linter)
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
|
2016-10-10 19:00:09 -04:00
|
|
|
call add(s:linters[a:filetype], l:new_linter)
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
endfunction
|
|
|
|
|
2018-04-24 16:48:33 -04:00
|
|
|
" 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
|
|
|
|
|
2017-04-11 16:10:08 -04:00
|
|
|
function! ale#linter#GetAll(filetypes) abort
|
2018-07-17 16:39:50 -04:00
|
|
|
" Don't return linters in the sandbox.
|
|
|
|
" Otherwise a sandboxed script could modify them.
|
|
|
|
if ale#util#InSandbox()
|
|
|
|
return []
|
|
|
|
endif
|
|
|
|
|
2017-04-11 16:10:08 -04:00
|
|
|
let l:combined_linters = []
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
|
2017-04-11 16:10:08 -04:00
|
|
|
for l:filetype in a:filetypes
|
2018-04-24 16:48:33 -04:00
|
|
|
" Load linters from runtimepath if we haven't done that yet.
|
|
|
|
if !has_key(s:runtime_loaded_map, l:filetype)
|
2017-04-11 16:10:08 -04:00
|
|
|
execute 'silent! runtime! ale_linters/' . l:filetype . '/*.vim'
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
|
2018-04-24 16:48:33 -04:00
|
|
|
let s:runtime_loaded_map[l:filetype] = 1
|
2017-04-11 16:10:08 -04:00
|
|
|
endif
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
|
2017-04-11 16:10:08 -04:00
|
|
|
call extend(l:combined_linters, get(s:linters, l:filetype, []))
|
|
|
|
endfor
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
|
2017-04-11 16:10:08 -04:00
|
|
|
return l:combined_linters
|
First pass at optimizing ale to autoload (#80)
* First pass at optimizing ale to autoload
First off, the structure/function names should be revised a bit,
but I will wait for @w0rp's input before unifying the naming style.
Second off, the docs probably need some more work, I just did some
simple find-and-replace work.
With that said, this pull brings major performance gains for ale. On my
slowest system, fully loading ale and all its code takes around 150ms.
I have moved all of ale's autoload-able code to autoload/, and in
addition, implemented lazy-loading of linters. This brings load time on
that same system down to 5ms.
The only downside of lazy loading is that `g:ale_linters` cannot be
changed at runtime; however, it also speeds up performance at runtime by
simplfying the logic greatly.
Please let me know what you think!
Closes #59
* Address Travis/Vint errors
For some reason, ale isn't running vint for me...
* Incorporate feedback, make fixes
Lazy-loading logic is much improved.
* Add header comments; remove incorrect workaround
* Remove unneeded plugin guards
* Fix lazy-loading linter logic
Set the wrong variable....
* Fix capitialization
2016-10-10 14:51:29 -04:00
|
|
|
endfunction
|
2016-10-11 18:11:45 -04:00
|
|
|
|
2017-04-25 18:52:13 -04:00
|
|
|
function! s:GetAliasedFiletype(original_filetype) abort
|
2017-11-11 19:11:50 -05:00
|
|
|
let l:buffer_aliases = get(b:, 'ale_linter_aliases', {})
|
|
|
|
|
2018-10-26 04:22:33 -04:00
|
|
|
" b:ale_linter_aliases can be set to a List or String.
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(l:buffer_aliases) is v:t_list
|
2018-10-26 04:22:33 -04:00
|
|
|
\|| type(l:buffer_aliases) is v:t_string
|
2017-11-11 19:11:50 -05:00
|
|
|
return l:buffer_aliases
|
|
|
|
endif
|
|
|
|
|
2017-04-25 18:52:13 -04:00
|
|
|
" Check for aliased filetypes first in a buffer variable,
|
|
|
|
" then the global variable,
|
|
|
|
" then in the default mapping,
|
|
|
|
" otherwise use the original filetype.
|
|
|
|
for l:dict in [
|
2017-11-11 19:11:50 -05:00
|
|
|
\ l:buffer_aliases,
|
2017-01-24 10:50:49 -05:00
|
|
|
\ g:ale_linter_aliases,
|
2017-04-25 18:52:13 -04:00
|
|
|
\ s:default_ale_linter_aliases,
|
|
|
|
\]
|
|
|
|
if has_key(l:dict, a:original_filetype)
|
|
|
|
return l:dict[a:original_filetype]
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
|
|
|
|
return a:original_filetype
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! ale#linter#ResolveFiletype(original_filetype) abort
|
|
|
|
let l:filetype = s:GetAliasedFiletype(a:original_filetype)
|
2017-01-24 10:50:49 -05:00
|
|
|
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(l:filetype) isnot v:t_list
|
2017-04-11 16:10:08 -04:00
|
|
|
return [l:filetype]
|
|
|
|
endif
|
|
|
|
|
2017-01-24 10:50:49 -05:00
|
|
|
return l:filetype
|
|
|
|
endfunction
|
|
|
|
|
2017-04-25 18:52:13 -04:00
|
|
|
function! s:GetLinterNames(original_filetype) abort
|
2017-11-11 18:55:04 -05:00
|
|
|
let l:buffer_ale_linters = get(b:, 'ale_linters', {})
|
|
|
|
|
|
|
|
" b:ale_linters can be set to 'all'
|
|
|
|
if l:buffer_ale_linters is# 'all'
|
|
|
|
return 'all'
|
|
|
|
endif
|
|
|
|
|
|
|
|
" b:ale_linters can be set to a List.
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(l:buffer_ale_linters) is v:t_list
|
2017-11-11 18:55:04 -05:00
|
|
|
return l:buffer_ale_linters
|
|
|
|
endif
|
|
|
|
|
2017-11-14 14:55:28 -05:00
|
|
|
" Try to get a buffer-local setting for the filetype
|
|
|
|
if has_key(l:buffer_ale_linters, a:original_filetype)
|
|
|
|
return l:buffer_ale_linters[a:original_filetype]
|
|
|
|
endif
|
|
|
|
|
|
|
|
" Try to get a global setting for the filetype
|
|
|
|
if has_key(g:ale_linters, a:original_filetype)
|
|
|
|
return g:ale_linters[a:original_filetype]
|
|
|
|
endif
|
|
|
|
|
|
|
|
" If the user has configured ALE to only enable linters explicitly, then
|
|
|
|
" don't enable any linters by default.
|
|
|
|
if g:ale_linters_explicit
|
|
|
|
return []
|
|
|
|
endif
|
|
|
|
|
|
|
|
" Try to get a default setting for the filetype
|
|
|
|
if has_key(s:default_ale_linters, a:original_filetype)
|
|
|
|
return s:default_ale_linters[a:original_filetype]
|
|
|
|
endif
|
2017-04-25 18:52:13 -04:00
|
|
|
|
|
|
|
return 'all'
|
|
|
|
endfunction
|
|
|
|
|
2016-10-21 22:02:20 -04:00
|
|
|
function! ale#linter#Get(original_filetypes) abort
|
2017-06-20 05:50:38 -04:00
|
|
|
let l:possibly_duplicated_linters = []
|
2016-10-11 18:11:45 -04:00
|
|
|
|
2017-10-02 12:11:54 -04:00
|
|
|
" Handle dot-separated filetypes.
|
2016-10-21 22:02:20 -04:00
|
|
|
for l:original_filetype in split(a:original_filetypes, '\.')
|
2017-02-13 17:11:35 -05:00
|
|
|
let l:filetype = ale#linter#ResolveFiletype(l:original_filetype)
|
2017-04-25 18:52:13 -04:00
|
|
|
let l:linter_names = s:GetLinterNames(l:original_filetype)
|
2017-01-24 10:50:49 -05:00
|
|
|
let l:all_linters = ale#linter#GetAll(l:filetype)
|
2016-10-21 22:02:20 -04:00
|
|
|
let l:filetype_linters = []
|
|
|
|
|
2018-07-24 20:27:28 -04:00
|
|
|
if type(l:linter_names) is v:t_string && l:linter_names is# 'all'
|
2016-10-21 22:02:20 -04:00
|
|
|
let l:filetype_linters = l:all_linters
|
2018-07-24 20:27:28 -04:00
|
|
|
elseif type(l:linter_names) is v:t_list
|
2016-10-21 22:02:20 -04:00
|
|
|
" Select only the linters we or the user has specified.
|
|
|
|
for l:linter in l:all_linters
|
2017-05-27 16:27:42 -04:00
|
|
|
let l:name_list = [l:linter.name] + l:linter.aliases
|
|
|
|
|
|
|
|
for l:name in l:name_list
|
|
|
|
if index(l:linter_names, l:name) >= 0
|
|
|
|
call add(l:filetype_linters, l:linter)
|
|
|
|
break
|
|
|
|
endif
|
|
|
|
endfor
|
2016-10-21 22:02:20 -04:00
|
|
|
endfor
|
|
|
|
endif
|
|
|
|
|
2017-06-20 05:50:38 -04:00
|
|
|
call extend(l:possibly_duplicated_linters, l:filetype_linters)
|
2016-10-21 22:02:20 -04:00
|
|
|
endfor
|
2016-10-11 18:11:45 -04:00
|
|
|
|
2017-06-20 05:50:38 -04:00
|
|
|
let l:name_list = []
|
|
|
|
let l:combined_linters = []
|
|
|
|
|
|
|
|
" Make sure we override linters so we don't get two with the same name,
|
|
|
|
" like 'eslint' for both 'javascript' and 'typescript'
|
|
|
|
"
|
|
|
|
" Note that the reverse calls here modify the List variables.
|
|
|
|
for l:linter in reverse(l:possibly_duplicated_linters)
|
|
|
|
if index(l:name_list, l:linter.name) < 0
|
|
|
|
call add(l:name_list, l:linter.name)
|
|
|
|
call add(l:combined_linters, l:linter)
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
|
|
|
|
return reverse(l:combined_linters)
|
2016-10-11 18:11:45 -04:00
|
|
|
endfunction
|
2017-07-02 08:17:24 -04:00
|
|
|
|
|
|
|
" Given a buffer and linter, get the executable String for the linter.
|
|
|
|
function! ale#linter#GetExecutable(buffer, linter) abort
|
|
|
|
return has_key(a:linter, 'executable_callback')
|
|
|
|
\ ? ale#util#GetFunction(a:linter.executable_callback)(a:buffer)
|
|
|
|
\ : a:linter.executable
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
" Given a buffer and linter, get the command String for the linter.
|
|
|
|
" The command_chain key is not supported.
|
|
|
|
function! ale#linter#GetCommand(buffer, linter) abort
|
|
|
|
return has_key(a:linter, 'command_callback')
|
|
|
|
\ ? ale#util#GetFunction(a:linter.command_callback)(a:buffer)
|
|
|
|
\ : a:linter.command
|
|
|
|
endfunction
|
2017-07-26 05:37:37 -04:00
|
|
|
|
|
|
|
" Given a buffer and linter, get the address for connecting to the server.
|
|
|
|
function! ale#linter#GetAddress(buffer, linter) abort
|
|
|
|
return has_key(a:linter, 'address_callback')
|
|
|
|
\ ? ale#util#GetFunction(a:linter.address_callback)(a:buffer)
|
|
|
|
\ : a:linter.address
|
|
|
|
endfunction
|