Trong Vim có cách nào để xóa mà không đưa văn bản vào sổ đăng ký không?


470

Sử dụng Vim tôi thường muốn thay thế một khối mã bằng một khối mà tôi vừa kéo.

Nhưng khi tôi xóa khối mã cần thay thế, chính khối đó sẽ đi vào thanh ghi xóa khối mà tôi vừa kéo. Vì vậy, tôi đã có thói quen kéo dài, sau đó chèn, sau đó xóa những gì tôi không muốn, nhưng với các khối mã lớn, điều này trở nên lộn xộn khi cố gắng giữ khối được chèn và khối để xóa riêng.

Vì vậy, cách nhanh nhất và nhanh nhất để thay thế văn bản trong Vim là gì?

  • Có cách nào để xóa văn bản mà không đưa nó vào sổ đăng ký không?
  • có cách nào để nói ví dụ: "thay thế từ tiếp theo" hoặc "thay thế cho đoạn tiếp theo"
  • hoặc là cách tốt nhất để sử dụng tính năng đa đăng ký bằng cách nào đó?

1
vim-Easyclip ( github.com/svermeulen/vim-easyclip ) được thiết kế để giải quyết vấn đề chính xác này
Steve Vermeulen

1
Tôi đã hỏi một câu hỏi, vô tình (tại thời điểm đó) trùng lặp với vấn đề thực tế của bạn , nhưng không quá nhiều câu hỏi tiêu đề. TL; DR - thay thế bằng những gì bạn đã sử dụng viwp(đối với word).
OJFord 4/2/2015

Câu trả lời:


429

Để xóa một cái gì đó mà không lưu nó trong một thanh ghi, bạn có thể sử dụng "thanh ghi lỗ đen":

"_d

Tất nhiên, bạn cũng có thể sử dụng bất kỳ thanh ghi nào khác không chứa bất cứ thứ gì bạn quan tâm.


4
Lúc đầu tôi nghĩ lệnh này không hoạt động đúng. Sau đó, tôi nhận ra mình đang sử dụng phiên bản "phím chết" của bàn phím mỹ. Với cách bố trí bàn phím này tôi phải gõ "<space>_d. Không gian là cần thiết để thực sự gõ ".
Sebastián Grignoli

4
Bất kỳ ý tưởng về việc làm này có chọn lọc trên các dòng trống? (Nếu tôi ddtrên một dòng trống, nó sẽ đi vào lỗ đen, nếu không thì nó ddgiống như bình thường).
Jonathan Dumaine

6
Để xóa một ký tự, hãy thử:"_x
kenorb

54
Đây là một lĩnh vực mà một trình soạn thảo văn bản tiêu chuẩn chiến thắng. Bạn chỉ cần nhấn phím xóa.
Vince Panuccio

22
Bạn cũng có thể lấy một cái gì đó bằng yyhoặc '3yy' (hoặc bất cứ thứ gì), đặt nó vào thanh ghi không tên, nhưng cũng bằng 0. Bạn có thể tiếp tục dán nó "0p, mặc dù đã sử dụng dsau đó.
Halfgaar

102

Vâng. Nó hơi phức tạp hơn trước khi xóa văn bản "cũ", nhưng:

Tôi bắt đầu với ..

line1
line2
line3
line4

old1
old2
old3
old4

Tôi shift+ vchọn dòng1, dòng 2, 3 và 4 và xóa chúng bằng dlệnh

Sau đó, tôi xóa các dòng 1-4 cũ theo cùng một cách.

Sau đó, làm

"2p

Điều đó sẽ dán các dòng được kéo dài thứ hai (dòng 1-4). "3psẽ làm thứ ba từ cuối cùng, v.v.

Vì vậy, tôi kết thúc với

line1
line2
line3
line4

Tham khảo: Tài liệu Vim về đăng ký đánh số


Nếu bạn chọn các dòng có <Shift-v>, bạn sẽ xóa chúng chỉ bằng d, không phải dd
Heikki Naski

31
1 đến 9 hoạt động để xóa. Để dán thứ cuối cùng thực sự kéo mạnh (với 'y'), bạn phải sử dụng "0p. Điều đó hữu ích trong trường hợp trước tiên bạn có một cái gì đó có ý định thay thế một cái gì đó khác, nhưng sau đó một cái gì đó ghi đè lên thanh ghi dán mặc định.
Rafael de F. Ferreira

Để biết thêm undo kiểm tra phức tạp ra các Gundo (undo đồ họa) kịch bản .
Lumi

