Trouble when I try to set a macro expression

Viewed 31

I have this file:

...
stuff
...

1 4 1
1 3 4
1 3 5
1 3 6
2 1 3

I'd like to do the sum of these 3 number and put the result as 4th number, and I want to do this for each line.

To do that, I do this:

qq # I register a macro with q letter
"ay # I move to the first line and first number (1) and save it into a
"by # I do the same with number 4
"cy # and for the last number of the line, number 1
esc+i # I go to insert mode and move to the position where I want the sum
ctrl+r+= # to go to the expression mode
ctrl+r+a + ctrl+r+b + ctrl+r+c # to take the numbers from the registers and sum them and I have the correct sum result pasted
esc # to exit from insert mode
q # to save the macro

If I use it with @q for the other lines, it does not work, but if I do it with the same line that I used while recording the macro, it works, and pastes the same duplicate result:

1 4 11
1 3 4
1 3 5
1 3 6
2 1 3

What am I doing wrong?

2 Answers
  • "ay, "by, and "cy do nothing on their own. y is an operator so it expects a motion. The proper commands would be "ayiw, "byiw, and "cyiw.
  • I am not sure what exactly you want to achieve with esc+i but it is very unlikely to allow you to append anything after the last number.
  • There are too many steps missing from your explanation anyway, so it's hard to debug your macro.

Here is how your recording should look, with every keystroke:

qq                                " start recording in @q
0                                 " move the cursor to the first column
"ayiw                             " yank the word under the cursor to @a
w                                 " move the cursor to the next word
"byiw                             " yank the word under the cursor to @b
w                                 " move the cursor to the next word
"cyiw                             " yank the word under the cursor to @c
A<Space>                          " append a space at the end of the line
<C-r>=<C-r>a+<C-r>b+<C-r>c<CR>    " insert the sum of @a, @b, and @c
<Esc>                             " leave insert mode
q                                 " stop recording

See :help 0, help text-objects, :help w, and :help A.

FWIW, here is a more scalable and predictable method:

qq
A <C-r>=getline('.')->split(' ')->reduce({ a, v -> a + v })<CR>
<Esc>
q

See :help getline(), :help split(), and :help reduce().

Select the range of lines that you want to sum and run:

:'<,'>s/\v^(\d+ )(\d+ )(\d+)/\=submatch(1) . submatch(2) . submatch(3) . ' ' . (submatch(1) + submatch(2) + submatch(3))

NOTE: '<,'> it will be automatically placed by vim

Explanation:

\v ................. very magic search (avoid many backslashes)
^ .................. start of line
() ................. regex group
\d+ ................ one digit or more
\= ................. expression register
submatch(1) ........ repeats the first regex group
Related