CTRL+V I CTRL+Y - duplicating text from current line.

11 views
Skip to first unread message

Chris Jones

unread,
Jul 3, 2021, 3:50:48 PM7/3/21
to vim...@googlegroups.com
Something that's been bugging me for some time.

I am working on an anthology of French literature and I need to xhtml
this renowned piece from the late 18th century:

| 000 ...
| 001 En tous lieux le cul nous appelle, <br />$
| 002 Le cul met tous les vits en rut,$
| 003 Le cul du bonheur est la voie,$
| 004 Dans le cul gît toute la joie,$
| 005 Mais, hors du cul point de salut.
| 006 ... etc. ^
| col. 60 ____________.

To start off with the cursor is at the beginning of line 001 and I need
to append html linebreaks to lines 002-004. Since I'd rather the source
of the document remain somewhat legible I much prefer having the <br />
tags well-separated from the actual text & neatly aligned in col. 60.

Clarification: the dollar sign at the end of l. 002--004 is NOT part of
the text: lacking a better solution it's only there to represent the
end-of-line: everything beyond in the vim buffer is a NUL character!

To save me some typing (and typos) this is the way I handle it:

1. f< " move cursor to the opening '<'
2. :set virtualedit=all " enable editing beyond end-of-line
3. j " move cursor l. 001 -> l 002
4. CTRL+V " switch to blockwise visual mode
5. 3j " select 1 column × 3 line block
6. I " (upper case) switch to 'block insert'
7. CTRL+Y (6 times) " 'clone' l. 001's <br /> on line 002
8. <ESC> " escape back to normal mode
9. :set virtualedit= " optional - depends on what follows

After hitting <ESC> I'd expect vim to 'magically' clone the '<br />'
already duplicated on l. 002 on lines 003-004. But nothing happens!
I end up with my html linebreak duplicated on l. 002 and nought on l.
003 & 004.

After tinkering with this for a little while I found that if I select
a one-column block on col. 60 (e.g.) including all lines where I need to
add my line breaks and then insert a space there, thus replacing the NUL
character there by a space (but also replacing all NUL characters
-so-to-speak- up to col. 60 by spaces the 1-8 sequence of keystrokes
does what I intend. But that's a LOT of extra work...

Is this to be expected or is it a 'feature'?

Is there a better way (excluding mouse'ing and plugin'ing) to achieve
this?

Thanks,

CJ

PS. As always it takes much longer to describe the editing sequence than
actually performing said sequence. (f<<C-P>j<C-V>3jI<C-Y>×6 + <ESC>) is
all there is to it. With a bit of practice it only takes a couple of
seconds.

PPS. Obviously this approach becomes a lot more useful when dealing with
large chunks of text/verse rather than the 5 lines in the example. It
also comes in handy (very) when editing long tables (in latex e.g.)

Jürgen Krämer

unread,
Jul 5, 2021, 3:20:29 AM7/5/21
to vim...@googlegroups.com
Hi,
from ":help v_b_I" I guess it is the documented behaviour:

| Visual-block Insert *v_b_I*
| With a blockwise selection, I{string}<ESC> will insert {string} at the start
| of block on every line of the block, provided that the line extends into the
| block. Thus lines that are short will remain unmodified. TABs are split to
| retain visual columns. Works only for adding text to a line, not for
| deletions. See |v_b_I_example|.


> Is there a better way (excluding mouse'ing and plugin'ing) to achieve
> this?

"A" in visual block mode is expected to first extend a line if 'virtualedit'
is set to "block" or "all" and the cursor is placed beyond the end of line,
so you might want to change the first step to "t<" and the sixth one to "A".

Regards,
Jürgen

Christian Brabandt

unread,
Jul 5, 2021, 3:28:26 AM7/5/21
to vim...@googlegroups.com
See also the documentation at :h v_b_I and :h v_b_A and see the `Note:`
section.

Best,
Christian
--
Kleine Bosheiten erhalten die Feindschaft.

Chris Jones

unread,
Jul 5, 2021, 7:12:11 PM7/5/21
to vim...@googlegroups.com
On Mon, Jul 05, 2021 at 03:20:17AM EDT, 'Jürgen Krämer' via vim_use wrote:
> Hi,
>
> Chris Jones schrieb am 03.07.2021 um 21:50:

[...]
>
> > Is there a better way (excluding mouse'ing and plugin'ing) to achieve
> > this?
>
> "A" in visual block mode is expected to first extend a line if 'virtualedit'
> is set to "block" or "all" and the cursor is placed beyond the end of line,
> so you might want to change the first step to "t<" and the sixth one to "A".

I should have mentioned that I indifferently use 'I' or 'A' depending on
the circumstances and that the result is the same. I have to force the
padding of the lines with spaces up to the insertion point (col. 60 in
the example) for it to work.

Small issue but I think this is not consistent behaviour: whatever the
doc says the user would expect block insert to insert something rather
than be left wondering uh-oh... what did I do wrong THIS time... :)

Not making an issue of it but perhaps virtualedit= should have an
additional flag that says complete all lines with white space before
performing the block insert?

Thanks,

CJ
Reply all
Reply to author
Forward
0 new messages