I had a recent refactor which was basically "take a 5-argument function call split over many lines and replace it with a different 1-argument call". I made a macro that found the code block I wanted, edited it to the desired syntax, saved the file, and opened the next file in the list I had opened. I opened vim for this occasion with `vim $(ag -l STRING_IN_REFACTORED_CODE)`, which used search results as a list of files to open with vim.
The most fun vim macro I've made solved a "solve this puzzle before we want to interview you" question. The problem was a URL to request that gave you a response to parse into the next URL, chained about 100 times. The vim macro took the URL in the current line, shelled out to make a network request for the result of `curl` with that line as an argument, and edited the result into the next URL to fetch.
A very common thing that happens to me is that I have to take big blocks of JSON, and map all the keys and values into something else, like HTML or CSV.
Without macros, this traditionally involves a lot of copy-paste-change-stuff repetition.
With a Vim macro, I can happily just do this once, assign it to a register, and repeat as needed, and even store it for later reuse if I want.
There are also, littler things, like jumping between HTML tags, or bulk-indents.
What makes Vim's macros better (in my opinion) that other editor's macros is that fact that they're simply stored in copy-paste registers, meaning that you can have many of them, store in a different file, copy them off the internet, or compose them together.
Not op but here they are really handy for creating and formatting repetitive code blocks. I find it particular useful when making testing\throwaway code.
For example, I may be testing a function and wanting to test a few scenarios on many IDs. So I will create a csv list of numbers and then use a macro to format it
your csv string will be like this (normally much longer)
134,234,367,4345
Then record the macro:
- type "myFunction("
- type ctrl + right arrow (this moves the cursor to after the comma)
- type backspace
- type ");"
- type enter key
then run stop recording and run the macro. It will produce:
myFunction(134);
myFunction(234);
myFunction(367);
myFunction(4345);
Which doesn't seem like a big time saver over regular copy and pasting. And you could have iterated over the csv string with a for loop. This is probably a really contrived and basic example but you find yourself thinking about using a macro anytime you have to do the same keystrokes over and over.
My favorite use of macros is as a sort of progressive global search and replace on steroids. I have @q bound to Space, so I can record a macro with qq, then hit space to repeat. Since the macro is just a list of commands in a register I can copy it out and edit it to tweak it, once I'm happy with it over a few lines I can make it recursive by adding @q to the end of it.
Compared to regex search and replace this is much more malleable, interactive, and ultimately powerful.
It's worth remembering that . (i.e. dot) repeats the last edit command. vim-repeat ( https://github.com/tpope/vim-repeat ) makes this even better.
Although, there are still several situations where macros are better, especially things that involve several motions and edits. (I tend to use qw because w is more convenient to hit after @).
Also, it's occasionally useful to remember that you can use the double quote character " to paste a macro, edit it and then update it. i.e. ( "ep .... edit ... ^"ed$ )
Also, vim-surround is one of those things that, once you've used it for a while, it's impossible to think of editing text without it: https://github.com/tpope/vim-surround
Somewhere between the default and your binding: @@ repeats the last macro. So you can record your macro, go to your search text, @q, n, then for all subsequent matches @@.
A common one is "here's an excel file, can you put these entries in the database". With macros it's easy to do a really complex transform of a line and then repeat it for every line.
Or the reverse, someone wants a report from some database in some specific format for whatever reason. It's often easier to do a simply query and vim the output rather than use the string functions of the DB.