-
Notifications
You must be signed in to change notification settings - Fork 21
Details of Visual mode paste
This is a survey of resolved issues with Visual mode paste. This page is intended to be a reference for the future development.
Visual mode paste is pasting a previously yanked/cut text over an area selected in Visual mode.
vim-easyclip implements Visual mode paste via EasyClip#Paste#PasteTextVisualMode()
function.
It can be found in autoload/EasyClip/Paste.vim file.
In general this function works as follows:
- start Visual mode with the same area as the previous area and the same mode (
normal! gv
), - check whether pasting should be done before the following or after the preceding text,
- delete the selected area (
normal! "_d
), - paste the previously yanked/cut text via
EasyClip#Paste#PasteText()
function.
By default, pasting is done before the following text. However, there are subtle differences in Visual mode operations that should be treated by pasting after the preceding text.
Most of the problems with Visual mode paste arose as edge cases of the deletion in Visual mode.
It is important to understand specifics of different Visual modes: characterwise, linewise, and blockwise.
See :help Visual
in Vim for a complete reference.
All examples below operate on the following file:
line one
line two
line three
All commands in examples assume the file is opened in Normal mode and the cursor is placed on the first character of the first line.
In this mode a selection is made in a simple WYSIWYG manner.
If a selected area is deleted in this mode, the cursor is placed on the next character after the last character of the selection.
Except if the selection ends at the last non-EOL character of a line or at the EOL character of the last line,
then the cursor is placed on the previous character before the first character of the selection.
But if the previous character before the first character of the selection and the first character of the selection are on separate lines, then the cursor is placed on the EOL character of the last line of the selection.
Also except if the selection ends at the EOL character of a line and the next line is empty (^$
),
then the cursor is placed on the previous character before the first character of the selection.
Note that EOL at the end of file is never deleted.
Edge cases
- When the selection ends at the last non-EOL character of a line.
- When the selection ends at the EOL character of the last line.
- When the selection is one of the two above and the first character of the selection and the previous character before the first character of the selection are on separate lines.
- When the selection ends at the EOL character of a line and the next line is empty (
^$
).
Example for the first case
Command: lv2feygvp
Expected result:
line one
line two
line three
Actual result if pasting is done before:
ine onel
line two
line three
Example for the second case
Command: Glv<End>ygvp
Expected result:
line one
line two
line three
Actual result if pasting is done before:
line one
line two
ine threel
Example for the third case
Command: jvfoygvp
Luckily, the third case is handled properly by Vim itself. Both Vim internal put commands p
and P
do pasting
before, when the cursor is placed on the EOL character of an empty line (^$
).
Since EasyClip#Paste#PasteText()
function ends up calling these Vim commands, there is no need for a workaround.
Example for the fourth case
Command to prepare the example file: jD
Command: lv<End>ygvp
Expected result:
line one
line three
Actual result if pasting is done before:
ine one
l
line three
In this mode a selection is made linewise and the selection of each line always starts at the first character of the line and ends at the EOL character of the same line.
If lines are deleted in this mode, the cursor is placed on the next line after the last line of the selection.
Except if the selection ends at the last line, then the cursor is placed on the previous line before the first line of the selection.
Edge cases
- When the selection ends at the last line.
Example
Command: GVygvp
Expected result:
line one
line two
line three
Actual result if pasting is done before:
line one
line three
line two
In this mode a selection is made blockwise. Even if the selection visually includes EOL characters,
Vim internal put commands p
and P
don't paste them and Vim internal delete command d
doesn't delete them.
Thus one can assume that EOL characters are never really included in the selection.
If a selected area is deleted in this mode, the cursor is placed on the next character after the last character of the first line of the selection.
Except if the first line of the selection ends at the last non-EOL character or at the EOL character of a line, then the cursor is placed on the previous character before the first character of the first line of the selection.
Edge cases
- When the first line of the selection ends at the last non-EOL character of a line.
- When the first line of the selection ends at the EOL character of a line.
Example for the first case
Command: fi<C-V>jfoygvp
Expected results:
line one
line two
line three
Actual result if pasting is done before:
ine onel
ine twol
line three
Example for the second case
Command: fi<C-V>j<End>ygvp
Expected results:
line one
line two
line three
Actual result if pasting is done before:
ine onel
ine twol
line three
Example why only the first line of the selection is important
In this example the first line of the selection doesn't end at the EOL character or at the last non-EOL character of the first line of file, but the second line of the selection ends at the EOL character of the second line of file.
Command to prepare the example file: jfidwkh
Command: fi<C-V>wjygvp
Expected results:
line one
ltwo
line three
Actual results if pasting is done after:
loine ne
l two
line three
Actual results if pasting is done before:
line one
ltwo
line three