Vim: Thay thế một dòng bằng một dòng khác bị giật trước đó


112

Ít nhất một lần mỗi ngày tôi gặp trường hợp sau:

A: This line should also replace line X
...
X: This is line should be replaced

Tôi tin rằng tôi không thực hiện nhiệm vụ đó một cách hiệu quả.

Những gì tôi làm:

  • Chuyển đến dòng A: AG
  • Yank dòng A: yy
  • Chuyển đến dòng X: XG
  • Dán dòng A: P
  • Chuyển về dòng cũ: j
  • Xóa dòng cũ: dd

Điều này có nhược điểm bổ sung là dòng X bây giờ nằm ​​trong thanh ghi mặc định, điều này gây khó chịu nếu tôi tìm thấy một dòng khác cần được thay thế bằng A. Việc chạy và dán từ một thanh ghi bổ sung ( "ayy , " aP ) làm cho công việc đơn giản này trở nên thậm chí kém hiệu quả.

Những câu hỏi của tôi:

  • Tôi có bỏ lỡ lệnh Vim tích hợp sẵn để thay thế một dòng bị giật trước đó không?
  • Nếu không, làm cách nào tôi có thể liên kết lệnh của riêng mình để lại (hoặc khôi phục) dòng bị kéo trong thanh ghi mặc định?

2
Đây là vấn đề lớn nhất của tôi với mô hình chỉnh sửa của Vim. Tôi muốn biết một giải pháp. Một trình soạn thảo CUA phân biệt giữa cắt và xóa, vì vậy bạn chỉ cần cắt một số văn bản, sau đó bạn có thể xóa và dán tất cả những gì bạn muốn. Với Vim, bất kỳ thao tác xóa nào bạn cũng làm cho văn bản đã cắt của bạn trở thành thùng rác. Bạn sẽ sử dụng nhiều lần gõ phím hơn so với một trình soạn thảo khác.
Bùn


@Mud tìm hiểu về :movevà sổ đăng ký lỗ đen ( _) (hoặc trên thực tế, chỉ cần đăng ký)
xem

2
@sehe Tôi hoàn toàn biết về sổ đăng ký, nhưng điều đó thêm 4 lần nhấn phím cho mỗi thao tác cắt / dán và yêu cầu phải suy nghĩ trước nhiều hơn. Khi bạn thực hiện nhiều chỉnh sửa, điều đó sẽ nhanh chóng tăng lên.
Bùn

Ngoài việc tiết kiệm một vài byte bộ nhớ, có lợi thế khi sử dụng thanh ghi lỗ đen so với bất kỳ thanh ghi nào khác không? Tôi lập luận rằng bất kỳ thanh ghi nào cũng có thể là một thanh ghi lỗ đen nếu bạn không đọc lại từ đó.
slblanc

Câu trả lời:


91

Những gì tôi sẽ làm:

  1. aG
  2. Y
  3. xG
  4. Vp

Bạn không phải để chế độ bình thường, nhưng nó sẽ kéo dòng. Tuy nhiên, bạn có thể sử dụng cách V"0pnày sẽ luôn đặt dòng bị kéo ở bước 2.


11
@duddle: yes, Ylà đồng nghĩa vớiyy
icecrime

8
Bước 1 và bước 2 có thể được kết hợp bằng cách sử dụng: ay [VD: 20y] Tiếp theo là Vp nên thực hiện thủ thuật. Bạn không cần phải đi đến một hàng để kéo nó.
Bharad

2
Nếu bạn ghi đè lên dòng bổ sung với ccCTRL + r0ESC thay vì V "0p sau đó tất cả các dòng sau đây có thể được thay thế bằng chỉ (repeater).
Jordan Morris

Ylà một từ đồng nghĩa với yy, nhưng tôi khuyên bạn nên ánh xạ lại nó y$để phù hợp DC.
mgold 21/09/13

Hãy xem câu trả lời của Jordan Morris stackoverflow.com/users/970673/jordan-morris dưới đây - thực sự sử dụng tối đa các lệnh vim bằng cách cho phép bạn lặp lại lệnh nhiều lần.
JESii

105

Vp: chọn dòng, dán những gì đã bị kéo


3
VPcũng hoạt động, điều này rất tiện lợi vì bạn có thể giữ phím Shift cho toàn bộ trình tự.
George Hilliard

23
một thủ thuật rất hay, mặc dù cần lưu ý một cảnh báo (có thể) quan trọng: điều này khiến thanh ghi yank được cập nhật với nội dung của dòng đang được ghi đè, vì vậy nó có thể không hoạt động tốt với một số tác vụ - ví dụ: nếu bạn muốn ghi đè cùng một dòng đến nhiều điểm đến.
underscore_d

8
@underscore_d, nó sẽ chơi đẹp nếu bạn làm vậy V"0p, nó sẽ dán từ thanh ghi bị kéo cuối cùng.
timblaktu

