Notifiers refactor.
Creates a notifier class. Changes the existing signer class to fit the new notifier. Moves balloons and highlighting to their own classes. Caches and speeds up EchoCurrentError(). Adds all relevant messages to balloons rather than using the first one. Fixes yet another (minor) bug related to g:syntastic_quiet_warnings.
This commit is contained in:
parent
01232979aa
commit
0deeefd08e
@ -21,22 +21,6 @@ runtime! plugin/syntastic/*.vim
|
||||
|
||||
let s:running_windows = has("win16") || has("win32")
|
||||
|
||||
if !exists("g:syntastic_enable_balloons")
|
||||
let g:syntastic_enable_balloons = 1
|
||||
endif
|
||||
if !has('balloon_eval')
|
||||
let g:syntastic_enable_balloons = 0
|
||||
endif
|
||||
|
||||
if !exists("g:syntastic_enable_highlighting")
|
||||
let g:syntastic_enable_highlighting = 1
|
||||
endif
|
||||
|
||||
" highlighting requires getmatches introduced in 7.1.040
|
||||
if v:version < 701 || (v:version == 701 && !has('patch040'))
|
||||
let g:syntastic_enable_highlighting = 0
|
||||
endif
|
||||
|
||||
if !exists("g:syntastic_echo_current_error")
|
||||
let g:syntastic_echo_current_error = 1
|
||||
endif
|
||||
@ -70,9 +54,9 @@ if !exists("g:syntastic_loc_list_height")
|
||||
endif
|
||||
|
||||
let s:registry = g:SyntasticRegistry.Instance()
|
||||
let s:signer = g:SyntasticSigner.New()
|
||||
call s:signer.SetUpSignStyles()
|
||||
let s:notifiers = g:SyntasticNotifiers.New()
|
||||
let s:modemap = g:SyntasticModeMap.Instance()
|
||||
let s:old_line = -1
|
||||
|
||||
function! s:CompleteCheckerName(argLead, cmdLine, cursorPos)
|
||||
let checker_names = []
|
||||
@ -93,7 +77,7 @@ highlight link SyntasticWarning SpellCap
|
||||
|
||||
augroup syntastic
|
||||
if g:syntastic_echo_current_error
|
||||
autocmd cursormoved * call s:EchoCurrentError()
|
||||
autocmd CursorMoved * call s:EchoCurrentError()
|
||||
endif
|
||||
|
||||
autocmd BufReadPost * if g:syntastic_check_on_open | call s:UpdateErrors(1) | endif
|
||||
@ -118,17 +102,7 @@ function! s:UpdateErrors(auto_invoked, ...)
|
||||
endif
|
||||
end
|
||||
|
||||
if g:syntastic_enable_balloons
|
||||
call s:RefreshBalloons()
|
||||
endif
|
||||
|
||||
if g:syntastic_enable_signs
|
||||
call s:signer.refreshSigns(s:LocList())
|
||||
endif
|
||||
|
||||
if g:syntastic_enable_highlighting
|
||||
call s:HighlightErrors()
|
||||
endif
|
||||
call s:notifiers.refresh(s:LocList())
|
||||
|
||||
let loclist = s:LocList()
|
||||
if g:syntastic_always_populate_loc_list && loclist.hasErrorsOrWarningsToDisplay()
|
||||
@ -172,6 +146,7 @@ endfunction
|
||||
"clear the loc list for the buffer
|
||||
function! s:ClearCache()
|
||||
unlet! b:syntastic_loclist
|
||||
let s:old_line = -1
|
||||
endfunction
|
||||
|
||||
function! s:CurrentFiletypes()
|
||||
@ -242,58 +217,6 @@ function! s:HideLocList()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"highlight the current errors using matchadd()
|
||||
"
|
||||
"The function `Syntastic_{filetype}_{checker}_GetHighlightRegex` is used
|
||||
"to override default highlighting. This function must take one arg (an
|
||||
"error item) and return a regex to match that item in the buffer.
|
||||
function! s:HighlightErrors()
|
||||
call s:ClearErrorHighlights()
|
||||
let loclist = s:LocList()
|
||||
|
||||
let fts = substitute(&ft, '-', '_', 'g')
|
||||
for ft in split(fts, '\.')
|
||||
|
||||
for item in loclist.filteredRaw()
|
||||
let group = item['type'] == 'E' ? 'SyntasticError' : 'SyntasticWarning'
|
||||
|
||||
if has_key(item, 'hl')
|
||||
call matchadd(group, '\%' . item['lnum'] . 'l' . item['hl'])
|
||||
elseif get(item, 'col')
|
||||
let lastcol = col([item['lnum'], '$'])
|
||||
let lcol = min([lastcol, item['col']])
|
||||
|
||||
"a bug in vim can sometimes cause there to be no 'vcol' key,
|
||||
"so check for its existence
|
||||
let coltype = has_key(item, 'vcol') && item['vcol'] ? 'v' : 'c'
|
||||
|
||||
call matchadd(group, '\%' . item['lnum'] . 'l\%' . lcol . coltype)
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
"remove all error highlights from the window
|
||||
function! s:ClearErrorHighlights()
|
||||
for match in getmatches()
|
||||
if stridx(match['group'], 'Syntastic') == 0
|
||||
call matchdelete(match['id'])
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
"set up error ballons for the current set of errors
|
||||
function! s:RefreshBalloons()
|
||||
let b:syntastic_balloons = {}
|
||||
let loclist = s:LocList()
|
||||
if loclist.hasErrorsOrWarningsToDisplay()
|
||||
for i in loclist.filteredRaw()
|
||||
let b:syntastic_balloons[i['lnum']] = i['text']
|
||||
endfor
|
||||
set beval bexpr=SyntasticErrorBalloonExpr()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"print as much of a:msg as possible without "Press Enter" prompt appearing
|
||||
function! s:WideMsg(msg)
|
||||
let old_ruler = &ruler
|
||||
@ -321,23 +244,18 @@ endfunction
|
||||
|
||||
"echo out the first error we find for the current line in the cmd window
|
||||
function! s:EchoCurrentError()
|
||||
let l = line('.')
|
||||
if l == s:old_line
|
||||
return
|
||||
endif
|
||||
let s:old_line = l
|
||||
|
||||
let loclist = s:LocList()
|
||||
"If we have an error or warning at the current line, show it
|
||||
let errors = loclist.filter({'lnum': line("."), "type": 'e'})
|
||||
let warnings = loclist.filter({'lnum': line("."), "type": 'w'})
|
||||
|
||||
let b:syntastic_echoing_error = len(errors) || len(warnings)
|
||||
if len(errors)
|
||||
return s:WideMsg(errors[0]['text'])
|
||||
endif
|
||||
if len(warnings)
|
||||
return s:WideMsg(warnings[0]['text'])
|
||||
endif
|
||||
|
||||
"Otherwise, clear the status line
|
||||
if b:syntastic_echoing_error
|
||||
let messages = loclist.messages()
|
||||
if has_key(messages, l)
|
||||
return s:WideMsg(messages[l])
|
||||
else
|
||||
echo
|
||||
let b:syntastic_echoing_error = 0
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@ -484,14 +402,6 @@ function! SyntasticMake(options)
|
||||
return errors
|
||||
endfunction
|
||||
|
||||
"get the error balloon for the current mouse position
|
||||
function! SyntasticErrorBalloonExpr()
|
||||
if !exists('b:syntastic_balloons')
|
||||
return ''
|
||||
endif
|
||||
return get(b:syntastic_balloons, v:beval_lnum, '')
|
||||
endfunction
|
||||
|
||||
"take a list of errors and add default values to them from a:options
|
||||
function! SyntasticAddToErrors(errors, options)
|
||||
for i in range(0, len(a:errors)-1)
|
||||
|
47
plugin/syntastic/balloons.vim
Normal file
47
plugin/syntastic/balloons.vim
Normal file
@ -0,0 +1,47 @@
|
||||
if exists("g:loaded_syntastic_notifier_balloons")
|
||||
finish
|
||||
endif
|
||||
let g:loaded_syntastic_notifier_balloons=1
|
||||
|
||||
if !exists("g:syntastic_enable_balloons")
|
||||
let g:syntastic_enable_balloons = 1
|
||||
endif
|
||||
|
||||
if !has('balloon_eval')
|
||||
let g:syntastic_enable_balloons = 0
|
||||
endif
|
||||
|
||||
let g:SyntasticNotifierBalloons = {}
|
||||
|
||||
" Public methods {{{1
|
||||
|
||||
function! g:SyntasticNotifierBalloons.New()
|
||||
let newObj = copy(self)
|
||||
return newObj
|
||||
endfunction
|
||||
|
||||
" Update the error balloons
|
||||
function! g:SyntasticNotifierBalloons.refresh(loclist)
|
||||
let b:syntastic_balloons = {}
|
||||
if a:loclist.hasErrorsOrWarningsToDisplay()
|
||||
for i in a:loclist.filteredRaw()
|
||||
if has_key(b:syntastic_balloons, i['lnum'])
|
||||
let b:syntastic_balloons[i['lnum']] .= "\n" . i['text']
|
||||
else
|
||||
let b:syntastic_balloons[i['lnum']] = i['text']
|
||||
endif
|
||||
endfor
|
||||
set beval bexpr=SyntasticNotifierBalloonsExpr()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Private functions {{{1
|
||||
|
||||
function! SyntasticNotifierBalloonsExpr()
|
||||
if !exists('b:syntastic_balloons')
|
||||
return ''
|
||||
endif
|
||||
return get(b:syntastic_balloons, v:beval_lnum, '')
|
||||
endfunction
|
||||
|
||||
" vim: set sw=4 sts=4 et fdm=marker:
|
63
plugin/syntastic/highlighting.vim
Normal file
63
plugin/syntastic/highlighting.vim
Normal file
@ -0,0 +1,63 @@
|
||||
if exists("g:loaded_syntastic_notifier_highlighting")
|
||||
finish
|
||||
endif
|
||||
let g:loaded_syntastic_notifier_highlighting=1
|
||||
|
||||
if !exists("g:syntastic_enable_highlighting")
|
||||
let g:syntastic_enable_highlighting = 1
|
||||
endif
|
||||
|
||||
" Highlighting requires getmatches introduced in 7.1.040
|
||||
if v:version < 701 || (v:version == 701 && !has('patch040'))
|
||||
let g:syntastic_enable_highlighting = 0
|
||||
endif
|
||||
|
||||
let g:SyntasticNotifierHighlighting = {}
|
||||
|
||||
" Public methods {{{1
|
||||
|
||||
function! g:SyntasticNotifierHighlighting.New()
|
||||
let newObj = copy(self)
|
||||
return newObj
|
||||
endfunction
|
||||
|
||||
" The function `Syntastic_{filetype}_{checker}_GetHighlightRegex` is used
|
||||
" to override default highlighting. This function must take one arg (an
|
||||
" error item) and return a regex to match that item in the buffer.
|
||||
function! g:SyntasticNotifierHighlighting.refresh(loclist)
|
||||
call self._reset()
|
||||
|
||||
let fts = substitute(&ft, '-', '_', 'g')
|
||||
for ft in split(fts, '\.')
|
||||
|
||||
for item in a:loclist.filteredRaw()
|
||||
let group = item['type'] == 'E' ? 'SyntasticError' : 'SyntasticWarning'
|
||||
|
||||
if has_key(item, 'hl')
|
||||
call matchadd(group, '\%' . item['lnum'] . 'l' . item['hl'])
|
||||
elseif get(item, 'col')
|
||||
let lastcol = col([item['lnum'], '$'])
|
||||
let lcol = min([lastcol, item['col']])
|
||||
|
||||
" a bug in vim can sometimes cause there to be no 'vcol' key,
|
||||
" so check for its existence
|
||||
let coltype = has_key(item, 'vcol') && item['vcol'] ? 'v' : 'c'
|
||||
|
||||
call matchadd(group, '\%' . item['lnum'] . 'l\%' . lcol . coltype)
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Private functions {{{1
|
||||
|
||||
" Remove all error highlights from the window
|
||||
function! g:SyntasticNotifierHighlighting._reset()
|
||||
for match in getmatches()
|
||||
if stridx(match['group'], 'Syntastic') == 0
|
||||
call matchdelete(match['id'])
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" vim: set sw=4 sts=4 et fdm=marker:
|
@ -63,13 +63,36 @@ function! g:SyntasticLoclist.errors()
|
||||
return self._cachedErrors
|
||||
endfunction
|
||||
|
||||
function! SyntasticLoclist.warnings()
|
||||
function! g:SyntasticLoclist.warnings()
|
||||
if !exists("self._cachedWarnings")
|
||||
let self._cachedWarnings = self.filter({'type': "W"})
|
||||
endif
|
||||
return self._cachedWarnings
|
||||
endfunction
|
||||
|
||||
" cache used by EchoCurrentError()
|
||||
function! g:SyntasticLoclist.messages()
|
||||
if !exists("self._cachedMessages")
|
||||
let self._cachedMessages = {}
|
||||
|
||||
for e in self.errors()
|
||||
if !has_key(self._cachedMessages, e['lnum'])
|
||||
let self._cachedMessages[e['lnum']] = e['text']
|
||||
endif
|
||||
endfor
|
||||
|
||||
if !self._quietWarnings
|
||||
for e in self.warnings()
|
||||
if !has_key(self._cachedMessages, e['lnum'])
|
||||
let self._cachedMessages[e['lnum']] = e['text']
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
|
||||
return self._cachedMessages
|
||||
endfunction
|
||||
|
||||
"Filter the list and return new native loclist
|
||||
"e.g.
|
||||
" .filter({'bufnr': 10, 'type': 'e'})
|
||||
|
34
plugin/syntastic/notifiers.vim
Normal file
34
plugin/syntastic/notifiers.vim
Normal file
@ -0,0 +1,34 @@
|
||||
if exists("g:loaded_syntastic_notifiers")
|
||||
finish
|
||||
endif
|
||||
let g:loaded_syntastic_notifiers=1
|
||||
|
||||
let g:SyntasticNotifiers = {}
|
||||
|
||||
let s:notifier_types = ['signs', 'balloons', 'highlighting']
|
||||
|
||||
" Public methods {{{1
|
||||
|
||||
function! g:SyntasticNotifiers.New()
|
||||
let newObj = copy(self)
|
||||
|
||||
let newObj._notifier = {}
|
||||
for type in s:notifier_types
|
||||
let class = substitute(type, '.*', 'SyntasticNotifier\u&', '')
|
||||
let newObj._notifier[type] = g:{class}.New()
|
||||
endfor
|
||||
|
||||
let newObj._enabled_types = copy(s:notifier_types)
|
||||
|
||||
return newObj
|
||||
endfunction
|
||||
|
||||
function! g:SyntasticNotifiers.refresh(loclist)
|
||||
for type in self._enabled_types
|
||||
if ( exists('b:syntastic_enable_'.type) ? b:syntastic_enable_{type} : g:syntastic_enable_{type} )
|
||||
call self._notifier[type].refresh(a:loclist)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" vim: set sw=4 sts=4 et fdm=marker:
|
@ -1,7 +1,7 @@
|
||||
if exists("g:loaded_syntastic_signer")
|
||||
if exists("g:loaded_syntastic_notifier_signs")
|
||||
finish
|
||||
endif
|
||||
let g:loaded_syntastic_signer=1
|
||||
let g:loaded_syntastic_notifier_signs=1
|
||||
|
||||
if !exists("g:syntastic_enable_signs")
|
||||
let g:syntastic_enable_signs = 1
|
||||
@ -28,21 +28,40 @@ if !has('signs')
|
||||
endif
|
||||
|
||||
|
||||
"start counting sign ids at 5000, start here to hopefully avoid conflicting
|
||||
"with any other code that places signs (not sure if this precaution is
|
||||
"actually needed)
|
||||
" start counting sign ids at 5000, start here to hopefully avoid conflicting
|
||||
" with any other code that places signs (not sure if this precaution is
|
||||
" actually needed)
|
||||
let s:first_sign_id = 5000
|
||||
let s:next_sign_id = s:first_sign_id
|
||||
|
||||
let g:SyntasticSigner = {}
|
||||
let g:SyntasticNotifierSigns = {}
|
||||
|
||||
"Public methods {{{1
|
||||
function! g:SyntasticSigner.New()
|
||||
let s:setup_done = 0
|
||||
|
||||
" Public methods {{{1
|
||||
|
||||
function! g:SyntasticNotifierSigns.New()
|
||||
let newObj = copy(self)
|
||||
|
||||
if !s:setup_done
|
||||
call self._setup()
|
||||
let s:setup_done = 1
|
||||
endif
|
||||
|
||||
return newObj
|
||||
endfunction
|
||||
|
||||
function! g:SyntasticSigner.SetUpSignStyles()
|
||||
" Update the error signs
|
||||
function! g:SyntasticNotifierSigns.refresh(loclist)
|
||||
let old_signs = copy(self._bufSignIds())
|
||||
call self._signErrors(a:loclist)
|
||||
call self._removeSigns(old_signs)
|
||||
let s:first_sign_id = s:next_sign_id
|
||||
endfunction
|
||||
|
||||
" Private methods {{{1
|
||||
|
||||
function! g:SyntasticNotifierSigns._setup()
|
||||
if has('signs')
|
||||
if !hlexists('SyntasticErrorSign')
|
||||
highlight link SyntasticErrorSign error
|
||||
@ -63,26 +82,20 @@ function! g:SyntasticSigner.SetUpSignStyles()
|
||||
highlight link SyntasticStyleWarningLine SyntasticWarningLine
|
||||
endif
|
||||
|
||||
"define the signs used to display syntax and style errors/warns
|
||||
exe 'sign define SyntasticError text='.g:syntastic_error_symbol.' texthl=SyntasticErrorSign linehl=SyntasticErrorLine'
|
||||
exe 'sign define SyntasticWarning text='.g:syntastic_warning_symbol.' texthl=SyntasticWarningSign linehl=SyntasticWarningLine'
|
||||
exe 'sign define SyntasticStyleError text='.g:syntastic_style_error_symbol.' texthl=SyntasticStyleErrorSign linehl=SyntasticStyleErrorLine'
|
||||
exe 'sign define SyntasticStyleWarning text='.g:syntastic_style_warning_symbol.' texthl=SyntasticStyleWarningSign linehl=SyntasticStyleWarningLine'
|
||||
" define the signs used to display syntax and style errors/warns
|
||||
exe 'sign define SyntasticError text=' . g:syntastic_error_symbol .
|
||||
\ ' texthl=SyntasticErrorSign linehl=SyntasticErrorLine'
|
||||
exe 'sign define SyntasticWarning text=' . g:syntastic_warning_symbol .
|
||||
\ ' texthl=SyntasticWarningSign linehl=SyntasticWarningLine'
|
||||
exe 'sign define SyntasticStyleError text=' . g:syntastic_style_error_symbol .
|
||||
\ ' texthl=SyntasticStyleErrorSign linehl=SyntasticStyleErrorLine'
|
||||
exe 'sign define SyntasticStyleWarning text=' . g:syntastic_style_warning_symbol .
|
||||
\ ' texthl=SyntasticStyleWarningSign linehl=SyntasticStyleWarningLine'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"update the error signs
|
||||
function! g:SyntasticSigner.refreshSigns(loclist)
|
||||
let old_signs = copy(self._bufSignIds())
|
||||
call self._signErrors(a:loclist)
|
||||
call self._removeSigns(old_signs)
|
||||
let s:first_sign_id = s:next_sign_id
|
||||
endfunction
|
||||
|
||||
"Private methods {{{1
|
||||
"
|
||||
"place signs by all syntax errs in the buffer
|
||||
function! g:SyntasticSigner._signErrors(loclist)
|
||||
" Place signs by all syntax errs in the buffer
|
||||
function! g:SyntasticNotifierSigns._signErrors(loclist)
|
||||
let loclist = a:loclist
|
||||
if loclist.hasErrorsOrWarningsToDisplay()
|
||||
|
||||
@ -111,9 +124,9 @@ function! g:SyntasticSigner._signErrors(loclist)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"return true if the given error item is a warning that, if signed, would
|
||||
"potentially mask an error if displayed at the same time
|
||||
function! g:SyntasticSigner._warningMasksError(error, llist)
|
||||
" Return true if the given error item is a warning that, if signed, would
|
||||
" potentially mask an error if displayed at the same time
|
||||
function! g:SyntasticNotifierSigns._warningMasksError(error, llist)
|
||||
if a:error['type'] !=? 'w'
|
||||
return 0
|
||||
endif
|
||||
@ -122,16 +135,16 @@ function! g:SyntasticSigner._warningMasksError(error, llist)
|
||||
return len(loclist.filter({ 'type': "E", 'lnum': a:error['lnum'] })) > 0
|
||||
endfunction
|
||||
|
||||
"remove the signs with the given ids from this buffer
|
||||
function! g:SyntasticSigner._removeSigns(ids)
|
||||
" Remove the signs with the given ids from this buffer
|
||||
function! g:SyntasticNotifierSigns._removeSigns(ids)
|
||||
for i in a:ids
|
||||
exec "sign unplace " . i
|
||||
call remove(self._bufSignIds(), index(self._bufSignIds(), i))
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
"get all the ids of the SyntaxError signs in the buffer
|
||||
function! g:SyntasticSigner._bufSignIds()
|
||||
" Get all the ids of the SyntaxError signs in the buffer
|
||||
function! g:SyntasticNotifierSigns._bufSignIds()
|
||||
if !exists("b:syntastic_sign_ids")
|
||||
let b:syntastic_sign_ids = []
|
||||
endif
|
||||
|
Loading…
Reference in New Issue
Block a user