Search code examples
vim

Vim doesn't replicate normal mode instructions accurately


I want to make a function which generates a block of text of variable line count. The text should go as follows:

1.wav
2.wav
3.wav
4.wav
...

My function looks like this:

function Rename(howmany)

    normal i1.wav
    normal yy

    let iter = 1
    while iter < a:howmany
        normal pp0^Ayy "^A is generated from <Ctrl-V> <Ctrl-A>
        let iter += 1
    endwhile

endfunction

The text generated with :call Rename(5) looks like this:

1.wav
1.wav
2.wav
2.wav
3.wav
3.wav
4.wav
4.wav
5.wav

Notice the repeating segment. If I were to recreate the normal mode steps one at a time (pp - paste line, 0 - go to the start of the line, ^A - increment the number, yy - yank the current line for further copying).

I made a quick fix which deletes every other line.

That fix looks like this:

function Rename(howmany)

    normal i1.wav
    normal yy

    let iter = 1
    while iter < a:howmany
        normal pp0yy
        let iter += 1
    endwhile

    normal gg

    let iter = 1
    while iter < a:howmany
        normal dd
        normal 
        let iter += 1
    endwhile

endfunction

Anyone know why this happens? And how I could fix this, so that I don't have to circumvent the main issue.


Solution

  • The cause of the problem is easy to spot:

    normal pp0^Ayy
           ^^
    

    There is no pp pendant to yy, there is only p. Therefore, pp puts the text from the default register two times:

    1.wav
    1.wav
    1.wav
    

    and you only increment the second one:

    1.wav
    1.wav
    2.wav
    

    The next loop yanks the last line and puts it two times again:

    1.wav
    1.wav
    2.wav
    2.wav
    2.wav
    

    and so on…

    Removing the extraneous p will fix the problem:

    function! Rename(howmany)
        normal i1.wav
        normal yy
        let iter = 1
        while iter < a:howmany
            normal p0^Ayy
            let iter += 1
        endwhile
    endfunction