1

I use machines with vim 8.1.2269

I have a common situation where I cross compile on one machine and debug on another. As such I'll generate an error.err file to use with vim's quickfix feature. I have some vimscript that manipulates the quickfix list to my liking, however one hiccup that I haven't been able to fix is changing the path/filename associated with a quickfix item.

If I have an error.err file that looks like

/home/users/me/foo.cpp:156:18: error: no matching function for call to 'foo'
            if (!foo(m, n, A,
                 ^~~~~~~~~~~~~~~~~~~~
/home/users/me/foo.hpp:242:6: note: candidate template ignored: could not match 'vector<type-parameter-0-0>' against 'float *'
bool foo(int64_t m, int64_t n, const std::vector<fp>& A,
     ^
/home/users/me/foo.cpp:156:18: error: no matching function for call to 'foo'
            if (!foo(m, n, A,
                 ^~~~~~~~~~~~~~~~~~~~
/home/users/me/foo.hpp:242:6: note: candidate template ignored: could not match 'vector<type-parameter-0-0>' against 'double *'
bool foo(int64_t m, int64_t n, const std::vector<fp>& A,
     ^

Then :cfile loads the the quickfix list as expected, and I'm able to add/delete/change items with getqflist() and setqflist(). In particular I can add items with

let l:list = getqflist()
call add(l:list, {'filename' : '/somepathhere/'})
call setqflist(l:list)

However, the list returned by getqflist() does not contain any information on the filename /home/users/me/foo.cpp or /somepathhere/:

[{'lnum': 156, 'bufnr': 2, 'col': 18, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': ' error: no matching function for call to ''foo'''},
 {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': 0, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': '            if (!foo(m, n, A,'},
 {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': 0, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': '                 ^~~~~~~~~~~~~~~~~~~~'},
 {'lnum': 242, 'bufnr': 3, 'col': 6, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': ' note: candidate template ignored: could not match ''vector<type-parameter-0-0>'' against ''float *'''},
 {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': 0, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'bool foo(int64_t m, int64_t n, const std::vector<fp>& A,'},
 {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': 0, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': '     ^'},
 {'lnum': 156, 'bufnr': 2, 'col': 18, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': ' error: no matching function for call to ''foo'''},
 {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': 0, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': '            if (!foo(m, n, A,'},
 {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': 0, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': '                 ^~~~~~~~~~~~~~~~~~~~'},
 {'lnum': 242, 'bufnr': 3, 'col': 6, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': ' note: candidate template ignored: could not match ''vector<type-parameter-0-0>'' against ''double *'''},
 {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': 0, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'bool foo(int64_t m, int64_t n, const std::vector<fp>& A,'},
 {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': 0, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': '     ^'},
 {'lnum': 0, 'bufnr': 5, 'col': 0, 'pattern': '', 'valid': 0, 'vcol': 0, 'nr': 0, 'type': '', 'module': '', 'text': ''}]

getqflist({'all' : 0}) also doesn't return any filename info. My question is where did this data go, and how can I change it?

4
  • 1
    Looks like 'bufnr': 2 and 'bufnr': 3 has that information... Try :echo bufname(2) and :echo bufname(3) to see that it should match your foo.cpp and foo.hpp...
    – filbranden
    Aug 11 at 19:09
  • 1
    Oh I see now. This answers the question
    – roro
    Aug 11 at 19:17
  • Turned it into an answer. Also looked into why they don't show up in :ls output (they're unlisted) and included that information there too. Cheers!
    – filbranden
    Aug 11 at 20:04
  • I just updated it to also cover the part about changing the filenames... I hope that's good for you. Feel free to leave more comments (or edit the answer) if you think it can be made more clear.
    – filbranden
    Aug 11 at 20:15
0

All the files in the quicklist are going to be opened in Vim buffers, and getqflist() will return the number of the buffer in the 'bufnr' field.

In your example, it looks like file /home/users/me/foo.cpp is in 'bufnr': 2 and /home/users/me/foo.hpp in 'bufnr': 3.

You can use bufname(2) and bufname(3) to get the name of those buffers, which will correspond to the paths to the files.

Note that the buffers are unlisted until you actually open them (for instance, by pressing Enter over one of those lines in the quickfix), so they won't show up in :ls or :buffers, but they will show up in :ls! or :buffers! which shows all buffers including the unlisted ones.

If you want to change the names, when you call setqflist() you can pass either a 'bufnr' or a 'filename' (used when 'bufnr' is not present or invalid), so you could modify the result of getqflist() to remove the buffer number references and populate a new 'filename' and then pass it back to setqflist().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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