]>
Commit | Line | Data |
---|---|---|
1 | "============================================================================ | |
2 | "File: syntastic.vim | |
3 | "Description: vim plugin for on the fly syntax checking | |
4 | "Maintainer: Martin Grenfell <martin.grenfell at gmail dot com> | |
5 | "Version: 2.3.0 | |
6 | "Last Change: 16 Feb, 2012 | |
7 | "License: This program is free software. It comes without any warranty, | |
8 | " to the extent permitted by applicable law. You can redistribute | |
9 | " it and/or modify it under the terms of the Do What The Fuck You | |
10 | " Want To Public License, Version 2, as published by Sam Hocevar. | |
11 | " See http://sam.zoy.org/wtfpl/COPYING for more details. | |
12 | " | |
13 | "============================================================================ | |
14 | ||
15 | if exists("g:loaded_syntastic_plugin") | |
16 | finish | |
17 | endif | |
18 | let g:loaded_syntastic_plugin = 1 | |
19 | ||
20 | let s:running_windows = has("win16") || has("win32") || has("win64") | |
21 | ||
22 | if !s:running_windows | |
23 | let s:uname = system('uname') | |
24 | endif | |
25 | ||
26 | if !exists("g:syntastic_enable_signs") | |
27 | let g:syntastic_enable_signs = 1 | |
28 | endif | |
29 | if !has('signs') | |
30 | let g:syntastic_enable_signs = 0 | |
31 | endif | |
32 | ||
33 | if !exists("g:syntastic_enable_balloons") | |
34 | let g:syntastic_enable_balloons = 1 | |
35 | endif | |
36 | if !has('balloon_eval') | |
37 | let g:syntastic_enable_balloons = 0 | |
38 | endif | |
39 | ||
40 | if !exists("g:syntastic_enable_highlighting") | |
41 | let g:syntastic_enable_highlighting = 1 | |
42 | endif | |
43 | ||
44 | if !exists("g:syntastic_echo_current_error") | |
45 | let g:syntastic_echo_current_error = 1 | |
46 | endif | |
47 | ||
48 | if !exists("g:syntastic_auto_loc_list") | |
49 | let g:syntastic_auto_loc_list = 2 | |
50 | endif | |
51 | ||
52 | if !exists("g:syntastic_auto_jump") | |
53 | let syntastic_auto_jump=0 | |
54 | endif | |
55 | ||
56 | if !exists("g:syntastic_quiet_warnings") | |
57 | let g:syntastic_quiet_warnings = 0 | |
58 | endif | |
59 | ||
60 | if !exists("g:syntastic_stl_format") | |
61 | let g:syntastic_stl_format = '[Syntax: line:%F (%t)]' | |
62 | endif | |
63 | ||
64 | if !exists("g:syntastic_mode_map") | |
65 | let g:syntastic_mode_map = {} | |
66 | endif | |
67 | ||
68 | if !has_key(g:syntastic_mode_map, "mode") | |
69 | let g:syntastic_mode_map['mode'] = 'active' | |
70 | endif | |
71 | ||
72 | if !has_key(g:syntastic_mode_map, "active_filetypes") | |
73 | let g:syntastic_mode_map['active_filetypes'] = [] | |
74 | endif | |
75 | ||
76 | if !has_key(g:syntastic_mode_map, "passive_filetypes") | |
77 | let g:syntastic_mode_map['passive_filetypes'] = [] | |
78 | endif | |
79 | ||
80 | if !exists("g:syntastic_check_on_open") | |
81 | let g:syntastic_check_on_open = 0 | |
82 | endif | |
83 | ||
84 | if !exists("g:syntastic_loc_list_height") | |
85 | let g:syntastic_loc_list_height = 10 | |
86 | endif | |
87 | ||
88 | command! SyntasticToggleMode call s:ToggleMode() | |
89 | command! SyntasticCheck call s:UpdateErrors(0) <bar> redraw! | |
90 | command! Errors call s:ShowLocList() | |
91 | ||
92 | highlight link SyntasticError SpellBad | |
93 | highlight link SyntasticWarning SpellCap | |
94 | ||
95 | augroup syntastic | |
96 | if g:syntastic_echo_current_error | |
97 | autocmd cursormoved * call s:EchoCurrentError() | |
98 | endif | |
99 | ||
100 | autocmd BufReadPost * if g:syntastic_check_on_open | call s:UpdateErrors(1) | endif | |
101 | autocmd BufWritePost * call s:UpdateErrors(1) | |
102 | ||
103 | autocmd BufWinEnter * if empty(&bt) | call s:AutoToggleLocList() | endif | |
104 | autocmd BufWinLeave * if empty(&bt) | lclose | endif | |
105 | augroup END | |
106 | ||
107 | ||
108 | "refresh and redraw all the error info for this buf when saving or reading | |
109 | function! s:UpdateErrors(auto_invoked) | |
110 | if !empty(&buftype) | |
111 | return | |
112 | endif | |
113 | ||
114 | if !a:auto_invoked || s:ModeMapAllowsAutoChecking() | |
115 | call s:CacheErrors() | |
116 | end | |
117 | ||
118 | if s:BufHasErrorsOrWarningsToDisplay() | |
119 | call setloclist(0, s:LocList()) | |
120 | endif | |
121 | ||
122 | if g:syntastic_enable_balloons | |
123 | call s:RefreshBalloons() | |
124 | endif | |
125 | ||
126 | if g:syntastic_enable_signs | |
127 | call s:RefreshSigns() | |
128 | endif | |
129 | ||
130 | if g:syntastic_auto_jump && s:BufHasErrorsOrWarningsToDisplay() | |
131 | silent! ll | |
132 | endif | |
133 | ||
134 | call s:AutoToggleLocList() | |
135 | endfunction | |
136 | ||
137 | "automatically open/close the location list window depending on the users | |
138 | "config and buffer error state | |
139 | function! s:AutoToggleLocList() | |
140 | if s:BufHasErrorsOrWarningsToDisplay() | |
141 | if g:syntastic_auto_loc_list == 1 | |
142 | call s:ShowLocList() | |
143 | endif | |
144 | else | |
145 | if g:syntastic_auto_loc_list > 0 | |
146 | ||
147 | "TODO: this will close the loc list window if one was opened by | |
148 | "something other than syntastic | |
149 | lclose | |
150 | endif | |
151 | endif | |
152 | endfunction | |
153 | ||
154 | "lazy init the loc list for the current buffer | |
155 | function! s:LocList() | |
156 | if !exists("b:syntastic_loclist") | |
157 | let b:syntastic_loclist = [] | |
158 | endif | |
159 | return b:syntastic_loclist | |
160 | endfunction | |
161 | ||
162 | "clear the loc list for the buffer | |
163 | function! s:ClearLocList() | |
164 | let b:syntastic_loclist = [] | |
165 | endfunction | |
166 | ||
167 | "detect and cache all syntax errors in this buffer | |
168 | " | |
169 | "depends on a function called SyntaxCheckers_{&ft}_GetLocList() existing | |
170 | "elsewhere | |
171 | function! s:CacheErrors() | |
172 | call s:ClearLocList() | |
173 | ||
174 | if filereadable(expand("%")) | |
175 | ||
176 | "sub - for _ in filetypes otherwise we cant name syntax checker | |
177 | "functions legally for filetypes like "gentoo-metadata" | |
178 | let fts = substitute(&ft, '-', '_', 'g') | |
179 | for ft in split(fts, '\.') | |
180 | if s:Checkable(ft) | |
181 | let errors = SyntaxCheckers_{ft}_GetLocList() | |
182 | "make errors have type "E" by default | |
183 | call SyntasticAddToErrors(errors, {'type': 'E'}) | |
184 | call extend(s:LocList(), errors) | |
185 | endif | |
186 | endfor | |
187 | endif | |
188 | endfunction | |
189 | ||
190 | "toggle the g:syntastic_mode_map['mode'] | |
191 | function! s:ToggleMode() | |
192 | if g:syntastic_mode_map['mode'] == "active" | |
193 | let g:syntastic_mode_map['mode'] = "passive" | |
194 | else | |
195 | let g:syntastic_mode_map['mode'] = "active" | |
196 | endif | |
197 | ||
198 | call s:ClearLocList() | |
199 | call s:UpdateErrors(1) | |
200 | ||
201 | echo "Syntastic: " . g:syntastic_mode_map['mode'] . " mode enabled" | |
202 | endfunction | |
203 | ||
204 | "check the current filetypes against g:syntastic_mode_map to determine whether | |
205 | "active mode syntax checking should be done | |
206 | function! s:ModeMapAllowsAutoChecking() | |
207 | let fts = split(&ft, '\.') | |
208 | ||
209 | if g:syntastic_mode_map['mode'] == 'passive' | |
210 | "check at least one filetype is active | |
211 | let actives = g:syntastic_mode_map["active_filetypes"] | |
212 | return !empty(filter(fts, 'index(actives, v:val) != -1')) | |
213 | else | |
214 | "check no filetypes are passive | |
215 | let passives = g:syntastic_mode_map["passive_filetypes"] | |
216 | return empty(filter(fts, 'index(passives, v:val) != -1')) | |
217 | endif | |
218 | endfunction | |
219 | ||
220 | "return true if there are cached errors/warnings for this buf | |
221 | function! s:BufHasErrorsOrWarnings() | |
222 | return !empty(s:LocList()) | |
223 | endfunction | |
224 | ||
225 | "return true if there are cached errors for this buf | |
226 | function! s:BufHasErrors() | |
227 | return len(s:ErrorsForType('E')) > 0 | |
228 | endfunction | |
229 | ||
230 | function! s:BufHasErrorsOrWarningsToDisplay() | |
231 | return s:BufHasErrors() || (!g:syntastic_quiet_warnings && s:BufHasErrorsOrWarnings()) | |
232 | endfunction | |
233 | ||
234 | function! s:ErrorsForType(type) | |
235 | return s:FilterLocList({'type': a:type}) | |
236 | endfunction | |
237 | ||
238 | function! s:Errors() | |
239 | return s:ErrorsForType("E") | |
240 | endfunction | |
241 | ||
242 | function! s:Warnings() | |
243 | return s:ErrorsForType("W") | |
244 | endfunction | |
245 | ||
246 | "Filter a loc list (defaults to s:LocList()) by a:filters | |
247 | "e.g. | |
248 | " s:FilterLocList({'bufnr': 10, 'type': 'e'}) | |
249 | " | |
250 | "would return all errors in s:LocList() for buffer 10. | |
251 | " | |
252 | "Note that all comparisons are done with ==? | |
253 | function! s:FilterLocList(filters, ...) | |
254 | let llist = a:0 ? a:1 : s:LocList() | |
255 | ||
256 | let rv = deepcopy(llist) | |
257 | for error in llist | |
258 | for key in keys(a:filters) | |
259 | let rhs = a:filters[key] | |
260 | if type(rhs) == 1 "string | |
261 | let rhs = '"' . rhs . '"' | |
262 | endif | |
263 | ||
264 | call filter(rv, "v:val['".key."'] ==? " . rhs) | |
265 | endfor | |
266 | endfor | |
267 | return rv | |
268 | endfunction | |
269 | ||
270 | if g:syntastic_enable_signs | |
271 | "define the signs used to display syntax and style errors/warns | |
272 | sign define SyntasticError text=>> texthl=error | |
273 | sign define SyntasticWarning text=>> texthl=todo | |
274 | sign define SyntasticStyleError text=S> texthl=error | |
275 | sign define SyntasticStyleWarning text=S> texthl=todo | |
276 | endif | |
277 | ||
278 | "start counting sign ids at 5000, start here to hopefully avoid conflicting | |
279 | "with any other code that places signs (not sure if this precaution is | |
280 | "actually needed) | |
281 | let s:first_sign_id = 5000 | |
282 | let s:next_sign_id = s:first_sign_id | |
283 | ||
284 | "place signs by all syntax errs in the buffer | |
285 | function! s:SignErrors() | |
286 | if s:BufHasErrorsOrWarningsToDisplay() | |
287 | ||
288 | let errors = s:FilterLocList({'bufnr': bufnr('')}) | |
289 | for i in errors | |
290 | let sign_severity = 'Error' | |
291 | let sign_subtype = '' | |
292 | if has_key(i,'subtype') | |
293 | let sign_subtype = i['subtype'] | |
294 | endif | |
295 | if i['type'] ==? 'w' | |
296 | let sign_severity = 'Warning' | |
297 | endif | |
298 | let sign_type = 'Syntastic' . sign_subtype . sign_severity | |
299 | ||
300 | if !s:WarningMasksError(i, errors) | |
301 | exec "sign place ". s:next_sign_id ." line=". i['lnum'] ." name=". sign_type ." file=". expand("%:p") | |
302 | call add(s:BufSignIds(), s:next_sign_id) | |
303 | let s:next_sign_id += 1 | |
304 | endif | |
305 | endfor | |
306 | endif | |
307 | endfunction | |
308 | ||
309 | "return true if the given error item is a warning that, if signed, would | |
310 | "potentially mask an error if displayed at the same time | |
311 | function! s:WarningMasksError(error, llist) | |
312 | if a:error['type'] !=? 'w' | |
313 | return 0 | |
314 | endif | |
315 | ||
316 | return len(s:FilterLocList({ 'type': "E", 'lnum': a:error['lnum'] }, a:llist)) > 0 | |
317 | endfunction | |
318 | ||
319 | "remove the signs with the given ids from this buffer | |
320 | function! s:RemoveSigns(ids) | |
321 | for i in a:ids | |
322 | exec "sign unplace " . i | |
323 | call remove(s:BufSignIds(), index(s:BufSignIds(), i)) | |
324 | endfor | |
325 | endfunction | |
326 | ||
327 | "get all the ids of the SyntaxError signs in the buffer | |
328 | function! s:BufSignIds() | |
329 | if !exists("b:syntastic_sign_ids") | |
330 | let b:syntastic_sign_ids = [] | |
331 | endif | |
332 | return b:syntastic_sign_ids | |
333 | endfunction | |
334 | ||
335 | "update the error signs | |
336 | function! s:RefreshSigns() | |
337 | let old_signs = copy(s:BufSignIds()) | |
338 | call s:SignErrors() | |
339 | call s:RemoveSigns(old_signs) | |
340 | let s:first_sign_id = s:next_sign_id | |
341 | endfunction | |
342 | ||
343 | "display the cached errors for this buf in the location list | |
344 | function! s:ShowLocList() | |
345 | if !empty(s:LocList()) | |
346 | let num = winnr() | |
347 | exec "lopen " . g:syntastic_loc_list_height | |
348 | if num != winnr() | |
349 | wincmd p | |
350 | endif | |
351 | endif | |
352 | endfunction | |
353 | ||
354 | "remove all error highlights from the window | |
355 | function! s:ClearErrorHighlights() | |
356 | for match in getmatches() | |
357 | if stridx(match['group'], 'Syntastic') == 0 | |
358 | call matchdelete(match['id']) | |
359 | endif | |
360 | endfor | |
361 | endfunction | |
362 | ||
363 | "check if a syntax checker exists for the given filetype - and attempt to | |
364 | "load one | |
365 | function! s:Checkable(ft) | |
366 | if !exists("g:loaded_" . a:ft . "_syntax_checker") | |
367 | exec "runtime syntax_checkers/" . a:ft . ".vim" | |
368 | endif | |
369 | ||
370 | return exists("*SyntaxCheckers_". a:ft ."_GetLocList") | |
371 | endfunction | |
372 | ||
373 | "set up error ballons for the current set of errors | |
374 | function! s:RefreshBalloons() | |
375 | let b:syntastic_balloons = {} | |
376 | if s:BufHasErrorsOrWarningsToDisplay() | |
377 | for i in s:LocList() | |
378 | let b:syntastic_balloons[i['lnum']] = i['text'] | |
379 | endfor | |
380 | set beval bexpr=SyntasticErrorBalloonExpr() | |
381 | endif | |
382 | endfunction | |
383 | ||
384 | "print as much of a:msg as possible without "Press Enter" prompt appearing | |
385 | function! s:WideMsg(msg) | |
386 | let old_ruler = &ruler | |
387 | let old_showcmd = &showcmd | |
388 | ||
389 | let msg = strpart(a:msg, 0, winwidth(0)-1) | |
390 | ||
391 | "This is here because it is possible for some error messages to begin with | |
392 | "\n which will cause a "press enter" prompt. I have noticed this in the | |
393 | "javascript:jshint checker and have been unable to figure out why it | |
394 | "happens | |
395 | let msg = substitute(msg, "\n", "", "g") | |
396 | ||
397 | set noruler noshowcmd | |
398 | redraw | |
399 | ||
400 | echo msg | |
401 | ||
402 | let &ruler=old_ruler | |
403 | let &showcmd=old_showcmd | |
404 | endfunction | |
405 | ||
406 | "echo out the first error we find for the current line in the cmd window | |
407 | function! s:EchoCurrentError() | |
408 | "If we have an error or warning at the current line, show it | |
409 | let errors = s:FilterLocList({'lnum': line("."), "type": 'e'}) | |
410 | let warnings = s:FilterLocList({'lnum': line("."), "type": 'w'}) | |
411 | ||
412 | let b:syntastic_echoing_error = len(errors) || len(warnings) | |
413 | if len(errors) | |
414 | return s:WideMsg(errors[0]['text']) | |
415 | endif | |
416 | if len(warnings) | |
417 | return s:WideMsg(warnings[0]['text']) | |
418 | endif | |
419 | ||
420 | "Otherwise, clear the status line | |
421 | if b:syntastic_echoing_error | |
422 | echo | |
423 | let b:syntastic_echoing_error = 0 | |
424 | endif | |
425 | endfunction | |
426 | ||
427 | "load the chosen checker for the current filetype - useful for filetypes like | |
428 | "javascript that have more than one syntax checker | |
429 | function! s:LoadChecker(checker) | |
430 | exec "runtime syntax_checkers/" . &ft . "/" . a:checker . ".vim" | |
431 | endfunction | |
432 | ||
433 | "return a string representing the state of buffer according to | |
434 | "g:syntastic_stl_format | |
435 | " | |
436 | "return '' if no errors are cached for the buffer | |
437 | function! SyntasticStatuslineFlag() | |
438 | if s:BufHasErrorsOrWarningsToDisplay() | |
439 | let errors = s:Errors() | |
440 | let warnings = s:Warnings() | |
441 | ||
442 | let output = g:syntastic_stl_format | |
443 | ||
444 | "hide stuff wrapped in %E(...) unless there are errors | |
445 | let output = substitute(output, '\C%E{\([^}]*\)}', len(errors) ? '\1' : '' , 'g') | |
446 | ||
447 | "hide stuff wrapped in %W(...) unless there are warnings | |
448 | let output = substitute(output, '\C%W{\([^}]*\)}', len(warnings) ? '\1' : '' , 'g') | |
449 | ||
450 | "hide stuff wrapped in %B(...) unless there are both errors and warnings | |
451 | let output = substitute(output, '\C%B{\([^}]*\)}', (len(warnings) && len(errors)) ? '\1' : '' , 'g') | |
452 | ||
453 | "sub in the total errors/warnings/both | |
454 | let output = substitute(output, '\C%w', len(warnings), 'g') | |
455 | let output = substitute(output, '\C%e', len(errors), 'g') | |
456 | let output = substitute(output, '\C%t', len(s:LocList()), 'g') | |
457 | ||
458 | "first error/warning line num | |
459 | let output = substitute(output, '\C%F', s:LocList()[0]['lnum'], 'g') | |
460 | ||
461 | "first error line num | |
462 | let output = substitute(output, '\C%fe', len(errors) ? errors[0]['lnum'] : '', 'g') | |
463 | ||
464 | "first warning line num | |
465 | let output = substitute(output, '\C%fw', len(warnings) ? warnings[0]['lnum'] : '', 'g') | |
466 | ||
467 | return output | |
468 | else | |
469 | return '' | |
470 | endif | |
471 | endfunction | |
472 | ||
473 | "A wrapper for the :lmake command. Sets up the make environment according to | |
474 | "the options given, runs make, resets the environment, returns the location | |
475 | "list | |
476 | " | |
477 | "a:options can contain the following keys: | |
478 | " 'makeprg' | |
479 | " 'errorformat' | |
480 | " | |
481 | "The corresponding options are set for the duration of the function call. They | |
482 | "are set with :let, so dont escape spaces. | |
483 | " | |
484 | "a:options may also contain: | |
485 | " 'defaults' - a dict containing default values for the returned errors | |
486 | " 'subtype' - all errors will be assigned the given subtype | |
487 | function! SyntasticMake(options) | |
488 | let old_loclist = getloclist(0) | |
489 | let old_makeprg = &makeprg | |
490 | let old_shellpipe = &shellpipe | |
491 | let old_shell = &shell | |
492 | let old_errorformat = &errorformat | |
493 | ||
494 | if !s:running_windows && (s:uname !~ "FreeBSD") | |
495 | "this is a hack to stop the screen needing to be ':redraw'n when | |
496 | "when :lmake is run. Otherwise the screen flickers annoyingly | |
497 | let &shellpipe='&>' | |
498 | let &shell = '/bin/bash' | |
499 | endif | |
500 | ||
501 | if has_key(a:options, 'makeprg') | |
502 | let &makeprg = a:options['makeprg'] | |
503 | endif | |
504 | ||
505 | if has_key(a:options, 'errorformat') | |
506 | let &errorformat = a:options['errorformat'] | |
507 | endif | |
508 | ||
509 | silent lmake! | |
510 | let errors = getloclist(0) | |
511 | ||
512 | call setloclist(0, old_loclist) | |
513 | let &makeprg = old_makeprg | |
514 | let &errorformat = old_errorformat | |
515 | let &shellpipe=old_shellpipe | |
516 | let &shell=old_shell | |
517 | ||
518 | if !s:running_windows && s:uname =~ "FreeBSD" | |
519 | redraw! | |
520 | endif | |
521 | ||
522 | if has_key(a:options, 'defaults') | |
523 | call SyntasticAddToErrors(errors, a:options['defaults']) | |
524 | endif | |
525 | ||
526 | " Add subtype info if present. | |
527 | if has_key(a:options, 'subtype') | |
528 | call SyntasticAddToErrors(errors, {'subtype': a:options['subtype']}) | |
529 | endif | |
530 | ||
531 | return errors | |
532 | endfunction | |
533 | ||
534 | "get the error balloon for the current mouse position | |
535 | function! SyntasticErrorBalloonExpr() | |
536 | if !exists('b:syntastic_balloons') | |
537 | return '' | |
538 | endif | |
539 | return get(b:syntastic_balloons, v:beval_lnum, '') | |
540 | endfunction | |
541 | ||
542 | "highlight the list of errors (a:errors) using matchadd() | |
543 | " | |
544 | "a:termfunc is provided to highlight errors that do not have a 'col' key (and | |
545 | "hence cant be done automatically). This function must take one arg (an error | |
546 | "item) and return a regex to match that item in the buffer. | |
547 | " | |
548 | "an optional boolean third argument can be provided to force a:termfunc to be | |
549 | "used regardless of whether a 'col' key is present for the error | |
550 | function! SyntasticHighlightErrors(errors, termfunc, ...) | |
551 | if !g:syntastic_enable_highlighting | |
552 | return | |
553 | endif | |
554 | ||
555 | call s:ClearErrorHighlights() | |
556 | ||
557 | let force_callback = a:0 && a:1 | |
558 | for item in a:errors | |
559 | let group = item['type'] == 'E' ? 'SyntasticError' : 'SyntasticWarning' | |
560 | if item['col'] && !force_callback | |
561 | let lastcol = col([item['lnum'], '$']) | |
562 | let lcol = min([lastcol, item['col']]) | |
563 | call matchadd(group, '\%'.item['lnum'].'l\%'.lcol.'c') | |
564 | else | |
565 | let term = a:termfunc(item) | |
566 | if len(term) > 0 | |
567 | call matchadd(group, '\%' . item['lnum'] . 'l' . term) | |
568 | endif | |
569 | endif | |
570 | endfor | |
571 | endfunction | |
572 | ||
573 | "take a list of errors and add default values to them from a:options | |
574 | function! SyntasticAddToErrors(errors, options) | |
575 | for i in range(0, len(a:errors)-1) | |
576 | for key in keys(a:options) | |
577 | if !has_key(a:errors[i], key) || empty(a:errors[i][key]) | |
578 | let a:errors[i][key] = a:options[key] | |
579 | endif | |
580 | endfor | |
581 | endfor | |
582 | return a:errors | |
583 | endfunction | |
584 | ||
585 | "take a list of syntax checkers for the current filetype and load the right | |
586 | "one based on the global settings and checker executable availabity | |
587 | " | |
588 | "a:checkers should be a list of syntax checker names. These names are assumed | |
589 | "to be the names of the vim syntax checker files that should be sourced, as | |
590 | "well as the names of the actual syntax checker executables. The checkers | |
591 | "should be listed in order of default preference. | |
592 | " | |
593 | "if a option called 'g:syntastic_[filetype]_checker' exists then attempt to | |
594 | "load the checker that it points to | |
595 | function! SyntasticLoadChecker(checkers) | |
596 | let opt_name = "g:syntastic_" . &ft . "_checker" | |
597 | ||
598 | if exists(opt_name) | |
599 | let opt_val = {opt_name} | |
600 | if index(a:checkers, opt_val) != -1 && executable(opt_val) | |
601 | call s:LoadChecker(opt_val) | |
602 | else | |
603 | echoerr &ft . " syntax not supported or not installed." | |
604 | endif | |
605 | else | |
606 | for checker in a:checkers | |
607 | if executable(checker) | |
608 | return s:LoadChecker(checker) | |
609 | endif | |
610 | endfor | |
611 | endif | |
612 | endfunction | |
613 | ||
614 | " vim: set et sts=4 sw=4: |