Vim: การเปลี่ยนบรรทัดด้วยอีกอันที่ดึงมาก่อน


114

อย่างน้อยวันละครั้งฉันมีสถานการณ์ต่อไปนี้:

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

ฉันเชื่อว่าฉันทำงานนั้นไม่ได้ผล

สิ่งที่ฉันทำ:

  • ไปที่บรรทัด A: AG
  • Yank บรรทัด A: yy
  • ไปที่บรรทัด X: XG
  • วางบรรทัด A: P
  • ย้ายไปสายเก่า: j
  • ลบบรรทัดเก่า: dd

สิ่งนี้มีข้อเสียเพิ่มเติมที่ตอนนี้บรรทัด X อยู่ในรีจิสเตอร์เริ่มต้นซึ่งน่ารำคาญหากฉันพบบรรทัดอื่นที่ควรแทนที่ด้วย A. Yanking ถึงและวางจากการลงทะเบียนเพิ่มเติม ( "ayy , " aP ) ทำให้งานง่าย ๆ นี้แม้กระทั่ง มีประสิทธิภาพน้อยกว่า

คำถามของฉัน:

  • ฉันพลาดคำสั่ง Vim ในตัวเพื่อแทนที่บรรทัดที่ดึงมาก่อนหรือไม่?
  • ถ้าไม่ฉันจะผูกคำสั่งของตัวเองที่ออก (หรือเรียกคืน) บรรทัดที่ดึงออกมาในรีจิสเตอร์เริ่มต้นได้อย่างไร

2
นี่เป็นปัญหาใหญ่เรื่องเดียวของฉันกับโมเดลการแก้ไขของ Vim ฉันอยากรู้วิธีแก้ปัญหา ตัวแก้ไข CUA แยกความแตกต่างระหว่างการตัดและการลบดังนั้นคุณเพียงแค่ตัดข้อความบางส่วนจากนั้นคุณสามารถลบและวางทั้งหมดที่คุณต้องการได้ ด้วย Vim การลบใด ๆ ที่คุณทำทิ้งขยะข้อความที่ถูกตัด คุณต้องใช้การกดแป้นพิมพ์มากกว่าที่คุณจะแก้ไขอีก
โคลน


@ มุดเรียนรู้:moveและหลุมดำลงทะเบียน ( _) (หรือในความเป็นจริงแค่ลงทะเบียน)
sehe

2
@sehe ฉันรู้ดีถึงการลงทะเบียน แต่นั่นจะเพิ่มการกดแป้นพิมพ์ 4 ครั้งต่อการตัด / วางและต้องใช้ความรอบคอบมากกว่านี้ เมื่อคุณทำการแก้ไขจำนวนมากสิ่งนั้นจะเพิ่มขึ้นอย่างรวดเร็ว
โคลน

นอกเหนือจากการประหยัดหน่วยความจำสองสามไบต์แล้วการใช้การลงทะเบียนหลุมดำจะมีประโยชน์มากกว่าการลงทะเบียนอื่น ๆ หรือไม่? ฉันจะเถียงว่าทะเบียนใด ๆ สามารถเป็นทะเบียนหลุมดำได้หากคุณไม่อ่านย้อนกลับไป
sleblanc

คำตอบ:


91

สิ่งที่ฉันจะทำ:

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

คุณไม่จำเป็นต้องออกจากโหมดปกติ แต่มันจะดึงเส้น อย่างไรก็ตามคุณสามารถใช้V"0pซึ่งจะทำให้เส้นดึงในขั้นตอนที่ 2 เสมอ


11
@duddle: ใช่Yเป็นคำพ้องความหมายyy
icecrime

8
ขั้นตอนที่ 1 และ 2 สามารถใช้ร่วมกันได้โดยใช้: ay [เช่น: 20y] ตามด้วย Vp ควรทำเคล็ดลับ คุณไม่ต้องไปต่อแถวเพื่อดึงมัน
Bharad

2
หากคุณเขียนทับบรรทัดเพิ่มเติมด้วย ccCTRL + r0ESC แทน V "0p บรรทัดต่อไปนี้ทั้งหมดจะถูกแทนที่ด้วย just (ตัวทำซ้ำ)
Jordan Morris

Yเป็นไวพจน์yyแต่ผมขอแนะนำให้แมปมันเพื่อy$ให้ตรงกับและD C
mgold

