1" cfilter.vim: Plugin to filter entries from a quickfix/location list
2" Last Change: Aug 23, 2018
3" Maintainer: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
4" Version: 1.1
5"
6" Commands to filter the quickfix list:
7"   :Cfilter[!] /{pat}/
8"       Create a new quickfix list from entries matching {pat} in the current
9"       quickfix list. Both the file name and the text of the entries are
10"       matched against {pat}. If ! is supplied, then entries not matching
11"       {pat} are used. The pattern can be optionally enclosed using one of
12"       the following characters: ', ", /. If the pattern is empty, then the
13"       last used search pattern is used.
14"   :Lfilter[!] /{pat}/
15"       Same as :Cfilter but operates on the current location list.
16"
17if exists("loaded_cfilter")
18    finish
19endif
20let loaded_cfilter = 1
21
22func s:Qf_filter(qf, searchpat, bang)
23    if a:qf
24	let Xgetlist = function('getqflist')
25	let Xsetlist = function('setqflist')
26	let cmd = ':Cfilter' . a:bang
27    else
28	let Xgetlist = function('getloclist', [0])
29	let Xsetlist = function('setloclist', [0])
30	let cmd = ':Lfilter' . a:bang
31    endif
32
33    let firstchar = a:searchpat[0]
34    let lastchar = a:searchpat[-1:]
35    if firstchar == lastchar &&
36		\ (firstchar == '/' || firstchar == '"' || firstchar == "'")
37	let pat = a:searchpat[1:-2]
38	if pat == ''
39	    " Use the last search pattern
40	    let pat = @/
41	endif
42    else
43	let pat = a:searchpat
44    endif
45
46    if pat == ''
47	return
48    endif
49
50    if a:bang == '!'
51	let cond = 'v:val.text !~# pat && bufname(v:val.bufnr) !~# pat'
52    else
53	let cond = 'v:val.text =~# pat || bufname(v:val.bufnr) =~# pat'
54    endif
55
56    let items = filter(Xgetlist(), cond)
57    let title = cmd . ' /' . pat . '/'
58    call Xsetlist([], ' ', {'title' : title, 'items' : items})
59endfunc
60
61com! -nargs=+ -bang Cfilter call s:Qf_filter(1, <q-args>, <q-bang>)
62com! -nargs=+ -bang Lfilter call s:Qf_filter(0, <q-args>, <q-bang>)
63