In Vim is there a way to delete without putting text in the register?

谁都会走 提交于 2019-11-26 05:59:36

问题


Using Vim I often want to replace a block of code with a block that I just yanked.

But when I delete the block of code that is to be replaced, that block itself goes into the register which erases the block I just yanked. So I\'ve got in the habit of yanking, then inserting, then deleting what I didn\'t want, but with large blocks of code this gets messy trying to keep the inserted block and the block to delete separate.

So what is the slickest and quickest way to replace text in Vim?

  • is there a way to delete text without putting it into the register?
  • is there a way to say e.g. \"replace next word\" or \"replace up to next paragraph\"
  • or is the best way to somehow use the multi-register feature?

回答1:


To delete something without saving it in a register, you can use the "black hole register":

"_d

Of course you could also use any of the other registers that don't hold anything you are interested in.




回答2:


Yep. It's slightly more convoluted than deleting the "old" text first, but:

I start off with..

line1
line2
line3
line4

old1
old2
old3
old4

I shift+v select the line1, line 2, 3 and 4, and delete them with the d command

Then I delete the old 1-4 lines the same way.

Then, do

"2p

That'll paste the second-last yanked lines (line 1-4). "3p will do the third-from-last, and so on..

So I end up with

line1
line2
line3
line4

Reference: Vim documentation on numbered register




回答3:


VIM docs: Numbered register 0 contains the text from the most recent yank command, unless the command specified another register with ["x].

E.g. we yank "foo" and delete "bar" - the registry 0 still contains "foo"! Hence "foo" can be pasted using "0p




回答4:


It's handy to have an easy mapping which lets you replace the current selection with buffer.

For example when you put this in your .vimrc

vmap r "_dP       // it's a capital 'p' on the end

then, after copying something into register (i.e. with 'y'), you can just select the text which you want to be replaced, and simply hit 'r' on your keyboard. The selection will be substituted with your current register.

Explanation:

vmap - mapping for visual mode
"_d - delete current selection into "black hole register"
P - paste



回答5:


I put the following in my vimrc:

noremap  y "*y
noremap  Y "*Y
noremap  p "*p
noremap  P "*P
vnoremap y "*y
vnoremap Y "*Y
vnoremap p "*p
vnoremap P "*P

Now I yank to and put from the clipboard register, and don't have to care what happens with the default register. An added benefit is that I can paste from other apps with minimal hassle. I'm losing some functionality, I know, but I just can't keep track of more than one register/clipboard anyway.




回答6:


For the specific example that you gave, if I understand the question then this might work:

*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)



回答7:


All yank and delete operations write to the unnamed register by default. However, the most recent yank and most recent delete are always stored (separately) in the numbered registers. The register 0 holds the most recent yank. The registers 1-9 hold the 9 most recent deletes (with 1 being the most recent).

In other words, a delete overwrites the most recent yank in the unnamed register, but it's still there in the 0 register. The blackhole-register trick ("_dd) mentioned in the other answers works because it prevents overwriting the unnamed register, but it's not necessary.

You reference a register using double quotes, so pasting the most recently yanked text can be done like this:

"0p

This is an excellent reference:

  • http://blog.sanctum.geek.nz/advanced-vim-registers/



回答8:


To emphasize what EBGreen said:

If you paste while selecting text, the selected text is replaced with the pasted text.

If you want to copy some text and then paste it in multiple locations, use "0p to paste. Numbered register 0 contains the text from the most recent yank command.


Also, you can list the contents of all of your registers:

:registers

That command makes it easier to figure out what register you want when doing something like dbr's answer. You'll also see the /,%,# registers. (See also :help registers)


And finally, check out cW and cW to change a word including and not including an trailing space. (Using capital W includes punctuation.)




回答9:


If you're using Vim then you'll have the visual mode, which is like selecting, but with the separating modes thing that's the basis of vi/vim.

What you want to do is use visual mode to select the source, then yank, then use visual mode again to select the scope of the destination, and then paste to text from the default buffer.

Example:

In a text file with:

1| qwer
2| asdf
3| zxcv
4| poiu

with the following sequence: ggVjyGVkp you'll end with:

1| qwer
2| asdf
3| qewr
4| asdf

Explained:

  • gg: go to first line
  • V: start visual mode with whole lines
  • j: go down one line (with the selection started on the previous lines this grows the selection one line down)
  • y: yank to the default buffer (the two selected lines, and it automatically exits you from visual mode)
  • G: go to the last line
  • V: start visual mode (same as before)
  • k: go up one line (as before, with the visual mode enabled, this grows the selection one line up)
  • p: paste (with the selection on the two last lines, it will replace those lines with whatever there is in the buffer -- the 2 first lines in this case)

This has the little inconvenient that puts the last block on the buffer, so it's somehow not desired for repeated pastings of the same thing, so you'll want to save the source to a named buffer with something like "ay (to a buffer called "a") and paste with something like "ap (but then if you're programming, you probably don't want to paste several times but to create a function and call it, right? RIGHT?).

If you are only using vi, then youll have to use invisible marks instead the visual mode, :he mark for more on this, I'm sorry but I'm not very good with this invisible marks thing, I'm pretty contaminated with visual mode.




回答10:


For 'replace word', try cw in normal mode.

For 'replace paragraph', try cap in normal mode.




