more refactors to the Notifier classes

Move the autoloc list toggling out into its own notifier class.

Move the function that echos the error on the current line out into its
own notifier.

A few other changes were required in the process:
* move s:WideMsg() out into syntastic#util autoload lib so it is
  available from the cursor notifier.
* move s:ShowLocList() into the LocList class so it is available for
  the autoloclist notifier
* move s:HideLocList() into Loclist as a class method mainly to keep the
  two show/hide methods together
* move the s:old_line var into the Cursor notifier where it is needed
This commit is contained in:
Martin Grenfell 2013-04-07 23:02:31 +01:00
parent 0deeefd08e
commit dc3d80a204
6 changed files with 124 additions and 84 deletions

View File

@ -67,6 +67,30 @@ function syntastic#util#versionIsAtLeast(installed, required)
return 1
endfunction
"print as much of a:msg as possible without "Press Enter" prompt appearing
function! syntastic#util#wideMsg(msg)
let old_ruler = &ruler
let old_showcmd = &showcmd
"convert tabs to spaces so that the tabs count towards the window width
"as the proper amount of characters
let msg = substitute(a:msg, "\t", repeat(" ", &tabstop), "g")
let msg = strpart(msg, 0, winwidth(0)-1)
"This is here because it is possible for some error messages to begin with
"\n which will cause a "press enter" prompt. I have noticed this in the
"javascript:jshint checker and have been unable to figure out why it
"happens
let msg = substitute(msg, "\n", "", "g")
set noruler noshowcmd
redraw
echo msg
let &ruler=old_ruler
let &showcmd=old_showcmd
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -55,8 +55,8 @@ endif
let s:registry = g:SyntasticRegistry.Instance()
let s:notifiers = g:SyntasticNotifiers.New()
let s:cursor_notifier = g:SyntasticNotifierCursor.New()
let s:modemap = g:SyntasticModeMap.Instance()
let s:old_line = -1
function! s:CompleteCheckerName(argLead, cmdLine, cursorPos)
let checker_names = []
@ -77,14 +77,14 @@ highlight link SyntasticWarning SpellCap
augroup syntastic
if g:syntastic_echo_current_error
autocmd CursorMoved * call s:EchoCurrentError()
autocmd CursorMoved * call s:cursor_notifier.refresh(s:LocList())
endif
autocmd BufReadPost * if g:syntastic_check_on_open | call s:UpdateErrors(1) | endif
autocmd BufWritePost * call s:UpdateErrors(1)
autocmd BufWinEnter * if empty(&bt) | call s:AutoToggleLocList() | endif
autocmd BufEnter * if &bt=='quickfix' && !empty(getloclist(0)) && !bufloaded(getloclist(0)[0].bufnr) | call s:HideLocList() | endif
autocmd BufWinEnter * if empty(&bt) | call g:SyntasticNotifierAutoloclist.AutoToggle(s:LocList()) | endif
autocmd BufEnter * if &bt=='quickfix' && !empty(getloclist(0)) && !bufloaded(getloclist(0)[0].bufnr) | call g:SyntasticLoclist.Hide() | endif
augroup END
@ -113,26 +113,6 @@ function! s:UpdateErrors(auto_invoked, ...)
call setloclist(0, loclist.filteredRaw())
silent! ll
endif
call s:AutoToggleLocList()
endfunction
"automatically open/close the location list window depending on the users
"config and buffer error state
function! s:AutoToggleLocList()
let loclist = s:LocList()
if loclist.hasErrorsOrWarningsToDisplay()
if g:syntastic_auto_loc_list == 1
call s:ShowLocList()
endif
else
if g:syntastic_auto_loc_list > 0
"TODO: this will close the loc list window if one was opened by
"something other than syntastic
lclose
endif
endif
endfunction
"lazy init the loc list for the current buffer
@ -146,7 +126,7 @@ endfunction
"clear the loc list for the buffer
function! s:ClearCache()
unlet! b:syntastic_loclist
let s:old_line = -1
call s:cursor_notifier.resetOldLine()
endfunction
function! s:CurrentFiletypes()
@ -199,64 +179,7 @@ endfunction
"display the cached errors for this buf in the location list
function! s:ShowLocList()
let loclist = s:LocList()
if loclist.hasErrorsOrWarningsToDisplay()
call setloclist(0, loclist.filteredRaw())
let num = winnr()
exec "lopen " . g:syntastic_loc_list_height
if num != winnr()
wincmd p
endif
endif
endfunction
function! s:HideLocList()
if len(filter( range(1,bufnr('$')), 'buflisted(v:val) && bufloaded(v:val)' )) == 1
quit
else
lclose
endif
endfunction
"print as much of a:msg as possible without "Press Enter" prompt appearing
function! s:WideMsg(msg)
let old_ruler = &ruler
let old_showcmd = &showcmd
"convert tabs to spaces so that the tabs count towards the window width
"as the proper amount of characters
let msg = substitute(a:msg, "\t", repeat(" ", &tabstop), "g")
let msg = strpart(msg, 0, winwidth(0)-1)
"This is here because it is possible for some error messages to begin with
"\n which will cause a "press enter" prompt. I have noticed this in the
"javascript:jshint checker and have been unable to figure out why it
"happens
let msg = substitute(msg, "\n", "", "g")
set noruler noshowcmd
redraw
echo msg
let &ruler=old_ruler
let &showcmd=old_showcmd
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()
let messages = loclist.messages()
if has_key(messages, l)
return s:WideMsg(messages[l])
else
echo
endif
call loclist.show()
endfunction
"the script changes &shellpipe and &shell to stop the screen flicking when

