ฉันจะแก้ไขซ้ำหลายบรรทัดใน Vim ได้อย่างไร


122

ฉันทราบดีว่าใน Vim ฉันมักจะทำซ้ำคำสั่งได้เพียงแค่เพิ่มตัวเลขไว้ข้างหน้า ตัวอย่างเช่นเราสามารถลบ 5 บรรทัดโดย:

5dd

นอกจากนี้ยังสามารถระบุช่วงของบรรทัดเพื่อใช้คำสั่งได้เช่น

:10,20s:hello:goodbye:gc

ฉันจะทำการ 'แก้ไขแนวตั้ง' ได้อย่างไร? ตัวอย่างเช่นฉันต้องการแทรกสัญลักษณ์เฉพาะพูดลูกน้ำที่การขอทาน (การข้ามช่องว่างเช่นสิ่งที่คุณจะได้รับถ้าคุณพิมพ์ลูกน้ำหลัง Shift-I ในโหมดคำสั่ง) ของทุกบรรทัดในที่กำหนด พิสัย. สิ่งนี้จะทำได้อย่างไร (โดยไม่ต้องใช้ระยะเวลาดาวน์ - ดาวน์ - งวด - ดาวน์ - ดาวน์)

คำตอบ:


107

:10,20s/^/,/

หรือใช้มาโครบันทึกด้วย:

q a i , ESC j h q

ใช้กับ:

@ a

คำอธิบาย: q aเริ่มต้นการบันทึกแมโครเพื่อลงทะเบียนa, qการบันทึกปลาย มีการลงทะเบียนเป็นaไปzใช้ได้สำหรับการนี้


ขอบคุณ จะเกิดอะไรขึ้นถ้าฉันต้องการเทียบเท่า shift-i? นั่นคือการข้ามช่องว่างเริ่มต้น?
saffsd

2
คำอธิบาย: ^\(\s*\)จับช่องว่างเริ่มต้นและบันทึกลงในทะเบียนซึ่งคุณสามารถอ่าน\1ได้
Svante

136

Ctrl- vเข้าสู่โหมดภาพในแนวบล็อก จากนั้นคุณสามารถเคลื่อนย้าย ( hjkl-wise เป็นปกติ) และถ้าคุณต้องการที่จะใส่บางสิ่งบางอย่างในหลายสายใช้-Shifti

ดังนั้นสำหรับข้อความ:

abc123abc
def456def
ghi789ghi

หากคุณกดCtrl- vโดยใช้เคอร์เซอร์อยู่เหนือ 1 ให้กดjสองครั้งเพื่อลงไปสองคอลัมน์จากนั้นShift- i,ESCข้อความของคุณจะมีลักษณะดังนี้:

abc,123abc
def,456def
ghi,789ghi

(เม็ดมีดแบบหลายบรรทัดมีความล่าช้าเล็กน้อยและจะไม่แสดงผลจนกว่าคุณจะกดESC)


3
ดี Ctrl-V หมายถึงตัวพิมพ์ใหญ่คุณสามารถพูดว่า Ctrl-Shift-v
Svante

8
จริงๆแล้วก็คือ CTRL-v หรือ CTRL-V Vim ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่สำหรับ CTRL- โค้ด (ดู: help CTRL- {char})
rampion

2
หลังจากค้นหาสาเหตุที่วิธีนี้ไม่ได้ผลเป็นเพราะใช้ทุน I (shift-i) แทน i (เช่นกันมันเป็นเพียง ctrl-v เนื่องจาก ctrl-shift-v ย้ายฉันไปที่จุดสิ้นสุด)
Willyfrog

4
ฉันอยากรู้. ทำไมพวกเขาไม่ใช้iโดยไม่มีปุ่ม shift?
off99555

1
ฉันไม่มีกะจะแทรกที่ตำแหน่งปัจจุบัน shift + i ถูกแทรกที่จุดเริ่มต้นของบรรทัด
Kevin P


44

หากคุณใช้ "." อยู่แล้ว เพื่อทำซ้ำคำสั่งสุดท้ายของคุณบ่อยครั้งฉันพบว่านี่เป็นทางออกที่สะดวกที่สุดจนถึงตอนนี้ ช่วยให้คุณสามารถทำซ้ำคำสั่งสุดท้ายของคุณในแต่ละบรรทัดของบล็อกภาพโดยใช้

" allow the . to execute once for each line of a visual selection
vnoremap . :normal .<CR>

1
สิ่งนี้มีประโยชน์ แต่ยังมีข้อ จำกัด เนื่องจาก.สายการทำงานที่ชาญฉลาดในโหมดภาพ ฉันคิดว่าโหมดภาพในกรณีนี้บางครั้งอาจสะดวกในการเลือกช่วงเส้น แต่คำสั่งและมาโครจะยืดหยุ่นและมีประสิทธิภาพมากกว่าในกรณีนี้
Bohr

23

ฉันเชื่อว่าวิธีที่ง่ายที่สุดในการทำเช่นนี้คือ

1) บันทึกมาโครสำหรับหนึ่งบรรทัดเรียกว่า 'a'; ในกรณีนี้หนึ่งประเภท

qa I, ESC jq

2) เลือกบล็อกของบรรทัดที่คุณต้องการใช้มาโคร

3) ใช้ฟังก์ชัน 'บรรทัดฐาน' เพื่อเรียกใช้มาโคร 'a' บนบล็อกของบรรทัดนี้กล่าวคือ

:'<,'>norm@a

17

ฉันคิดว่าวิธีที่ง่ายที่สุดคือบันทึกมาโครแล้วทำซ้ำมาโครหลาย ๆ ครั้งตามที่คุณต้องการ ตัวอย่างเช่นหากต้องการเพิ่มเครื่องหมายจุลภาคที่จุดเริ่มต้นของทุกบรรทัดให้พิมพ์:

q a I , ESC j q

เพื่อทำซ้ำ 5 ครั้งให้คุณป้อน

5 @ a

2

ผมใช้ป้องกันโหมดภาพ สิ่งนี้ช่วยให้คุณทำการแทรก / แก้ไขในหลาย ๆ บรรทัดได้ (aka 'การแก้ไขแนวตั้ง')


1
ลิงค์ของคุณเสีย
Christopher Hunter

2

เมื่อการแก้ไขของคุณบันทึกไว้แล้วใน.โอเปอเรเตอร์ให้ทำดังต่อไปนี้:

  1. เลือกข้อความที่คุณต้องการใช้ตัวดำเนินการโดยใช้โหมดภาพ
  2. จากนั้นรันคำสั่ง :norm .

1

นอกเหนือจากมาโครตามที่ตอบไปแล้วสำหรับกรณีเฉพาะของการแทรกลูกน้ำในช่วงของบรรทัด (พูดจากบรรทัดที่ 10 ถึง 20) คุณอาจทำสิ่งต่อไปนี้

:10,20s/\(.*\)/,\1

นั่นคือคุณสามารถสร้างกลุ่มที่มีหมายเลขตรงกับ \ (และ \) และใช้ \ 1 ในสตริงแทนที่เพื่อพูดว่า "แทนที่ด้วยเนื้อหาของการจับคู่"

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