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.

Cutú Chiqueño
  • 855
  • 1
  • 10
  • 24
  • 1
    You need implement the "only within a visual selection" part by yourself. http://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. – Kent Jan 31 '14 at 15:43

3 Answers3

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/ %
Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
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.

Peter Rincker
  • 43,539
  • 9
  • 74
  • 101
  • 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. – Cutú Chiqueño Jan 31 '14 at 21:38
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>
Jeff
  • 1,787
  • 9
  • 14