Skip to content

Instantly share code, notes, and snippets.

@PeterRincker
Last active February 28, 2019 19:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save PeterRincker/33345cf7fdeb9038611e4a338a0067f3 to your computer and use it in GitHub Desktop.
Save PeterRincker/33345cf7fdeb9038611e4a338a0067f3 to your computer and use it in GitHub Desktop.
Filter the quickfix list
" :Cfilter[!] /{pat}/
" :Cfilter[!] {pat}
" Filter the quickfix looking for pattern, `{pat}`. The pattern can match the filename or text.
" Providing `!` will invert the match (just like `grep -v`).
" Note: :cfilter command abbreviation is provided for convenience
"
" :Lfilter[!] /{pat}/
" :Lfilter[!] {pat}
" Same as :Cfilter but use the location list.
" Note: :lfilter command abbreviation is provided for convenience
" :Cfilter
function! s:cfilter(prefix, list, bang, pat)
let pat = a:pat =~ '^\([/''"]\).*\1$' ? a:pat[1:-2] : a:pat
let pat = pat == '' ? @/ : pat
let Id = {v -> v}
let keys = {'bufnr': {v -> bufname(v)}, 'module': Id, 'text': Id}
let args = a:list =~ 'loc' ? ['.'] : []
let GetList = function('get' . a:list . 'list', args)
let SetList = function('set' . a:list . 'list', args)
let Cmp = {k,v -> has_key(keys, k) && call(keys[k], [v]) =~ pat}
let Bang = a:bang == '!' ? {cnt -> cnt == 0} : {cnt -> cnt > 0}
let title = get(call(GetList, [{'title': 1}]), 'title', '')
let title = title . '|' . a:prefix . 'filter' . a:bang . ' ' . a:pat
let entries = call(GetList, [])
let entries = filter(entries, {_,dict-> call(Bang, [len(filter(copy(dict), Cmp))])})
let cnt = len(entries)
call call(SetList, [entries])
call call(SetList, [[], 'a', {'title': title}])
echo 'Filtered list: ' . (a:bang ? 'not ' : '') . 'matching ' . a:pat . ' (' . cnt .' items)'
endfunction
command! -nargs=1 -bang Cfilter call <SID>cfilter('C', 'qf', '<bang>', <q-args>)
command! -nargs=1 -bang Lfilter call <SID>cfilter('L', 'loc', '<bang>', <q-args>)
function! s:exabbrev(lhs, ...)
let rhs = substitute(join(a:000, ' '), "'", "''", 'g')
execute 'cnoreabbrev <expr> ' . a:lhs . ' getcmdtype() == ":" && getcmdline() ==# "' . a:lhs . '" ? expand(''' . rhs . ''') : "' . a:lhs . '"'
endfunction
if !exists(':cfilter')
call s:exabbrev('cfilter', 'Cfilter')
endif
if !exists(':lfilter')
call s:exabbrev('lfilter', 'Lfilter')
endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment