How to use VIM to combine the power of macros and regex

vim

Solution

I haven't learned all the new-fangled vim-only features; I learned vi before vim and this solution will work in any vi-ish editor. There might be an even better solution using vim features, perhaps.

What I would usually do in this case is use the `:map` command to bind several keys, each one doing part of the above. You need to pick some keys you can live without for a while; I often use `g` and `v` for this. @Neil Forrester suggested using function keys, which is a great idea.

Now, you showed regular expression patterns with parens indicating a match group. (In vi or vim, you actually need to put a backslash before each paren to make it "magic"; see the documentation.) For this solution, however, I am instead going to use the `f` command, which (f)inds a specified character; and/or the `t` command, which jumps un(t)il a character. `f` jumps up to a character, where `t` jumps just before a character. So, with `f"` we can jump to the first double-quote of a string, and then using `t"` we can jump until just before the second double quote. So, the sequence `f"lyt"` would find the first double-quote, move one char to the right, then yank everything until the next double quote. But, let's store the yanked text into one of the 26 named buffers; let's just use buffer "a": `f"l"ayt"` This is a little bit confusing, because we must use `"a` to refer to named buffer "a" but we have lots of other `"` characters that we are looking for.

Also, within a "map" you may need to record a keystroke for the Enter key. The way you do that is to hit Ctrl+V, then hit the Enter key. This will display as `^M`. In my code below, if you see `^M` it is not intended to mean an actual `^` followed by an actual `M` but rather a single key that represents the Enter key.

So now, we can make our two key mappings. Let's bind `v` to do steps 1 and 2, and `g` to do steps 3 and 4.

:map v /^Description "/^Mf"l"ayt"

:map g /^TEXT "/^Mf"ldt""aP

Don't forget, use Ctrl+V and Enter rather than actually typing ^M, so you can't just copy/paste the above without editing it.

Now, use the `v` key to do steps 1 and 2, and the `g` key to do steps 3 and 4. By alternately hitting the two keys you can do a lot pretty quick.

There might also be a way to do this by using scripting in vim, but on the other hand, you might just want to write a short Python script (or your favorite language) if you want to script this. The two key macros, above, really do provide a fast way to do this sort of thing in vim.

vim has some sort of feature for recording keys as you type them, which I think can be used to quickly create this sort of macro.

Problem

I find my myself frequently with a problems that need to combine regular expressions, some kind of movement, and copying and pasting. I'm sure there is some way to do this in vim but I haven't seen anything bringing it all together. As an example right now the problem I am trying to solve is like this. - Find a line that is /^Description "(.*)"/ - Save the captured text - Go to the line that is /^TEXT "(.*)-/ - Replace the captured text above with the captured text from step 2 - Repeat as necessary moving forward through the file Does anyone know of a way to quickly automate this type of task in VIM?

Original source