diff options
Diffstat (limited to 'autoload/vimtex/qf')
| -rw-r--r-- | autoload/vimtex/qf/biblatex.vim | 250 | ||||
| -rw-r--r-- | autoload/vimtex/qf/bibtex.vim | 187 | ||||
| -rw-r--r-- | autoload/vimtex/qf/latexlog.vim | 209 | ||||
| -rw-r--r-- | autoload/vimtex/qf/pplatex.vim | 98 | ||||
| -rw-r--r-- | autoload/vimtex/qf/pulp.vim | 67 | 
5 files changed, 811 insertions, 0 deletions
diff --git a/autoload/vimtex/qf/biblatex.vim b/autoload/vimtex/qf/biblatex.vim new file mode 100644 index 00000000..2e5e08a5 --- /dev/null +++ b/autoload/vimtex/qf/biblatex.vim @@ -0,0 +1,250 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email:      karl.yngve@gmail.com +" + +function! vimtex#qf#biblatex#addqflist(blg) abort " {{{1 +  if get(g:vimtex_quickfix_blgparser, 'disable') | return | endif + +  try +    call s:biblatex.addqflist(a:blg) +  catch /biblatex Aborted/ +  endtry +endfunction + +" }}}1 + +let s:biblatex = { +      \ 'file' : '', +      \ 'types' : [], +      \ 'db_files' : [], +      \} +function! s:biblatex.addqflist(blg) abort " {{{1 +  let self.file = a:blg +  let self.root = fnamemodify(a:blg, ':h') +  if empty(self.file) | throw 'biblatex Aborted' | endif + +  let self.types = map( +        \ filter(items(s:), 'v:val[0] =~# ''^type_'''), +        \ 'v:val[1]') +  let self.db_files = [] + +  let self.errorformat_saved = &l:errorformat +  setlocal errorformat=%+E%.%#\>\ ERROR%m +  setlocal errorformat+=%+W%.%#\>\ WARN\ -\ Duplicate\ entry%m +  setlocal errorformat+=%+W%.%#\>\ WARN\ -\ The\ entry%.%#cannot\ be\ encoded%m +  setlocal errorformat+=%-G%.%# +  execute 'caddfile' fnameescape(self.file) +  let &l:errorformat = self.errorformat_saved + +  call self.fix_paths() +endfunction + +" }}}1 +function! s:biblatex.fix_paths() abort " {{{1 +  let l:qflist = getqflist() +  try +    let l:title = getqflist({'title': 1}) +  catch /E118/ +    let l:title = 'Vimtex errors' +  endtry + +  for l:qf in l:qflist +    for l:type in self.types +      if l:type.fix(self, l:qf) | break | endif +    endfor +  endfor + +  call setqflist(l:qflist, 'r') + +  " Set title if supported +  try +    call setqflist([], 'r', l:title) +  catch +  endtry +endfunction + +" }}}1 +function! s:biblatex.get_db_files() abort " {{{1 +  if empty(self.db_files) +    let l:preamble = vimtex#parser#preamble(b:vimtex.tex, { +          \ 'root' : b:vimtex.root, +          \}) +    let l:files = map( +          \ filter(l:preamble, 'v:val =~# ''\\addbibresource'''), +          \ 'matchstr(v:val, ''{\zs.*\ze}'')') +    let self.db_files = [] +    for l:file in l:files +      if filereadable(l:file) +        let self.db_files += [l:file] +      elseif filereadable(expand(l:file)) +        let self.db_files += [expand(l:file)] +      else +        let l:cand = vimtex#kpsewhich#run(l:file) +        if len(l:cand) == 1 +          let self.db_files += [l:cand[0]] +        endif +      endif +    endfor +  endif + +  return self.db_files +endfunction + +" }}}1 +function! s:biblatex.get_filename(name) abort " {{{1 +  if !filereadable(a:name) +    for l:root in [self.root, b:vimtex.root] +      let l:candidate = fnamemodify(simplify(l:root . '/' . a:name), ':.') +      if filereadable(l:candidate) +        return l:candidate +      endif +    endfor +  endif + +  return a:name +endfunction + +" }}}1 +function! s:biblatex.get_key_pos(key) abort " {{{1 +  for l:file in self.get_db_files() +    let l:lnum = self.get_key_lnum(a:key, l:file) +    if l:lnum > 0 +      return [l:file, l:lnum] +    endif +  endfor + +  return [] +endfunction + +" }}}1 +function! s:biblatex.get_key_lnum(key, filename) abort " {{{1 +  if !filereadable(a:filename) | return 0 | endif + +  let l:lines = readfile(a:filename) +  let l:lnums = range(len(l:lines)) +  let l:annotated_lines = map(l:lnums, '[v:val, l:lines[v:val]]') +  let l:matches = filter(l:annotated_lines, 'v:val[1] =~# ''^\s*@\w*{\s*\V' . a:key . '''') + +  return len(l:matches) > 0 ? l:matches[-1][0]+1 : 0 +endfunction + +" }}}1 +function! s:biblatex.get_entry_key(filename, lnum) abort " {{{1 +  for l:file in self.get_db_files() +    if fnamemodify(l:file, ':t') !=# a:filename | continue | endif + +    let l:entry = get(filter(readfile(l:file, 0, a:lnum), 'v:val =~# ''^@'''), -1) +    if empty(l:entry) | continue | endif + +    return matchstr(l:entry, '{\v\zs.{-}\ze(,|$)') +  endfor + +  return '' +endfunction + +" }}}1 + +" +" Parsers for the various warning types +" + +let s:type_parse_error = {} +function! s:type_parse_error.fix(ctx, entry) abort " {{{1 +  if a:entry.text =~# 'ERROR - BibTeX subsystem.*expected end of entry' +    let l:matches = matchlist(a:entry.text, '\v(\S*\.bib).*line (\d+)') +    let a:entry.filename = a:ctx.get_filename(fnamemodify(l:matches[1], ':t')) +    let a:entry.lnum = l:matches[2] + +    " Use filename and line number to get entry name +    let l:key = a:ctx.get_entry_key(a:entry.filename, a:entry.lnum) +    if !empty(l:key) +      let a:entry.text = 'biblatex: Error parsing entry with key "' . l:key . '"' +    endif +    return 1 +  endif +endfunction + +" }}}1 + +let s:type_duplicate = {} +function! s:type_duplicate.fix(ctx, entry) abort " {{{1 +  if a:entry.text =~# 'WARN - Duplicate entry' +    let l:matches = matchlist(a:entry.text, '\v: ''(\S*)'' in file ''(.{-})''') +    let l:key = l:matches[1] +    let a:entry.filename = a:ctx.get_filename(l:matches[2]) +    let a:entry.lnum = a:ctx.get_key_lnum(l:key, a:entry.filename) +    let a:entry.text = 'biblatex: Duplicate entry key "' . l:key . '"' +    return 1 +  endif +endfunction + +" }}}1 + +let s:type_no_driver = {} +function! s:type_no_driver.fix(ctx, entry) abort " {{{1 +  if a:entry.text =~# 'No driver for entry type' +    let l:key = matchstr(a:entry.text, 'entry type ''\v\zs.{-}\ze''') +    let a:entry.text = 'biblatex: Using fallback driver for ''' . l:key . '''' + +    let l:pos = a:ctx.get_key_pos(l:key) +    if !empty(l:pos) +      let a:entry.filename = a:ctx.get_filename(l:pos[0]) +      let a:entry.lnum = l:pos[1] +      if has_key(a:entry, 'bufnr') +        unlet a:entry.bufnr +      endif +    endif + +    return 1 +  endif +endfunction + +" }}}1 + +let s:type_not_found = {} +function! s:type_not_found.fix(ctx, entry) abort " {{{1 +  if a:entry.text =~# 'The following entry could not be found' +    let l:key = split(a:entry.text, ' ')[-1] +    let a:entry.text = 'biblatex: Entry with key ''' . l:key . ''' not found' + +    for [l:file, l:lnum, l:line] in vimtex#parser#tex(b:vimtex.tex) +      if l:line =~# g:vimtex#re#not_comment . '\\\S*\V' . l:key +        let a:entry.lnum = l:lnum +        let a:entry.filename = l:file +        unlet a:entry.bufnr +        break +      endif +    endfor + +    return 1 +  endif +endfunction + +" }}}1 + +let s:type_encoding = {} +function! s:type_encoding.fix(ctx, entry) abort " {{{1 +  if a:entry.text =~# 'The entry .* has characters which cannot' +    let l:key = matchstr(a:entry.text, 'The entry ''\v\zs.{-}\ze''') +    let a:entry.text = 'biblatex: Entry with key ''' . l:key . ''' has non-ascii characters' + +    let l:pos = a:ctx.get_key_pos(l:key) +    if !empty(l:pos) +      let a:entry.filename = a:ctx.get_filename(l:pos[0]) +      let a:entry.lnum = l:pos[1] +      if has_key(a:entry, 'bufnr') +        unlet a:entry.bufnr +      endif +    endif + +    return 1 +  endif +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/qf/bibtex.vim b/autoload/vimtex/qf/bibtex.vim new file mode 100644 index 00000000..94bdcafa --- /dev/null +++ b/autoload/vimtex/qf/bibtex.vim @@ -0,0 +1,187 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email:      karl.yngve@gmail.com +" + +function! vimtex#qf#bibtex#addqflist(blg) abort " {{{1 +  if get(g:vimtex_quickfix_blgparser, 'disable') | return | endif + +  try +    call s:bibtex.addqflist(a:blg) +  catch /BibTeX Aborted/ +  endtry +endfunction + +" }}}1 + +let s:bibtex = { +      \ 'file' : '', +      \ 'types' : [], +      \ 'db_files' : [], +      \} +function! s:bibtex.addqflist(blg) abort " {{{1 +  let self.file = a:blg +  if empty(self.file) || !filereadable(self.file) | throw 'BibTeX Aborted' | endif + +  let self.types = map( +        \ filter(items(s:), 'v:val[0] =~# ''^type_'''), +        \ 'v:val[1]') +  let self.db_files = [] + +  let self.errorformat_saved = &l:errorformat +  setlocal errorformat=%+E%.%#---line\ %l\ of\ file\ %f +  setlocal errorformat+=%+EI\ found\ %.%#---while\ reading\ file\ %f +  setlocal errorformat+=%+WWarning--empty\ %.%#\ in\ %.%m +  setlocal errorformat+=%+WWarning--entry\ type\ for%m +  setlocal errorformat+=%-C--line\ %l\ of\ file\ %f +  setlocal errorformat+=%-G%.%# +  execute 'caddfile' fnameescape(self.file) +  let &l:errorformat = self.errorformat_saved + +  call self.fix_paths() +endfunction + +" }}}1 +function! s:bibtex.fix_paths() abort " {{{1 +  let l:qflist = getqflist() +  try +    let l:title = getqflist({'title': 1}) +  catch /E118/ +    let l:title = 'Vimtex errors' +  endtry + +  for l:qf in l:qflist +    for l:type in self.types +      if l:type.fix(self, l:qf) | break | endif +    endfor +  endfor + +  call setqflist(l:qflist, 'r') + +  " Set title if supported +  try +    call setqflist([], 'r', l:title) +  catch +  endtry +endfunction + +" }}}1 +function! s:bibtex.get_db_files() abort " {{{1 +  if empty(self.db_files) +    let l:build_dir = fnamemodify(b:vimtex.ext('log'), ':.:h') . '/' +    for l:file in map( +          \ filter(readfile(self.file), 'v:val =~# ''Database file #\d:'''), +          \ 'matchstr(v:val, '': \zs.*'')') +      if filereadable(l:file) +        call add(self.db_files, l:file) +      elseif filereadable(l:build_dir . l:file) +        call add(self.db_files, l:build_dir . l:file) +      endif +    endfor +  endif + +  return self.db_files +endfunction + +" }}}1 +function! s:bibtex.get_key_loc(key) abort " {{{1 +  for l:file in self.get_db_files() +    let l:lines = readfile(l:file) +    let l:lnum = 0 +    for l:line in l:lines +      let l:lnum += 1 +      if l:line =~# '^\s*@\w*{\s*\V' . a:key +        return [l:file, l:lnum] +      endif +    endfor +  endfor + +  return [] +endfunction + +" }}}1 + +" +" Parsers for the various warning types +" + +let s:type_syn_error = {} +function! s:type_syn_error.fix(ctx, entry) abort " {{{1 +  if a:entry.text =~# '---line \d\+ of file' +    let a:entry.text = split(a:entry.text, '---')[0] +    return 1 +  endif +endfunction + +" }}}1 + +let s:type_empty = { +      \ 're' : '\vWarning--empty (.*) in (\S*)', +      \} +function! s:type_empty.fix(ctx, entry) abort " {{{1 +  let l:matches = matchlist(a:entry.text, self.re) +  if empty(l:matches) | return 0 | endif + +  let l:type = l:matches[1] +  let l:key = l:matches[2] + +  unlet a:entry.bufnr +  let a:entry.text = printf('Missing "%s" in "%s"', l:type, l:key) + +  let l:loc = a:ctx.get_key_loc(l:key) +  if !empty(l:loc) +    let a:entry.filename = l:loc[0] +    let a:entry.lnum = l:loc[1] +  endif + +  return 1 +endfunction + +" }}}1 + +let s:type_style_file_defined = { +      \ 're' : '\vWarning--entry type for "(\w+)"', +      \} +function! s:type_style_file_defined.fix(ctx, entry) abort " {{{1 +  let l:matches = matchlist(a:entry.text, self.re) +  if empty(l:matches) | return 0 | endif + +  let l:key = l:matches[1] + +  unlet a:entry.bufnr +  let a:entry.text = 'Entry type for "' . l:key . '" isn''t style-file defined' + +  let l:loc = a:ctx.get_key_loc(l:key) +  if !empty(l:loc) +    let a:entry.filename = l:loc[0] +    let a:entry.lnum = l:loc[1] +  endif + +  return 1 +endfunction + +" }}}1 + +let s:type_no_bibstyle = {} +function! s:type_no_bibstyle.fix(ctx, entry) abort " {{{1 +  if a:entry.text =~# 'I found no \\bibstyle' +    let a:entry.text = 'BibTeX found no \bibstyle command (missing \bibliographystyle?)' +    let a:entry.filename = b:vimtex.tex +    unlet a:entry.bufnr +    for [l:file, l:lnum, l:line] in vimtex#parser#tex(b:vimtex.tex) +      if l:line =~# g:vimtex#re#not_comment . '\\bibliography' +        let a:entry.lnum = l:lnum +        let a:entry.filename = l:file +        break +      endif +    endfor +    return 1 +  endif +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/qf/latexlog.vim b/autoload/vimtex/qf/latexlog.vim new file mode 100644 index 00000000..0046543e --- /dev/null +++ b/autoload/vimtex/qf/latexlog.vim @@ -0,0 +1,209 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email:      karl.yngve@gmail.com +" + +function! vimtex#qf#latexlog#new() abort " {{{1 +  return deepcopy(s:qf) +endfunction + +" }}}1 + + +let s:qf = { +      \ 'name' : 'LaTeX logfile', +      \} + +function! s:qf.init(state) abort dict "{{{1 +  let self.config = get(g:, 'vimtex_quickfix_latexlog', {}) +  let self.config.default = get(self.config, 'default', 1) +  let self.config.packages = get(self.config, 'packages', {}) +  let self.config.packages.default = get(self.config.packages, 'default', +        \ self.config.default) + +  let self.types = map( +        \ filter(items(s:), 'v:val[0] =~# ''^type_'''), +        \ 'v:val[1]') +endfunction + +" }}}1 +function! s:qf.set_errorformat() abort dict "{{{1 +  " +  " Note: The errorformat assumes we're using the -file-line-error with +  "       [pdf]latex. For more info, see |errorformat-LaTeX|. +  " + +  " Push file to file stack +  setlocal errorformat=%-P**%f +  setlocal errorformat+=%-P**\"%f\" + +  " Match errors +  setlocal errorformat+=%E!\ LaTeX\ %trror:\ %m +  setlocal errorformat+=%E%f:%l:\ %m +  setlocal errorformat+=%E!\ %m + +  " More info for undefined control sequences +  setlocal errorformat+=%Z<argument>\ %m + +  " More info for some errors +  setlocal errorformat+=%Cl.%l\ %m + +  " +  " Define general warnings +  " +  let l:default = self.config.default +  if get(self.config, 'font', l:default) +    setlocal errorformat+=%+WLaTeX\ Font\ Warning:\ %.%#line\ %l%.%# +    setlocal errorformat+=%-CLaTeX\ Font\ Warning:\ %m +    setlocal errorformat+=%-C(Font)%m +  else +    setlocal errorformat+=%-WLaTeX\ Font\ Warning:\ %m +  endif + +  if !get(self.config, 'references', l:default) +    setlocal errorformat+=%-WLaTeX\ %.%#Warning:\ %.%#eference%.%#undefined%.%#line\ %l%.%# +    setlocal errorformat+=%-WLaTeX\ %.%#Warning:\ %.%#undefined\ references. +  endif + +  if get(self.config, 'general', l:default) +    setlocal errorformat+=%+WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%# +    setlocal errorformat+=%+WLaTeX\ %.%#Warning:\ %m +  endif + +  if get(self.config, 'overfull', l:default) +    setlocal errorformat+=%+WOverfull\ %\\%\\hbox%.%#\ at\ lines\ %l--%*\\d +    setlocal errorformat+=%+WOverfull\ %\\%\\hbox%.%#\ at\ line\ %l +    setlocal errorformat+=%+WOverfull\ %\\%\\vbox%.%#\ at\ line\ %l +  endif + +  if get(self.config, 'underfull', l:default) +    setlocal errorformat+=%+WUnderfull\ %\\%\\hbox%.%#\ at\ lines\ %l--%*\\d +    setlocal errorformat+=%+WUnderfull\ %\\%\\vbox%.%#\ at\ line\ %l +  endif + +  " +  " Define package related warnings +  " +  let l:default = self.config.packages.default +  if get(self.config.packages, 'natbib', l:default) +    setlocal errorformat+=%+WPackage\ natbib\ Warning:\ %m\ on\ input\ line\ %l. +  else +    setlocal errorformat+=%-WPackage\ natbib\ Warning:\ %m\ on\ input\ line\ %l. +  endif + +  if get(self.config.packages, 'biblatex', l:default) +    setlocal errorformat+=%+WPackage\ biblatex\ Warning:\ %m +    setlocal errorformat+=%-C(biblatex)%.%#in\ t%.%# +    setlocal errorformat+=%-C(biblatex)%.%#Please\ v%.%# +    setlocal errorformat+=%-C(biblatex)%.%#LaTeX\ a%.%# +    setlocal errorformat+=%-C(biblatex)%m +  else +    setlocal errorformat+=%-WPackage\ biblatex\ Warning:\ %m +  endif + +  if get(self.config.packages, 'babel', l:default) +    setlocal errorformat+=%+WPackage\ babel\ Warning:\ %m +    setlocal errorformat+=%-Z(babel)%.%#input\ line\ %l. +    setlocal errorformat+=%-C(babel)%m +  else +    setlocal errorformat+=%-WPackage\ babel\ Warning:\ %m +  endif + +  if get(self.config.packages, 'hyperref', l:default) +    setlocal errorformat+=%+WPackage\ hyperref\ Warning:\ %m +    setlocal errorformat+=%-C(hyperref)%m\ on\ input\ line\ %l. +    setlocal errorformat+=%-C(hyperref)%m +  else +    setlocal errorformat+=%-WPackage\ hyperref\ Warning:\ %m +  endif + +  if get(self.config.packages, 'scrreprt', l:default) +    setlocal errorformat+=%+WPackage\ scrreprt\ Warning:\ %m +    setlocal errorformat+=%-C(scrreprt)%m +  else +    setlocal errorformat+=%-WPackage\ scrreprt\ Warning:\ %m +  endif + +  if get(self.config.packages, 'fixltx2e', l:default) +    setlocal errorformat+=%+WPackage\ fixltx2e\ Warning:\ %m +    setlocal errorformat+=%-C(fixltx2e)%m +  else +    setlocal errorformat+=%-WPackage\ fixltx2e\ Warning:\ %m +  endif + +  if get(self.config.packages, 'titlesec', l:default) +    setlocal errorformat+=%+WPackage\ titlesec\ Warning:\ %m +    setlocal errorformat+=%-C(titlesec)%m +  else +    setlocal errorformat+=%-WPackage\ titlesec\ Warning:\ %m +  endif + +  if get(self.config.packages, 'general', l:default) +    setlocal errorformat+=%+WPackage\ %.%#\ Warning:\ %m\ on\ input\ line\ %l. +    setlocal errorformat+=%+WPackage\ %.%#\ Warning:\ %m +    setlocal errorformat+=%-Z(%.%#)\ %m\ on\ input\ line\ %l. +    setlocal errorformat+=%-C(%.%#)\ %m +  endif + +  " Ignore unmatched lines +  setlocal errorformat+=%-G%.%# +endfunction + +" }}}1 +function! s:qf.addqflist(tex, log) abort dict "{{{1 +  if empty(a:log) || !filereadable(a:log) +    throw 'Vimtex: No log file found' +  endif + +  let self.errorformat_saved = &l:errorformat +  call self.set_errorformat() +  execute 'caddfile' fnameescape(a:log) +  let &l:errorformat = self.errorformat_saved + +  " Apply some post processing of the quickfix list +  let self.main = a:tex +  let self.root = b:vimtex.root +  call self.fix_paths() +endfunction + +" }}}1 +function! s:qf.pprint_items() abort dict " {{{1 +  return [[ 'config', self.config ]] +endfunction + +" }}}1 +function! s:qf.fix_paths() abort dict " {{{1 +  let l:qflist = getqflist() + +  for l:qf in l:qflist +    " For errors and warnings that don't supply a file, the basename of the +    " main file is used. However, if the working directory is not the root of +    " the LaTeX project, than this results in bufnr = 0. +    if l:qf.bufnr == 0 +      let l:qf.bufnr = bufnr(self.main) +      continue +    endif + +    " The buffer names of all file:line type errors are relative to the root of +    " the main LaTeX file. +    let l:file = fnamemodify( +          \ simplify(self.root . '/' . bufname(l:qf.bufnr)), ':.') +    if !filereadable(l:file) | continue | endif + +    if !bufexists(l:file) +      execute 'badd' l:file +    endif + +    let l:qf.filename = l:file +    let l:qf.bufnr = bufnr(l:file) +  endfor + +  call setqflist(l:qflist, 'r') +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/qf/pplatex.vim b/autoload/vimtex/qf/pplatex.vim new file mode 100644 index 00000000..39e9a03e --- /dev/null +++ b/autoload/vimtex/qf/pplatex.vim @@ -0,0 +1,98 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" CreatedBy:    Johannes Wienke (languitar@semipol.de) +" Maintainer:   Karl Yngve Lervåg +" Email:        karl.yngve@gmail.com +" + +function! vimtex#qf#pplatex#new() abort " {{{1 +  return deepcopy(s:qf) +endfunction + +" }}}1 + + +let s:qf = { +      \ 'name' : 'LaTeX logfile using pplatex', +      \} + +function! s:qf.init(state) abort dict "{{{1 +  if !executable('pplatex') +    call vimtex#log#error('pplatex is not executable!') +    throw 'vimtex: Requirements not met' +  endif + +  " Automatically remove the -file-line-error option if we use the latexmk +  " backend (for convenience) +  if a:state.compiler.name ==# 'latexmk' +    let l:index = index(a:state.compiler.options, '-file-line-error') +    if l:index >= 0 +      call remove(a:state.compiler.options, l:index) +    endif +  endif +endfunction + +function! s:qf.set_errorformat() abort dict "{{{1 +  " Each new item starts with two asterics followed by the file, potentially +  " a line number and sometimes even the message itself is on the same line. +  " Please note that the trailing whitspaces in the error formats are +  " intentional as pplatex produces these. + +  " Start of new items with file and line number, message on next line(s). +  setlocal errorformat=%E**\ Error\ \ \ in\ %f\\,\ Line\ %l:%m +  setlocal errorformat+=%W**\ Warning\ in\ %f\\,\ Line\ %l:%m +  setlocal errorformat+=%I**\ BadBox\ \ in\ %f\\,\ Line\ %l:%m + +  " Start of items with with file, line and message on the same line. There are +  " no BadBoxes reported this way. +  setlocal errorformat+=%E**\ Error\ \ \ in\ %f\\,\ Line\ %l:%m +  setlocal errorformat+=%W**\ Warning\ in\ %f\\,\ Line\ %l:%m + +  " Start of new items with only a file. +  setlocal errorformat+=%E**\ Error\ \ \ in\ %f:%m +  setlocal errorformat+=%W**\ Warning\ in\ %f:%m +  setlocal errorformat+=%I**\ BadBox\ \ in\ %f:%m + +  " Start of items with with file and message on the same line. There are +  " no BadBoxes reported this way. +  setlocal errorformat+=%E**\ Error\ in\ %f:%m +  setlocal errorformat+=%W**\ Warning\ in\ %f:%m + +  " Some errors are difficult even for pplatex +  setlocal errorformat+=%E**\ Error\ \ :%m + +  " Anything that starts with three spaces is part of the message from a +  " previously started multiline error item. +  setlocal errorformat+=%C\ \ \ %m\ on\ input\ line\ %l. +  setlocal errorformat+=%C\ \ \ %m + +  " Items are terminated with two newlines. +  setlocal errorformat+=%-Z + +  " Skip statistical results at the bottom of the output. +  setlocal errorformat+=%-GResult%.%# +  setlocal errorformat+=%-G +endfunction + +" }}}1 +function! s:qf.addqflist(tex, log) abort dict " {{{1 +  if empty(a:log) || !filereadable(a:log) +    throw 'Vimtex: No log file found' +  endif + +  let l:tmp = fnameescape(fnamemodify(a:log, ':r') . '.pplatex') +  let l:log = fnameescape(a:log) + +  silent call system(printf('pplatex -i %s >%s', l:log, l:tmp)) +  let self.errorformat_saved = &l:errorformat +  call self.set_errorformat() +  execute 'caddfile' l:tmp +  let &l:errorformat = self.errorformat_saved +  silent call system('rm ' . l:tmp) +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/qf/pulp.vim b/autoload/vimtex/qf/pulp.vim new file mode 100644 index 00000000..0f0b73ef --- /dev/null +++ b/autoload/vimtex/qf/pulp.vim @@ -0,0 +1,67 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email:      karl.yngve@gmail.com +" + +function! vimtex#qf#pulp#new() abort " {{{1 +  return deepcopy(s:qf) +endfunction + +" }}}1 + + +let s:qf = { +      \ 'name' : 'LaTeX logfile using pulp', +      \} + +function! s:qf.init(state) abort dict "{{{1 +  if !executable('pulp') +    call vimtex#log#error('pulp is not executable!') +    throw 'vimtex: Requirements not met' +  endif + +  " Automatically remove the -file-line-error option if we use the latexmk +  " backend (for convenience) +  if a:state.compiler.name ==# 'latexmk' +    let l:index = index(a:state.compiler.options, '-file-line-error') +    if l:index >= 0 +      call remove(a:state.compiler.options, l:index) +    endif +  endif +endfunction + +function! s:qf.set_errorformat() abort dict "{{{1 +  setlocal errorformat= +  setlocal errorformat+=%-G%*[^\ ])\ %.%# +  setlocal errorformat+=%-G%.%#For\ some\ reason%.%# +  setlocal errorformat+=%W%f:%l-%*[0-9?]:\ %*[^\ ]\ warning:\ %m +  setlocal errorformat+=%E%f:%l-%*[0-9?]:\ %*[^\ ]\ error:\ %m +  setlocal errorformat+=%W%f:%l-%*[0-9?]:\ %m +  setlocal errorformat+=%W%l-%*[0-9?]:\ %m +  setlocal errorformat+=%-G%.%# +endfunction + +" }}}1 +function! s:qf.addqflist(tex, log) abort dict " {{{1 +  if empty(a:log) || !filereadable(a:log) +    call setqflist([]) +    throw 'Vimtex: No log file found' +  endif + +  let l:tmp = fnameescape(fnamemodify(a:log, ':r') . '.pulp') +  let l:log = fnameescape(a:log) + +  silent call system(printf('pulp %s >%s', l:log, l:tmp)) +  let self.errorformat_saved = &l:errorformat +  call self.set_errorformat() +  execute 'caddfile' l:tmp +  let &l:errorformat = self.errorformat_saved +  silent call system('rm ' . l:tmp) +endfunction + +" }}}1 + +endif  | 
