0

To my .vimrc I added a hook which automates entering the quickfix after :grep processing:

autocmd QuickFixCmdPost [^l]* nested cwindow 20

Another thing I care about but can't achieve is automation of applying highlight/color of all found occurrences while being in the quickfix. What I observed, it's really easy to do manually:

/pattern

by re-typing the same pattern which went to the :grep we will get all occurrences highlighted in all of the files referenced by the quickfix.

Is it possible to program it so that vim will know the grep's matches (or at least the pattern passed) and automatically perform the /pattern search command after :cwindow is executed - or perform any other method to apply that highlight?


UPDATE

Assuming we can deliver a custom command for :grep in .vimrc, like:

command! -nargs=+ G execute "grep -rIn <args> ."

now the pattern itself is provided by the means of a custom command which might be helpful(?).

I admit I'm not a good vim programmer. Can it all be somehow chained together (as another autocmd/function and preserving the effect of cwindow hook) to get that highlight to be applied?

  • This won't be easy, as the regex expressions of grep are different from Vims. – Ralf May 2 at 6:11
2

Option 1 Hack

A hack... you could get the title of the quickfix window, and then strip off the parts that arent the search term:

    let pattern = getqflist({'title' : 0}).title
    let pattern = strip_off_not_search_parts(pattern)

And then add a match with:

    call clearmatches()
    silent call matchadd('Search', pattern) " Hi group / pattern

I have found it hard to get the search highlighting as if you typed it, you could try feedkeys() but I had little joy with it.

Option 2 Wrapper

You are going to want to improve it as time passes by :) I recommend vim the hardway, and :help input

function! GrepWithHighlight()
    let searchString = input("Input search string: ")
    if searchString == '' || searchString == '\n'
        echom "Aborted Search."
        return
    endif
    exe 'vimgrep /'.searchString.'/ **/*'
    " Open the quickfix window first so match applies to it
    copen
    call clearmatches()
    silent call matchadd('Search', searchString) " Hi group / pattern
endfunction
noremap <leader>v :call GrepWithHighlight()<Cr>
| improve this answer | |
  • Thanks. And how to chain it all together with my hook to get these instructions executed (I'm not good at vim programming I admit)? Does this involve another autocmd/function? I'd appreciate some minimal aggregated example. – bloody May 2 at 8:10
  • Please also look at my question's update. Perhaps we don't have to "hack" it from the quickfix title. Can it be somehow crafted taking advantage of input at higher level? – bloody May 2 at 8:42
  • It was late, my wife was calling me to bed, hence i didnt flesh out the 1st option completely last night, and was such a hack didnt seem worth completing. If you okay with a wrapper, see option2 I added. – run_the_race May 2 at 9:04
  • Your function works perfectly. I let myself inject grep instead of vimgrep after all because it's much faster and the highlight works equally fine as well. Thank you very much! – bloody May 2 at 14:45
1

After experiments I have observed that matchadd() proposed by run_the_race highlights occurrences only in the quickfix window but not in the window with file buffers which would be even more desirable. We could apply matchadd() twice (before copen and after) but this method has side-effects while applying to files anyway (e.g. clearmatches() also clears existing custom matches).

For above reasons I tried to replace matchadd() with regular search highlight (managed by hlsearch and the search register) but this is impossible to achieve within a function, what :h function-search-undo clearly states. Therefore I figured out slightly different solution (seems even simpler by occasion):

autocmd QuickFixCmdPost * nested cwindow 20 | redraw!
command! -nargs=+ Grep execute "let @/ = '<args>' | set hlsearch | silent grep -rI <args> ."
noremap <leader>g :Grep<space>

redraw! prevents weird artifacts when drawing quickfix over quickfix or grep returns no results. let @/ = and hl search take care about populating the search register and triggering the highlight itself. silent avoids a need of pressing Enter after shell processing. Of course one can add custom "must be" options between grep and <args> strings, like:

--exclude=tags --exclude-dir=build --exclude-dir=.git

It's most ergonomic and robust highlighted grep I could reach (keeping in mind that some REGEX inconsistencies between grep and vim may diverge the highlight effect, for that one can use vimgrep which is unacceptably slow).

| improve this answer | |
  • 1
    Glad you found a solution you are happy with.. "matchadd()... highlights occurrences only in file buffers but not in quickfix items": I use matchadd to highlight the quickfix window, so I don't quite understand? (I use it in a wrapper around ripgrep). A benefits of using matchadd is as one works through the QF entries, one may be doing incsearches, but with matchadd the search terms remain highlighted in the QF window (matchadd is window local, and hence clearmatches() only changed the QF window). One can use :cn and :cp (or vim-unimpaired [q or ]q) to jump between QF matches. – run_the_race May 4 at 21:26
  • @run_the_race [1] You're right, I'm sorry for inaccuracy, I have edited my answer to make it truthful (I tested different variations and I accidentally referred not to your original code). The thing is that I cared both about "in-files" highlight and in quickfix what I expressed in my question by "(...) we will get all occurrences highlighted in all of the files referenced by the quickfix". – bloody May 5 at 9:04
  • 1
    @run_the_race [2] And a few versions of matchadd which I tried ultimately proved less likeable (it would be then even cool to may use n/N in files, although I perfectly understand your assumption with "only quickfix highlight" - and then have it independent from hlsearch - but not quite in aggregated solution if you know what I mean + this "global" clearmatches issue). Anyway I appreciate your answer not less, it was a driving force behind. The upvote fully deserved. – bloody May 5 at 9:16
  • I like you idea about incsearch too, so will incorporate both ways (hlsearch and matchadd) into my search, giving what I feel the best of both. – run_the_race May 6 at 13:09
  • @run_the_race Oh, I haven't even thought about this. I must check this combination out too:) Thanks. – bloody May 7 at 17:02

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.