add a class to encapsulate loclists
Add SyntasticLoclist class to wrap up loclists, and move loclist query methods from syntatic.vim to the new class. Make SyntasticChecker#getLocList() return a SyntasticLoclist.
This commit is contained in:
parent
f67d4881ca
commit
8f4695c6de
@ -137,7 +137,8 @@ function! s:UpdateErrors(auto_invoked)
|
|||||||
call s:CacheErrors()
|
call s:CacheErrors()
|
||||||
end
|
end
|
||||||
|
|
||||||
call setloclist(0, s:LocList())
|
let loclist = s:LocList()
|
||||||
|
call setloclist(0, loclist.toRaw())
|
||||||
|
|
||||||
if g:syntastic_enable_balloons
|
if g:syntastic_enable_balloons
|
||||||
call s:RefreshBalloons()
|
call s:RefreshBalloons()
|
||||||
@ -151,7 +152,7 @@ function! s:UpdateErrors(auto_invoked)
|
|||||||
call s:HighlightErrors()
|
call s:HighlightErrors()
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if g:syntastic_auto_jump && s:BufHasErrorsOrWarningsToDisplay()
|
if g:syntastic_auto_jump && loclist.hasErrorsOrWarningsToDisplay()
|
||||||
silent! ll
|
silent! ll
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -161,7 +162,8 @@ endfunction
|
|||||||
"automatically open/close the location list window depending on the users
|
"automatically open/close the location list window depending on the users
|
||||||
"config and buffer error state
|
"config and buffer error state
|
||||||
function! s:AutoToggleLocList()
|
function! s:AutoToggleLocList()
|
||||||
if s:BufHasErrorsOrWarningsToDisplay()
|
let loclist = s:LocList()
|
||||||
|
if loclist.hasErrorsOrWarningsToDisplay()
|
||||||
if g:syntastic_auto_loc_list == 1
|
if g:syntastic_auto_loc_list == 1
|
||||||
call s:ShowLocList()
|
call s:ShowLocList()
|
||||||
endif
|
endif
|
||||||
@ -178,16 +180,14 @@ endfunction
|
|||||||
"lazy init the loc list for the current buffer
|
"lazy init the loc list for the current buffer
|
||||||
function! s:LocList()
|
function! s:LocList()
|
||||||
if !exists("b:syntastic_loclist")
|
if !exists("b:syntastic_loclist")
|
||||||
let b:syntastic_loclist = []
|
let b:syntastic_loclist = g:SyntasticLoclist.New([])
|
||||||
endif
|
endif
|
||||||
return b:syntastic_loclist
|
return b:syntastic_loclist
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
"clear the loc list for the buffer
|
"clear the loc list for the buffer
|
||||||
function! s:ClearCache()
|
function! s:ClearCache()
|
||||||
let b:syntastic_loclist = []
|
unlet! b:syntastic_loclist
|
||||||
unlet! b:syntastic_errors
|
|
||||||
unlet! b:syntastic_warnings
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
"detect and cache all syntax errors in this buffer
|
"detect and cache all syntax errors in this buffer
|
||||||
@ -196,6 +196,7 @@ endfunction
|
|||||||
"elsewhere
|
"elsewhere
|
||||||
function! s:CacheErrors()
|
function! s:CacheErrors()
|
||||||
call s:ClearCache()
|
call s:ClearCache()
|
||||||
|
let newLoclist = g:SyntasticLoclist.New([])
|
||||||
|
|
||||||
if filereadable(expand("%"))
|
if filereadable(expand("%"))
|
||||||
|
|
||||||
@ -205,14 +206,10 @@ function! s:CacheErrors()
|
|||||||
for ft in split(fts, '\.')
|
for ft in split(fts, '\.')
|
||||||
let checkers = s:registry.getActiveCheckers(ft)
|
let checkers = s:registry.getActiveCheckers(ft)
|
||||||
for checker in checkers
|
for checker in checkers
|
||||||
let errors = checker.getLocList()
|
let loclist = checker.getLocList()
|
||||||
|
|
||||||
if !empty(errors)
|
if !loclist.isEmpty()
|
||||||
"keep only lines that effectively match an error/warning
|
let newLoclist = newLoclist.extend(loclist)
|
||||||
let errors = s:FilterLocList({'valid': 1}, errors)
|
|
||||||
"make errors have type "E" by default
|
|
||||||
call SyntasticAddToErrors(errors, {'type': 'E'})
|
|
||||||
call extend(s:LocList(), errors)
|
|
||||||
|
|
||||||
"only get errors from one checker at a time
|
"only get errors from one checker at a time
|
||||||
break
|
break
|
||||||
@ -220,6 +217,8 @@ function! s:CacheErrors()
|
|||||||
endfor
|
endfor
|
||||||
endfor
|
endfor
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
let b:syntastic_loclist = newLoclist
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
"toggle the g:syntastic_mode_map['mode']
|
"toggle the g:syntastic_mode_map['mode']
|
||||||
@ -252,56 +251,6 @@ function! s:ModeMapAllowsAutoChecking()
|
|||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:BufHasErrorsOrWarningsToDisplay()
|
|
||||||
if empty(s:LocList())
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
return len(s:Errors()) || !g:syntastic_quiet_warnings
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Errors()
|
|
||||||
if !exists("b:syntastic_errors")
|
|
||||||
let b:syntastic_errors = s:FilterLocList({'type': "E"})
|
|
||||||
endif
|
|
||||||
return b:syntastic_errors
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Warnings()
|
|
||||||
if !exists("b:syntastic_warnings")
|
|
||||||
let b:syntastic_warnings = s:FilterLocList({'type': "W"})
|
|
||||||
endif
|
|
||||||
return b:syntastic_warnings
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
"Filter a loc list (defaults to s:LocList()) by a:filters
|
|
||||||
"e.g.
|
|
||||||
" s:FilterLocList({'bufnr': 10, 'type': 'e'})
|
|
||||||
"
|
|
||||||
"would return all errors in s:LocList() for buffer 10.
|
|
||||||
"
|
|
||||||
"Note that all comparisons are done with ==?
|
|
||||||
function! s:FilterLocList(filters, ...)
|
|
||||||
let llist = a:0 ? a:1 : s:LocList()
|
|
||||||
|
|
||||||
let rv = []
|
|
||||||
|
|
||||||
for error in llist
|
|
||||||
|
|
||||||
let passes_filters = 1
|
|
||||||
for key in keys(a:filters)
|
|
||||||
if error[key] !=? a:filters[key]
|
|
||||||
let passes_filters = 0
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
if passes_filters
|
|
||||||
call add(rv, error)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
return rv
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
if g:syntastic_enable_signs
|
if g:syntastic_enable_signs
|
||||||
"define the signs used to display syntax and style errors/warns
|
"define the signs used to display syntax and style errors/warns
|
||||||
exe 'sign define SyntasticError text='.g:syntastic_error_symbol.' texthl=error'
|
exe 'sign define SyntasticError text='.g:syntastic_error_symbol.' texthl=error'
|
||||||
@ -318,9 +267,10 @@ let s:next_sign_id = s:first_sign_id
|
|||||||
|
|
||||||
"place signs by all syntax errs in the buffer
|
"place signs by all syntax errs in the buffer
|
||||||
function! s:SignErrors()
|
function! s:SignErrors()
|
||||||
if s:BufHasErrorsOrWarningsToDisplay()
|
let loclist = s:LocList()
|
||||||
|
if loclist.hasErrorsOrWarningsToDisplay()
|
||||||
|
|
||||||
let errors = s:FilterLocList({'bufnr': bufnr('')})
|
let errors = loclist.filter({'bufnr': bufnr('')})
|
||||||
for i in errors
|
for i in errors
|
||||||
let sign_severity = 'Error'
|
let sign_severity = 'Error'
|
||||||
let sign_subtype = ''
|
let sign_subtype = ''
|
||||||
@ -348,7 +298,8 @@ function! s:WarningMasksError(error, llist)
|
|||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return len(s:FilterLocList({ 'type': "E", 'lnum': a:error['lnum'] }, a:llist)) > 0
|
let loclist = g:SyntasticLoclist.New(a:llist)
|
||||||
|
return len(loclist.filter({ 'type': "E", 'lnum': a:error['lnum'] })) > 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
"remove the signs with the given ids from this buffer
|
"remove the signs with the given ids from this buffer
|
||||||
@ -377,8 +328,9 @@ endfunction
|
|||||||
|
|
||||||
"display the cached errors for this buf in the location list
|
"display the cached errors for this buf in the location list
|
||||||
function! s:ShowLocList()
|
function! s:ShowLocList()
|
||||||
if !empty(s:LocList())
|
let loclist = s:LocList()
|
||||||
call setloclist(0, s:LocList())
|
if !loclist.isEmpty()
|
||||||
|
call setloclist(0, loclist.toRaw())
|
||||||
let num = winnr()
|
let num = winnr()
|
||||||
exec "lopen " . g:syntastic_loc_list_height
|
exec "lopen " . g:syntastic_loc_list_height
|
||||||
if num != winnr()
|
if num != winnr()
|
||||||
@ -398,11 +350,12 @@ endfunction
|
|||||||
"the callback even if it can be highlighted automatically.
|
"the callback even if it can be highlighted automatically.
|
||||||
function! s:HighlightErrors()
|
function! s:HighlightErrors()
|
||||||
call s:ClearErrorHighlights()
|
call s:ClearErrorHighlights()
|
||||||
|
let loclist = s:LocList()
|
||||||
|
|
||||||
let fts = substitute(&ft, '-', '_', 'g')
|
let fts = substitute(&ft, '-', '_', 'g')
|
||||||
for ft in split(fts, '\.')
|
for ft in split(fts, '\.')
|
||||||
|
|
||||||
for item in s:LocList()
|
for item in loclist.toRaw()
|
||||||
|
|
||||||
let force_callback = has_key(item, 'force_highlight_callback') && item['force_highlight_callback']
|
let force_callback = has_key(item, 'force_highlight_callback') && item['force_highlight_callback']
|
||||||
|
|
||||||
@ -436,8 +389,9 @@ endfunction
|
|||||||
"set up error ballons for the current set of errors
|
"set up error ballons for the current set of errors
|
||||||
function! s:RefreshBalloons()
|
function! s:RefreshBalloons()
|
||||||
let b:syntastic_balloons = {}
|
let b:syntastic_balloons = {}
|
||||||
if s:BufHasErrorsOrWarningsToDisplay()
|
let loclist = s:LocList()
|
||||||
for i in s:LocList()
|
if loclist.hasErrorsOrWarningsToDisplay()
|
||||||
|
for i in loclist.toRaw()
|
||||||
let b:syntastic_balloons[i['lnum']] = i['text']
|
let b:syntastic_balloons[i['lnum']] = i['text']
|
||||||
endfor
|
endfor
|
||||||
set beval bexpr=SyntasticErrorBalloonExpr()
|
set beval bexpr=SyntasticErrorBalloonExpr()
|
||||||
@ -471,9 +425,10 @@ endfunction
|
|||||||
|
|
||||||
"echo out the first error we find for the current line in the cmd window
|
"echo out the first error we find for the current line in the cmd window
|
||||||
function! s:EchoCurrentError()
|
function! s:EchoCurrentError()
|
||||||
|
let loclist = s:LocList()
|
||||||
"If we have an error or warning at the current line, show it
|
"If we have an error or warning at the current line, show it
|
||||||
let errors = s:FilterLocList({'lnum': line("."), "type": 'e'})
|
let errors = loclist.filter({'lnum': line("."), "type": 'e'})
|
||||||
let warnings = s:FilterLocList({'lnum': line("."), "type": 'w'})
|
let warnings = loclist.filter({'lnum': line("."), "type": 'w'})
|
||||||
|
|
||||||
let b:syntastic_echoing_error = len(errors) || len(warnings)
|
let b:syntastic_echoing_error = len(errors) || len(warnings)
|
||||||
if len(errors)
|
if len(errors)
|
||||||
@ -540,9 +495,10 @@ endfunction
|
|||||||
"
|
"
|
||||||
"return '' if no errors are cached for the buffer
|
"return '' if no errors are cached for the buffer
|
||||||
function! SyntasticStatuslineFlag()
|
function! SyntasticStatuslineFlag()
|
||||||
if s:BufHasErrorsOrWarningsToDisplay()
|
let loclist = s:LocList()
|
||||||
let errors = s:Errors()
|
if loclist.hasErrorsOrWarningsToDisplay()
|
||||||
let warnings = s:Warnings()
|
let errors = loclist.errors()
|
||||||
|
let warnings = loclist.warnings()
|
||||||
|
|
||||||
let num_errors = len(errors)
|
let num_errors = len(errors)
|
||||||
let num_warnings = len(warnings)
|
let num_warnings = len(warnings)
|
||||||
@ -558,13 +514,14 @@ function! SyntasticStatuslineFlag()
|
|||||||
"hide stuff wrapped in %B(...) unless there are both errors and warnings
|
"hide stuff wrapped in %B(...) unless there are both errors and warnings
|
||||||
let output = substitute(output, '\C%B{\([^}]*\)}', (num_warnings && num_errors) ? '\1' : '' , 'g')
|
let output = substitute(output, '\C%B{\([^}]*\)}', (num_warnings && num_errors) ? '\1' : '' , 'g')
|
||||||
|
|
||||||
|
|
||||||
"sub in the total errors/warnings/both
|
"sub in the total errors/warnings/both
|
||||||
let output = substitute(output, '\C%w', num_warnings, 'g')
|
let output = substitute(output, '\C%w', num_warnings, 'g')
|
||||||
let output = substitute(output, '\C%e', num_errors, 'g')
|
let output = substitute(output, '\C%e', num_errors, 'g')
|
||||||
let output = substitute(output, '\C%t', len(s:LocList()), 'g')
|
let output = substitute(output, '\C%t', loclist.length(), 'g')
|
||||||
|
|
||||||
"first error/warning line num
|
"first error/warning line num
|
||||||
let output = substitute(output, '\C%F', s:LocList()[0]['lnum'], 'g')
|
let output = substitute(output, '\C%F', loclist.toRaw()[0]['lnum'], 'g')
|
||||||
|
|
||||||
"first error line num
|
"first error line num
|
||||||
let output = substitute(output, '\C%fe', num_errors ? errors[0]['lnum'] : '', 'g')
|
let output = substitute(output, '\C%fe', num_errors ? errors[0]['lnum'] : '', 'g')
|
||||||
|
@ -36,7 +36,8 @@ function! g:SyntasticChecker.name()
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! g:SyntasticChecker.getLocList()
|
function! g:SyntasticChecker.getLocList()
|
||||||
return self._locListFunc()
|
let list = self._locListFunc()
|
||||||
|
return g:SyntasticLoclist.New(list)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! g:SyntasticChecker.getHighlightRegexFor(error)
|
function! g:SyntasticChecker.getHighlightRegexFor(error)
|
||||||
|
92
plugin/syntastic/loclist.vim
Normal file
92
plugin/syntastic/loclist.vim
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
if exists("g:loaded_syntastic_loclist")
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
let g:loaded_syntastic_list=1
|
||||||
|
|
||||||
|
let g:SyntasticLoclist = {}
|
||||||
|
|
||||||
|
" Public methods {{{1
|
||||||
|
|
||||||
|
function! g:SyntasticLoclist.New(rawLoclist)
|
||||||
|
let newObj = copy(self)
|
||||||
|
let newObj._quietWarnings = g:syntastic_quiet_warnings
|
||||||
|
|
||||||
|
let llist = copy(a:rawLoclist)
|
||||||
|
let llist = filter(llist, 'v:val["valid"] == 1')
|
||||||
|
|
||||||
|
for e in llist
|
||||||
|
if empty(e['type'])
|
||||||
|
let e['type'] = 'E'
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let newObj._rawLoclist = llist
|
||||||
|
|
||||||
|
return newObj
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! g:SyntasticLoclist.extend(other)
|
||||||
|
let list = self.toRaw()
|
||||||
|
call extend(list, a:other.toRaw())
|
||||||
|
return g:SyntasticLoclist.New(list)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! g:SyntasticLoclist.toRaw()
|
||||||
|
return copy(self._rawLoclist)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! g:SyntasticLoclist.isEmpty()
|
||||||
|
return empty(self._rawLoclist)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! g:SyntasticLoclist.length()
|
||||||
|
return len(self._rawLoclist)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! g:SyntasticLoclist.hasErrorsOrWarningsToDisplay()
|
||||||
|
if empty(self._rawLoclist)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
return len(self.errors()) || !self._quietWarnings
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! g:SyntasticLoclist.errors()
|
||||||
|
if !exists("self._cachedErrors")
|
||||||
|
let self._cachedErrors = self.filter({'type': "E"})
|
||||||
|
endif
|
||||||
|
return self._cachedErrors
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! SyntasticLoclist.warnings()
|
||||||
|
if !exists("self._cachedWarnings")
|
||||||
|
let self._cachedWarnings = self.filter({'type': "W"})
|
||||||
|
endif
|
||||||
|
return self._cachedWarnings
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
"Filter the list and return new native loclist
|
||||||
|
"e.g.
|
||||||
|
" .filter({'bufnr': 10, 'type': 'e'})
|
||||||
|
"
|
||||||
|
"would return all errors for buffer 10.
|
||||||
|
"
|
||||||
|
"Note that all comparisons are done with ==?
|
||||||
|
function! g:SyntasticLoclist.filter(filters)
|
||||||
|
let rv = []
|
||||||
|
|
||||||
|
for error in self._rawLoclist
|
||||||
|
|
||||||
|
let passes_filters = 1
|
||||||
|
for key in keys(a:filters)
|
||||||
|
if error[key] !=? a:filters[key]
|
||||||
|
let passes_filters = 0
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if passes_filters
|
||||||
|
call add(rv, error)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return rv
|
||||||
|
endfunction
|
Loading…
x
Reference in New Issue
Block a user