@timblaktu Bạn có thể giải thích những gì V"0pkhông? V chuyển sang chế độ dòng trực quan và p là để dán. "Và 0 để làm gì? Cảm ơn
theprogrammer

43

Điều này có một nhược điểm bổ sung là dòng X bây giờ nằm ​​trong thanh ghi mặc định, điều này gây khó chịu nếu tôi tìm thấy một dòng khác nên được thay thế bằng A.

Để xóa văn bản mà không ảnh hưởng đến các thanh ghi bình thường, bạn có thể sử dụng thanh ghi Lỗ đen "_:

"_dd

10
Tôi thêm một số ánh xạ Vimrc của tôi để làm dddluôn luôn sử dụng các lỗ đen, và xxxthực hiện điều mà hầu hết các biên tập viên sẽ gọi là "cắt" (xóa và lưu vào sổ đăng ký mặc định):noremap x d noremap xx dd noremap d "_d noremap dd "_dd
IMSoP

2
Tôi cảnh giác với việc ánh xạ lại mọi thứ trong VIM, vì điều này có thể không dễ dàng trên các máy tính khác hoặc trong các plugin kiểu VIM cho IDE. Ngoài ra, các nhà thiết kế của VIM có xu hướng giải quyết các vấn đề với ánh xạ mặc định nếu bạn thực sự tìm hiểu kỹ.
Jordan Morris

15

Xây dựng dựa trên các câu trả lời đề xuất sử dụng Vphoặc VPdán trên một dòng - để tránh thay đổi nội dung của thanh ghi yank, tôi thấy lệnh tiện lợi nhất chỉ đơn giản là:

VPY


Đây là giải pháp đơn giản nhất mà vẫn giữ nguyên nội dung bên trong. Cảm ơn nhiều!
heylookearchme

14
  1. yy
  2. j (di chuyển đến dòng bạn muốn thay thế), và sau đó
  3. Vp (chữ hoa v và sau đó là p, sẽ thay thế bằng nội dung bị kéo dài)

tuyệt vời! Thực sự rất ngắn và giúp bạn dễ dàng chọn nhiều dòng với chế độ trực quan. Nó cũng giữ nguyên bộ đệm dán. Thật khó chịu khi dd ghi đè lên bộ đệm đó ...
Aktau

@Aktau điều này không giữ nguyên bộ đệm.
Jordan Morris

9

Tôi sẽ sử dụng chế độ dòng lệnh (Ex) và thực hiện hai lệnh sau

:XmA
:Ad

Thao tác này chỉ đơn giản là di chuyển dòng X xuống ngay dưới A, sau đó xóa A sẽ di chuyển dòng đó lên

Ví dụ

:7m3
:3d

Bạn có thể đưa ra một ví dụ không? Khi tôi nhấn ví dụ: 50Gm30G Vim đi đến dòng 50 và sau đó xuống dưới cùng và đó là nó. Ngoài ra: Quảng cáo không làm bất cứ điều gì cho A = 50 hoặc A = 50G
giòn

7
  1. Di chuyển đến đầu dòng đầu tiên.

  2. y, $- sao chép dòng không có dấu ngắt dòng ở cuối

  3. Di chuyển đến đầu dòng mục tiêu.

    1. V, p- chỉ thay thế một dòng mục tiêu

    2. c, c, Ctrlr, 0, Esc- thay thế dòng mục tiêu với yank gốc

  4. Di chuyển đến đầu dòng mục tiêu tiếp theo.

  5. . - lặp lại lệnh đã phát ở 4.2.

Ghi chú:

  • 4.1 là y, $bởi vì nếu bạn làm y, yhoặc Ybạn sẽ sao chép các linebreak, và Ctrlr0thực sự làm tăng linebreak bên dưới dòng mục tiêu của bạn.

  • 4.2 thay thế V p, không hoạt động với lặp lại vì về mặt kỹ thuật, hành động cuối cùng là xóa, vì vậy .sẽ chỉ xóa một dòng.

  • Nếu có ai biết cách phát hành 'thay thế dòng hiện tại bằng đăng ký' từ chế độ EX (dòng lệnh), tôi muốn nghe ý kiến ​​của bạn (và để biết bạn đã tìm thấy tài liệu ở đâu). Có thể có một lệnh EX lặp lại nhanh hơn 4.2 và / hoặc không có cảnh báo ngắt dòng.


1
Bước 4.2 là kẻ giết người ở đây, vì bây giờ bạn có thể lặp lại toàn bộ quy trình bằng lệnh dot như trong 4.3 - đó là tất cả những gì vim là về!
JESii

1
Tôi không hiểu. 'AG' đặt nhà sản xuất của tôi ở cuối dòng, vào chế độ chèn và nhập 'G'. Nó là gì mà tôi không nhận được?
gustafbstrom

