VIM Thay thế từ bằng nội dung của bộ đệm dán?


110

Tôi cần thực hiện một loạt các thay thế từ trong một tệp và muốn thực hiện bằng lệnh vi, không phải lệnh EX chẳng hạn :%s///g. Tôi biết rằng đây là cách thông thường để thay thế từ tại vị trí con trỏ hiện tại: cw<text><esc>nhưng có cách nào để thực hiện việc này với nội dung của thanh ghi không có tên như văn bản thay thế và không ghi đè lên thanh ghi không?


8
GIẢI PHÁP: Đối với nhu cầu trước mắt của tôi, tôi đã sử dụng 12yl12 ký tự "_cw^r0để thay thế một từ. Sau đó, tôi đã có thể sử dụng .lệnh để lặp lại việc thay thế trong toàn bộ tệp.
kéo dài

Câu trả lời:


127

Tôi đang nghĩ bằng cách "dán" bạn có nghĩa là thanh ghi không tên (yank / đặt / thay đổi / xóa / thay thế), phải không? (Vì đó là lệnh sẽ bị ghi đè bởi lệnh thay đổi.)

Thanh ghi thường được chỉ định bằng cách gõ "tên (ký tự đơn) của thanh ghi, như "aysau đó "apkéo vào thanh ghi a, sau đó nhập nội dung của thanh ghi a. Tương tự với lệnh thay đổi. Trong trường hợp này, nếu bạn không muốn các văn bản bạn loại bỏ bằng lệnh thay đổi để đi bất cứ nơi nào, bạn có thể sử dụng đăng ký lỗ đen "_: "_cw. Sau đó, khi ở chế độ chèn, bạn có thể nhấn ctrl-R theo sau vào thanh ghi mà bạn muốn (có thể ") để đưa nội dung của thanh ghi đó vào.

  • "* - đăng ký lựa chọn (dán nút giữa)
  • "+ - thanh ghi clipboard (có thể cũng có thể truy cập bằng ctrl-shift-v thông qua thiết bị đầu cuối)
  • "" - thanh ghi mặc định (không được đặt tên) của vim yank / put / change / delete / thay thế.

Câu trả lời ngắn: "_cw^R"

Chỉnh sửa: như những người khác đang đề xuất, tất nhiên bạn có thể sử dụng một thanh ghi khác cho yank (hoặc bất cứ thứ gì) đã đưa văn bản của bạn vào thanh ghi mặc định. Tuy nhiên, không phải lúc nào bạn cũng nghĩ đến điều đó đầu tiên, vì vậy thật tuyệt khi thực hiện một lệnh thay đổi duy nhất mà không làm mất nó. Mặc dù nó không hoàn toàn bị thổi bay. Có các thanh ghi được đánh số "0thông qua "9:

Vim điền vào các thanh ghi này bằng văn bản từ các lệnh yank và delete.

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 với ["x].

Thanh ghi được đánh số 1 chứa văn bản bị xóa bởi lệnh xóa hoặc thay đổi gần đây nhất, trừ khi lệnh chỉ định một thanh ghi khác hoặc văn bản ít hơn một dòng (thanh ghi xóa nhỏ được sử dụng sau đó). Một ngoại lệ được thực hiện cho các nhà điều hành xóa với các lệnh chuyển động: %, (, ), `, /, ?, n, N, {}. Thanh ghi "1 luôn được sử dụng sau đó (điều này tương thích với Vi). Thanh ghi" - cũng được sử dụng nếu việc xóa nằm trong một dòng.

Với mỗi lần xóa hoặc thay đổi liên tiếp, Vim chuyển nội dung trước đó của thanh ghi 1 thành thanh ghi 2, 2 thành 3, v.v., làm mất nội dung trước đó của thanh ghi 9.


1
Được rồi, nghĩ rằng tôi đã sao chép đủ tài liệu trên sổ đăng ký vào câu trả lời của mình chưa? Đó là tất cả dưới đây :help registers.
Cascabel

48

Sử dụng thông tin trong bài đăng này, tôi đã hình thành bản đồ hữu ích này. Tôi chọn 'cp' vì nó biểu thị "thay đổi dán"

nmap <silent> cp "_cw<C-R>"<Esc>

BIÊN TẬP:

Ngoài ra, tôi đã tiến thêm một bước nữa và ủng hộ mọi chuyển động.

Để nhận được lệnh tương đương ở trên, nó sẽ là cpw"thay đổi dán từ"

"This allows for change paste motion cp{motion}
nmap <silent> cp :set opfunc=ChangePaste<CR>g@
function! ChangePaste(type, ...)
    silent exe "normal! `[v`]\"_c"
    silent exe "normal! p"
endfunction

<silent> khiến nó không hoạt động với tôi ... bất kỳ ý kiến ​​nào tại sao lại như vậy? Tôi là một n00b trong ánh xạ và chức năng.
Hollister

Vấn đề duy nhất với điều này là bạn không thể chọn một thanh ghi để dán với ... nhưng trong trường hợp đó tôi cho rằng bạn chỉ có thể CW và sử dụng tổ hợp phím CTRL + R
Steve Vermeulen

2
Có thể có một cách tốt hơn để thêm đăng ký đặt tên nhưng các công việc sau cho tôi: nmap <silent> cp :let g:currentRegister=v:register<cr>:set opfunc=ChangePaste<CR>g@ function! ChangePaste(type, ...) silent exe "normal! `[v`]\"_c".getreg(g:currentRegister) endfunction
Steve Vermeulen

@eventualEntropy cái này hoạt động tốt để thay thế dòng, làm thế nào để tôi có thể làm cho cái này hoạt động cho các từ thay vì dòng, tôi vẫn đang học vim. Cảm ơn đã giúp đỡ.
Xavitoj Cheema

@XavitojCheema Tôi thậm chí không nhớ đã đưa ra nhận xét đó, haha. Nhưng khi nó quay ra, tôi đã thực sự kể từ khi viết một plugin để cung cấp chức năng này ( github.com/svermeulen/vim-easyclip )
Steve Vermeulen

27

Bạn có thể sử dụng chế độ trực quan của vim cho việc này. ví dụ: sao chép một từ: yevà sau đó ghi đè một từ khác bằng từ đã sao chép:vep


9
Điều này hoạt động, nhưng cũng cần lưu ý rằng hình dán trực quan sẽ ghi đè bộ đệm yank cho văn bản mới bị xóa.
ostler.c

24

Nếu con trỏ của bạn ở trên từ bạn muốn thay thế bằng nội dung của sổ đăng ký không tên, bạn có thể sử dụng viwp. vchuyển sang chế độ trực quan, iwchọn từ bên trong và pđặt nội dung của sổ đăng ký vào vị trí của nó.

Trong thực tế, khi tôi cần thay thế một từ (tên hàm, v.v.) bằng từ khác, tôi sẽ chuyển đến từ để sử dụng thay thế, yiwkéo từ bên trong vào thanh ghi không có tên, sau đó chuyển đến từ I ' m thay thế, và viwpthay thế nó. Một cách khá nhanh chóng để thay thế một từ này cho một từ khác. Nếu bạn đã tìm kiếm ( /) cho từ mà bạn đang thay thế để tìm từ đó, bạn có thể chỉ cần nhấn nđể đến lần xuất hiện tiếp theo mà bạn cần thay thế. Rõ ràng là không thể thay thế cho việc sử dụng :%s/find/replace/g, nhưng đối với một vài thay thế nhanh chóng, nó có thể hữu ích, đặc biệt nếu bạn đã có từ mới trong sổ đăng ký.


4
Tôi ngạc nhiên vì đây không phải là giải pháp được chấp nhận: tất cả những điều trên, mặc dù linh hoạt hơn trong một số trường hợp cạnh, nhưng dài dòng hơn nhiều vì chỉ đơn giản là 'hoán đổi thanh ghi không có tên hiện tại cho một lựa chọn ở đâu đó,' đó là tình huống ban đầu. người hỏi đã đến đây cho.
ELLIOTTCABLE

1
Điều này rất hữu ích và trực quan.
lacostenycoder

6

Nếu bạn sử dụng một sổ đăng ký đã đặt tên (ví dụ: sử dụng "ayhoặc "ad, v.v., để điền vào sổ đăng ký dán của bạn), bạn có thể làm điều gì đó như

cw<CTRL-R>a<esc>

Mà sẽ thay thế từ bằng nội dung của sổ đăng ký a. Theo như tôi có thể nói, bạn không thể sử dụng thanh ghi mặc định vì khi bạn đăng ký, cwnó sẽ được lấp đầy bởi từ bị cắt bởi lệnh đó.


Bạn có thể sử dụng đăng ký mặc định! Kiểm tra câu trả lời của tôi.
Cascabel

2

Ý bạn là bộ đệm dán hệ thống hay thanh ghi vi?

Nếu bạn muốn sử dụng bộ đệm dán hệ thống thì bạn vẫn ổn và có thể làm dw"+P- hãy "chọn một thanh ghi và "+là bộ đệm dán hệ thống.

Nếu không, hãy sao chép vào thanh ghi không mặc định với nói "ayđể sao chép vào thanh ghi avà sau đó để thay thế một cái gì đó làmdw"aP


Cảm ơn, Hamish. Tôi đã thử điều đó, nhưng dwxóa khoảng trắng ở cuối sau những gì tôi sẽ coi là "từ", trong khi cwchỉ thay đổi từ. Vì lý do đó, dwsẽ không hiệu quả với tôi.
kéo dài

Trong trường hợp đó desẽ hiệu quả với bạn - nó sẽ xóa đến cuối từ này, trong khi dwsẽ xóa đến đầu từ tiếp theo.
Hamish Downer

1

Bạn có thể sử dụng ywđể kéo từ, sau đó bạn có thể thay đổi từ bằng từ bị kéo bằng cách vipwkéo từ và dán từ bị kéo trước đó.


0

Bạn có thể sử dụng đăng ký cho điều đó:

văn bản thay thế vị trí đầu tiên trong sổ đăng ký <mark some text>"ay

atên đăng ký ở đâu

sau đó bạn có thể sử dụng đăng ký đó để thay thế

ve"ap


Thật không may, tôi không thể đơn giản lặp lại thao tác dán cuối cùng qua ., đó là một việc khác mà tôi muốn làm. Cảm ơn, mặc dù. Nhiều đánh giá cao.
kéo dài

0

Hoặc bạn có thể làm Shift+ v- p(chọn toàn bộ dòng và dán vào 'vị trí của nó)


1
hoặc pdw ... Bạn không yêu vim? : P
elimirks
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.