回答11:


A minimal invasive solution for the lazy ones:

Register 0 always contains the last yank (as Rafael, alex2k8 and idbrii have already mentioned). Unfortunately selecting register 0 all the time can be quite annoying, so it would be nice if p uses "0 by default. This can be achieved by putting the following lines into your .vimrc:

noremap p "0p
noremap P "0P
for s:i in ['"','*','+','-','.',':','%','/','=','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
    execute 'noremap "'.s:i.'p "'.s:i.'p'
    execute 'noremap "'.s:i.'P "'.s:i.'P'
endfor

The first line maps each p stroke to "0p. However, this prevents p from accessing any other registers. Therefore all p strokes with an explicitly selected register are mapped to the equivalent commandline expression within the for-loop. The same is done for P.

This way the standard behaviour is preserved, except for the implicit p and P strokes, which now use register 0 by default.

Hint 1: The cut command is now "0d instead of just d. But since I'm lazy this is way too long for me ;) Therefore I'm using the following mapping:

noremap <LEADER>d "0d
noremap <LEADER>D "0D

The leader key is \ by default, so you can easily cut text by typing \d or \D.

Hint 2: The default timeout for multi-key mappings is pretty short. You might want to increase it to have more time when selecting a register. See :help timeoutlen for details, I'm using:

set timeout timeoutlen=3000 ttimeoutlen=100



回答12:


Well, first do this command:

:h d

Then you will realize that you can delete into a specific register. That way you won't alter what is in your default register.




回答13:


Text deleted, while in insert mode, doesn't go into default register.




回答14:


My situation: in Normal mode, when I delete characters using the x keypress, those deletions overwrite my latest register -- complicating edits where I want to delete characters using x and paste something I have in my most recent register (e.g. pasting the same text at two or more places).

I tried the suggestion in the accepted answer ("_d), but it did not work.

However, from the accepted answer/comments at https://vi.stackexchange.com/questions/122/performing-certain-operations-without-clearing-register, I added this to my ~/.vimrc, which works (you may have to restart Vim):

nnoremap x "_x

That is, I can now do my normal yank (y), delete (d), and paste (p) commands -- and characters I delete using x no longer populate the most recent registers.




回答15:


The two solutions I use in the right contexts are;

  • highlight what you want to replace using Vims VISUAL mode then paste the register.

I use this mostly out of habit as I only found the second solution much later, eg

yiw   " yank the whole word
viwp  " replace any word with the default register
  • YankRing. With this plugin you can use the keybinding <ctrl>+<p> to replace the previous numbered register with the one you just pasted.

Basically you go about pasting as you would, but when you realise that you have since overwritten the default register thus losing what you actually wanted to paste you can <C-P> to find and replace from the YankRing history!

One of those must have plugins...




回答16:


I found a very useful mapping for your purpose:

xnoremap p "_dP

Deleted text is put in "black hole register", and the yanked text remains.

Source: http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text




回答17:


In the windows version (probably in Linux also), you can yank into the system's copy/paste buffer using "*y (i.e. preceding your yank command with double-quotes and asterisk).

You can then delete the replaceable lines normally and paste the copied text using "*p.




回答18:


I often make a mistake when following the commands to 'y'ank then '"_d'elete into a black hole then 'p'aste. I prefer to 'y'ank, then delete however I like, then '"0p' from the 0 register, which is where the last copied text gets pushed to.




回答19:


For emacs-evil users, the function (evil-paste-pop) can be triggered after pasting, and cycles through previous entries in the kill-ring. Assuming you bound it to <C-p> (default in Spacemacs), you would hit p followed by as many <C-p> as needed.




回答20:


For Dvorak users, one very convenient method is to just delete unneeded text into the "1 register instead of the "_ black hole register, if only because you can press " + 1 with the same shift press and a swift pinky motion since 1 is the key immediately above " in Dvorak (PLUS d is in the other hand, which makes the whole command fast as hell).

Then of course, the "1 register could be used for other things because of it's convenience, but unless you have a purpose more common than replacing text I'd say it's a pretty good use of the register.




回答21:


For those of you who are primary interested of not overwriting the unnamed register when you replace a text via virtual selection and paste.

You could use the following solution which is easy and works best for me:

xnoremap <expr> p 'pgv"'.v:register.'y'

It's from the answers (and comments) here: How to paste over without overwriting register

It past the selection first, then the selection with the new text is selected again (gv). Now the register which was last used in visual mode (normally the unnamed register but works also side effect free if you use another register for pasting). And then yank the new value to the register again.

PS: If you need a simpler variant which works also with intellj idea plugin vim-simulation you can take this one (downside: overwrite unnamed register even if another register was given for pasting):

vnoremap p pgvy




回答22:


For those who use JetBrans IDE (PhpStorm, WebStorm, IntelliJ IDEA) with IdeaVim. You may be experiencing problems with remapping like nnoremap d "_d and using it to delete a line dd. Possible solution for you: nnoremap dd "_dd

There are issues on youtrack, please vote for them: https://youtrack.jetbrains.com/issue/VIM-1189 https://youtrack.jetbrains.com/issue/VIM-1363



来源:https://stackoverflow.com/questions/54255/in-vim-is-there-a-way-to-delete-without-putting-text-in-the-register

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!