@gustafbstrom phê bình công bằng - xin lỗi chữ A được cho là đại diện cho số dòng, nhưng tôi không chỉ ra được điều đó. Đã chỉnh sửa.
Jordan Morris

5

Đây là những gì tôi sẽ làm

  • Di chuyển đầu dòng A, AG(trong đó A rõ ràng là số dòng)
  • Yank dòng cho một số thanh ghi, ví dụ a (không có dòng mới). Kiểu"ay$
  • Di chuyển để chèn dòng, XG
  • Dòng thay thế, S
  • Chèn từ thanh ghi a, Ctrl-Ra

4

Bạn có thể sử dụng điều này với chế độ trực quan.

  • Chuyển đến dòng A: AG
  • Chọn dòng có chế độ trực quan: VESC
  • chuyển đến dòng X: XG
  • Vào chế độ thay thế cho dòng: S
  • Dán dòng bạn đã sao chép: shift+ insert(hoặc bất kỳ thứ gì khác mà bạn ánh xạ mà bạn có để dán từ khay nhớ tạm).

Ah. CHƯA BIẾT VỀ THƯƠNG VS . Tuy nhiên, các bước của bạn không hiệu quả với tôi vì tôi không kéo khay nhớ tạm hệ điều hành của mình, đây là bảng duy nhất tôi có thể truy cập ở chế độ chèn. Vì vậy, tôi sẽ phải rời khỏi chế độ chèn trước.
giòn

3

Bạn cũng có thể làm:

Vy (in normal mode at the line you want to copy)
Vp (in normal mode at the line you want to replace)
  • Không tạo khoảng trắng hoặc kết thúc dòng.
  • Con trỏ được đặt ở đầu văn bản được sao chép.

Các phím giống nhau có thể được sử dụng để kéo / dán nhiều hơn một dòng.

V (in normal mode at what you want to yank)
(use jk to move the selection)
y (to yank the selection)
V (in normal mode at where you want to paste)
(use jk to move the selection)
p (to replace the selection with the yanked lines)

2

Bạn có thể sử dụng các lệnh này trong Chế độ bình thường:

:AmX | Xd

các mlệnh là cho m[ove], trong đó di chuyển dòng số A sau dòng số X, nếu bạn muốn sao chép thay vì di chuyển đường dây, sử dụng co[py]. các dlệnh là cho d[elete].

Bạn có thể di chuyển (sao chép bằng cách sử dụng co) một loạt các dòng bằng cách sử dụng

:start,end m X

2

Theo nhận xét gần đây của cicld (cảm ơn bạn!), Tôi thấy rằng tôi đã không nắm bắt được đầy đủ vấn đề ban đầu. Di chuyển dòng là không thích hợp, nhưng sao chép thì được (vì dòng bị kéo.) Vì vậy, tôi sẽ sửa đổi nó thành:

:1t20:20d_
  1. Sao chép dòng đầu tiên ( :tlệnh là bí danh cho :copy) sau dòng 20 (sẽ đặt nó trên dòng 21)

  2. Xóa dòng 20, đưa dòng đã xóa vào thanh ghi 'lỗ đen' ( _) (tức là không ảnh hưởng đến bộ đệm yank hiện tại)

Như đã đề cập trong nhận xét gần đây, điều này sẽ không ảnh hưởng đến vị trí con trỏ hiện tại.


1
  1. : ay (trong đó a là số dòng. Ví dụ: 20y). Điều này kéo dài một dòng (dự định chơi chữ).
  2. Vp

1

Tôi thấy sử dụng lệnh Ex cho việc này dễ dàng hơn; Ví dụ. để chuyển dòng 9 thành 46:

 :46|9m.|-1d

Thao tác này sẽ di chuyển con trỏ đến dòng 46, di chuyển dòng 9 xuống dưới dòng hiện tại, sau đó xóa dòng trước đó (vì dòng đã di chuyển là dòng hiện tại).

Hoặc sử dụng (các) dấu, sử dụng dấu 'a':

:46ma a|9m'a|'ad

Cái hay của các lệnh EX là bạn có thể chạy chúng ở bất cứ đâu con trỏ của bạn (ở chế độ bình thường). Tôi thích :1m20|.+1d(di chuyển dòng 1 đến dòng 20 và xóa dòng tiếp theo, tức là văn bản ở dòng 20 trước đó). Cùng một ý tưởng mặc dù!
khoanh tròn

1

Tôi thường phải Y một dòng và thay thế nó ở nhiều nơi, mỗi vị trí có một giá trị khác nhau (có nghĩa là tôi không thể thực hiện regex).

Y để kéo dòng gốc mong muốn

và sau đó trên mỗi dòng mà bạn muốn thay thế, VpzeroY


0

tôi sẽ đơn giản sử dụng đăng ký "Lỗ đen":

được:

nnoremap <Cd> "_dd

giải pháp sẽ là:

<Cd> yy

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.