ลองดูคำตอบของ Jordan Morris stackoverflow.com/users/970673/jordan-morrisด้านล่าง - ใช้คำสั่ง vim อย่างเต็มที่โดยให้คุณทำซ้ำคำสั่งหลาย ๆ ครั้ง
JESii

107

Vp: เลือกบรรทัดวางสิ่งที่ดึงออกมา


4
VPทำงานได้ดีเช่นกันซึ่งมีประโยชน์เพราะคุณสามารถกด Shift ค้างไว้สำหรับลำดับทั้งหมดได้
George Hilliard

24
เคล็ดลับที่ดีมากแม้ว่ามันจะคุ้มค่าที่จะสังเกต (อาจ) ข้อแม้ที่สำคัญ: สิ่งนี้ทำให้การลงทะเบียน yank ได้รับการอัปเดตด้วยเนื้อหาของบรรทัดที่ถูกเขียนทับดังนั้นจึงอาจเล่นได้ไม่ดีกับงานบางอย่างเช่นหากคุณต้องการเขียนทับ บรรทัดเดียวกันไปยังปลายทางหลายแห่ง
underscore_d

8
@underscore_d มันเล่นได้ดีถ้าคุณทำV"0pซึ่งวางจากการลงทะเบียนที่ดึงครั้งสุดท้าย
timblaktu

@timblaktu คุณอธิบายได้V"0pไหมว่าอะไร? V เข้าสู่โหมด Visual line line และ p สำหรับวาง "และ 0 สำหรับอะไรขอบคุณ
theprogrammer

43

สิ่งนี้มีข้อเสียเพิ่มเติมที่ตอนนี้บรรทัด X อยู่ในการลงทะเบียนเริ่มต้นซึ่งน่ารำคาญหากฉันพบบรรทัดอื่นที่ควรแทนที่ด้วย A

ในการลบข้อความโดยไม่ส่งผลกระทบต่อรีจิสเตอร์ปกติคุณสามารถใช้ Black hole register "_:

"_dd

10
ฉันเพิ่มการแมปลงใน. vimrc ของฉันเพื่อสร้างdและddใช้หลุมดำเสมอxและxxดำเนินการในสิ่งที่บรรณาธิการส่วนใหญ่เรียกว่า "ตัด" (ลบและบันทึกลงในทะเบียนเริ่มต้น):noremap x d noremap xx dd noremap d "_d noremap dd "_dd
IMSoP

2
ฉันระวังการรีแมปสิ่งต่างๆใน VIM เนื่องจากอาจไม่ใช่เรื่องง่ายในคอมพิวเตอร์เครื่องอื่นหรือในปลั๊กอินสไตล์ VIM สำหรับ IDE นักออกแบบของ VIM มักจะแก้ปัญหาเกี่ยวกับการแมปเริ่มต้นหากคุณขุดจริงๆ
Jordan Morris

15

จากคำตอบที่แนะนำให้ใช้VpหรือVPวางทับบรรทัด - เพื่อหลีกเลี่ยงการเปลี่ยนแปลงเนื้อหาของการลงทะเบียน yank ฉันพบว่าคำสั่งที่เหมาะกับสรีระมากที่สุดคือ:

VPY


นี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุดที่ทำให้เนื้อหาดึงเหมือนเดิม ขอบคุณมาก!
heylookltsme

14
  1. ปป
  2. j (เลื่อนไปยังบรรทัดที่คุณต้องการแทนที่) จากนั้น
  3. Vp (ตัวพิมพ์ใหญ่ v แล้ว p จะแทนที่ด้วยเนื้อหาที่ดึงออกมา)

สุดยอด! สั้นมากและทำให้ง่ายต่อการเลือกหลายบรรทัดด้วยโหมดภาพ นอกจากนี้ยังคงบัฟเฟอร์การวางไว้เหมือนเดิม มันน่ารำคาญเมื่อ dd เขียนทับบัฟเฟอร์นั้น ...
Aktau

@Aktau นี้ไม่ได้ปล่อยให้บัฟเฟอร์เหมือนเดิม
Jordan Morris

9

ฉันจะใช้โหมด commandline (Ex) และทำสองคำสั่งต่อไปนี้

:XmA
:Ad

แค่นี้ก็ย้ายบรรทัด X ไปอยู่ใต้ A จากนั้นลบ A ย้ายที่ขึ้นบรรทัดใหม่

