Search code examples
vimvi

Trouble when I try to set a macro expression


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?


Solution

    • "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().