Cut and paste in Vim without moving next line up - vim

When I cut and paste in VIM by pressing v, and go to the end of the line using $, and press d, the next line gets moved up to the same line I'm cutting.
How do I stop this?

It moves up because you have removed all the characters including line return/feed.
There are multiple solutions as usual with Vim. There is no "one true way" but you can try the following commands.
You can use D (capital) in normal mode which will erase everything until the end of line.
See :help D
Using another motion
What you could do instead of using $ to move to the end of the line, use g_. It will move to the last non blank character of the line and won't select line return.
See :help g_
So vg_d should work as you want.
Using Replace
Alternatively, what you could do instead of cutting, you could replace the erased character by a blank using the space character.
So v$rSPACE should work to erase but it will not save the replaced characters in register (for pasting later for example).

To cut everything from current cursor position until the end, use C.
:he C will help you:
Delete from the cursor position to the end of the
line and [count]-1 more lines [into register x], and
start insert. Synonym for c$ (not |linewise|).
Doing so will cause the current line (assuming you are on the start of the line when hitting C) to become empty and the content is (by default) yanked into register "
Edit:
As Xavier notes in his comment (and his answer), the same could be achieved with D. It also cuts everything from current cursor position until the end of the line but doesn't go in insert mode after doing it.

If you use these keystroke sequence then next line would not move up.
v $ h d
It is moving up because EOL character $ is also getting deleted without moving cursor 1 character back.

Just skip the visual mode and swap the other two commands, ie. press d $.
This is shorter than your starting one and doesn't break your tradition introducing other keystrokes you may not be familiar with.

Related

VIM Delete From Cursor to Another Location in File

