Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the easiest/most elegant way to iterate over matches in a vim script/function?

Tags:

vim

I am looking for an elegant solution to (within vim script) iterate over all matches of a regular expression in a buffer. That would be something like

fu! DoSpecialThingsWithMatchedLines()

  for matched_line_no in (GetMatchedPositions("/foo\\>.*\\<bar"))
      let line = getline(matched_line_no)
      call DoItPlease(line)
  end for

endfu

Is there something like this? I am not necessarily looking for a full fledged solution, any pointer directing me into the right direction will do.

Thanks / Rene

like image 872
René Nyffenegger Avatar asked Dec 29 '22 08:12

René Nyffenegger


1 Answers

Most of the time I'd use michael's solution with :global

You can also play with filter(getline('1','$'), 'v:val =~ "foo\\>.*\\<bar"') if you really want to use :for.

Otherwise, you can simply call search() in a loop.

EDIT: 9 years later, in scripts, I'd now use map() + filter()

:call map(filter(getline('1','$'), 'v:val =~ "foo\\>.*\\<bar"'), 'DoItPlease(v:val)')

This:

  • is much faster than :for based solutions,
  • is much friendlier to debug (given Vim-script integrated debugger as of today)
  • leaves the various registers/history unchanged
like image 192
Luc Hermitte Avatar answered Jan 14 '23 12:01

Luc Hermitte