Consider this mapping:
vnoremap <leader>U ygv"=toupper(@@)<cr>p
It will yank the current visual selection, select it back, and then put a modified version of it. In this case, uppercase letters.
This works great on character-wise and linewise Visual modes, where the final
p command will replace the contents of the previous selection, leaving everything else in place.
However, in block-wise Visual mode, it doesn't work as expected. Even though the resulting register has the same "format" as the one before the transformation, the put operation ends up shifting things around, putting the multi-line content in the first line of the block and breaking some lines as it does that.
This same problem doesn't happen if I simply put the register, unmodified. Inspecting the register with
:reg " doesn't show anything out of the ordinary.
In fact, applying the transformation manually with
:let @@ = toupper(@@) and inspecting the register afterwards doesn't show anything that's been lost, but putting it into a Visual block selection still fails at that point.
So I ask:
- Is there some magic in how contents coming from Visual block yanks/deletes are stored into registers?
- If so, is there anyway to inspect that, see it?
- Is there any way to reproduce that, so that after the
toupper()conversion I could still be able to preserve that it's meant to be a block?
- If that's not possible, are there any workarounds available for this situation?
I looked at help for Visual block mode and didn't find anything (in fact, didn't find specific help on
toupper() is just a simple example. Of course I could simply use
U for that case. The use of
toupper() is just as a proxy for a more general transformation. (This issue came up as I was writing an answer to this question.)