0

In https://stackoverflow.com/a/11790464/5354137, there is a very detailed description how to, e.g. perform the same insert to the beginnings of all selected lines by placing the cursor over the first character of the first line, then after <C-v> moving down, then Isomething<Esc><down> inserting something everywhere.

But how does one do the same thing in the case of lines of unequal length, such as:

'Lorem ipsum
'dolor sit amet,
'consectetur adipiscing elit,
'sed do...

to their respective line endings? E.g. if I wanted to insert ', after m, ,, , and ., how would I do that without resorting to :substitute? (Or to a plugin, just using original vim-fu...)

Sixtyfive
  • 1,150
  • 8
  • 19

3 Answers3

4

Substitute (original answer)

The easiest way to do it is with the :substitute command. Select the lines in visual mode and then do:

:'<,'>s/$/',/<CR>

The $ stands for the end of the line. Note that vim will already write the :'<,'> part, so you only have to type from there.

Using a macro

With the question having been updated and :substitute off the table, I'd suggest recording a macro. Place the cursor on the line with "Lorm ipsum" and do:

qaA',<Esc>jq

then call the macro three times for the remaining lines. Either by hitting @ a lot:

@a@@@@

or with the more elegant

3@a

Using a recursive macro

As commented by @AndR, it's possible to record a macro that calls itself which will run until it reaches the end of the buffer:

qaqqaA',<Esc>j@aq

Note that the macro already calls itself with @a.

Afterwards, call @a and single quotes will be appended to every line until the end of the buffer.

Without visual selection

Both @AndR's answer using :normal and my :substitute answer above rely on a visual selection of the lines to modify. It is possible without that by typing in a range or line numbers. For "Lorem ipsum..." on lines 1 through 4, type either of the two commands:

:1,4s/$/',/
:1,4norm A',

This has the benefit that it works without a visual selection and from anywhere in the buffer.

Friedrich
  • 2,011
  • 2
  • 17
  • 19
  • Thank you for the answer Friedrich. I should have specified that I was specifically looking for a way to achieve this without resorting to `:s`. Sorry for that! I'll update the question accordingly. – Sixtyfive Feb 04 '23 at 11:41
  • You can record a recursive macro to execute it on all remaining lines (see here https://vim.fandom.com/wiki/Record_a_recursive_macro) – And R Feb 04 '23 at 13:35
  • `:<,>norm! @a` also executes the macro on the visually selected lines – And R Feb 04 '23 at 13:37
  • 1
    Upvoted it now because I think your answer really adds to the question. Maybe edit to reflect And R's comment as well? Otoh still hoping Rocco might turn their comment into an answer, as that technique to me fits best with the one employed in the linked answer. – Sixtyfive Feb 04 '23 at 14:14
  • @Sixtyfive thanks a lot. I added two more options. – Friedrich Feb 04 '23 at 18:17
  • @Sixtyfive If I understand you correctly, i think the `$` is enough to answer, so just comments. Now I've added the relevant other details and write the answer. – Rocco Feb 04 '23 at 18:30
  • For the recursive macro to run without side effects, it has to be emptied before the recording starts, like this `qaq`, or fancier `:let @a=""` – And R Feb 04 '23 at 20:33
  • @AndR put another edit on top of it with `qaq`. – Friedrich Feb 05 '23 at 15:40
2

Based on your reference link and reproduction steps, this is your problem halfway:

But how does one do the same thing in the case of lines of unequal length ...

Follow the link and use the first method Using only visual-block mode, let's start with step 5:

  1. Select any column, hit <C-v> to enter visual-block mode and expand your selection toward the bottom:

    'Lo[r]em ipsum
    'do[l]or sit amet,
    'co[n]sectetur adipiscing elit,
    'se[d] do...
    
  2. Hit $ or <End> (see :help $), will get the selection like this:

    'Lo[rem ipsum]
    'do[lor sit amet,]
    'co[nsectetur adipiscing elit,]
    'se[d do...]
    
  3. Hit A',<Esc> to achieve your goal:

    'Lorem ipsum',
    'dolor sit amet,',
    'consectetur adipiscing elit,',
    'sed do...',
    

Note and supplement:

If you use the latest Vim9 and your virtualedit option contains block, when you hit $ or <End>, you may see this selection (Vim8 won't):

'Lo[rem ipsum                  ]
'do[lor sit amet,              ]
'co[nsectetur adipiscing elit, ]
'se[d do...                    ]

This could be a issue with the VIM9 or an intentional design? I don't know, but don't care, just press A. You'll see your cursor at the end of the first line, which is fine (| is the cursor position):

'Lorem ipsum|
'dolor sit amet,
'consectetur adipiscing elit,
'sed do...

Then you enter the text you need (e.g. ',) and <Esc> ends editing, it works fine:

'Lorem ipsum',
'dolor sit amet,',
'consectetur adipiscing elit,',
'sed do...',

As a supplement, oppositely, if you want to insert text in the same column where has no text when there are irregular endings : You can add block to your virtualedit option (see :h 'virtualedit'), using other left-right-motions (e.g. l or |) instead of $ to get this selection:

'Lo[rem ipsum                  ]
'do[lor sit amet,              ]
'co[nsectetur adipiscing elit, ]
'se[d do...                    ]

When you press A, the cursor will be at (| is the cursor position):

'Lorem ipsum                  |
'dolor sit amet,              
'consectetur adipiscing elit, 
'sed do...                    

Then enter the text you want (e.g. ',), hit <Esc> to obtain:

'Lorem ipsum                  ',
'dolor sit amet,              ',
'consectetur adipiscing elit, ',
'sed do...                    ',
Rocco
  • 471
  • 1
  • 3
  • 7
  • In your last listing of the text, there's a lot of whitespace between the text and the quote. How to get rid of it? We could use `:s` or `:norm` or a macro or ... ;) – Friedrich Feb 04 '23 at 19:02
  • @Friedrich In any case, using `$` to expand selection to the endings with ***visual-block*** mode, then hit `A',` always achieve this task. You should read the content before the **NOTE** section is enough. The reason why I added the latter supplement is because I found that when I update to **Vim9**, if `virtualedit` includes `block`, the selection is displayed differently from the previous case. But don't care, **using the `$` command will always move to the last character in the line, not past it**. – Rocco Feb 05 '23 at 03:57
  • As a comparison and hint, the last part shows what will happen when you use `l` or `|` command to select the selection area like `$` (**Vim9** & ***visual-block*** & `virtualedit` includes `block`). In addition, of course, `:s` or `:normal` or ***macro*** are also very common methods, thanks for your suggestions and detailed additions. – Rocco Feb 05 '23 at 03:57
1

Here the goal can be achieved by appending ' at the end of each line. In one line you'd normally do A'. In order to do this this in each line of the visual selection, run

:<,>norm A'

Assuming that you have selected the needed lines visually (with v or V).

See :h :normal for details.

And R
  • 487
  • 1
  • 14
  • 17