2017-06-15 08:30:34 +00:00
|
|
|
" Author: w0rp <devw0rp@gmail.com>, David Alexander <opensource@thelonelyghost.com>
|
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 18:51:29 +00:00
|
|
|
" Description: Primary code path for the plugin
|
|
|
|
" Manages execution of linters when requested by autocommands
|
|
|
|
|
|
|
|
let s:lint_timer = -1
|
2017-04-25 22:52:13 +00:00
|
|
|
let s:queued_buffer_number = -1
|
2017-03-21 14:52:02 +00:00
|
|
|
let s:should_lint_file_for_buffer = {}
|
2017-08-12 09:47:06 +00:00
|
|
|
let s:error_delay_ms = 1000 * 60 * 2
|
2017-08-08 23:05:55 +00:00
|
|
|
|
2017-08-12 09:47:06 +00:00
|
|
|
let s:timestamp_map = {}
|
2017-08-08 23:05:55 +00:00
|
|
|
|
2017-08-12 09:47:06 +00:00
|
|
|
" Given a key for a script variable for tracking the time to wait until
|
|
|
|
" a given function should be called, a funcref for a function to call, and
|
|
|
|
" a List of arguments, call the function and return whatever value it returns.
|
|
|
|
"
|
|
|
|
" If the function throws an exception, then the function will not be called
|
|
|
|
" for a while, and 0 will be returned instead.
|
|
|
|
function! ale#CallWithCooldown(timestamp_key, func, arglist) abort
|
|
|
|
let l:now = ale#util#ClockMilliseconds()
|
|
|
|
|
|
|
|
if l:now < get(s:timestamp_map, a:timestamp_key, -1)
|
|
|
|
return 0
|
|
|
|
endif
|
|
|
|
|
|
|
|
let s:timestamp_map[a:timestamp_key] = l:now + s:error_delay_ms
|
|
|
|
|
|
|
|
let l:return_value = call(a:func, a:arglist)
|
|
|
|
|
|
|
|
let s:timestamp_map[a:timestamp_key] = -1
|
|
|
|
|
|
|
|
return l:return_value
|
|
|
|
endfunction
|
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 18:51:29 +00:00
|
|
|
|
2017-05-26 20:21:15 +00:00
|
|
|
" Return 1 if a file is too large for ALE to handle.
|
|
|
|
function! ale#FileTooLarge() abort
|
|
|
|
let l:max = ale#Var(bufnr(''), 'maximum_file_size')
|
|
|
|
|
|
|
|
return l:max > 0 ? (line2byte(line('$') + 1) > l:max) : 0
|
|
|
|
endfunction
|
|
|
|
|
2017-10-14 16:31:58 +00:00
|
|
|
let s:getcmdwintype_exists = exists('*getcmdwintype')
|
|
|
|
|
2017-02-14 21:02:49 +00:00
|
|
|
" A function for checking various conditions whereby ALE just shouldn't
|
|
|
|
" attempt to do anything, say if particular buffer types are open in Vim.
|
2017-07-31 23:03:24 +00:00
|
|
|
function! ale#ShouldDoNothing(buffer) abort
|
2017-10-14 15:51:12 +00:00
|
|
|
" The checks are split into separate if statements to make it possible to
|
|
|
|
" profile each check individually with Vim's profiling tools.
|
|
|
|
|
2017-10-14 18:22:19 +00:00
|
|
|
" Don't perform any checks when newer NeoVim versions are exiting.
|
|
|
|
if get(v:, 'exiting', v:null) isnot v:null
|
|
|
|
return 1
|
|
|
|
endif
|
|
|
|
|
2017-02-14 21:02:49 +00:00
|
|
|
" Do nothing for blacklisted files
|
2017-10-15 09:35:33 +00:00
|
|
|
if index(g:ale_filetype_blacklist, getbufvar(a:buffer, '&filetype')) >= 0
|
2017-10-14 15:51:12 +00:00
|
|
|
return 1
|
|
|
|
endif
|
|
|
|
|
|
|
|
" Do nothing if running from command mode
|
2017-10-14 16:31:58 +00:00
|
|
|
if s:getcmdwintype_exists && !empty(getcmdwintype())
|
2017-10-14 15:51:12 +00:00
|
|
|
return 1
|
|
|
|
endif
|
|
|
|
|
|
|
|
" Do nothing if running in the sandbox
|
|
|
|
if ale#util#InSandbox()
|
|
|
|
return 1
|
|
|
|
endif
|
|
|
|
|
|
|
|
" Do nothing if ALE is disabled.
|
|
|
|
if !ale#Var(a:buffer, 'enabled')
|
|
|
|
return 1
|
|
|
|
endif
|
|
|
|
|
|
|
|
" Do nothing if the file is too large.
|
|
|
|
if ale#FileTooLarge()
|
|
|
|
return 1
|
|
|
|
endif
|
|
|
|
|
|
|
|
" Do nothing from CtrlP buffers with CtrlP-funky.
|
2017-10-14 16:11:30 +00:00
|
|
|
if exists(':CtrlPFunky') is 2
|
|
|
|
\&& getbufvar(a:buffer, '&l:statusline') =~# 'CtrlPMode.*funky'
|
2017-10-14 15:51:12 +00:00
|
|
|
return 1
|
|
|
|
endif
|
|
|
|
|
|
|
|
return 0
|
2017-02-14 21:02:49 +00:00
|
|
|
endfunction
|
|
|
|
|
2017-07-31 23:03:24 +00:00
|
|
|
" (delay, [linting_flag, buffer_number])
|
2017-03-14 23:51:57 +00:00
|
|
|
function! ale#Queue(delay, ...) abort
|
2017-07-31 23:03:24 +00:00
|
|
|
if a:0 > 2
|
2017-03-14 23:51:57 +00:00
|
|
|
throw 'too many arguments!'
|
|
|
|
endif
|
|
|
|
|
2017-03-21 14:52:02 +00:00
|
|
|
" Default linting_flag to ''
|
|
|
|
let l:linting_flag = get(a:000, 0, '')
|
2017-08-08 23:05:55 +00:00
|
|
|
let l:buffer = get(a:000, 1, bufnr(''))
|
|
|
|
|
2017-08-12 09:47:06 +00:00
|
|
|
return ale#CallWithCooldown(
|
|
|
|
\ 'dont_queue_until',
|
|
|
|
\ function('s:ALEQueueImpl'),
|
|
|
|
\ [a:delay, l:linting_flag, l:buffer],
|
|
|
|
\)
|
2017-08-08 23:05:55 +00:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:ALEQueueImpl(delay, linting_flag, buffer) abort
|
2017-08-10 23:31:42 +00:00
|
|
|
if a:linting_flag isnot# '' && a:linting_flag isnot# 'lint_file'
|
2017-03-21 13:38:27 +00:00
|
|
|
throw "linting_flag must be either '' or 'lint_file'"
|
2017-03-14 23:51:57 +00:00
|
|
|
endif
|
|
|
|
|
2017-08-08 23:05:55 +00:00
|
|
|
if type(a:buffer) != type(0)
|
2017-07-31 23:03:24 +00:00
|
|
|
throw 'buffer_number must be a Number'
|
|
|
|
endif
|
|
|
|
|
2017-08-08 23:05:55 +00:00
|
|
|
if ale#ShouldDoNothing(a:buffer)
|
2016-10-31 14:47:08 +00:00
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2017-03-21 14:52:02 +00:00
|
|
|
" Remember that we want to check files for this buffer.
|
|
|
|
" We will remember this until we finally run the linters, via any event.
|
2017-08-08 23:05:55 +00:00
|
|
|
if a:linting_flag is# 'lint_file'
|
2017-10-15 09:35:33 +00:00
|
|
|
let s:should_lint_file_for_buffer[a:buffer] = 1
|
2017-03-21 14:52:02 +00:00
|
|
|
endif
|
2017-03-14 23:51:57 +00:00
|
|
|
|
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 18:51:29 +00:00
|
|
|
if s:lint_timer != -1
|
|
|
|
call timer_stop(s:lint_timer)
|
|
|
|
let s:lint_timer = -1
|
|
|
|
endif
|
|
|
|
|
2017-08-08 23:05:55 +00:00
|
|
|
let l:linters = ale#linter#Get(getbufvar(a:buffer, '&filetype'))
|
2017-07-07 22:47:41 +00:00
|
|
|
|
|
|
|
" Don't set up buffer data and so on if there are no linters to run.
|
|
|
|
if empty(l:linters)
|
|
|
|
" If we have some previous buffer data, then stop any jobs currently
|
|
|
|
" running and clear everything.
|
2017-08-08 23:05:55 +00:00
|
|
|
if has_key(g:ale_buffer_info, a:buffer)
|
|
|
|
call ale#engine#RunLinters(a:buffer, [], 1)
|
2017-07-07 22:47:41 +00: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 18:51:29 +00:00
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
|
|
|
if a:delay > 0
|
2017-08-08 23:05:55 +00:00
|
|
|
let s:queued_buffer_number = a:buffer
|
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 18:51:29 +00:00
|
|
|
let s:lint_timer = timer_start(a:delay, function('ale#Lint'))
|
|
|
|
else
|
2017-08-08 23:05:55 +00:00
|
|
|
call ale#Lint(-1, a:buffer)
|
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 18:51:29 +00:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! ale#Lint(...) abort
|
2017-07-31 23:03:24 +00:00
|
|
|
if a:0 > 1
|
|
|
|
" Use the buffer number given as the optional second argument.
|
|
|
|
let l:buffer = a:2
|
|
|
|
elseif a:0 > 0 && a:1 == s:lint_timer
|
|
|
|
" Use the buffer number for the buffer linting was queued for.
|
|
|
|
let l:buffer = s:queued_buffer_number
|
|
|
|
else
|
|
|
|
" Use the current buffer number.
|
|
|
|
let l:buffer = bufnr('')
|
|
|
|
endif
|
2017-04-25 22:52:13 +00:00
|
|
|
|
2017-08-12 09:47:06 +00:00
|
|
|
return ale#CallWithCooldown(
|
|
|
|
\ 'dont_lint_until',
|
|
|
|
\ function('s:ALELintImpl'),
|
|
|
|
\ [l:buffer],
|
|
|
|
\)
|
2017-08-08 23:05:55 +00:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:ALELintImpl(buffer) abort
|
|
|
|
if ale#ShouldDoNothing(a:buffer)
|
2017-07-07 22:47:41 +00:00
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2017-04-25 22:52:13 +00:00
|
|
|
" Use the filetype from the buffer
|
2017-08-08 23:05:55 +00:00
|
|
|
let l:linters = ale#linter#Get(getbufvar(a:buffer, '&filetype'))
|
2017-03-21 14:52:02 +00:00
|
|
|
let l:should_lint_file = 0
|
|
|
|
|
|
|
|
" Check if we previously requested checking the file.
|
2017-08-08 23:05:55 +00:00
|
|
|
if has_key(s:should_lint_file_for_buffer, a:buffer)
|
|
|
|
unlet s:should_lint_file_for_buffer[a:buffer]
|
2017-06-15 08:30:34 +00:00
|
|
|
" Lint files if they exist.
|
2017-08-08 23:05:55 +00:00
|
|
|
let l:should_lint_file = filereadable(expand('#' . a:buffer . ':p'))
|
2017-03-21 14:52:02 +00: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 18:51:29 +00:00
|
|
|
|
2017-08-08 23:05:55 +00:00
|
|
|
call ale#engine#RunLinters(a:buffer, l:linters, l:should_lint_file)
|
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 18:51:29 +00:00
|
|
|
endfunction
|
2017-03-21 14:52:02 +00:00
|
|
|
|
|
|
|
" Reset flags indicating that files should be checked for all buffers.
|
|
|
|
function! ale#ResetLintFileMarkers() abort
|
|
|
|
let s:should_lint_file_for_buffer = {}
|
|
|
|
endfunction
|
2017-04-15 23:16:48 +00:00
|
|
|
|
2017-08-08 23:05:55 +00:00
|
|
|
function! ale#ResetErrorDelays() abort
|
2017-08-12 09:47:06 +00:00
|
|
|
let s:timestamp_map = {}
|
2017-08-08 23:05:55 +00:00
|
|
|
endfunction
|
|
|
|
|
2017-05-05 22:03:19 +00:00
|
|
|
let g:ale_has_override = get(g:, 'ale_has_override', {})
|
|
|
|
|
|
|
|
" Call has(), but check a global Dictionary so we can force flags on or off
|
|
|
|
" for testing purposes.
|
|
|
|
function! ale#Has(feature) abort
|
|
|
|
return get(g:ale_has_override, a:feature, has(a:feature))
|
|
|
|
endfunction
|
|
|
|
|
2017-04-15 23:16:48 +00:00
|
|
|
" Given a buffer number and a variable name, look for that variable in the
|
|
|
|
" buffer scope, then in global scope. If the name does not exist in the global
|
|
|
|
" scope, an exception will be thrown.
|
|
|
|
"
|
|
|
|
" Every variable name will be prefixed with 'ale_'.
|
|
|
|
function! ale#Var(buffer, variable_name) abort
|
2017-05-30 21:15:24 +00:00
|
|
|
let l:nr = str2nr(a:buffer)
|
2017-04-15 23:16:48 +00:00
|
|
|
let l:full_name = 'ale_' . a:variable_name
|
|
|
|
|
2017-05-30 21:15:24 +00:00
|
|
|
if bufexists(l:nr)
|
|
|
|
let l:vars = getbufvar(l:nr, '')
|
|
|
|
elseif has_key(g:, 'ale_fix_buffer_data')
|
|
|
|
let l:vars = get(g:ale_fix_buffer_data, l:nr, {'vars': {}}).vars
|
|
|
|
else
|
|
|
|
let l:vars = {}
|
|
|
|
endif
|
|
|
|
|
|
|
|
return get(l:vars, l:full_name, g:[l:full_name])
|
2017-04-15 23:16:48 +00:00
|
|
|
endfunction
|
2017-05-12 08:20:16 +00:00
|
|
|
|
2017-05-20 22:32:41 +00:00
|
|
|
" Initialize a variable with a default value, if it isn't already set.
|
|
|
|
"
|
|
|
|
" Every variable name will be prefixed with 'ale_'.
|
|
|
|
function! ale#Set(variable_name, default) abort
|
|
|
|
let l:full_name = 'ale_' . a:variable_name
|
|
|
|
let l:value = get(g:, l:full_name, a:default)
|
|
|
|
let g:[l:full_name] = l:value
|
|
|
|
|
|
|
|
return l:value
|
|
|
|
endfunction
|
|
|
|
|
2017-05-12 08:20:16 +00:00
|
|
|
" Escape a string suitably for each platform.
|
2017-05-15 19:21:18 +00:00
|
|
|
" shellescape does not work on Windows.
|
2017-05-12 08:20:16 +00:00
|
|
|
function! ale#Escape(str) abort
|
2017-08-08 07:39:13 +00:00
|
|
|
if fnamemodify(&shell, ':t') is? 'cmd.exe'
|
2017-06-14 10:05:49 +00:00
|
|
|
" If the string contains spaces, it will be surrounded by quotes.
|
|
|
|
" Otherwise, special characters will be escaped with carets (^).
|
|
|
|
return substitute(
|
|
|
|
\ a:str =~# ' '
|
|
|
|
\ ? '"' . substitute(a:str, '"', '""', 'g') . '"'
|
|
|
|
\ : substitute(a:str, '\v([&|<>^])', '^\1', 'g'),
|
|
|
|
\ '%',
|
|
|
|
\ '%%',
|
|
|
|
\ 'g',
|
|
|
|
\)
|
2017-05-12 08:20:16 +00:00
|
|
|
endif
|
2017-05-25 23:06:16 +00:00
|
|
|
|
|
|
|
return shellescape (a:str)
|
2017-05-12 08:20:16 +00:00
|
|
|
endfunction
|