2

For some reason I get, what I call an "uneven" output from Ack/Ag in the quickfix list window.

My project directory structure is the following:

/home/user/projects/myproject
 |
 ---- llvm-or1k
 |
 ---- clang-or1k

I did a search with Ag using the following command:

:ag --nogroup --nocolor --column -S -U BuildSchedGraph /home/user/projects/myproject

And got the following output (snippet)

...

/home/user/projects/myproject/llvm-or1k/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h|176 col 63| /// BuildSchedUnits, AddSchedEdges - Helper functions for BuildSchedGraph.

llvm-or1k/lib/CodeGen/SelectionDAG/ScheduleDAGVLIW.cpp|100 col 3| BuildSchedGraph(AA);

/home/user/projects/myproject/llvm-or1k/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp|336 col 3| BuildSchedGraph(NULL);

...

I can't understand why the first and the last "finds" have /home/user/projects/myproject prepended to the path while the second one doesn't.

This is becoming quite annoying.

Any help is appreciated.

2 Answers 2

6

Yes, it is annoying.

When Vim creates a quickfix list from the output of a program such as Ack, it creates a buffer for each file in the quickfix list using the name provided by the other program. This is often a full path name. Vim simplifies or resolves those names to relative path names upon certain events. The problem is that those names are not resolved when the quickfix list is displayed, so you see a mixture of full path names and relative path names.

There is no good solution available to users.

I have a workaround that is very much a hack, but it works for me because of the way I use Vim. That is, when I'm working on a project for which I use quickfix lists generated from programs such as cscope, I always start Vim in the top-level directory of the project and never use :cd or :lcd. It turns out that executing :cd is one of the events that causes Vim to resolve its buffer names, so I have the following in my ~/.vimrc:

au BufAdd * exe "cd" fnameescape(getcwd())

As Vim creates the quickfix list, it adds a buffer for each file. That autocommand executes :cd to the current working directory for each file added and causes the file names to be resolved. Executing :cd like that is a no-op in my case. Again, this is a hack and it has side effects depending on what you're doing, but it works for me in my situation and makes my quickfix lists more appealing. It may work for you, too.

11
  • 1
    Actually it could be fixed, by post-processing the output of ack / ag to call fnamemodify(file, ':~:.') on all filenames before feeding it back to be parsed with errorformat. This would involve replacing makeprg and make (or Make from dispatch) with system() and cgetexpr. Not really a complicated change, but it would involve a change in the philosophical approach to the problem. :)
    – lcd047
    Commented Sep 23, 2015 at 7:44
  • @garyjohn Just to make it clear for myself. I see a mixture of output because in some cases there is a certain event happening and after the event Vim resolves the path to relative. In those cases when it doesn't happen the path stays the the same. Am I correct?
    – flashburn
    Commented Sep 23, 2015 at 16:09
  • @lcd047 Will you be able to guide me through the process of using your approach, i.e fnamemodify(file, ':~:.'), etc. I know asking to help on this is a long shot but I've never done anything like this before and would greatly appreciate the help.
    – flashburn
    Commented Sep 23, 2015 at 16:13
  • @flashburn: What I observed was that when I had visited a file, so that it was in my buffer list (:ls), it would have a relative path name. Any quickfix "hits" to files already in my buffer list would appear in the quickfix list with the names used for the buffers, i.e., relative path names. Any quickfix "hits" to files not in the buffer list would be added to the buffer list (visible using :ls!; note the !) with the names as given by the program creating the list, usually full path names. So the initial difference in appearance was due to whether or not I had already opened the file.
    – garyjohn
    Commented Sep 23, 2015 at 17:20
  • 1
    I use find, ctags, gtags and grep. I use find in a script with some other filters to build lists of files for ctags and gtags, then run those programs to build their indexes. The ctags index is sorted so that Vim can use a fast binary search. I use gtags-cscope as a better cscope. I use a Vim script to make an easier interface to Vim's cscope commands. I haven't seen any advantage to using ack instead of grep. When I'm not looking for a symbol with ctags or gtags, I usually want to search every file in the project. Otherwise, I use grep's --include= option.
    – garyjohn
    Commented Sep 23, 2015 at 18:25
0

As garyjohn pointed out:

It turns out that executing :cd is one of the events that causes Vim to resolve its buffer names.

So you can use that in a simple command:

command! Copen cd / | copen

You may want to cd to a more useful directory.

You could make this automatic with QuickFixCmdPost. See :h QuickFixCmdPost-example:

au QuickfixCmdPost make cd /home/user/projects/myproject | copen

or with garyjohn's no-op method:

au QuickfixCmdPost make exe "cd" fnameescape(getcwd())

But using cwd means some paths will be relative and some absolute. Using the project root makes them all relative.

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.