In Vim, how do I apply a macro to a set of lines?
Asked Answered
P

4

296

I have a file with a bunch of lines. I have recorded a macro that performs an operation on a single line. I want to repeat that macro on all of the remaining lines in the file. Is there a quick way to do this?

I tried Ctrl+Q, highlighted a set of lines, and pressed @@, but that didn't seem to do the trick.

Pontianak answered 23/12, 2008 at 21:51 Comment(3)
Offtopic question: I wasn't aware of VIM macros ( or didn't wanted to be aware :P ) Do you have some nice "lazy reader" oriented link on VIM macros?Zap
Sure, this: oreillynet.com/mac/blog/2006/07/… sums it up pretty well.Pontianak
You can also check :he complex-repeat from inside vimExsect
E
493

Use the normal command in Ex mode to execute the macro on multiple/all lines:

Execute the macro stored in register a on lines 5 through 10.

:5,10norm! @a

Execute the macro stored in register a on lines 5 through the end of the file.

:5,$norm! @a

Execute the macro stored in register a on all lines.

:%norm! @a

Execute the macro store in register a on all lines matching pattern.

:g/pattern/norm! @a

To execute the macro on visually selected lines, press V and the j or k until the desired region is selected. Then type :norm! @a and observe the that following input line is shown.

:'<,'>norm! @a

Enter :help normal in vim to read more.

Euonymus answered 23/12, 2008 at 22:2 Comment(11)
Adding a : first doesn't allow me to use @Pontianak
Yes it does. You type the whole thing on the line and then press enter.Euonymus
Ah, it was the norm! part that I was missing.Pontianak
Yes, :help normal in vim or the link I just added.Euonymus
Anything to help a fellow non-emacs user!Euonymus
Nice!! Beginner tip: use V then j/k to highlight the lines you want, then type just :norm! @aOrnithine
To add to the very helpful tip from @KevinBourrillion, when pressing : after highlighting the lines, the Ex input line will instead read :'<,'> to which you will then add rest of what Kevin suggested. This will make the final command read: :'<,'>norm! @a.Cuticula
I do not understand why the ! is necessary at the end; other norm usages do not require it.Sterrett
@GabeMoothart The ! avoids user remapping of keys. You may not need it, but an answer that works for everyone requires it.Euonymus
In emacs evil mode I get this error /bin/bash: @a: command not found. It works when I remove the !Sunglasses
Great examples. Run the macro up to a certain pattern? e.g. macro searches for "public class" and then I tell it to run to the next "^}" (end of class)? E.g. I need to renumber all the ProtoMember(id) numbers within a class and restart counter with each class.Gunpoint
G
66

Use global to run the macro 'a' on all lines that contain 'pattern'

:g/pattern/normal! @a

For help, check: :help global.

Gob answered 13/3, 2011 at 22:19 Comment(1)
Just for clarification for future users: this a global Ex command.Aerograph
R
55

You can also do this:

In normal mode:

[number of times to apply the macro] @ [register]

For example:

1000@q

Apply the macro in register q to the next 1000 lines.

Update: the accepted answer is a lot better

Update: as @kevinliu pointed out, you likely want to end the macro with a j to go to the next line.

Represent answered 3/1, 2014 at 22:26 Comment(6)
This stops on the last line, and doesn't execute multiple time on the last line, which I was afraid of.Spirit
@Hubro, these answers from other users worked for me: :%norm! @a and vGG :norm! @aRepresent
For some reason, this worked awesomely, and the accepted answer didn't. My macro involved inserting a new line, doing stuff, and moving to the next line.Gazelle
@jasonszhao yes same here. but is there anyway to not say 1000 but all lines till end.. and still take care of the new line, doing stuff, etc.Vergievergil
I think it should be pointed out that your macro must end with a j command to go down to the next line otherwise it will try to apply it to the same line.Totalizer
@KevinLiu that is the important part, the author failed to point out in the first place.Am‚lie
H
2

There's also a plugin called RangeMacro, does exactly what you want! For everyone that can't guess by the name, what it does: it repeats a recorded macro for each line in a given range, no matter if by visual selection or by a :40,50 / :+10

See http://www.vim.org/scripts/script.php?script_id=3271

Hutchins answered 13/3, 2011 at 18:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.