Lucas Roberts
Lucas Roberts

Reputation: 1343

Editing every 3rd line of file in vim

I was making a templated list of methods in vim for a python project. I added lines between each method and wanted to add a pass to each method for now-until I implement the method, this will still be interpretable python code. In vim I know how to edit spatially contiguous lines of a file using :10,17s/<search regex>/<substitute>/ but after doing my edits to add empty lines between methods, I needed to insert the a pass every 3rd line. The way I found to do this used pipes and & via: :10s/<search regex>/<substitute>|13&|16& etc. I had maybe 15 of the ampersands chained together to get this to work. Is there a more succint way to get this behaviour in vim?

To address comment, here is a minimal example, in the file myfile.py I have:

def _fun1(self):


def _fun2(self):


def _fun3(self):


def _fun4(self):

...etc

On the 2nd line, the 5th line, the 8th line, etc. I want to insert pass (w/4 spaces before to keep consistent spacings), /i have this up to _fun15(self): so would like to get the behavior w/o 14 |lineNo&s chained together. Perhaps an incrementing feature w/a variable for the line numbers or some other code that creates the behavior.

Upvotes: 0

Views: 94

Answers (3)

SergioAraujo
SergioAraujo

Reputation: 11810

To put 'pass' with indentation below each function definition I would use:

:g/^def/put ='    pass'

^ ........... begining of each line
put ......... puts contents bellow

To squeeze blank lines:

:g/^$/,/./-1j 

a global command the gets from each empty line ^$
until next non-empty line minus one, performs a join command

Upvotes: 0

romainl
romainl

Reputation: 196566

Here is one possible way:

:g/def _fun/normal! opass
  • On each line matching def _fun
  • open a new line below…
  • and insert pass.

If you want to have one single line between each stub:

:g/def _fun/normal! opass^OJ^Ox
  • On each line matching def _fun
  • open a new line below…
  • insert pass
  • leave insert mode for a single command…
  • join the line below with the current line…
  • leave insert mode for a single command…
  • and remove that pesky <Space>.

Upvotes: 3

Hauleth
Hauleth

Reputation: 23566

Record a macro

qajopass<Esc>jq

Now execute it by running @a (next time you can use @@).


As @midor said it can be then used with :g command in form of:

:g/def _fun\d\+/norm @a

To execute this macro on all matching lines.

Upvotes: 2

Related Questions