1

I use :make to run a python script to build a C++ project. Usually, the output errors are C++ errors and :compiler msvc parses them correctly. Rarely, the error is a python one and I want :compiler python instead.

Is it possible to re-parse the quickfix with a different errorformat without re-running the command that generated the output?

The best solution I've got is to hope the python lines survived as unrecognized lines (prefixed with || and load them out of the quickfix buffer, but this seems brittle:

:copen | 0,$yank | new | put | %s/^|| // | compiler python | cgetbuffer | bdelete! | nohlsearch
1
  • I think when quickfix throws lines away, they’re gone, but you could use the quickfix functions to process the entries? Or combine the errorformats? (PS :%yank)
    – D. Ben Knoble
    Commented Oct 10, 2023 at 22:05

2 Answers 2

1

Your use case is a special one that is not fully covered by either :compiler msvc or :compiler python so making your own "compiler" seems to make the most sense. Now, how to go about it?

The errorformat set in $VIMRUNTIME/compiler/msvc.vim is simply the default one.

The errorformat set in your third-party script completely replaces the default value with a custom one.

One thing I would try would be to replace the = in:

CompilerSet errorformat=%A%\\s%#File\ \"%f\"\\,\ line\ %l\\,\ in%.%#

with a += and see how it goes. This would append the custom errorformat to the default one and, presumably, match both the C++ errors and the Python ones.

The drawback, here, would be that errorformat is a rather large comma-seprated list of values that are tried in order, which can give you false positives. Maybe you could identify the value(s) that effectively match your C++ errors (say %f:%l:%c:%m) and do something like:

" in compiler/mine.vim
CompilerSet errorformat=%f:%l:%c:%m
CompilerSet errorformat+=%A%\\s%#File\ \"%f\"\\,\ line\ %l\\,\ in%.%#
etc.
1
  • I was hoping for a post-process solution, but I guess that information is lost? This is helpful, but don't I need to explicitly set efm& in case efm already changed? Also, I don't think I'd want other invocations of python to recognize msvc errors, but I guess I could make a new compiler/pybuild.vim that merges the two together with something like: compiler msvc | let c_ef = &efm | compiler python | let &efm=c_ef ..','..&efm (maybe needs unlet current_compiler too...). Thanks for the answer!
    – idbrii
    Commented Oct 12, 2023 at 17:31
0

I didn't want to copypaste the contents of my (custom) compiler/msvc.vim and compiler/python.vim into another file, so instead I found a solution that combines the C++ and python errorformat and uses the python makeprg.

Saved as ~/.vim/compiler/py_msvc.vim:

" Compiler: python that builds C++ with msvc

if exists("current_compiler")
  finish
endif

" Use :runtime because :compiler makes vim setup CompilerSet which errors if
" it's already setup.
runtime compiler/msvc.vim
silent! unlet g:current_compiler
let c_ef = &errorformat

runtime compiler/python.vim
silent! unlet g:current_compiler

" Prepend so C errors are recognized first.
let &errorformat=c_ef ..','..&errorformat

let g:current_compiler = 'py_msvc'

" vim:set sw=2 sts=2:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.