1

Let's say I have three files opened in my buffer list: file1,file2 and file3. I know that if I use the command :vimgrep /pattern/ ## I'll populate the quickfix list with the files that have the pattern that I have determined on vimgrep. Also, if I use :vimgrep /PATTERN/ ## | cfdo argdelete % | bdelete I'll close all files in buffer that are inside my quickfix list, remaining only the ones that don't match the pattern.

So far, everything is fine. However, I'd like to be able to do the opposite, to keep open all files in buffer that match a regular expression while closing the ones that don't match it. How can I do it?

7
  • If this isn't possible then using 'grepprg' with external (shell-based) grep might get you where you want to go. – B Layer Apr 25 at 0:14
  • @BLayer I see, considering that I have one list of files on my buffer list and another list of files on my quickfix list. Is it possible to get the difference between these two lists somehow? At first sight it seems like it would be simpler for me. – raylight Apr 25 at 0:34
  • grep -v show the lines that do not match the pattern... Try grep -L for the files that don't have any lines matching the pattern. (Not sure if that's enough to populate the quick fix list with it using :grep command, but maybe try that and see how far it takes you.) – filbranden Apr 25 at 3:59
  • Just out of curiosity, did you find a solution? – B Layer May 5 at 5:49
  • 1
    It can work using that method. You just have to get 'grepprg' and 'grepformat' right. I'll add an answer shortly – B Layer May 5 at 18:27
1

To recap:

  • OP wanted to populate quickfix list with buffers that DON'T match pattern given to :vimgrep.
  • I suggested that 'grepprg' could be used if :vimgrep couldn't.
  • OP revised requirements based on better understanding of quickfix: wants to DELETE those same buffers.
  • OP found a solution for the IS matching case and quickfix: :vimgrep /exp/ ## | cfdo argdelete % | bdelete
  • ...but didn't think the inverse could be done analogously.

In fact, my original suggestion is still valid even with the new goal. This is how you can do it with command-line grep and 'grepprg':

:set grepprg=grep\ -L
:set grepformat=%f
:grep PATTERN ##
:cfdo argdelete % | bdelete

The key things here are to

  1. Specify command line grep with the flag (-L) that returns names of files that DO NOT include the given pattern.
  2. Change 'grepformat' to account for grep only returning filename (%f) and not line numbers.

The rest is nearly identical to the is matching case except we use :grep instead of :vimgrep and we don't surround the pattern with delimiters (e.g. //).

I did a quick test with six buffers loaded, four of which contained text matching my pattern of choice. Ran all of the above and was left with just the other two buffers.

Update: Some feedback from @raylight (OP):

Since I work a lot with snippets on shortcuts I've adapted it for one line like

:set grepprg=grep\ -L | set grepformat=%f | grep 'expression' ## | cfdo argd % | bd

The expression seems to work better when it's around single quotes for some reason too (I've tested with a word containing ` and it didn't work without the single quotes)

4
  • Cool, that was exactly what I was looking for when I made the question... Since I work a lot with snippets on shortcuts I've adapted it for one line like :set grepprg=grep\ -L | set grepformat=%f | grep 'expression' ## | cfdo argd % | bd. The expression seems to work better when it's around single quotes for some reason too (I've tested with a word containing ` and it didn't work without the single quotes). – raylight May 5 at 18:53
  • Great! Glad it's working for you. There may be other tweaks that make further improvements. I didn't dive deep on the edge cases. :) Would you mind updating your question to match the new reality for the benefit of others who might be interested? Thanks. – B Layer May 5 at 18:57
  • 1
    You know what you might want to try? set grepprg=grep\ -L\ $*. The $* gets replaced with arguments by Vim. Probably more robust...may fix that problem with backticks/quotes. – B Layer May 5 at 19:06
  • 1
    Sure, I've edited the question to fit with the final problem that I had. About the $*, I made the change but so far it seems to be working the same for the cases that I've tested. But I'll leave it inside the snippet since it may be more robust, thanks! – raylight May 5 at 19:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.