The reason the pipe isn't functioning like you'd expect is because you're not grepping through the shell, you're grepping through Vim (see digression). For instance, this would be using your shell from Vim to perform your search:
:!grep -R 'color:' . | grep -v '@'
! at the beginning, which means "execute this command from the shell" (see
:h :!). This doesn't help your underlying problem, however, because your shell's end result won't go the quickfix list. This simply executes the whole command at the shell, lets you see it, and returns you to Vim.
Your fastest solution might be to employ grep's
--exclude (note: see EDIT below):
:grep -R --exclude='*@*' 'color:' .
:grep is different from
:!grep in that Vim is using a file pattern searcher of your choice as an Ex command within Vim, not the shell. The
grepprg option indicates which file pattern searcher to use (use
:set grepprg? to see what's currently set). If you have
set grepprg=grep\ -nH in your
.vimrc, for instance, then
:grep will indeed use
grepprg is set to
internal, however, then
:grep will use
:vimgrep instead, which will require a Vim search pattern. (You might be familiar with the Vim search pattern from using
:h :grep and
:h :vimgrep for details. Also, if you like ack or ag, you can set
grepprg to tell
:grep to use them instead of regular grep or vimgrep.
@the_velour_fog Thanks for correcting me by pointing out that grep's
--exclude is excluding files to grep, rather than omitting lines that otherwise match grep's search pattern.
One solution is to use Vim script's
setqflist() to pass searches to the existing quickfix list and populate a new one. See Kent's Stack Overflow answer and resulting QFGrep on GitHub. With this script, you can perform your first grep/ack like normal, then use the following actions:
<Leader>g input pattern to do further filtering
<Leader>v input pattern to do further inverted filtering (like grep -v)
<Leader>r restore the Quickfix/location-list with original entries