Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automating insert befores in VIM

Tags:

vim

I would like to quickly modify the document

00
01
10
11

to look like

000
001
010
011
100
101
110
111

Of course I can do it brute force (as shown above) but I would like to do it quickly as I find I am doing a lot of these. My approach so far has been to yank and paste 4Y 4j 4P

00
01
10
11
00
01
10
11

Then is there a command do insert 0's before each line 4 times? I know it's something like 4, 0, i, 0, esc ~~ I want that to be 4 rounds of 0 (move to left of line), insert mode, insert 0, reinter command mode.

Thanks

like image 966
SwimBikeRun Avatar asked Feb 17 '23 09:02

SwimBikeRun


1 Answers

  • Using visual-block mode:

    y3j
    <C-v>3j
    I0<Esc>
    '>
    p
    <C-v>3j
    I1<Esc>
    

    One could start with the 1 padding and use P to skip the '>:

    y3j
    <C-v>3j
    I1<Esc>
    P
    <C-v>3j
    I0<Esc>
    
  • Using only Ex commands:

    :,+3y<CR>
    :,+3norm! I0<CR>
    :put
    :<Up> "use commandline history to save some typing
    <Backspace>1<CR>
    
  • Using a mix of substitution and normal mode commands:

    y3j
    :,+3s/^/0<CR>
    p
    :<Up>
    <Backspace>1<CR>
    

If you do that a lot, recording this in a macro is probably the best strategy. At that point, how the actual padding is done is not really relevant as the only typing you do is @x and the macro will probably be instantaneous anyway.

What you do during the recording doesn't really matter, here is an example:

qx
y3j
:,+3s/^/0<CR>
p
:,+3s/^/1<CR>
q

Supposing you have this:

[0]0
01
10
11

Hitting @x turns the above into that:

000
001
010
011
100
101
110
111

Your macro is saved into register x and will still be available for your next Vim session.

And I'm sure someone could come up with a nice one liner.

edit

Step-by-step explanation of the macro above:

  • qx, start recording in register x (it can be any available register).

  • y3j, yank the current line and the next three.

  • :, no explanation needed.

  • ,+3, this is the range we are working on. A more correct way to define this range would have been .,+3. The start line and the end line of the range are separated by a coma.

    The start line being the current line we can omit it to save some typing so we are left with the coma, followed by the end line, expressed relatively from the current line, +3.

  • s/^/0<CR>, this is a simple substitution.

    The ^ in the search pattern means "the beginning of the line". It doesn't match the first character so it's perfectly suited for situations like this one, where we want to prepend something to a line.

    So, basically we prepend the line with a 0. It can be whatever you want.

    When you execute a substitution against a range, the substitution is performed on each line of the range. Here, we have four lines so each line is prepended with a 0.

  • <CR>, is, well… the <Enter> key used to execute the substitution.

  • p, paste the four lines that what we yanked before below the current line.

  • :,+3s/^/1<CR>, same as before but with a 1.

  • q, end recording.

And, to answer your comment, here is how you turn this:

00
01
10
11

into that:

00 0.0
01 0.0
10 0.0
11 0.0

You need to use another "anchor". ^ is "the beginning of the line", $ is "the end of the line" so the substitution becomes:

:,+3s/$/ 0.0
like image 81
romainl Avatar answered Feb 28 '23 10:02

romainl