Paste to end of the file in VIM without moving cursor - vim

In a text document, I'm [visually or otherwise] selecting several lines, cutting them with d... I'd like to paste these lines to the end of the file without moving the cursor. Is there a relatively simple way to do this?

Use the Implicit Mark from Last Jump
You can use the implicit mark (e.g. ') to return your cursor to the location it occupied just before the last jump. For example:
Gp''
This will (G)o to the end of the file, (p)aste the contents after the last line, and then return to your position at the time you typed G.

There are a few ways:
Marks
Set a mark, do your paste, then jump back to the mark
m':$pu<cr>``
Visual mode
Visually select your lines, copy them, append, and then restore visual selection (optionally delete)
y:$pu<cr>gv
Append to the file
Visually select your lines, use :w to append to the file, and then reload the file. (Note: will move the cursor to the start of the visually selected lines)
:w >><cr>:e!
Create your own command/mapping
You can create your own command and/or mapping that will use winsaveview() and winrestview() to append then restore the cursor.

You can define a mapping which marks the current location, pastes at the end of the buffer using :$put then returns to the original cursor location using the mark.
This works because :put allows a line number prefix (the last line being representable as $). From :help put:
:[line]pu[t] [x] Put the text [from register x]
This would map it to <leader>p:
:nnoremap <leader>p :mark '<cr>:$put<cr>`'
It sets the ' mark at the cursor, pastes at the end, then returns to the ' mark with `

Depends on how you mean "without moving the cursor".
This will paste at the bottom of the current file and then allow you to continue where you cut the lines from.
split window with :split
move to bottom with shift+g
paste with p
close the duplicate split view (zz or :q)
If you dont like the split view, you can use the ctrl+o to jump back after G
move to bottom with shift+g
paste with p
jump back with ctrl+o

Related

Vim: How do I paste a column of text (from clipboard) after a different column of text?

I'm testing proxies with my script that looks like that:
$proxy = "http://name:pass#133.245.122.91:80";
$proxy2 = "http://name:pass#133.245.229.241:80";
$proxy3 = "http://name:pass#133.245.113.197:80";
...
$proxy100 = "http://name:pass#133.245.212.197:80";
I get new proxies by email so can I copy new proxies and insert it instead of the old ones by Vim:
"http://name:pass#133.245.122.91:80";
"http://name:pass#133.245.229.241:80";
"http://name:pass#133.245.113.197:80";
...
"http://name:pass#133.245.212.197:80";
Right know I'm doing it as was described on this page How do I paste a column of text after a different column of text in Vim?
Use visual block (ctrl-v) to cut the letter column. Then move to the
first line of the number column. Move to the end and make one space.
Then paste the letter column.
I'm curious, how it can be done without extra step, just paste data from clipboard?
The short version: you can't. There are ways around it, but they aren't necessarily simpler. Longer version follows.
Vim has three ways of marking regions of text: linewise (you start this mode when you press V), characterwise (triggered when you press v), and blockwise (when you press Ctrl-v). The marked region is copied to a register, and this register has an attribute, the "type", that reflects the way you did the marking, linewise, characterwise, or blockwise. What happens when you paste from a register depends on this type.
Now, when you copy from system's clipboard the result is stored in the * register, and the type is always set to linewise. Thus you can't paste a column mode "without extra step". You can however set the type of the * register to blockwise before pasting:
call setreg('*', #*, 'b')
Thus, replacing the list of your proxies would go something like this:
copy the new list to clipboard, from the mail message
run :call setreg('*', #*, 'b') to set the type of the * register to blockwise
go to the old list, press Ctrl-v and mark it; assuming there's nothing else in the file aside from the proxies, a Vim golfer's way of doing that might be something along the lines of:
f" - go to the first "
Ctrl-v - start marking
?;Enter - go to the last ;
paste the new list over the selection, with "*p.
You can simplify the last step a little, by making the * and + registers always refer to the same value. To do that, add this to your vimrc:
set clipboard=unnamedplus,autoselect,exclude:cons\\\\|linux
With this setting the incantation becomes:
copy the new list from mail
run :call setreg('+', #+, 'b')
go to the old list and mark it with Ctrl-v as above
press p to paste the new list over it.
You don't need this dance if you have the new list in a file that you can open with Vim:
open the file with the old list
open the file with the new list in a separate copy of Vim
mark the new proxies with Ctrl-v and yank them with y
in the other Vim mark the old list with Ctrl-v and paste the new one over it with p.
This still involves using the system clipboard under the hood, but the second copy of Vim takes care of setting the type of the relevant register to blockwise.
I don't know any direct way to do this. If it is really important to you, you will probably need some set up before you do the actual editing, which only adds to the amount of typing you have to do (however you can add commands to your vimrc to make it permanent). You might set up some keyboard macro, or use the following map command:
:imap <CR> <Esc>j011lC
Now move to the first " sign and press C, then start pasting (only works in a terminal). Whenever you paste a newline, the map will move you to column 11 in the next line.
Remember to :iunmap <CR> when you are done.

Vim select the ends of multiple lines (block mode, but where the ending column varies)

Is there any way in vim that I can select the end of all these lines? (I'm only showing the end of the lines in these screenshots).
In block mode I can get them all if the bottom line is longer than the rest, but if the bottom line is shorter, the longer lines are truncated.
EDIT | I guess I can just pad out the bottom line with spaces before I select, then delete the spaces later.
Put your cursor on the top-left character you want to be part of the block.
Enter block selection mode with ctrl+v
Select to the end of the line with $ (this is the step you're missing; if you move to the end of the first line using $ then the selection will extend to the end of subsequent lines as well)
Move down 3 lines with 3j
There's more information in the Vim documentation's section on visual mode which you can read online, or just type :help v_$ in Vim.
Click somewhere (anywhere) in the first line you wish to append text to.
Press Control + V.
Press Down to create an arbitrary vertical block selection that spans the desired lines.
Press $ to expand the visual block selection to the ends of every line selected.
Press Shift + A to append text to every selected line.
Type the text you want to append.
Press Escape and the text will be appended across the selected lines.
Alternately, you can set the virtualedit (:h 'virtualedit') setting so that, any time you're in visual block mode, you can move the cursor around even past the ends of lines. E.g. :set virtualedit=block.
If you're looking to select the very last character of every line, like if you want to add something after the quotes at the end of each line, you can do the following:
Put your cursor over the very last character (in this example, the last quote on the first line)
Enter block mode: control + V
Move down to select as many lines as you want to change.
Insert at the end of the line: shift + A
Type what you want to add and then exit Visual mode
You text should now be inserted at the end of each selected line!
Hope this is helpful to others like me searching for an answer similar, but not exactly the same, as the above.
I don't know if is a new thing. But if you press $ two times (instead one) the block goes to the end of all lines without creating extra spaces).
Tested on nvim 0.7.2.

How can vim keep the content of register when pasting over selected text?

I have a line of text I have yanked yy. Now I want to use this text to replace lines at several other places. The trouble is that when I select V the line to be replaced, and paste p, the text that was selected is automatically yanked! That's what I don't want.
Changing the register does not work, because both the paste and the yank are done with the newly selected register.
What is the command to keep the content of the register when pasting over selected text?
Your original selection should remain in register 0. So you can move through the file and paste your yanked line over other lines using: V"0p
Each time you p over something it goes into the default register.
To work around this feature you have to use "_, "the black hole register", before you p. Here is a custom mapping I have in my ~/.vimrc:
vnoremap <leader>p "_dP
It deletes the selected content and drops it in the black hole register (this means that the selected text disappears forever) and puts the content of the default register in place of the previously selected text while leaving the default register intact.
I use it often when I need to replace a loooooooong url in a few places with another looooooong url and crafting a s// would be too cumbersome.

Paste multiple times

What is the best way replace multiple lines with the contents of the clipboard?
The problem I'm having is when I yank a line and paste it over another line the "yank" is replaced with the line I just replace. Now, if I want to replace another line with the same line I have to go back up and yank it again.
There's got to be a better way to do this.
I have this in my .vimrc:
xnoremap p pgvy
(note: this will work only with the default register, but this mapping is easy to remember). Writing a more elaborate version would be possible. Also, you still can use P to get the old behaviour.
"0 should have the contents of your yank. It's a bit more tedious to type, but "0p should do what you want.
Alternatively, don't select-and-replace the old lines up front. If you find those lines with a search, just hit n. over and over (after an initial p), then when they're all pasted, do ndd followed by as many n.s as necessary.
The biggest mental switch I've needed to make when moving to Vim is to figure out how to apply group edits sequentially. I.e. rather than doing a bunch of edits on a line and then doing a bunch of the same edits on another line, I'll do the first edit on a bunch of lines (using . to great effect), then the second edit on a bunch of lines, etc. Alternatively, the use of macros may help as they are fantastic, but sometimes a little more tedious to get working correctly with "complex" changes.
I often use another registry, copy the line you need to some named registry "ay and then paste from there "ap
When you paste over a selection in Vim it will replace the default register with the contents of the selection. If pasting over a selection is wiping out the contents of the clipboard register then very likely you have the following line in your .vimrc
set clipboard=unnamed
One option is to remove that and use the explicit clipboard register "+
Another option is to use any of the other explicitly named registers (a-z). After the first paste yank the line back into "c for example and then use "cp to paste from there on out.
Instead of using copy/paste, it is often better to use a text object command such as ciw to change the inner word. This method has the advantage of being easily repeatable using the . repeat command.
yiw Yank inner word (copy word under cursor, say "first").
... Move the cursor to another word (say "second").
ciw<C-r>0 Change "second", replacing it with "first" ( is Ctrl-R).
... Move the cursor to another word (say "third").
. Change "third", replacing it with "first".
use np where n is the number of how much time you want to paste the lines eg 3p will paste 3 lines.

How to paste something between html tags in Vim?

Pressing p pastes things bellow the current line, dit deletes things inside html tags. How do I paste something inside html tags?
Nor here
<p>I want to paste something here</p>
Not here
I usually just do vitp which visually selects the inner contents of the tag, then pastes over what is selected.
Works for me.
The result of pressing P and p depends on what you have in the selected register at the time. If you delete or yank one or more entire lines (e.g. with dd, Y or Vd commands), then pressing P will insert the contents of your register on the line above the current line, whereas p will insert on the line below the cursor.
If you delete or yank a section of text less than a line (e.g. with the D, or yw commands), then P will insert the contents of your register directly before the current cursor position, and p will insert directly after the cursor (i.e. on the same line).
If it helps, you could consider the linewise selection as being analogous to block html elements (such as <div>), and characterwise selection as being analogous to inline html elements (such as span).
So to answer your question: it depends. Supposing you have a linewise section of text in the register, you would want to break the target tag onto two lines before doing the paste operation. In your example, rather than doing dit to delete the contents of the tag, do cit to delete the same section and go into insert mode. Hit return once, to insert a new line, then esc to go back into normal mode, then P to insert your linewise register above the line with the closing tag.
If you didn't want to split the tag onto multiple lines, you would instead have to make sure that you yanked a characterwise selection into the register. Then you could run:
"_ditP
"_ deletes the text into the black hole register, ensuring it doesn't overwrite what is in your default register. dit deletes the contents of the tag, and P pastes the contents of your default register before the cursor position.
remove the current content between the tags with the command
cit
that will 'change in tags' and once that content is gone, you can paste with middle click or if you need go back into command mode and use your normal p/etc.
vitp should handle a linewise paste.
You can press "v" for visual, then go to where the cursor is, and press p or P.

Resources