View File

@ -0,0 +1,40 @@
if exists("g:loaded_syntastic_notifier_autoloclist")
finish
endif
let g:loaded_syntastic_notifier_autoloclist=1
"TODO: this var is a hack required for the Notifiers class. This is complicated
"because this notification type doesnt use the same option naming convention
"that Notifiers assumes
"
"i.e. it uses g:syntastic_auto_loc_list which has 3 possible values rather
"than just on or off
let g:syntastic_enable_autoloclist=1
let g:SyntasticNotifierAutoloclist = {}
" Public methods {{{1
"
function! g:SyntasticNotifierAutoloclist.New()
let newObj = copy(self)
return newObj
endfunction
function! g:SyntasticNotifierAutoloclist.refresh(loclist)
call g:SyntasticNotifierAutoloclist.AutoToggle(a:loclist)
endfunction
function! g:SyntasticNotifierAutoloclist.AutoToggle(loclist)
if a:loclist.hasErrorsOrWarningsToDisplay()
if g:syntastic_auto_loc_list == 1
call a:loclist.show()
endif
else
if g:syntastic_auto_loc_list > 0
"TODO: this will close the loc list window if one was opened by
"something other than syntastic
lclose
endif
endif
endfunction

View File

@ -0,0 +1,33 @@
if exists("g:loaded_syntastic_notifier_cursor")
finish
endif
let g:loaded_syntastic_notifier_cursor=1
let g:SyntasticNotifierCursor = {}
" Public methods {{{1
function! g:SyntasticNotifierCursor.New()
let newObj = copy(self)
let newObj.oldLine = -1
return newObj
endfunction
function! g:SyntasticNotifierCursor.refresh(loclist)
let l = line('.')
if l == self.oldLine
return
endif
let self.oldLine = l
let messages = a:loclist.messages()
if has_key(messages, l)
return syntastic#util#wideMsg(messages[l])
else
echo
endif
endfunction
function! g:SyntasticNotifierCursor.resetOldLine()
let self.oldLine = -1
endfunction

View File

@ -120,4 +120,24 @@ function! g:SyntasticLoclist.filter(filters)
return rv
endfunction
"display the cached errors for this buf in the location list
function! g:SyntasticLoclist.show()
if self.hasErrorsOrWarningsToDisplay()
call setloclist(0, self.filteredRaw())
let num = winnr()
exec "lopen " . g:syntastic_loc_list_height
if num != winnr()
wincmd p
endif
endif
endfunction
function! g:SyntasticLoclist.Hide()
if len(filter( range(1,bufnr('$')), 'buflisted(v:val) && bufloaded(v:val)' )) == 1
quit
else
lclose
endif
endfunction
" vim: set sw=4 sts=4 et fdm=marker:

View File

@ -5,7 +5,7 @@ let g:loaded_syntastic_notifiers=1
let g:SyntasticNotifiers = {}
let s:notifier_types = ['signs', 'balloons', 'highlighting']
let s:notifier_types = ['signs', 'balloons', 'highlighting', 'autoloclist']
" Public methods {{{1