One way to do it would be to:
- use
:args
to populate the arglist with all the files in which you're interested
- use
search()
to check whether your pattern can be found in each file, and if it does not, add its path to a list
- give that list to
getqflist()
to transform it into a quickfix list, and invoke setqflist()
to add it onto the stack of quickfix lists
For example, if you're looking for all the files matching the glob /etc/*.conf
, but not containing the pattern network
, you could execute these 3 lines:
args /etc/*.conf
let lines = [] | sil argdo if ! search('network', 'nW') | let lines += [expand('%:p')] | endif
call setqflist(getqflist({'lines': lines, 'efm': '%f'}).items) | cw
To make this easier, you could wrap the code inside a function and call it from a custom Ex command:
com -nargs=* Vimgrepv call s:vimgrepv(<q-args>)
fu s:vimgrepv(args) abort
let usage =<< trim END
Vimgrepv /some pattern/ file ...
Vimgrepv pattern file ...
END
let pat = '^\(\i\@!.\)\(.\{-}\)\1\s\+\(.*\)'
let g = [2, 3]
if match(a:args, pat) == -1
let pat = '\(\S\+\)\s\+\(.*\)'
let g = [1, 2]
endif
try
let [pat, files] = matchlist(a:args, pat)[g[0]:g[1]]
catch /^Vim\%((\a\+)\)\=:E688:/
echo join(usage, "\n") | return
endtry
arglocal | let curbuf = bufnr('%')
exe 'args '..files
let lines = []
sil argdo if ! search(pat, 'nW') | let lines += [expand('%:p')] | endif
argglobal | exe 'b '..curbuf
call setqflist(getqflist({'lines': lines, 'efm': '%f'}).items) | cw
call setqflist([], 'a', {'title': printf('files in %s NOT containing %s', files, pat)})
endfu
It installs the custom command Vimgrepv
, which you could use like this:
:Vimgrepv /some pattern/ file ...
or like this:
:Vimgrepv pattern file ...
For more info, see:
:h :args
:h :argdo
:h search()
:h getqflist()
:h setqflist()
:vglobal
andsetqflist()