Implement a more efficient statusbar
The statusbar now keeps its state in a separate variable, in order to avoid excess iterations. The engine now updates said variable on run, and a new function is made available for external statusbars to call (to avoid dependencies on internal implementation details of ale). To keep things light, the status bar code is not loaded unless invoked by the user or an external plugin. On the first load it will update itself from the global loclist, after that, the engine will handle all updates. The external integration function, `ale#statusline#Count()`, will return a tuple in the format [E, W] (where E is errors, W is warnings), unless no data exists (ie, the plugin doesn't have a linter for a file or has not run yet), in which case it returns 0/false.
This commit is contained in:
parent
f4159ac7ee
commit
dc58db7640
@ -2,14 +2,18 @@
|
||||
" Description: Utility functions related to cleaning state.
|
||||
|
||||
function! ale#cleanup#Buffer(buffer) abort
|
||||
if has_key(g:ale_buffer_should_reset_map, a:buffer)
|
||||
call remove(g:ale_buffer_should_reset_map, a:buffer)
|
||||
if has_key(g:ale_buffer_count_map, a:buffer)
|
||||
call remove(g:ale_buffer_count_map, a:buffer)
|
||||
endif
|
||||
|
||||
if has_key(g:ale_buffer_loclist_map, a:buffer)
|
||||
call remove(g:ale_buffer_loclist_map, a:buffer)
|
||||
endif
|
||||
|
||||
if has_key(g:ale_buffer_should_reset_map, a:buffer)
|
||||
call remove(g:ale_buffer_should_reset_map, a:buffer)
|
||||
endif
|
||||
|
||||
if has_key(g:ale_buffer_sign_dummy_map, a:buffer)
|
||||
call remove(g:ale_buffer_sign_dummy_map, a:buffer)
|
||||
endif
|
||||
|
@ -98,7 +98,7 @@ function! s:HandleExit(job) abort
|
||||
" Sort the loclist again.
|
||||
" We need a sorted list so we can run a binary search against it
|
||||
" for efficient lookup of the messages in the cursor handler.
|
||||
call sort(g:ale_buffer_loclist_map[l:buffer], 'ale#util#LocItemCompare')
|
||||
call sort(g:ale_buffer_loclist_map[l:buffer], 's:LocItemCompare')
|
||||
|
||||
if g:ale_set_loclist
|
||||
call setloclist(0, g:ale_buffer_loclist_map[l:buffer])
|
||||
@ -108,6 +108,11 @@ function! s:HandleExit(job) abort
|
||||
call ale#sign#SetSigns(l:buffer, g:ale_buffer_loclist_map[l:buffer])
|
||||
endif
|
||||
|
||||
if exists('*ale#statusline#Update')
|
||||
" Don't load/run if not already loaded.
|
||||
call ale#statusline#Update(l:buffer, g:ale_buffer_loclist_map[l:buffer])
|
||||
endif
|
||||
|
||||
" Mark line 200, column 17 with a squiggly line or something
|
||||
" matchadd('ALEError', '\%200l\%17v')
|
||||
endfunction
|
||||
@ -136,6 +141,26 @@ function! s:FixLocList(buffer, loclist) abort
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:LocItemCompare(left, right) abort
|
||||
if a:left['lnum'] < a:right['lnum']
|
||||
return -1
|
||||
endif
|
||||
|
||||
if a:left['lnum'] > a:right['lnum']
|
||||
return 1
|
||||
endif
|
||||
|
||||
if a:left['col'] < a:right['col']
|
||||
return -1
|
||||
endif
|
||||
|
||||
if a:left['col'] > a:right['col']
|
||||
return 1
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! ale#engine#Invoke(buffer, linter) abort
|
||||
if has_key(a:linter, 'job')
|
||||
" Stop previous jobs for the same linter.
|
||||
|
@ -1,20 +1,12 @@
|
||||
" Author: KabbAmine <amine.kabb@gmail.com>
|
||||
" Description: Statusline related function(s)
|
||||
|
||||
function! ale#statusline#Status() abort
|
||||
" Returns a formatted string that can be integrated in the
|
||||
" statusline
|
||||
|
||||
let l:buffer = bufnr('%')
|
||||
let l:loclist = g:ale_buffer_loclist_map
|
||||
|
||||
if !has_key(l:loclist, l:buffer)
|
||||
return ''
|
||||
endif
|
||||
|
||||
" Update the buffer error/warning count with data from loclist.
|
||||
function! ale#statusline#Update(buffer, loclist) abort
|
||||
let l:errors = 0
|
||||
let l:warnings = 0
|
||||
for l:entry in l:loclist[l:buffer]
|
||||
|
||||
for l:entry in a:loclist
|
||||
if l:entry.type ==# 'E'
|
||||
let l:errors += 1
|
||||
else
|
||||
@ -22,8 +14,41 @@ function! ale#statusline#Status() abort
|
||||
endif
|
||||
endfor
|
||||
|
||||
let l:errors = l:errors ? printf(g:ale_statusline_format[0], l:errors) : ''
|
||||
let l:warnings = l:warnings ? printf(g:ale_statusline_format[1], l:warnings) : ''
|
||||
let g:ale_buffer_count_map[a:buffer] = [l:errors, l:warnings]
|
||||
endfunction
|
||||
|
||||
" Returns a tuple of errors and warnings (or false if no data exists)
|
||||
" for use in third-party integrations.
|
||||
function! ale#statusline#Count(buffer) abort
|
||||
if !has_key(g:ale_buffer_count_map, a:buffer)
|
||||
if has_key(g:ale_buffer_loclist_map, a:buffer)
|
||||
call ale#statusline#Update(a:buffer, g:ale_buffer_loclist_map[a:buffer])
|
||||
return ale#statusline#Count(a:buffer)
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endif
|
||||
|
||||
return g:ale_buffer_count_map[a:buffer]
|
||||
endfunction
|
||||
|
||||
" Returns a formatted string that can be integrated in the statusline.
|
||||
function! ale#statusline#Status() abort
|
||||
let l:buffer = bufnr('%')
|
||||
|
||||
if !has_key(g:ale_buffer_count_map, l:buffer)
|
||||
if has_key(g:ale_buffer_loclist_map, l:buffer)
|
||||
call ale#statusline#Update(l:buffer, g:ale_buffer_loclist_map[l:buffer])
|
||||
return ale#statusline#Status()
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:errors = g:ale_buffer_count_map[l:buffer][0] ?
|
||||
\ printf(g:ale_statusline_format[0], g:ale_buffer_count_map[l:buffer][0]) : ''
|
||||
let l:warnings = g:ale_buffer_count_map[l:buffer][1] ?
|
||||
\ printf(g:ale_statusline_format[1], g:ale_buffer_count_map[l:buffer][1]) : ''
|
||||
let l:no_errors = g:ale_statusline_format[2]
|
||||
|
||||
" Different formats if no errors or no warnings
|
||||
|
@ -43,23 +43,3 @@ function! ale#util#GetFunction(string_or_ref) abort
|
||||
|
||||
return a:string_or_ref
|
||||
endfunction
|
||||
|
||||
function! ale#util#LocItemCompare(left, right) abort
|
||||
if a:left['lnum'] < a:right['lnum']
|
||||
return -1
|
||||
endif
|
||||
|
||||
if a:left['lnum'] > a:right['lnum']
|
||||
return 1
|
||||
endif
|
||||
|
||||
if a:left['col'] < a:right['col']
|
||||
return -1
|
||||
endif
|
||||
|
||||
if a:left['col'] > a:right['col']
|
||||
return 1
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
@ -24,6 +24,7 @@ endif
|
||||
|
||||
" Globals
|
||||
|
||||
let g:ale_buffer_count_map = {}
|
||||
let g:ale_buffer_loclist_map = {}
|
||||
let g:ale_buffer_should_reset_map = {}
|
||||
let g:ale_buffer_sign_dummy_map = {}
|
||||
@ -98,7 +99,8 @@ let g:ale_echo_msg_error_str = get(g:, 'ale_echo_msg_error_str', 'Error')
|
||||
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
|
||||
|
||||
" This flag can be set to 0 to disable echoing when the cursor moves.
|
||||
if get(g:, 'ale_echo_cursor', 1)
|
||||
let g:ale_echo_cursor = get(g:, 'ale_echo_cursor', 1)
|
||||
if g:ale_echo_cursor
|
||||
augroup ALECursorGroup
|
||||
autocmd!
|
||||
autocmd CursorMoved,CursorHold * call ale#cursor#EchoCursorWarningWithDelay()
|
||||
@ -120,10 +122,10 @@ let g:ale_warn_about_trailing_whitespace =
|
||||
|
||||
" Housekeeping
|
||||
|
||||
augroup ALECleanup
|
||||
augroup ALECleanupGroup
|
||||
autocmd!
|
||||
" Clean up buffers automatically when they are unloaded.
|
||||
autocmd BufUnload * call ale#cleanup#Buffer('<abuf>')
|
||||
autocmd BufUnload * call ale#cleanup#Buffer(expand('<abuf>'))
|
||||
augroup END
|
||||
|
||||
" Backwards Compatibility
|
||||
|
Loading…
Reference in New Issue
Block a user