Is it possible to use vimgrep for a visual selection of the current file?
Asked Answered
L

3

5

I would like to search with vimgrep only within a visual selection of the current file and not the whole file. Is that possible and how? I couldn't find something for this case with Google or in vim help.

The reason why I want this is because I need the result in the quicklist (copen) and :g/FOO which is showing the matching lines at the bottom is not doing this job.

Lithea answered 31/1, 2014 at 15:34 Comment(1)
You need implement the "only within a visual selection" part by yourself. vim.wikia.com/wiki/Search_using_quickfix_to_list_occurrences here you can find how to search pattern in current file and put in qflist. what you could do is writing a wrapper function, save the range of the '< and '>, after qflist was filled, you filter the entries, remove the entries outside the selection range. I think it won't be too complicated.Elanorelapid
A
7

Yes, you can, as Vim has special regular expression atoms for mark positions, and the start and end of the visual selection is marked by '< and '>. As there are atoms for on / before / after a mark, we need to combine those to cover the entire range of selected lines:

On the selection start | after the selection start and before the selection end | on the selection end.

To limit the search to the current file, the special % keyword is used.

:vimgrep/\%(\%'<\|\%>'<\%<'>\|\%'>\)FOO/ %
Aureomycin answered 31/1, 2014 at 16:9 Comment(1)
thanks, it was exactly I was looking for and very well described so I understand the logic behind it.Mccartan
L
4

You are on the right path with using :g command. The basic idea is do something like this:

:g/FOO/caddexpr expand("%") . ":" . line(".") .  ":" . getline(".")

Now lets make it a command

command! -range -nargs=+ VisualSeach cgetexpr []|<line1>,<line2>g/<args>/caddexpr expand("%") . ":" . line(".") .  ":" . getline(".")

Now you can do :VisualSearch FOO and it will add the searches to the quickfix list.

Note that the issue w/ this is only finds one match per line.

Leakey answered 31/1, 2014 at 18:21 Comment(1)
thx a lot, it does the job, although I slightly prefer the solution of @Ingo as it less scripting and more worked out within the logic of vimgrep. Still thanks.Mccartan
M
2

This is from Steve Losh's vimrc. It makes * work on the visual selection. I've gotten pretty dependent on it.

" Visual Mode */# from Scrooloose {{{
function! s:VSetSearch()
let temp = @@
norm! gvy
let @/ = '\V' . substitute(escape(@@, '\'), '\n', '\\n', 'g')
let @@ = temp
endfunction

vnoremap * :<C-u>call <SID>VSetSearch()<CR>//<CR><c-o>
vnoremap # :<C-u>call <SID>VSetSearch()<CR>??<CR><c-o>
Mcclendon answered 31/1, 2014 at 16:55 Comment(1)
Edited to include the vnoremapsMcclendon

© 2022 - 2024 — McMap. All rights reserved.