Tuesday, June 2, 2020

Re: changing pathnames in quickfix list

On Tue, May 12, 2020 at 09:02:57AM -0700, duvall@comfychair.org wrote:

> I have a Makefile rule that builds some go packages in a directory a few levels
> down from the current directory:
>
> cd down/down/down && $(GO) build $(GO_BUILD_FLAGS) -o ../../../../$(@) $*
>
> When I run :make, it builds as expected, but if I have an error, then I get
> something like
>
> # dir1/dir2/pkg
> dir2/pkg/foo.go:53:16: undefined: "github.com/pkg/errors".Wrrapf
>
> The quickfix list loads "dir2/pkg/foo.go", which doesn't exist: the file is
> actually at "down/down/down/dir2/pkg/foo.go".
>
> Is there a way to get the right information into the quickfix list?
>
> I tried adding "%Dcd\ %f\ " to 'errorformat', relying on the "missing leave
> directory" heuristics to figure the rest out, but that didn't seem to work.
>
> I could write a function for QuickFixCmdPost that would look at each buffer,
> grab its name, and if the name didn't exist, load the real file into a buffer,
> change the list, and wipeout the incorrect buffer, but a) it's a lot of work,
> and b) we end up loading a lot of buffers for bogus files.
>
> I feel like there's got to be a way to intercept the quickfix list before vim
> has parsed it, or at least before it's created buffers for the files with
> errors. Is there? Should there be?

After patch 0869 came out, implementing 'quickfixtextfunc', I thought perhaps
that would be the answer I was looking for. Alas, it seems to be useful only to
manipulate the text of the quickfix window, not the list loaded by :make. But
it got me looking at this again, and I decided to give the QuickFixCmdPost
solution a shot. It was easier than I thought, even though it doesn't work
quite right:

function! FixQuickFix()
let qflist = getqflist()
for i in qflist
let fname = buffer_name(i.bufnr)
if fname =~ "\.go$"
let fname = "down/down/down/" . fname
let i.bufnr = bufadd(fname)
" call bufload(i.bufnr)
" call setbufvar(i.bufnr, "&buflisted", 1)
endif
endfor
call setqflist(qflist, 'r')
endfunction

I run :make, and the build runs, and fails as expected, but vim doesn't switch
to the buffer with the file containing the first error. I get a "Press ENTER or
type command to continue" message after the make completes, and then a second
one after showing me the first line of the output (not the first error), but
then it just leaves me in the buffer I was originally in.

:clist is what I expect:

17 down/down/down/pkg/foo.go:503 col 14: undefined: tst
18 Makefile:981: recipe for target 'bin/foo' failed

and :cnext takes me to that first error, but it's not done automatically.

The "too many buffers loaded" problem is definitely here:

:ls!
1 %a "Makefile" line 6
2u "pkg/foo.go" line 0
3u "down/down/down/pkg/foo.go" line 0
4u h- "[Quickfix List]" line 19

Makefile was my original buffer. You can see that two buffers exist for the
file where the problem occurred: one prior to the edit made by FixQuickFix(),
and one after.

If I uncomment the setbufvar() line, it definitely ends up listed, and if I call
bufload(), then the buffer is definitely loaded (complaints about an existing
swapfile, if it's open in another vim), but neither one nor both together give
me the behavior I'm expecting. I can put "cnext" at the end of it (not
requiring either of the bufload() or setbufvar() calls), and that works, but
then I don't know of any way to distinguish between :make and :make!.

Is there anything else I can do without extra support from vim?

Thanks,
Danek

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/20200602170807.GA17747%40comfychair.org.

No comments: