IT story

Vim에서 레지스터에 텍스트를 넣지 않고 삭제할 수있는 방법이 있습니까?

hot-time 2020. 12. 23. 07:33
반응형

Vim에서 레지스터에 텍스트를 넣지 않고 삭제할 수있는 방법이 있습니까?


Vim을 사용하여 코드 블록을 방금 잡아 당긴 블록으로 대체하고 싶습니다.

그러나 교체 할 코드 블록을 삭제하면 해당 블록 자체가 레지스터로 이동하여 방금 잡아 당긴 블록을 지 웁니다. 그래서 나는 홱 잡아 당기고, 삽입하고, 내가 원하지 않는 것을 삭제하는 습관을 가지고 있지만, 큰 코드 블록을 사용하면 삽입 된 블록과 블록을 따로 삭제하려고하는 것이 지저분해진다.

그렇다면 Vim에서 텍스트를 교체하는 가장 빠르고 매끄럽고 빠른 방법은 무엇일까요?

  • 레지스터에 넣지 않고 텍스트를 삭제하는 방법이 있습니까?
  • 예를 들어 "다음 단어 바꾸기"또는 "다음 단락으로 바꾸기"라고 말하는 방법이 있습니까?
  • 아니면 어떻게 든 다중 등록 기능을 사용하는 가장 좋은 방법입니까?

레지스터에 저장하지 않고 삭제하려면 "블랙홀 레지스터"를 사용할 수 있습니다.

"_d

물론 관심있는 항목이없는 다른 레지스터를 사용할 수도 있습니다.


네. "이전"텍스트를 먼저 삭제하는 것보다 약간 복잡하지만 다음과 같습니다.

먼저 ..

line1
line2
line3
line4

old1
old2
old3
old4

나는 shift+ vline1, line 2, 3 및 4를 선택하고 d명령으로 삭제합니다.

그런 다음 이전 1-4 줄을 같은 방식으로 삭제합니다.

그런 다음

"2p

두 번째 마지막 줄을 붙여 넣습니다 (1-4 행). "3p마지막에서 세 번째 작업을 수행합니다.

그래서 나는

line1
line2
line3
line4

참조 : 번호가 매겨진 레지스터에 대한 Vim 문서


VIM 문서 : 번호가 매겨진 레지스터 0에는 명령이 [ "x]로 다른 레지스터를 지정하지 않는 한 가장 최근의 yank 명령의 텍스트가 포함됩니다.

예를 들어 "foo"를 잡아 당기고 "bar"를 삭제합니다. 레지스트리 0에는 여전히 "foo"가 포함되어 있습니다! 따라서 "foo"는 다음을 사용하여 붙여 넣을 수 있습니다."0p


현재 선택을 버퍼로 대체 할 수있는 쉬운 매핑을 갖는 것이 편리합니다.

예를 들어 이것을 .vimrc에 넣으면

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

그런 다음 레지스터에 무언가를 복사 한 후 (예 : 'y') 교체 할 텍스트를 선택하고 키보드에서 'r'을 누르기 만하면됩니다. 선택은 현재 등록으로 대체됩니다.

설명:

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

내 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

이제 클립 보드 레지스터에 홱 잡아 당기고 기본 레지스터에서 어떤 일이 발생하는지 신경 쓸 필요가 없습니다. 또 다른 이점은 번거 로움을 최소화하면서 다른 앱에서 붙여 넣을 수 있다는 것입니다. 일부 기능이 손실되고 있지만 어쨌든 둘 이상의 레지스터 / 클립 보드를 추적 할 수 없습니다.


귀하가 제공 한 특정 예의 경우 질문을 이해하면 다음과 같이 작동 할 수 있습니다.

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

모든 yank 및 delete 작업은 기본적으로 명명되지 않은 레지스터에 기록됩니다. 그러나 가장 최근의 yank와 가장 최근의 삭제는 항상 번호가 매겨진 레지스터에 별도로 저장됩니다. 레지스터 0에는 가장 최근의 yank가 있습니다. 레지스터 1-9에는 가장 최근의 9 개 삭제 항목이 있습니다 ( 1가장 최근 항목 포함).

즉, 삭제는 이름이 지정되지 않은 레지스터의 가장 최근 yank를 덮어 쓰지만 레지스터에는 여전히 존재합니다 0. "_dd다른 답변에서 언급 한 블랙홀 등록 트릭 ( )은 이름이 지정되지 않은 레지스터를 덮어 쓰는 것을 방지하기 때문에 작동하지만 필요하지는 않습니다.

큰 따옴표를 사용하여 레지스터를 참조하므로 가장 최근에 잡아 당긴 텍스트를 다음과 같이 붙여 넣을 수 있습니다.

"0p

이것은 훌륭한 참고 자료입니다.


EBGreen의 말 을 강조하기 위해 :

텍스트를 선택하면서 붙여 넣으면 선택한 텍스트가 붙여 넣은 텍스트 로 바뀝니다 .

일부 텍스트를 복사 한 다음 여러 위치 "0p에 붙여 넣으 려면 사용 하여 붙여 넣으십시오. 번호가 매겨진 레지스터 0에는 가장 최근의 yank 명령의 텍스트가 포함됩니다.


또한 모든 레지스터의 내용을 나열 할 수 있습니다.

:registers

이 명령을 사용하면 dbr 's answer 과 같은 작업을 할 때 원하는 레지스터를 쉽게 파악할 수 있습니다 . /, %, # 레지스터도 볼 수 있습니다. (참조 :help registers)


그리고 마지막으로, 체크 아웃 cWcW후행 공백을 포함하여 포함하지 단어를 변경할 수 있습니다. (대문자 사용 W에는 구두점이 포함됩니다.)


Vim을 사용하는 경우 선택과 같은 시각적 모드가 있지만 vi / vim의 기본이되는 분리 모드가 있습니다.

원하는 것은 시각적 모드를 사용하여 소스를 선택한 다음 얀크 한 다음 다시 시각적 모드를 사용하여 대상 범위를 선택한 다음 기본 버퍼의 텍스트에 붙여 넣는 것입니다.

예:

다음이 포함 된 텍스트 파일 :

1 | qwer
2 | asdf
3 | zxcv
4 | 포 이우

다음 순서로 ggVjyGVkp끝납니다.

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

설명 :

  • gg: 첫 번째 줄로 이동
  • V: 전체 라인으로 비주얼 모드 시작
  • j: 한 줄 아래로 이동 (이전 줄에서 선택을 시작하면 선택 항목이 한 줄 아래로 늘어납니다)
  • y: 기본 버퍼로 홱 잡아 당기십시오 (선택된 두 줄이 자동으로 비주얼 모드를 종료합니다)
  • G: 마지막 줄로 이동
  • V: 시각 모드 시작 (이전과 동일)
  • k: 한 줄 위로 이동 (이전과 마찬가지로 시각적 모드가 활성화 된 경우 선택 항목이 한 줄 위로 증가 함)
  • 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.


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

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


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

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.


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


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.


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...


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


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.


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.


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.


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


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.


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

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

반응형