Automatically sort Quickfix list
Talk0this wiki
created 2009 · complexity basic · author EUEU · version 7.0
After running a cscope command, you may have duplicate entries in your quickfix list, for instance when a header file is shared by multiple projects. This tip shows how to sort the quickfix list by file name and line number, and remove duplicates.
Script
Edit
Create file ~/.vim/plugin/quickfix.vim (Unix) or $HOME/vimfiles/plugin/quickfix.vim (Windows) containing the script below, then restart Vim. After a quickfix command such as :grep is run, the script will automatically be invoked by the QuickfixCmdPost event, and the quickfix list will be sorted by file name and line number, and duplicates will be removed.
function! s:CompareQuickfixEntries(i1, i2)
if bufname(a:i1.bufnr) == bufname(a:i2.bufnr)
return a:i1.lnum == a:i2.lnum ? 0 : (a:i1.lnum < a:i2.lnum ? -1 : 1)
else
return bufname(a:i1.bufnr) < bufname(a:i2.bufnr) ? -1 : 1
endif
endfunction
function! s:SortUniqQFList()
let sortedList = sort(getqflist(), 's:CompareQuickfixEntries')
let uniqedList = []
let last = ''
for item in sortedList
let this = bufname(item.bufnr) . "\t" . item.lnum
if this !=# last
call add(uniqedList, item)
let last = this
endif
endfor
call setqflist(uniqedList)
endfunction
autocmd! QuickfixCmdPost * call s:SortUniqQFList()
Original script
Edit
TO DO
- Following is the original code. I am fairly confident that the version shown above is equivalent, but I'm keeping the original code for a while in the hope it will get more checking.
- I do not undertand how two buffers could have the same name while having different buffer numbers (buffer names seem to be unique). I would therefore think that '
bufname()' could be omitted so the tests simply check buffer numbers, rather than buffer names. JohnBeckett 12:07, May 13, 2010 (UTC)
- As far as I can remember I had problems with duplicated entries in my quickfix list because on Ms Windows some file would appear with both 8.3 short names and long name in wy quickfix list as a result of a CScope command. This is why I did that but I am not sure whether this is really required.EUEU 16:06, May 18, 2010 (UTC)
function! <SID>CompareQuickfixEntries(i1, i2)
if bufname((a:i1).bufnr) == bufname((a:i2).bufnr)
return (a:i1).lnum == (a:i2).lnum ? 0 : ( (a:i1).lnum < (a:i2).lnum ? -1 : 1)
elseif bufname((a:i1).bufnr) < bufname((a:i2).bufnr)
return -1
else
return 1
endif
endfunction
function! SortUniqQFList()
let s:sortedList = sort(getqflist(), "<SID>CompareQuickfixEntries")
let s:uniqedList = []
let s:olditem = {}
for s:item in s:sortedList
if s:olditem == {}
let s:uniqedList += [s:item]
elseif bufname((s:item).bufnr) != bufname((s:olditem).bufnr)
let s:uniqedList += [s:item]
elseif (s:item).lnum != (s:olditem).lnum
let s:uniqedList += [s:item]
endif
let s:olditem = s:item
endfor
call setqflist(s:uniqedList)
endfunction
au QuickfixCmdPost * call SortUniqQFList()
Comments
Edit
Possibly bufname() could be omitted from each expression like bufname(a:i1.bufnr) because buffer names are unique, except that more than one buffer can have an empty name. Also should contemplate Windows systems where buffer names (like file names) are not case sensitive. Using == to compare two names is either case sensitive or not, depending on the setting of 'ignorecase'. JohnBeckett 05:01, May 15, 2010 (UTC)