1
0

preprocess.vim 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. if exists('g:loaded_syntastic_preprocess_autoload') || !exists('g:loaded_syntastic_plugin')
  2. finish
  3. endif
  4. let g:loaded_syntastic_preprocess_autoload = 1
  5. let s:save_cpo = &cpo
  6. set cpo&vim
  7. " Public functions {{{1
  8. function! syntastic#preprocess#cabal(errors) abort " {{{2
  9. let out = []
  10. let star = 0
  11. for err in a:errors
  12. if star
  13. if err ==# ''
  14. let star = 0
  15. else
  16. let out[-1] .= ' ' . err
  17. endif
  18. else
  19. call add(out, err)
  20. if err =~# '\m^*\s'
  21. let star = 1
  22. endif
  23. endif
  24. endfor
  25. return out
  26. endfunction " }}}2
  27. function! syntastic#preprocess#checkstyle(errors) abort " {{{2
  28. let out = []
  29. let fname = expand('%', 1)
  30. for err in a:errors
  31. if match(err, '\m<error\>') > -1
  32. let line = str2nr(matchstr(err, '\m\<line="\zs\d\+\ze"'))
  33. if line == 0
  34. continue
  35. endif
  36. let col = str2nr(matchstr(err, '\m\<column="\zs\d\+\ze"'))
  37. let type = matchstr(err, '\m\<severity="\zs.\ze')
  38. if type !~? '^[EW]'
  39. let type = 'E'
  40. endif
  41. let message = syntastic#util#decodeXMLEntities(matchstr(err, '\m\<message="\zs[^"]\+\ze"'))
  42. call add(out, join([fname, type, line, col, message], ':'))
  43. elseif match(err, '\m<file name="') > -1
  44. let fname = syntastic#util#decodeXMLEntities(matchstr(err, '\v\<file name\="\zs[^"]+\ze"'))
  45. endif
  46. endfor
  47. return out
  48. endfunction " }}}2
  49. function! syntastic#preprocess#cppcheck(errors) abort " {{{2
  50. return map(copy(a:errors), 'substitute(v:val, ''\v^\[[^]]+\]\zs( -\> \[[^]]+\])+\ze:'', "", "")')
  51. endfunction " }}}2
  52. " @vimlint(EVL102, 1, l:true)
  53. " @vimlint(EVL102, 1, l:false)
  54. " @vimlint(EVL102, 1, l:null)
  55. function! syntastic#preprocess#flow(errors) abort " {{{2
  56. " JSON artifacts
  57. let true = 1
  58. let false = 0
  59. let null = ''
  60. " A hat tip to Marc Weber for this trick
  61. " http://stackoverflow.com/questions/17751186/iterating-over-a-string-in-vimscript-or-parse-a-json-file/19105763#19105763
  62. try
  63. let errs = eval(join(a:errors, ''))
  64. catch
  65. let errs = {}
  66. endtry
  67. let out = []
  68. if type(errs) == type({}) && has_key(errs, 'errors') && type(errs['errors']) == type([])
  69. for e in errs['errors']
  70. if type(e) == type({}) && has_key(e, 'message') && type(e['message']) == type([]) && len(e['message'])
  71. let m = e['message'][0]
  72. let t = e['message'][1:]
  73. try
  74. let msg =
  75. \ m['path'] . ':' .
  76. \ m['line'] . ':' .
  77. \ m['start'] . ':' .
  78. \ (m['line'] ==# m['endline'] && str2nr(m['end']) > 0 ? m['end'] . ':' : '') .
  79. \ ' ' . m['descr']
  80. if len(t)
  81. let msg .= ' ' . join(map(t,
  82. \ 'v:val["descr"] . " (" . v:val["path"] . ":" . v:val["line"] . ":" . v:val["start"] . ' .
  83. \ '"," . (v:val["line"] !=# v:val["endline"] ? v:val["endline"] . ":" : "") . ' .
  84. \ 'v:val["end"] . ")"'))
  85. endif
  86. let msg = substitute(msg, '\r', '', 'g')
  87. let msg = substitute(msg, '\n', ' ', 'g')
  88. call add(out, msg)
  89. catch /\m^Vim\%((\a\+)\)\=:E716/
  90. call syntastic#log#warn('checker javascript/flow: unknown error format')
  91. let out = []
  92. break
  93. endtry
  94. else
  95. call syntastic#log#warn('checker javascript/flow: unknown error format')
  96. let out = []
  97. break
  98. endif
  99. endfor
  100. else
  101. call syntastic#log#warn('checker javascript/flow: unknown error format')
  102. endif
  103. return out
  104. endfunction " }}}2
  105. " @vimlint(EVL102, 0, l:true)
  106. " @vimlint(EVL102, 0, l:false)
  107. " @vimlint(EVL102, 0, l:null)
  108. function! syntastic#preprocess#killEmpty(errors) abort " {{{2
  109. return filter(copy(a:errors), 'v:val !=# ""')
  110. endfunction " }}}2
  111. function! syntastic#preprocess#perl(errors) abort " {{{2
  112. let out = []
  113. for e in a:errors
  114. let parts = matchlist(e, '\v^(.*)\sat\s(.{-})\sline\s(\d+)(.*)$')
  115. if !empty(parts)
  116. call add(out, parts[2] . ':' . parts[3] . ':' . parts[1] . parts[4])
  117. endif
  118. endfor
  119. return syntastic#util#unique(out)
  120. endfunction " }}}2
  121. " @vimlint(EVL102, 1, l:true)
  122. " @vimlint(EVL102, 1, l:false)
  123. " @vimlint(EVL102, 1, l:null)
  124. function! syntastic#preprocess#prospector(errors) abort " {{{2
  125. " JSON artifacts
  126. let true = 1
  127. let false = 0
  128. let null = ''
  129. " A hat tip to Marc Weber for this trick
  130. " http://stackoverflow.com/questions/17751186/iterating-over-a-string-in-vimscript-or-parse-a-json-file/19105763#19105763
  131. try
  132. let errs = eval(join(a:errors, ''))
  133. catch
  134. let errs = {}
  135. endtry
  136. let out = []
  137. if type(errs) == type({}) && has_key(errs, 'messages')
  138. if type(errs['messages']) == type([])
  139. for e in errs['messages']
  140. if type(e) == type({})
  141. try
  142. if e['source'] ==# 'pylint'
  143. let e['location']['character'] += 1
  144. endif
  145. let msg =
  146. \ e['location']['path'] . ':' .
  147. \ e['location']['line'] . ':' .
  148. \ e['location']['character'] . ': ' .
  149. \ e['code'] . ' ' .
  150. \ e['message'] . ' ' .
  151. \ '[' . e['source'] . ']'
  152. call add(out, msg)
  153. catch /\m^Vim\%((\a\+)\)\=:E716/
  154. call syntastic#log#warn('checker python/prospector: unknown error format')
  155. let out = []
  156. break
  157. endtry
  158. else
  159. call syntastic#log#warn('checker python/prospector: unknown error format')
  160. let out = []
  161. break
  162. endif
  163. endfor
  164. else
  165. call syntastic#log#warn('checker python/prospector: unknown error format')
  166. endif
  167. endif
  168. return out
  169. endfunction " }}}2
  170. " @vimlint(EVL102, 0, l:true)
  171. " @vimlint(EVL102, 0, l:false)
  172. " @vimlint(EVL102, 0, l:null)
  173. function! syntastic#preprocess#rparse(errors) abort " {{{2
  174. let errlist = copy(a:errors)
  175. " remove uninteresting lines and handle continuations
  176. let i = 0
  177. while i < len(errlist)
  178. if i > 0 && errlist[i][:1] ==# ' ' && errlist[i] !~# '\m\s\+\^$'
  179. let errlist[i-1] .= errlist[i][1:]
  180. call remove(errlist, i)
  181. elseif errlist[i] !~# '\m^\(Lint:\|Lint checking:\|Error in\) '
  182. call remove(errlist, i)
  183. else
  184. let i += 1
  185. endif
  186. endwhile
  187. let out = []
  188. let fname = ''
  189. for e in errlist
  190. if match(e, '\m^Lint: ') == 0
  191. let parts = matchlist(e, '\m^Lint: \(.*\): found on lines \([0-9, ]\+\)\(+\(\d\+\) more\)\=')
  192. if len(parts) >= 3
  193. for line in split(parts[2], '\m,\s*')
  194. call add(out, 'E:' . fname . ':' . line . ': ' . parts[1])
  195. endfor
  196. endif
  197. if len(parts) >= 5 && parts[4] !=# ''
  198. call add(out, 'E:' . fname . ':0: ' . parts[1] . ' - ' . parts[4] . ' messages not shown')
  199. endif
  200. elseif match(e, '\m^Lint checking: ') == 0
  201. let fname = matchstr(e, '\m^Lint checking: \zs.*')
  202. elseif match(e, '\m^Error in ') == 0
  203. call add(out, substitute(e, '\m^Error in .\+ : .\+\ze:\d\+:\d\+: ', 'E:' . fname, ''))
  204. endif
  205. endfor
  206. return out
  207. endfunction " }}}2
  208. function! syntastic#preprocess#tslint(errors) abort " {{{2
  209. return map(copy(a:errors), 'substitute(v:val, ''\m^\(([^)]\+)\)\s\(.\+\)$'', ''\2 \1'', "")')
  210. endfunction " }}}2
  211. function! syntastic#preprocess#validator(errors) abort " {{{2
  212. let out = []
  213. for e in a:errors
  214. let parts = matchlist(e, '\v^"([^"]+)"(.+)')
  215. if len(parts) >= 3
  216. " URL decode, except leave alone any "+"
  217. let parts[1] = substitute(parts[1], '\m%\(\x\x\)', '\=nr2char("0x".submatch(1))', 'g')
  218. let parts[1] = substitute(parts[1], '\m\\"', '"', 'g')
  219. let parts[1] = substitute(parts[1], '\m\\\\', '\\', 'g')
  220. call add(out, '"' . parts[1] . '"' . parts[2])
  221. endif
  222. endfor
  223. return out
  224. endfunction " }}}2
  225. " @vimlint(EVL102, 1, l:true)
  226. " @vimlint(EVL102, 1, l:false)
  227. " @vimlint(EVL102, 1, l:null)
  228. function! syntastic#preprocess#vint(errors) abort " {{{2
  229. " JSON artifacts
  230. let true = 1
  231. let false = 0
  232. let null = ''
  233. " A hat tip to Marc Weber for this trick
  234. " http://stackoverflow.com/questions/17751186/iterating-over-a-string-in-vimscript-or-parse-a-json-file/19105763#19105763
  235. try
  236. let errs = eval(join(a:errors, ''))
  237. catch
  238. let errs = []
  239. endtry
  240. let out = []
  241. if type(errs) == type([])
  242. for e in errs
  243. if type(e) == type({})
  244. try
  245. let msg =
  246. \ e['file_path'] . ':' .
  247. \ e['line_number'] . ':' .
  248. \ e['column_number'] . ':' .
  249. \ e['severity'][0] . ': ' .
  250. \ e['description'] . ' (' .
  251. \ e['policy_name'] . ')'
  252. call add(out, msg)
  253. catch /\m^Vim\%((\a\+)\)\=:E716/
  254. call syntastic#log#warn('checker vim/vint: unknown error format')
  255. let out = []
  256. break
  257. endtry
  258. else
  259. call syntastic#log#warn('checker vim/vint: unknown error format')
  260. let out = []
  261. break
  262. endif
  263. endfor
  264. else
  265. call syntastic#log#warn('checker vim/vint: unknown error format')
  266. endif
  267. return out
  268. endfunction " }}}2
  269. " @vimlint(EVL102, 0, l:true)
  270. " @vimlint(EVL102, 0, l:false)
  271. " @vimlint(EVL102, 0, l:null)
  272. " }}}1
  273. let &cpo = s:save_cpo
  274. unlet s:save_cpo
  275. " vim: set sw=4 sts=4 et fdm=marker: