4

I would like to search for some pattern with :vimgrep in the current directory:

:vimgrep /pattern/ *

However this returns the results by filenames ordered alphabetically.

If I run :vimgrepadd the results for the current file get duplicated:

:vimgrep /pattern/ %
:vimgrepadd /pattern/ *

How can I change this so that results from the current file are always on top and not duplicated?

4

You can sort the resulting quickfix list to give priority to current buffer, then run uniq() on it. Sadly you need to handle sorting quickfix items almost completely. For example the following will sort the results by buffer, then by line, then column, then text. If you need more precise sorting you can add more fields (see :h getqflist() to see what's available):

function! s:CmpQf(a, b) abort
    if a:a.bufnr == a:b.bufnr
        if a:a.lnum == a:b.lnum
            if a:a.col == a:b.col
                if a:a.text ==# a:b.text
                    return 0
                else
                    return a:a.text < a:b.text ? -1 : 1
                endif
            else
                return a:a.col < a:b.col ? -1 : 1
            endif
        else
            return a:a.lnum < a:b.lnum ? -1 : 1
        endif
    else
        return bufname(a:a.bufnr) <=# bufname(a:b.bufnr) ? -1 : 1
    endif
endfunction

function! s:SortQf(a, b) abort
    let buf = bufnr('')
    if a:a.bufnr == buf
        return a:b.bufnr == buf ? s:CmpQf(a:a, a:b) : -1
    else
        return a:b.bufnr == buf ? 1 : s:CmpQf(a:a, a:b)
    endif
endfunction

call setqflist(uniq(sort(getqflist(), '<SID>SortQf')), 'r')

Save this to a file, run your queries, and the source the file:

:vimgrep /pattern/ %
:vimgrepadd /pattern/ *
...
:so ~/qfdedupe.vim
:copen

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.