I'm trying to learn VI/VIM. I would like to know how to deleted the text from my cursor to some other spot in the file. I know how to delete a line (dd) and multiple lines (5dd) and to the end of a line (d$), but not, for example, from the cursor to the middle of the next line or the middle of the next two or three lines.
Thanks for any tips.
Cheers!
You can use any motion after a d. For example, to delete two words, you can do d2w. Or to delete 10 characters to the left, you can do d10h, or to delete next two lines, do d2j. For something more complicated like 'delete up to middle of next line', I usually just do v to go into selection mode, select what I need with hjkl, and hit d to delete it. If you do block selection mode Ctrl+v you can select a block that needs deletion and hit d. Hope that helps.
What do you mean "the middle"?
You delete with d{motion}, and that includes things like:
d5w - delete the next 5 words
d/test - delete up to the word test
see
:help d
:help motion
and the motion.txt linked in the help (also online http://vimdoc.sourceforge.net/htmldoc/motion.html )
I used to have vi macros to delete between marks. e.g. use ma to make mark a, and then put your cursor where you want it and:
mb'a"ad'b will make mark b and delete from mark a to b into buffer 'a'
mb'a"ay'b will copy (not delete)
"ap will get the text back.
(from memory this is whole line based, not "position on a line")

vi/vim editor, copy a block (not usual action)

In vi/vim editor, I need to copy a block. There are many ways, but one way is very quick.
label the first line by some way,
then label the end line by some way,
then put some command to copy the labeled lines.
then copy, may using 'p', but not sure.
Anybody know the commands (not yy or 10yy)?
just use V to select lines or v to select chars or Ctrlv to select a block.
When the selection spans the area you'd like to copy just hit y and use p to paste it anywhere you like...
Their Documentation says:
Cut and paste:
Position the cursor where you want to begin cutting.
Press v to select characters (or uppercase V to select whole lines).
Move the cursor to the end of what you want to cut.
Press d to cut (or y to copy).
Move to where you would like to paste.
Press P to paste before the cursor, or p to paste after.
Copy and paste is performed with the same steps except for step 4 where you would press y instead of d:
d = delete = cut
y = yank = copy
Another option which may be easier to remember would be to place marks on the two lines with ma and mb, then run :'a,'byank.
Many different ways to accomplish this task, just offering another.
I found the below command much more convenient. If you want to copy lines from 6 to 12 and paste from the current cursor position.
:6,12 co .
If you want to copy lines from 6 to 12 and paste from 100th line.
:6,12t100
Source: https://www.reddit.com/r/vim/comments/8i6vbd/efficient_ways_of_copying_few_lines/
It sounds like you want to place marks in the file.
mx places a mark named x under the cursor
y'x yanks everything between the cursor's current position and the line containing mark x.
You can use 'x to simply move the cursor to the line with your mark.
You can use `x (a back-tick) to move to the exact location of the mark.
One thing I do all the time is yank everything between the cursor and mark x into the clipboard.
You can do that like this:
"+y'x
NOTE: In some environments the clipboard buffer is represented by a * in stead of a +.
Similar questions with some good answers:
How to copy/paste text from vi to different applications
How to paste from buffer in ex mode of vim?
Keyboard shortcuts to that are:
For copy: Place cursor on starting of block and press md and then goto end of block and press y'd. This will select the block to paste it press p
For cut: Place cursor on starting of block and press ma and then goto end of block and press d'a. This will select the block to paste it press p
You can do it as you do in vi, for example to yank lines from 3020 to the end, execute this command (write the block to a file):
:3020,$ w /tmp/yank
And to write this block in another line/file, go to the desired position and execute next command (insert file written before):
:r /tmp/yank
(Reminder: don't forget to remove file: /tmp/yank)

vim: go to the last character of line plus one

I have a problem when I use the paste command (remapped to C-V) at the end of the line.
Of course it inserts a char before the last one, and not after...
However if I want to insert one after that I have to insert a space, paste the text and delete the space.
Is there a way to make Vim go to the end of the line, plus one char so I can paste quickly?
There are two paste commands in vi; P to paste before the cursor position and p to paste after the cursor position. Make sure you are remapping p.
The default behaviour of put is to do as you require, rather than what Ctrl+V does. Maybe you could remap C-V to "*p.

How to insert a block of white spaces starting at the cursor position in vi?

Suppose I have the piece of text below with the cursor staying at the first A currently,
AAAA
BBB
CC
D
How can I add spaces in front of each line to make it like, and it would be great if the number of columns of spaces can be specified on-the-fly, e.g., two here.
AAAA
BBB
CC
D
I would imagine there is a way to do it quickly in visual mode, but any ideas?
Currently I'm copying the first column of text in visual mode twice, and replace the entire two column to spaces, which involves > 5 keystrokes, too cumbersome.
Constraint:
Sorry that I didn't state the question clearly and might create some confusions.
The target is only part of a larger file, so it would be great if the number of rows and columns starting from the first A can be specified.
Edit:
Thank both #DeepYellow and #Johnsyweb, apparently >} and >ap are all great tips that I was not aware of, and they both could be valid answers before I clarified on the specific requirement for the answer to my question, but in any case, #luser droog 's answer stands out as the only viable answer. Thank you everyone!
I'd use :%s/^/ /
You could also specify a range of lines :10,15s/^/ /
Or a relative range :.,+5s/^/ /
Or use regular expressions for the locations :/A/,/D/>.
For copying code to paste on SO, I usually use sed from the terminal sed 's/^/ /' filename
Shortcut
I just learned a new trick for this. You enter visual mode v, select the region (with regular movement commands), then hit : which gives you this:
:'<,'>
ready for you to type just the command part of the above commands, the marks '< and '> being automatically set to the bounds of the visual selection.
To select and indent the current paragraph:
vip>
or
vip:>
followed by enter.
Edit:
As requested in the comments, you can also add spaces to the middle of a line using a regex quantifier \{n} on the any meta-character ..
:%s/^.\{14}/& /
This adds a space 14 chars from the left on each line. Of course % could be replaced by any of the above options for specifying the range of an ex command.
When on the first A, I'd go in block visual mode ctrl-v, select the lines you want to modify, press I (insert mode with capital i), and apply any changes I want for the first line. Leaving visual mode esc will apply all changes on the first line to all lines.
Probably not the most efficient on number of key-strokes, but gives you all the freedom you want before leaving visual mode. I don't like it when I have to specify by hand the line and column range in a regex command.
I'd use >}.
Where...
>: Shifts right and
}: means until the end of the paragraph
Hope this helps.
Ctrl + v (to enter in visual mode)
Use the arrow keys to select the lines
Shift + i (takes you to insert mode)
Hit space keys or whatever you want to type in front of the selected lines.
Save the changes (Use :w) and now you will see the changes in all the selected lines.
I would do like Nigu. Another solution is to use :normal:
<S-v> to enter VISUAL-LINE mode
3j or jjj or /D<CR> to select the lines
:norm I<Space><Space>, the correct range ('<,'>) being inserted automatically
:normal is probably a bit overkill for this specific case but sometimes you may want to perform a bunch of complex operations on a range of lines.
You can select the lines in visual mode, and type >. This assumes that you've set your tabs up to insert spaces, e.g.:
setl expandtab
setl shiftwidth=4
setl tabstop=4
(replace 4 with your preference in indentation)
If the lines form a paragraph, >ap in normal mode will shift the whole paragraph above and below the current position.
Let's assume you want to shift a block of code:
setup the count of spaces used by each shift command, :set shiftwidth=1, default is 8.
press Ctrl+v in appropriate place and move cursor up k or down j to select some area.
press > to shift the block and . to repeat the action until desired position (if cursor is missed, turn back with h or b).
Another thing you could try is a macro. If you do not know already, you start a macro with q and select the register to save the macro... so to save your macro in register a you would type qa in normal mode.
At the bottom there should be something that says recording. Now just do your movement as you would like.
So in this case you wanted 2 spaces in front of every line, so with your cursor already at the beginning of the first line, go into insert mode, and hit space twice. Now hit escape to go to normal mode, then down to the next line, then to the beginning of that line, and press q. This ends and saves the macro
(so that it is all in one place, this is the full list of key combinations you would do, where <esc> is when you press the escape key, and <space> is where you hit the space bar: qai<space><space><esc>j0q This saves the macro in register a )
Now to play the macro back you do # followed by the register you saved it in... so in this example #a. Now the second line will also have 2 spaces in front of them.
Macros can also run multiple times, so if I did 3#a the macro would run 3 times, and you would be done with this.
I like using macros for this like this because it is more intuitive to me, because I can do exactly what I want it to do, and just replay it multiple times.
I was looking for similar solution, and use this variation
VG:norm[N]I
N = numbers of spaces to insert.
V=Crtl-V
*** Notice *** put space immediate after I.

Why does Vim position the caret one character off with $ (end of line)?

Observe a line in a Vim instance:
Now I hit $:
Why does my cursor not go all the way to the end? Once I try inserting, the text gets inserted before the last character! Even if I try to move right again while still in normal mode I get the bell. Oddly, when in edit mode I can move to the actual end of line with the right arrow key!
Does anyone know why Vim does this? On 7.3 by the way. Thanks for the help.
Pressing $ while in command mode causes the cursor to move to the end of the line, effectively highlighting the last character. Hit i here to insert before the last character, or a to append to the line. It is slightly ambiguous here, because you're using a pipe character as a cursor rather than a rectangular block cursor. Have a look at ":help termcap-cursor-shape" if you want to change that.
If the goal is to append to the end of the line, A will jump to the end of the line and enter insert mode with a single keypress.
Use a to append a character after the current.
Or, to go to the end of the line and append in 1 step, use capital A. I.e. shiftA.
Similarly shift-I to insert at the beginning of the line without first having to press ^.
The cursor can't be between two characters, it is always on a character.
If you press $ then x, you will correctly delete the last printable character of the current line.
What you are observing is the fact that using i, you are always inserting your text before the selected character. If you want to insert after the selected character, you have to use a or better A as it has already been mentioned.
In other words:
i means "insert before character under cursor".
a means "insert after character under cursor".
mnemonic for a : a for "append".

Resources