Here is my problem:
I am in visual mode.
I select text and copy it to the buffer. ((y)ank)
I select another text which I want to replace and paste the buffer. ((p)aste)
Now the second selection has been replaced in the buffer, however I want the first one to still sit in there.
Any ideas?
Often, this behavior is useful. When you don't want it, you can instead do the usual yank, then paste (officially, 'put') with "0p. You can do this however many times you like.
See :help v_p for more.
If you want to avoid the overwrite, you need to delete first. You can use "_ to select the blackhole buffer, then delete d, then paste before P and you'll avoid the buffer being set.
While this does not technically answer the question (not using default buffer) it does solve the symptom of the problem so I thought I would still share. I get around this issue with a solution to a different problem.
I have mapped "Copy, paste" (yank, put) from the system clipboard to "Ctrl-Shift-C, Ctrl-Shift-V" (Ctrl-C, Ctrl-V if caps lock is on). This can be used in place of y with the same effect.
If I use the system buffer for copy it does not get overwritten when I paste.
I added this to my .vimrc
vnoremap <C-V> "*p
vnoremap <C-C> "*y
As a bonus it will give you easy access to the system clipboard.
Related
Vim always manages to clip off at least of couple of characters when I copy something from a text file, such as a public rsa key for example.
Generally, I open a text file in my computer, highlight the text, copy it to my clipboard. I go into my terminal (with Vim already open) and then:
i (for insert)
ctrl+shift+v
Am I doing something wrong?
I've double checked, and triple checked, this, and I am absolutely sure that I highlighted all of the text that I needed to copy. Other times it works fine. There does not seem to be any consistency in regards to when it happens.
Anyone experience this?
This usually happens because something in the pasted text triggers a key mapping unexpectedly. This is what paste mode is for.
Do this before pasting:
:set paste
And turn it off after:
:set nopaste
This can be annoying to type frequently, so there is a way to map it to a key combination. I use ,p for this, and have this in my .vimrc:
set pastetoggle=,p
(Yes, I use an actual comma here, not <Leader>. That's because <Leader> won't work here, as this isn't technically a mapping.)
This is a toggle, so you can use it to turn the mode on and off. It works in both normal mode and insert mode.
You do want to turn it off after the paste. Since paste mode disables your insert mappings, you don't want to leave it on all the time.
You can read more about the paste option with :help 'paste.
The annoyance of toggling to and form paste mode can be avoided by using "+p or "*p. (You're putting the quoteplus register).
More often than not, I prefer "+P, since this leaves my cursor at the end of properly formatted put. see :help quoteplus for details. So the whole workflow is:
outside of vim: copy to clipboard
inside of vim: "+P
According to official vim wiki copying any text into system clipboard is a something I've never expected to see in a text editor created by humans.
gg"+yG – copy the entire buffer into + (normal mode)
Copy/Pasting between the browser and a text file with 6 keystrokes is something I refuse to accept as normality.
Are there any sane alternatives?
It's not difficult, it's powerful. As the yank command takes a {motion}, you can copy arbitrary (and precisely selected) text areas, all with the same command. Likewise, "+ is just one destination of many, and Vim's named registers are very useful.
You may have noticed that most people (sometimes heavily) customize their Vim setup. On top of the powerful editing abstractions, that puts it on yet another level (at the expense of now being dependent on your Vim configuration).
So, if you need to copy the entire buffer to the system clipboard often, create your own shortcut, and persist it in your ~/.vimrc. For example:
:nnoremap <F2> :%yank +<CR>
There you have it: copying with a single keystroke (cp. :help key-notation for how keys are specified; as function keys are sparse, I would prefer <Leader>y instead).
If you often yank (various areas) to the system clipboard, making that the default register might also be worthwhile:
:set clipboard^=unnamedplus
To break it down:
gg
Move the cursor to the beginning of the buffer
"+
Set the target for copy to the system clipboard register
yG
Copy ("yank") everything from the cursor position to the end of the buffer (i.e. the whole file).
To give another example. If you want to copy just the current word to the clipboard you might perform:
"+yw
Since "w" is the command to move the cursor to the end of the current word.
If you want to shorten a regularly repeated action you could record a macro, or map a keyboard shortcut.
When I want to copy a whole file I just do :%y+
: Enter ex command
y[ank]
+ To clipboard register
In vim I frequently end up undoing more than I want to after a messed up paste from the system clipboard. Is there a better way?
To reproduce:
Open iTerm # or terminal
vi # open vim
i # enter insert mode
type some stuff
Cmd-V # paste the contents of the OS X clipboard
The paste is a mess because I haven't :set paste. So
Esc # enter command mode
u # undo
but that undoes my typing as well as my paste.
Is there a different undo I can use? Apart from remembering to :set paste before pasting is there a better way to do this in general?
This is not the answer you're looking for, but you really should stop using vim as a non-modal editor. If you want to paste then return to normal mode and use vim's paste commands.
Assuming that you have a vim version with clipboard access this should do the trick "+p. You can also facilitate this by setting your unnamed register to be the + (or *) register, such that pasting from clipboard becomes a simple p.
The following question has a great answer that includes all this information How to make vim paste from (and copy to) system's clipboard?.
I'm not sure there's anything you can do after the fact, but one solution is to hit Ctrl-G u in insert mode just before you paste. This breaks the undo block into two separate blocks - so the paste will be remembered as a separate undoable action.
Granted if you have to remember to do this, you might as well just use :set paste instead - but on the upside it's fewer keystrokes and you don't have to go to command mode first.
Take a look at this plugin, it can auto run :set paste! when you use Cmd-V(or Ctrl-V) to paste some text. And leave paste mode when you finished.
The following mappings create an additional undo point (via :help i_CTRL-G_u) before pasting in insert mode. This way, you can undo the paste separately.
inoremap <C-r> <C-g>u<C-r>
inoremap <C-v> <C-g>u<C-v>
Actually the solution is you have to go to command mode(e.g. Esc) first and re-enter the insert mode, but it only works if I type manually but it seems "randomly" stop working if I test it in ~/.vimrc. Google doesn't help at all.
I spends a lot of time try to fix this issue and I just figure out the reason in my case:
Don't map the paste key same with the terminal existing paste key
e.g. Ctrl+Shift+V will paste in my Konsole terminal, but if I assign this key <C-S-v> in ~/.vimrc, the "undo for only single paste instead of multiple pastes" will not working.
In my case, I have to use <C-v> instead of <C-S-v>:
inoremap <C-v> <Esc>"+pi<Esc>i<Right><Right>
Your case may difference, but the point is same: don't assign the same paste key conflicts with existing terminal emulator key.
I've 100% proved this conclusion by set my terminal paste key to Ctrl+V and now <C-v> stop working but <C-S-v> working.
Note also that the vim is too sensitive and strange. I figure out I have to use i and then 2 Right keys manually to make it works in the correct cursor position, that's means I have to put i and 2 Right keys in the ~/.vimrc too. Your case might difference, but the point is same, ensure the keys+order in ~/.vimrc 100% match with what you type manually.
I've recently stumbled upon this useful feature:
nnoremap D "_d
Allowing me to do "Dd" or "D$" in order to delete things without overriding the default buffer. However,
nnoremap V "_v
doesn't seem to do the trick when I try and replace text by selecting and pasting over it.
Any suggestions on how I accomplish that?
Thanks in advance.
I don't quite understand what you are trying to achieve.
d is an operator, so you can decide to put the result of the delete operation into a given register; the _ register in your case.
However v is not an operator, it is only a command to switch from normal to visual mode. So I don't think that "_v makes much sense.
You might be thinking of another operator like c (change), y(yank) or p (paste)
To get the full list of operators, type :help operators
You should have a look at :help registers, you might find what you want, it describes all the registers and how they behave.
short extract :
"" is the default register
"0 always contains the content of the latest "yank"
"1 always contains the content of the latest "delete" or "change"
The other numbered registers are used to keep the history of your previous actions.
So rather than avoiding to delete the default register when you are deleting you might use :
"0p when pasting to be sure to paste the last yanked text and not what you have just deleted.
Edit : Add some Vim speak
A buffer is the in-memory text of the file you are editing. It contains the whole file. :ls will display a list of open buffers.
A register is a buffer (for lack of better word) where your deleted or copied text goes. It could be a word, a line, etc. :reg will display the content of all your registers.
I use vim (Actually gvim on windows) as my main text editor. In my work flow I have to copy sentences to/from various external sources, therefore I use clipboard=unnamed to save me key strokes (p instead of "*p).
I copy text from an outer source and I want to paste it over two different places in vim. I mark the first one (v) and then use p to paste over it. The problem is that at this point I lose the original buffer and can't paste it in the second place. It does not exist in the unnamed buffer, the * buffer or the numbered buffers. My guess is that pasting over selection is putting the "pasted over" text in the unnamed buffer.
How can I paste my original string in two locations? i.e. prevent it from getting lost from the buffers.
Thanks.
Try this:
:vmap p "_xP
vmap means to make a mapping that only applies in visual mode.
p is the key to create the mapping for.
"_ is the black hole register. This is used in any situation where you want to delete text without affecting any registers.
xP means delete the selected text, then paste before the resulting cursor position.
You could set up a mapping to ease your pain:
:vmap <F5> "zxP
This will delete the visually selected text, but put it in a different register, so the clipboard isn't affected. Change <F5> to whatever is easiest for you.
I don't know if I misunderstand you but I tried what you are doing and I have no problem in doing that with the + drop-register.
My workflow:
copy a sentence in an external application (ie. browser)
visual select a sentence in vim and replaced it with "+p or p (with clipboard=unnamed set)
visually select another sentence and replace it with "+p
Sadly when pasting the second time you have to explicitly paste from the + register. Therefore I would recommend a mapping for p/P instead of using clipboard=unnamed
nmap p "+p
Try using
:registers
to see the contents of the different registers.
I don't know how to do that on Windows. With KDE, the clipboard has a history that you can select from, so you could do the paste, select the previous selection from the clipboard, and paste in the new location.
That said, it sounds like it might make more sense for you to have it in only one location, then write a script to take that input and create the output you need. Can you elaborate more on what it is you are trying to accomplish?
Check the value of the 'guioptions' options. Make sure the 'a' flag is not set. Also, check that the 'clipboard' option and verify that neither the 'unnamed' or 'autoselect' flags are set.
:set go-=a
:set clipboard-=unnamed