ตัวอย่างเช่น

:7m3
:3d

คุณสามารถยกตัวอย่างได้หรือไม่? เมื่อฉันกดเช่น 50Gm30G Vim ไปที่บรรทัด 50 จากนั้นไปที่ด้านล่างและนั่นแหล่ะ นอกจากนี้: โฆษณาไม่ได้ทำอะไรให้ A = 50 หรือ A = 50G
กรอบ

7
  1. ย้ายไปที่จุดเริ่มต้นของบรรทัดแรก

  2. y, $- คัดลอกบรรทัดโดยไม่มีเส้นแบ่งที่ส่วนท้าย

  3. ย้ายไปที่จุดเริ่มต้นของเส้นเป้าหมาย

    1. V, p- แทนที่เส้นเป้าหมายเพียงเส้นเดียว

    2. c, c, Ctrlr, 0, Esc- เปลี่ยนเส้นเป้าหมายที่มีการงัดเดิม

  4. ย้ายไปที่จุดเริ่มต้นของบรรทัดเป้าหมายถัดไป

  5. . - ทำซ้ำคำสั่งที่ออกเมื่อ 4.2

หมายเหตุ:

  • 4.1 y, $เพราะถ้าคุณทำy, yหรือYคุณจะคัดลอก LINEBREAK และCtrlr0จริงเพิ่ม LINEBREAK ด้านล่างบรรทัดเป้าหมายของคุณ

  • 4.2 แทนที่V pซึ่งใช้ไม่ได้กับการทำซ้ำเนื่องจากในทางเทคนิคแล้วการกระทำสุดท้ายคือลบดังนั้น.จะลบบรรทัด

  • หากใครรู้วิธีออก 'แทนที่บรรทัดปัจจุบันด้วย register' จากโหมด EX (บรรทัดคำสั่ง) ฉันต้องการรับฟังความคิดเห็นจากคุณ (และต้องการทราบว่าคุณพบเอกสารที่ใด) อาจมีคำสั่ง EX ที่ทำซ้ำได้ซึ่งเร็วกว่า 4.2 และ / หรือไม่มีข้อแม้ของ linebreak


1
ขั้นตอนที่ 4.2 เป็นนักฆ่าที่นี่ในขณะนี้คุณสามารถทำซ้ำกระบวนการทั้งหมดด้วยคำสั่ง dot เช่นเดียวกับใน 4.3 - นั่นคือสิ่งที่เป็นกลุ่ม!
JESii

1
ฉันไม่เข้าใจ 'AG' วางเครื่องชงของฉันไว้ที่ท้ายบรรทัดเข้าสู่โหมดแทรกและเข้าสู่ 'G' อะไรที่ฉันไม่ได้รับ?
gustafbstrom

@gustafbstrom วิจารณ์อย่างยุติธรรม - ขอโทษที่ A ควรจะเป็นตัวแทนของหมายเลขบรรทัด แต่ฉันไม่สามารถชี้ให้เห็นได้ แก้ไขแล้ว
Jordan Morris

5

นี่คือสิ่งที่ฉันจะทำ

  • ย้ายจุดเริ่มต้นของบรรทัด A AG(โดยที่ A คือหมายเลขบรรทัดอย่างชัดเจน)
  • ลากเส้นไปยังรีจิสเตอร์บางตัวเช่น a (ไม่มีบรรทัดใหม่) ประเภท"ay$
  • ย้ายไปแทรกบรรทัด XG
  • แทนบรรทัด S
  • แทรกจาก register a, Ctrl-Ra

4

คุณสามารถใช้สิ่งนี้กับโหมดภาพ

  • ไปที่บรรทัด A: AG
  • เลือกเส้นด้วยโหมดภาพ: VESC
  • ไปที่บรรทัด X: XG
  • เข้าสู่โหมดแทนที่สำหรับบรรทัด: S
  • วางบรรทัดที่คุณคัดลอก: shift+ insert(หรือสิ่งอื่น ๆ ที่คุณทำแผนที่ที่คุณมีสำหรับวางจากคลิปบอร์ด)

อา. ไม่ทราบเกี่ยวกับVและS อย่างไรก็ตามขั้นตอนของคุณไม่ได้ผลสำหรับฉันเนื่องจากฉันไม่ดึงไปที่คลิปบอร์ดระบบปฏิบัติการของฉันซึ่งเป็นเพียงขั้นตอนเดียวที่ฉันสามารถเข้าถึงได้ในโหมดแทรก ดังนั้นฉันจะต้องออกจากโหมดแทรกก่อน
กรอบ

