diff --git a/plugin/syntastic.vim b/plugin/syntastic.vim index c3ad2c88..32117c39 100644 --- a/plugin/syntastic.vim +++ b/plugin/syntastic.vim @@ -19,7 +19,7 @@ if has('reltime') lockvar! g:syntastic_start endif -let g:syntastic_version = '3.4.0-75' +let g:syntastic_version = '3.4.0-76' lockvar g:syntastic_version " Sanity checks {{{1 @@ -142,7 +142,7 @@ let s:modemap = g:SyntasticModeMap.Instance() function! s:CompleteCheckerName(argLead, cmdLine, cursorPos) " {{{2 let checker_names = [] for ft in s:resolveFiletypes() - call extend(checker_names, keys(s:registry.getCheckersMap(ft))) + call extend(checker_names, s:registry.getNamesOfAvailableCheckers(ft)) endfor return join(checker_names, "\n") endfunction " }}}2 @@ -319,8 +319,15 @@ function! s:CacheErrors(checker_names) " {{{2 endfor let names = [] + let unavailable_checkers = 0 for checker in clist let cname = checker.getFiletype() . '/' . checker.getName() + if !checker.isAvailable() + call syntastic#log#debug(g:SyntasticDebugTrace, 'CacheErrors: Checker ' . cname . ' is not available') + let unavailable_checkers += 1 + continue + endif + call syntastic#log#debug(g:SyntasticDebugTrace, 'CacheErrors: Invoking checker: ' . cname) let loclist = checker.getLocList() @@ -357,7 +364,7 @@ function! s:CacheErrors(checker_names) " {{{2 " }}}3 " issue warning about no active checkers {{{3 - if empty(clist) + if len(clist) == unavailable_checkers if !empty(a:checker_names) if len(a:checker_names) == 1 call syntastic#log#warn('checker ' . a:checker_names[0] . ' is not available') diff --git a/plugin/syntastic/checker.vim b/plugin/syntastic/checker.vim index 33da5663..c3655f7f 100644 --- a/plugin/syntastic/checker.vim +++ b/plugin/syntastic/checker.vim @@ -98,7 +98,10 @@ function! g:SyntasticChecker.makeprgBuild(opts) " {{{2 endfunction " }}}2 function! g:SyntasticChecker.isAvailable() " {{{2 - return self._isAvailableFunc() + if !has_key(self, '_available') + let self._available = self._isAvailableFunc() + endif + return self._available endfunction " }}}2 " }}}1 diff --git a/plugin/syntastic/registry.vim b/plugin/syntastic/registry.vim index 57f671cc..fd16429e 100644 --- a/plugin/syntastic/registry.vim +++ b/plugin/syntastic/registry.vim @@ -106,14 +106,13 @@ let g:SyntasticRegistry = {} " Public methods {{{1 -" TODO: Handling of filetype aliases: all public methods take aliases as +" Note: Handling of filetype aliases: all public methods take aliases as " parameters, all private methods take normalized filetypes. Public methods " are thus supposed to normalize filetypes before calling private methods. function! g:SyntasticRegistry.Instance() " {{{2 if !exists('s:SyntasticRegistryInstance') let s:SyntasticRegistryInstance = copy(self) - let s:SyntasticRegistryInstance._checkerRaw = {} let s:SyntasticRegistryInstance._checkerMap = {} endif @@ -126,29 +125,23 @@ function! g:SyntasticRegistry.CreateAndRegisterChecker(args) " {{{2 call registry._registerChecker(checker) endfunction " }}}2 -function! g:SyntasticRegistry.isCheckable(ftalias) " {{{2 +" Given a list of checker names hints_list, return a map name --> checker. +" If hints_list is empty, user settings are are used instead. Checkers are +" not checked for availability (that is, the corresponding IsAvailable() are +" not run). +function! g:SyntasticRegistry.getCheckers(ftalias, hints_list) " {{{2 let ft = s:normaliseFiletype(a:ftalias) - call self._loadCheckers(ft) - return !empty(self._checkerMap[ft]) -endfunction " }}}2 + call self._loadCheckersFor(ft) -function! g:SyntasticRegistry.getCheckersMap(ftalias) " {{{2 - let ft = s:normaliseFiletype(a:ftalias) - call self._loadCheckers(ft) - return self._checkerMap[ft] -endfunction " }}}2 - -function! g:SyntasticRegistry.getCheckers(ftalias, list) " {{{2 - let checkers_map = self.getCheckersMap(a:ftalias) + let checkers_map = self._checkerMap[ft] if empty(checkers_map) return [] endif - let ft = s:normaliseFiletype(a:ftalias) call self._checkDeprecation(ft) let names = - \ !empty(a:list) ? a:list : + \ !empty(a:hints_list) ? syntastic#util#unique(a:hints_list) : \ exists('b:syntastic_checkers') ? b:syntastic_checkers : \ exists('g:syntastic_' . ft . '_checkers') ? g:syntastic_{ft}_checkers : \ get(s:defaultCheckers, ft, 0) @@ -157,6 +150,12 @@ function! g:SyntasticRegistry.getCheckers(ftalias, list) " {{{2 \ self._filterCheckersByName(checkers_map, names) : [checkers_map[keys(checkers_map)[0]]] endfunction " }}}2 +" Same as getCheckers(), but keep only the checkers available. This runs the +" corresponding IsAvailable() functions for all checkers. +function! g:SyntasticRegistry.getCheckersAvailable(ftalias, hints_list) " {{{2 + return filter(self.getCheckers(a:ftalias, a:hints_list), 'v:val.isAvailable()') +endfunction " }}}2 + function! g:SyntasticRegistry.getKnownFiletypes() " {{{2 let types = keys(s:defaultCheckers) @@ -173,6 +172,12 @@ function! g:SyntasticRegistry.getKnownFiletypes() " {{{2 return syntastic#util#unique(types) endfunction " }}}2 +function! g:SyntasticRegistry.getNamesOfAvailableCheckers(ftalias) " {{{2 + let ft = s:normaliseFiletype(a:ftalias) + call self._loadCheckersFor(ft) + return keys(filter( copy(self._checkerMap[ft]), 'v:val.isAvailable()' )) +endfunction " }}}2 + function! g:SyntasticRegistry.echoInfoFor(ftalias_list) " {{{2 echomsg "Syntastic version: " . g:syntastic_version echomsg "Info for filetype: " . join(a:ftalias_list, '.') @@ -183,13 +188,13 @@ function! g:SyntasticRegistry.echoInfoFor(ftalias_list) " {{{2 let active = [] for ft in ft_list - call extend(available, map( keys(self.getCheckersMap(ft)), 'ft . "/" . v:val' )) - call extend(active, map( self.getCheckers(ft, []), 'ft . "/" . v:val.getName()' )) + call extend(available, map( self.getNamesOfAvailableCheckers(ft), 'ft . "/" . v:val' )) + call extend(active, map( self.getCheckersAvailable(ft, []), 'ft . "/" . v:val.getName()' )) endfor else let ft = ft_list[0] - let available = keys(self.getCheckersMap(ft)) - let active = map(self.getCheckers(ft, []), 'v:val.getName()') + let available = self.getNamesOfAvailableCheckers(ft) + let active = map(self.getCheckersAvailable(ft, []), 'v:val.getName()') endif echomsg "Available checker(s): " . join(sort(available)) @@ -202,47 +207,34 @@ endfunction " }}}2 function! g:SyntasticRegistry._registerChecker(checker) abort " {{{2 let ft = a:checker.getFiletype() - - if !has_key(self._checkerRaw, ft) - let self._checkerRaw[ft] = [] + if !has_key(self._checkerMap, ft) let self._checkerMap[ft] = {} endif - call self._validateUniqueName(a:checker) - let name = a:checker.getName() - call add(self._checkerRaw[ft], name) - - if a:checker.isAvailable() - let self._checkerMap[ft][name] = a:checker + if has_key(self._checkerMap[ft], name) + throw 'Syntastic: Duplicate syntax checker name: ' . ft . '/' . name endif + + let self._checkerMap[ft][name] = a:checker endfunction " }}}2 function! g:SyntasticRegistry._filterCheckersByName(checkers_map, list) " {{{2 return filter( map(copy(a:list), 'get(a:checkers_map, v:val, {})'), '!empty(v:val)' ) endfunction " }}}2 -function! g:SyntasticRegistry._loadCheckers(filetype) " {{{2 - if has_key(self._checkerRaw, a:filetype) +function! g:SyntasticRegistry._loadCheckersFor(filetype) " {{{2 + if has_key(self._checkerMap, a:filetype) return endif execute "runtime! syntax_checkers/" . a:filetype . "/*.vim" - if !has_key(self._checkerRaw, a:filetype) - let self._checkerRaw[a:filetype] = [] + if !has_key(self._checkerMap, a:filetype) let self._checkerMap[a:filetype] = {} endif endfunction " }}}2 -function! g:SyntasticRegistry._validateUniqueName(checker) abort " {{{2 - let ft = a:checker.getFiletype() - let name = a:checker.getName() - if index(self._checkerRaw[ft], name) > -1 - throw 'Syntastic: Duplicate syntax checker name: ' . ft . '/' . name - endif -endfunction " }}}2 - " Check for obsolete variable g:syntastic__checker function! g:SyntasticRegistry._checkDeprecation(filetype) " {{{2 if exists('g:syntastic_' . a:filetype . '_checker') && !exists('g:syntastic_' . a:filetype . '_checkers') diff --git a/syntax_checkers/sh/sh.vim b/syntax_checkers/sh/sh.vim index 0cae2429..5c3a4f84 100644 --- a/syntax_checkers/sh/sh.vim +++ b/syntax_checkers/sh/sh.vim @@ -41,8 +41,9 @@ endfunction function! s:ForwardToZshChecker() let registry = g:SyntasticRegistry.Instance() - if registry.isCheckable('zsh') - return registry.getCheckers('zsh', ['zsh'])[0].getLocListRaw() + let zsh_checkers = registry.getCheckersAvailable('zsh', ['zsh']) + if !empty(zsh_checkers) + return zsh_checkers[0].getLocListRaw() else return [] endif