@ RafaeldeF.Ferreira: Nhận xét của bạn không phải là câu trả lời cho câu hỏi này, nhưng nó thực sự giải quyết được vấn đề thực tế khiến OP phải đặt câu hỏi ngay từ đầu. Đối với tôi, đó là vấn đề thực sự.
0xc0de

76

Tài liệu VIM: Thanh ghi được đánh số 0 chứa văn bản từ lệnh yank gần đây nhất, trừ khi lệnh chỉ định một thanh ghi khác có ["x].

Ví dụ: chúng tôi đã lấy "foo" và xóa "thanh" - sổ đăng ký 0 vẫn chứa "foo"! Do đó "foo" có thể được dán bằng cách sử dụng"0p


53

Thật tiện lợi khi có một ánh xạ dễ dàng cho phép bạn thay thế lựa chọn hiện tại bằng bộ đệm.

Ví dụ: khi bạn đặt cái này trong .vimrc của bạn

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

sau đó, sau khi sao chép một cái gì đó vào thanh ghi (tức là với 'y'), bạn có thể chỉ cần chọn văn bản mà bạn muốn được thay thế và chỉ cần nhấn 'r' trên bàn phím. Việc lựa chọn sẽ được thay thế bằng đăng ký hiện tại của bạn.

Giải trình:

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

1
Để có phiên bản nâng cao hơn, hãy kiểm tra: stackoverflow.com/questions/290465/
Thẻ

Tôi muốn sử dụngvmap <C-P> "_dP
Harry Lee

7
Bạn chỉ có thể đặt văn bản mà không xóa lựa chọn. Ví dụ, Vpthay thế dòng hiện tại của bạn bằng dòng được lấy ngay lập tức.
Bobby Marinoff

Giải pháp này không khắc phục được vấn đề dthường được sử dụng để xóa.
Victor Yarema

35

Tôi đặt như sau trong vimrc của tôi:

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

Bây giờ tôi đã kéo và đặt từ thanh ghi clipboard và không phải quan tâm điều gì xảy ra với thanh ghi mặc định. Một lợi ích bổ sung là tôi có thể dán từ các ứng dụng khác với rắc rối tối thiểu. Tôi đang mất một số chức năng, tôi biết, nhưng tôi chỉ không thể theo dõi nhiều hơn một đăng ký / clipboard.


6
Thay vì tất cả các bản sửa lỗi đó, bạn cũng có thể set clipboard=unnamedhoặc set clipboard=unnamedplus, thay đổi bảng tạm mặc định thành *hoặc +, tương ứng.
Steve

5
@Steve Nếu bạn làm điều đó, thì d sẽ ghi đè lên yank cuối cùng vào thanh ghi clipboard, đó là những gì câu hỏi đang cố gắng tránh.
79E09796

1
@ 79E09796, tôi không có ý ám chỉ rằng nó sẽ; Tôi đã bình luận về câu trả lời này và không phải là câu hỏi ban đầu.
Steve

1
Tôi đặt những thứ này trong .vimrc của tôi và bây giờ yanking không hoạt động. Bất cứ ý tưởng tại sao?
tba

2
@tba thay thế noremap bằng nnoremap (hai n) và nó sẽ hoạt động tốt.
meain

24

Đối với ví dụ cụ thể mà bạn đã đưa ra, nếu tôi hiểu câu hỏi thì điều này có thể hoạt động:

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

6
Điều này hoạt động tốt trừ khi bạn muốn dán qua nhiều lựa chọn.

23

Tất cả các hoạt động yank và xóa ghi vào thanh ghi không tên theo mặc định. Tuy nhiên, lần xóa gần đây nhất và gần đây nhất luôn được lưu trữ (riêng) trong các thanh ghi được đánh số. Sổ đăng ký 0giữ yank gần đây nhất. Các thanh ghi 1-9giữ 9 lần xóa gần đây nhất (với lần xóa 1gần đây nhất).

Nói cách khác, việc xóa ghi đè lên yank gần đây nhất trong sổ đăng ký chưa được đặt tên, nhưng nó vẫn còn trong 0sổ đăng ký. Thủ thuật đăng ký lỗ đen ( "_dd) được đề cập trong các câu trả lời khác hoạt động vì nó ngăn chặn việc ghi đè lên thanh ghi không tên, nhưng không cần thiết.

Bạn tham chiếu một thanh ghi bằng cách sử dụng dấu ngoặc kép, do đó, việc dán văn bản được sắp xếp gần đây nhất có thể được thực hiện như sau:

"0p

Đây là một tài liệu tham khảo tuyệt vời:


16

Để nhấn mạnh những gì EBGreen đã nói :

Nếu bạn dán trong khi chọn văn bản, văn bản đã chọn sẽ được thay thế bằng văn bản đã dán.

Nếu bạn muốn sao chép một số văn bản và sau đó dán nó vào nhiều vị trí, sử dụng "0pđể dán. Thanh ghi được đánh số 0 chứa văn bản từ lệnh yank gần đây nhất.


Ngoài ra, bạn có thể liệt kê nội dung của tất cả các thanh ghi của bạn:

:registers

Lệnh đó giúp dễ dàng hơn trong việc tìm ra đăng ký bạn muốn khi làm điều gì đó như câu trả lời của dbr . Bạn cũng sẽ thấy các thanh ghi /,%, #. (Xem thêm :help registers)


Và cuối cùng, hãy kiểm tra cWcWthay đổi một từ bao gồm và không bao gồm một khoảng trắng ở cuối. (Sử dụng vốn Wbao gồm dấu câu.)


10

Nếu bạn đang sử dụng Vim thì bạn sẽ có chế độ trực quan, giống như chọn, nhưng với chế độ tách biệt, đó là cơ sở của vi / vim.

Những gì bạn muốn làm là sử dụng chế độ trực quan để chọn nguồn, sau đó kéo dài, sau đó sử dụng lại chế độ trực quan để chọn phạm vi của đích và sau đó dán vào văn bản từ bộ đệm mặc định.

Thí dụ:

Trong tệp văn bản có:

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

với trình tự sau: ggVjyGVkpbạn sẽ kết thúc bằng:

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

Giải thích:

  • gg: đi đến dòng đầu tiên
  • V: bắt đầu chế độ trực quan với toàn bộ dòng
  • j: đi xuống một dòng (với lựa chọn bắt đầu trên các dòng trước, điều này sẽ tăng lựa chọn xuống một dòng)
  • y: yank vào bộ đệm mặc định (hai dòng được chọn và nó tự động thoát khỏi chế độ trực quan)
  • G: đi đến dòng cuối cùng
  • V: bắt đầu chế độ trực quan (giống như trước)
  • k: đi lên một dòng (như trước đây, với chế độ trực quan được bật, điều này sẽ tăng lựa chọn một dòng lên)
  • p: paste (với lựa chọn trên hai dòng cuối cùng, nó sẽ thay thế các dòng đó bằng bất cứ thứ gì có trong bộ đệm - 2 dòng đầu tiên trong trường hợp này)

Điều này có một chút bất tiện khi đặt khối cuối cùng vào bộ đệm, do đó, bằng cách nào đó không mong muốn cho các lần dán lặp lại của cùng một thứ, vì vậy bạn sẽ muốn lưu nguồn vào bộ đệm có tên như "ay(vào bộ đệm có tên là "a ") và dán bằng thứ gì đó như "ap(nhưng sau đó nếu bạn đang lập trình, có lẽ bạn không muốn dán nhiều lần mà chỉ tạo một hàm và gọi nó, phải không? ĐÚNG ?).

Nếu bạn chỉ sử dụng vi, thì bạn sẽ phải sử dụng các dấu vô hình thay vì chế độ trực quan, :he markđể biết thêm về điều này, tôi xin lỗi nhưng tôi không rành lắm với điều đánh dấu vô hình này, tôi khá ô nhiễm với chế độ trực quan.


10

Đối với 'thay thế từ', hãy thử cwở chế độ bình thường.

Đối với 'thay thế đoạn', hãy thử capở chế độ bình thường.


1
Để 'thay thế đến đoạn tiếp theo', hãy thử c}ở chế độ bình thường.
jabirali

Tại sao "nắp" làm điều này? Không phải là "a" và "p" là viết tắt của "chắp thêm" và "dán"?
WiSaGaN

2
@WiSaGaN "ap" là viết tắt của "một đoạn": vimhelp.appspot.com/motion.txt.html#object-select
Swaroop CH

9

Một giải pháp xâm lấn tối thiểu cho những người lười biếng:

Đăng ký 0luôn chứa các yank cuối cùng (như Rafael , alex2k8idbrii đã đề cập). Thật không may, việc chọn đăng ký 0mọi lúc có thể khá khó chịu, vì vậy sẽ rất tuyệt nếu psử dụng "0theo mặc định. Điều này có thể đạt được bằng cách đặt các dòng sau vào .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

Dòng đầu tiên ánh xạ mỗi pnét đến "0p. Tuy nhiên, điều này ngăn chặn ptruy cập vào bất kỳ đăng ký khác. Do đó, tất cả các pnét với một thanh ghi được chọn rõ ràng được ánh xạ tới biểu thức dòng lệnh tương đương trong vòng lặp for. Điều tương tự được thực hiện cho P.

Bằng cách này, hành vi tiêu chuẩn được bảo tồn, ngoại trừ ẩn pPđột quỵ, hiện sử dụng đăng ký 0theo mặc định.

Gợi ý 1: Lệnh cắt bây giờ "0dthay vì chỉ d. Nhưng vì tôi lười nên điều này quá dài đối với tôi;) Vì vậy, tôi đang sử dụng ánh xạ sau:

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

Khóa lãnh đạo \theo mặc định, vì vậy bạn có thể dễ dàng cắt văn bản bằng cách nhập \dhoặc \D.

Gợi ý 2: Thời gian chờ mặc định cho ánh xạ đa khóa khá ngắn. Bạn có thể muốn tăng nó để có thêm thời gian khi chọn đăng ký. Xem :help timeoutlenđể biết chi tiết, tôi đang sử dụng:

set timeout timeoutlen=3000 ttimeoutlen=100

7

Vâng, đầu tiên làm lệnh này:

:h d

Sau đó, bạn sẽ nhận ra rằng bạn có thể xóa vào một đăng ký cụ thể. Bằng cách đó, bạn sẽ không thay đổi những gì trong đăng ký mặc định của bạn.


1
["x]d{motion} Delete text that {motion} moves over [into register x]- Vim:h d
Wes Turner

5

Tình huống của tôi: trong Normalchế độ, khi tôi xóa các ký tự bằng cách xnhấn phím, các thao tác xóa đó sẽ ghi đè lên thanh ghi mới nhất của tôi - làm phức tạp các chỉnh sửa trong đó tôi muốn xóa các ký tự bằng cách sử dụng xvà dán thứ gì đó tôi có trong sổ đăng ký gần đây nhất của mình (ví dụ: dán cùng một văn bản vào hai hoặc nhiều nơi hơn).

Tôi đã thử đề xuất trong câu trả lời được chấp nhận ( "_d), nhưng nó không hoạt động.

Tuy nhiên, từ câu trả lời / nhận xét được chấp nhận tại /vi/122/performing-certain-operations-without-clear-register , tôi đã thêm nó vào ~/.vimrc, cái này hoạt động (bạn có thể phải khởi động lại Vim ):

nnoremap x "_x

Đó là, bây giờ tôi có thể thực hiện các lệnh yank ( y), xóa ( d) và dán ( p) bình thường của mình - và các ký tự tôi xóa bằng cách xkhông sử dụng các thanh ghi gần đây nhất.


4

Văn bản đã bị xóa, trong khi ở chế độ chèn, không đi vào đăng ký mặc định.


2
nhưng xóa bất kỳ số lượng văn bản đáng kể nào trong chế độ mặc định là SLOW
Hamish Downer

3

Hai giải pháp tôi sử dụng trong bối cảnh phù hợp là;

  • làm nổi bật những gì bạn muốn thay thế bằng VISUALchế độ Vims sau đó dán thanh ghi.

Tôi sử dụng điều này chủ yếu theo thói quen vì tôi chỉ tìm thấy giải pháp thứ hai muộn hơn, vd

yiw   " yank the whole word
viwp  " replace any word with the default register
  • YankRing . Với plugin này, bạn có thể sử dụng phím <ctrl>+<p>bấm để thay thế thanh ghi được đánh số trước đó bằng thanh ghi bạn vừa dán.

Về cơ bản, bạn sẽ tiếp tục dán như bạn muốn, nhưng khi bạn nhận ra rằng bạn đã ghi đè lên thanh ghi mặc định, do đó mất đi những gì bạn thực sự muốn dán, bạn có thể <C-P>tìm và thay thế từ lịch sử YankRing!

Một trong số đó phải có plugin ...



2

Trong phiên bản windows (có thể trong Linux cũng vậy), bạn có thể kéo vào bộ đệm sao chép / dán của hệ thống bằng cách sử dụng "*y(tức là trước lệnh yank của bạn với dấu ngoặc kép và dấu hoa thị).

Sau đó, bạn có thể xóa các dòng có thể thay thế bình thường và dán văn bản đã sao chép bằng cách sử dụng "*p.


2

Tôi thường mắc lỗi khi làm theo các lệnh để 'y'ank then' "_d'elete vào một lỗ đen rồi 'p'aste. Tôi thích' y'ank, sau đó xóa theo cách tôi thích, sau đó '" 0p' từ thanh ghi 0, là nơi mà văn bản sao chép cuối cùng được đẩy tới.


2

Đối với người dùng emacs-evil, chức năng này (evil-paste-pop)có thể được kích hoạt sau khi dán và chuyển qua các mục trước trong vòng kill. Giả sử bạn đã ràng buộc nó <C-p>(mặc định trong Spacemacs), bạn sẽ đạt pđược nhiều thứ <C-p>cần thiết.


1

Đối với người dùng Dvorak, một phương pháp rất thuận tiện là chỉ cần xóa văn bản không cần thiết vào "thanh ghi 1 thay vì" thanh ghi lỗ đen, nếu chỉ vì bạn có thể nhấn "+ 1 với cùng một lần nhấn shift và chuyển động hồng hào nhanh từ 1 chìa khóa ngay phía trên "trong Dvorak (PLUS d nằm ở mặt khác, khiến cho toàn bộ lệnh nhanh như địa ngục).

Tất nhiên, sau đó, "1 thanh ghi có thể được sử dụng cho những thứ khác vì sự tiện lợi của nó, nhưng trừ khi bạn có mục đích phổ biến hơn là thay thế văn bản, tôi nói rằng đó là cách sử dụng thanh ghi khá tốt.


1

Đối với những người bạn quan tâm chính không ghi đè lên thanh ghi không tên khi bạn thay thế một văn bản thông qua lựa chọn ảo và dán.

Bạn có thể sử dụng giải pháp sau đây dễ dàng và hiệu quả nhất với tôi:

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

Đó là từ câu trả lời (và ý kiến) ở đây: Cách dán mà không cần ghi đè

Nó qua lựa chọn trước, sau đó lựa chọn với văn bản mới được chọn lại (gv). Bây giờ thanh ghi được sử dụng lần cuối trong chế độ trực quan (thông thường là thanh ghi không tên nhưng hoạt động cũng không có tác dụng phụ nếu bạn sử dụng một thanh ghi khác để dán). Và sau đó kéo giá trị mới vào thanh ghi một lần nữa.

PS: Nếu bạn cần một biến thể đơn giản hơn, cũng hoạt động với mô phỏng vim-plugin intellj, bạn có thể lấy cái này (nhược điểm: ghi đè lên thanh ghi không tên ngay cả khi đăng ký khác được đưa ra để dán):

vnoremap p pgvy



0

Sở thích thỉnh thoảng của Vim vì sự phức tạp so với tính thực tế gây gánh nặng cho người dùng khi áp dụng các thanh ghi để sao chép / xóa hành động - khi thường xuyên hơn, người ta chỉ muốn dán những gì đã sao chép và "quên" những gì đã bị xóa.

Tuy nhiên, thay vì chống lại các thanh ghi phức tạp của vim, hãy làm cho chúng thuận tiện hơn: chọn một thanh ghi "mặc định" để lưu trữ lần xóa mới nhất của bạn. Ví dụ: gửi xóa đến thanh ghi d (để mở ac cho sử dụng đặc biệt; d là một bản ghi nhớ đẹp):

nnoremap d "dd           "send latest delete to d register
nnoremap D "dD           "send latest delete to d register 
nnoremap dd "ddd         "send latest delete to d register
nnoremap x "_x           "send char deletes to black hole, not worth saving
nnoremap <leader>p "dp   "paste what was deleted
nnoremap <leader>P "dP   "paste what was deleted

Cách tiếp cận này ngăn chặn việc xóa khỏi các dấu hiệu bị chặn, nhưng NHƯNG không đăng ký xóa - người ta có thể dán (trở lại) những gì đã bị xóa thay vì mất nó trong một lỗ đen (như trong câu trả lời được chấp nhận). Trong ví dụ trên, việc thu hồi này được thực hiện với hai ánh xạ p lãnh đạo. Một lợi ích của phương pháp này, là nó cung cấp cho bạn khả năng chọn những gì cần dán: (a) những gì vừa được kéo, hoặc (b) những gì vừa bị xóa.


0

đăng ký 0 đến 9 là những điều mới nhất bạn đã cắt hoặc cắt, v.v. và KHÔNG bao gồm những thứ đã bị xóa, v.v. vẫn là thứ cuối cùng bạn kéo / cắt.

yiw #goes cho cả đăng ký mặc định và đăng ký 0

nó kéo từ con trỏ vào

công cụ bị xóa, vv sẽ đi đến đăng ký mặc định, nhưng KHÔNG đăng ký 0

ở chế độ tiêu chuẩn:

"0p #put nội dung đăng ký 0

trong chế độ chèn:

ctrl-r 0 #put nội dung của thanh ghi 0

Tôi cũng có một người bạn luôn kéo / cắt để đăng ký x lol.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.