3

คุณยังสามารถทำ:

Vy (in normal mode at the line you want to copy)
Vp (in normal mode at the line you want to replace)
  • ไม่สร้างช่องว่างหรือสิ้นสุดบรรทัด
  • เคอร์เซอร์วางอยู่ที่จุดเริ่มต้นของข้อความที่คัดลอก

สามารถใช้คีย์เดียวกันเพื่อดึง / วางมากกว่าหนึ่งบรรทัด

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

คุณสามารถใช้คำสั่งนี้ในโหมดปกติ:

:AmX | Xd

mคำสั่งสำหรับm[ove]ซึ่งย้ายจำนวนสาย A หลังจากที่หมายเลขบรรทัด X co[py]ถ้าคุณต้องการที่จะคัดลอกแทนการย้ายสายการใช้งาน คำสั่งสำหรับdd[elete]

คุณสามารถย้าย (คัดลอกโดยใช้co) ช่วงของบรรทัดโดยใช้

:start,end m X

2

จากความคิดเห็นล่าสุดโดยcicld (ขอบคุณ!) ฉันเห็นว่าฉันไม่เข้าใจประเด็นเดิมอย่างเต็มที่ การย้ายเส้นไม่เหมาะสม แต่การคัดลอก (เนื่องจากเส้นถูกดึง) ดังนั้นฉันจะแก้ไขใหม่เป็น:

:1t20:20d_
  1. คัดลอกบรรทัดที่ 1 ( :tคำสั่งเป็นนามแฝงสำหรับ:copy) หลังบรรทัด 20 (จะวางไว้ในบรรทัดที่ 21)

  2. ลบบรรทัดที่ 20 วางบรรทัดที่ถูกลบลงในรีจิสเตอร์ 'blackhole' ( _) (กล่าวคือไม่ส่งผลกระทบต่อบัฟเฟอร์ดึงปัจจุบัน)

ตามที่กล่าวไว้ในความคิดเห็นล่าสุดสิ่งนี้จะไม่ส่งผลต่อตำแหน่งเคอร์เซอร์ปัจจุบัน


1
  1. : ay (โดยที่ a คือหมายเลขบรรทัดตัวอย่าง: 20y) สิ่งนี้ดึงเส้น (เล่นสำนวนตั้งใจ)
  2. Vp

1

ฉันพบว่ามันง่ายกว่าที่จะใช้คำสั่ง Ex สำหรับสิ่งนี้ เช่น เพื่อย้ายบรรทัดที่ 9 ถึง 46:

 :46|9m.|-1d

การดำเนินการนี้จะย้ายเคอร์เซอร์ไปที่บรรทัด 46 เลื่อนบรรทัดที่ 9 ด้านล่างปัจจุบันจากนั้นลบบรรทัดก่อนหน้า (เนื่องจากบรรทัดที่ย้ายคือบรรทัดปัจจุบัน)

หรือใช้เครื่องหมายโดยใช้เครื่องหมาย 'a':

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

ความสวยงามของคำสั่ง EX คือคุณสามารถเรียกใช้งานได้ทุกที่ที่เคอร์เซอร์อยู่ (ในโหมดปกติ) ฉันชอบ:1m20|.+1d(ย้ายบรรทัด 1 ไปบรรทัด 20 และลบบรรทัดถัดไปกล่าวคือข้อความที่อยู่ที่บรรทัด 20 ก่อนหน้านี้) คิดเหมือนกัน!
ประมาณ

1

ฉันมักจะต้อง Y หนึ่งบรรทัดและแทนที่ในหลาย ๆ ตำแหน่งซึ่งแต่ละค่ามีค่าต่างกัน (ซึ่งหมายความว่าฉันไม่สามารถสร้างนิพจน์ทั่วไปได้)

Y เพื่อดึงเส้นเดิมที่ต้องการ

จากนั้นในทุกบรรทัดที่คุณต้องการแทนที่ VpzeroY


0

ฉันจะใช้การลงทะเบียน "หลุมดำ" ง่ายๆ:

ให้:

nnoremap <Cd> "_dd

วิธีแก้ปัญหาคือ:

<Cd> yy

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.