Is there way to show search matches in a separate window similar to Acrobat?

52 views
Skip to first unread message

Peng Yu

unread,
Aug 19, 2016, 6:36:07 PM8/19/16
to vim_use
Hi, The attached image shows what is available in Acrobat, where all
the search results will show in one window with search keyword
highlighted. This can be convenient as one can easily see the search
results across all the document and can jump to the hit easily by
clicking.

Is there something similar in vim?

Note that I found something like `g/pattern/#`. However, it only print
all the matches, but it does not allow one to select the hits and does
not highlight the hits.

--
Regards,
Peng
Screen Shot 2016-08-19 at 5.32.17 PM.png

Erik Falor

unread,
Aug 19, 2016, 7:19:24 PM8/19/16
to Peng Yu, vim_use
On Fri, Aug 19, 2016 at 05:35:48PM -0500, Peng Yu wrote:
> Hi, The attached image shows what is available in Acrobat, where all
> the search results will show in one window with search keyword
> highlighted. This can be convenient as one can easily see the search
> results across all the document and can jump to the hit easily by
> clicking.
>
> Is there something similar in vim?

You may try

:vimgrep /pattern/ % | copen

or

:lvimgrep /pattern/ % | lopen

The '%' refers to the current file. You may use * and ** to refer to
many files at once (recursively).

--
Erik Falor
Registered Linux User #445632 http://unnovative.net
signature.asc

Peng Yu

unread,
Aug 19, 2016, 9:43:12 PM8/19/16
to vim_use
On Fri, Aug 19, 2016 at 6:19 PM, Erik Falor <ewf...@gmail.com> wrote:
> On Fri, Aug 19, 2016 at 05:35:48PM -0500, Peng Yu wrote:
>> Hi, The attached image shows what is available in Acrobat, where all
>> the search results will show in one window with search keyword
>> highlighted. This can be convenient as one can easily see the search
>> results across all the document and can jump to the hit easily by
>> clicking.
>>
>> Is there something similar in vim?
>
> You may try
>
> :vimgrep /pattern/ % | copen
>
> or
>
> :lvimgrep /pattern/ % | lopen
>
> The '%' refers to the current file. You may use * and ** to refer to
> many files at once (recursively).

Thanks. Is there a way to simultaneously highlight all the matches in
the newly opened window?


--
Regards,
Peng

Ben Fritz

unread,
Aug 25, 2016, 10:13:48 AM8/25/16
to vim_use

Sorry for the drive-by post, but I threw this together because you reminded me I've wanted the same thing.

Put the following in ~/.vim/ftplugin/qf.vim:

""" begin """
function! QfHlMatch()
if exists('w:quickfix_title') && w:quickfix_title =~ 'vimgrep'
if exists('b:QF_HL_id')
call matchdelete(b:QF_HL_id)
endif
let pat = substitute(w:quickfix_title, '\v.*vimgrep\s+(.)(%(%(\1)@!.|\\@<=\1)+)\1.*', '\2', '')
let b:QF_HL_id = matchadd('IncSearch', pat)
endif
endfun

augroup QF_HL
au! * <buffer>
au WinEnter <buffer> call QfHlMatch()
augroup END

call QfHlMatch()
""" end """

It uses the quickfix window title to extract the pattern used for the search. There may be a better way to get that.

If you need help understanding what's going on in that regex, consult the :help for:

/\%(
/\@<=
/\@!

etc.

The purpose of the regex is to strip out everything before the vimgrep pattern, delimited by an arbitrary character, keep up to the first non-escaped delimiter character, and strip out everything after. I've noticed it may do weird things if you use certain weird delimiters in certain cases but it mostly seems to work. There may be a better way.

I used IncSearch rather than Search because the current line in the quickfix list is already highlighted with Search. If you have different highlighting defined for each of those you'll be able to see the match even on the current line.

Matches update whenever you enter the quickfix list window. You could use CursorHold or similar if you want it to update automatically without going to the window.

Ben Fritz

unread,
Aug 25, 2016, 10:22:26 AM8/25/16
to vim_use
On Thursday, August 25, 2016 at 9:13:48 AM UTC-5, Ben Fritz wrote:
> Put the following in ~/.vim/ftplugin/qf.vim:
>
> """ begin """
> function! QfHlMatch()
> if exists('w:quickfix_title') && w:quickfix_title =~ 'vimgrep'
> if exists('b:QF_HL_id')
> call matchdelete(b:QF_HL_id)
> endif
> let pat = substitute(w:quickfix_title, '\v.*vimgrep\s+(.)(%(%(\1)@!.|\\@<=\1)+)\1.*', '\2', '')
> let b:QF_HL_id = matchadd('IncSearch', pat)
> endif
> endfun
>

Oops, b:QF_HL_id should be w:QF_HL_id throughout.

Reply all
Reply to author
Forward
0 new messages