What I'd like to do is "add a column" to the quickfix list that displays that "type" (so, for @CHECK it would be CHECK, and so on)
An input file and the desired quickfix window would have helped, but try to source this code:
com -bar QfTodo call s:qf_todo()
fu s:qf_todo() abort
sil vim /@\u\+/gj %
let curfile = expand('%:p')
call setqflist([], 'r', #{
\ lines : getqflist()->map('curfile .. "|" .. v:val.lnum .. " " .. v:val.col .. "|" .. v:val.text'),
\ efm : '%f|%l %c|%m',
\ quickfixtextfunc : 's:quickfixtextfunc',
\ })
copen
endfu
fu s:quickfixtextfunc(info) abort
if a:info.quickfix
let qfl = getqflist(#{id: a:info.id, items: 1}).items
else
let qfl = getloclist(a:info.winid, #{id: a:info.id, items: 1}).items
endif
let l = []
for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
let e = qfl[idx]
let fname = bufname(e.bufnr)->fnamemodify(':t')
let displayed = printf('%s|%d col %d|%s| %s',
\ fname,
\ e.lnum,
\ e.col,
\ matchstr(e.text, '@\zs\u\+'),
\ e.text
\ )
call add(l, displayed)
endfor
call sort(l, function('s:MySort'))
return l
endfu
fu s:MySort(i, j) abort
let s1 = split(a:i, '|')[2]
let s2 = split(a:j, '|')[2]
return s1 ==# s2 ? 0 : s1 ># s2 ? 1 : -1
endfu
It requires the patches 8.2.0869 and 8.2.0959, which provide the global option 'quickfixtextfunc'
, as well as a quickfix list attribute with the same name.
Now assuming your file is displayed in the current window, run this command to populate the quickfix list with all the lines containing an @
character followed by a sequence of uppercase alphabetic characters (like CHECK
, FIXME
, or TODO
):
:QfTodo
and to be able to filter this to keep only one "type" (so maybe keep only FIXME or only TODO).
Load the default cfilter plugin:
:packadd cfilter
Then, run this command to only keep the TODOs:
:Cfilter TODO
Or this command to only keep the FIXMEs:
:Cfilter FIXME
Or this command to only keep the CHECKs:
:Cfilter CHECK
If possible, I'd also like to sort this list alphabetically according to the type.
This should be done by the call to sort()
in the previous s:quickfixtextfunc()
function.
call sort(l, function('s:MySort'))
If you care about speed, here is the same code rewritten in Vim9 script:
vim9script
com -bar QfTodo QfTodo()
def QfTodo()
sil! vim /@\u\+/gj %
var curfile: string = expand('%:p')
setqflist([], 'r', {
lines: getqflist()
->mapnew((_, v: dict<any>): string =>
curfile .. '|' .. v.lnum .. ' ' .. v.col .. '|' .. v.text),
efm: '%f|%l %c|%m',
quickfixtextfunc: 'QuickfixTextFunc',
})
copen
enddef
def QuickfixTextFunc(info: dict<number>): list<string>
var qfl: list<any>
if info.quickfix
qfl = getqflist({id: info.id, items: 1}).items
else
qfl = getloclist(info.winid, {id: info.id, items: 1}).items
endif
var l: list<string> = []
for idx in range(info.start_idx - 1, info.end_idx - 1)
var e: dict<any> = qfl[idx]
var fname: string = bufname(e.bufnr)->fnamemodify(':t')
var displayed: string = printf('%s|%d col %d|%s| %s',
fname,
e.lnum,
e.col,
matchstr(e.text, '@\zs\u\+'),
e.text
)
add(l, displayed)
endfor
sort(l, MySort)
return l
enddef
def MySort(i: string, j: string): number
var s1: string = split(i, '|')[2]
var s2: string = split(j, '|')[2]
return s1 == s2 ? 0 : s1 > s2 ? 1 : -1
enddef
On my machine, it seems to be about twice as fast. This requires a recent Vim version. It works on 8.2.2332.
For more info, see:
vimgrep #@\u\+#j **
, which seems to do the trick for now. I guess I can write a function that searches for only one type is easy enough to do, too. The main problem here is just convenience ^^ I'd really like to find out how to get more customizable lists.