Vim multiline แก้ไขเช่นใน sublimetext?


133

ฉันเริ่มใช้ gvim และไม่ค่อยเข้าใจว่าการแก้ไขหลายบรรทัดทำงานอย่างไรใน gvim

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

ข้อความต้นฉบับ:

asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;

ctrl + q, jjjjjj, $ ทุกอย่างถูกเลือกแล้วฉันกด I เพื่อทำการแทรกแบบหลายบรรทัด

ความตั้งใจของฉันคือการแทรกเครื่องหมายคำพูดในบรรทัดแรกจากนั้นจึงกด Esc:

asd "asd asd" asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;

เกิดอะไรขึ้น? ฉันคาดว่าจะมีพฤติกรรมคล้ายกับข้อความของ sublimetext:

ป้อนคำอธิบายภาพที่นี่

หากคุณไม่ทราบวิธีการทำงานเพียงแค่ทำซ้ำการกระทำสำหรับทุกบรรทัด บรรลุธรรมได้อย่างไร? แล้ว vim มาทำอะไรที่นี่?


เพียงบันทึกมาโครแป้นพิมพ์เพื่อเปลี่ยนบรรทัดแรกจากนั้นเล่นมาโครสำหรับบรรทัดอื่น ๆ ทั้งหมด
high5

คำตอบ:


215

ทำสิ่งที่คุณโปรดปรานด้วยการวางเลเยอร์ความเข้ากันได้ของ Windows

<C-v>ทางลัดปกติสำหรับการเข้าสู่โหมดภาพบล็อกคือ

คนอื่น ๆ จัดการกับมาโครการบันทึกต่อไปนี้เป็นแนวคิดอื่น ๆ :

ใช้โหมดบล็อกภาพเท่านั้น

  1. วางเคอร์เซอร์ไว้ที่คำที่สอง:

    asd |a|sd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    
  2. กด<C-v>เพื่อเข้าสู่โหมดบล็อกภาพและขยายการเลือกของคุณไปทางด้านล่าง:

    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    
  3. กดI"<Esc>เพื่อรับ:

    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    
  4. วางเคอร์เซอร์ไว้ที่อักขระสุดท้ายของคำที่สาม:

    asd "asd as|d| asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    
  5. กด<C-v>เพื่อเข้าสู่โหมดบล็อกภาพและขยายการเลือกของคุณไปทางด้านล่าง:

    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    
  6. กดA"<Esc>เพื่อรับ:

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    

ด้วยภาพบล็อกโหมดและSurround.vim

  1. วางเคอร์เซอร์ไว้ที่คำที่สอง:

    asd |a|sd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    
  2. กด<C-v>เพื่อเข้าสู่โหมดบล็อกภาพและขยายการเลือกของคุณไปทางด้านล่างและทางขวา:

    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    
  3. กดS"เพื่อล้อมรอบการเลือกของคุณด้วย ":

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    

ด้วยโหมดเส้นภาพและ:normal.

  1. กดVเพื่อเลือกทั้งบรรทัดและขยายไปทางด้านล่าง:

    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    
  2. ดำเนินการคำสั่งนี้: :'<,'>norm ^wi"<C-v><Esc>eea"<CR>เพื่อรับ:

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    
    • :norm[al]อนุญาตให้คุณดำเนินการคำสั่งโหมดปกติในช่วงของบรรทัด ( '<,'>ส่วนนี้จะถูกเพิ่มโดยอัตโนมัติโดย Vim และหมายถึง "ดำเนินการกับพื้นที่ที่เลือก")

    • ^ วางเคอร์เซอร์ไว้ที่อักขระตัวแรกของบรรทัด

    • w ย้ายไปที่คำถัดไป

    • i"แทรก"ก่อนเคอร์เซอร์

    • <C-v><Esc>เป็นวิธีของ Vim ในการป้อนอักขระควบคุมในบริบทนี้ที่นี่จะ<Esc>ใช้เพื่อออกจากโหมดแทรก

    • ee เลื่อนไปยังจุดสิ้นสุดของคำถัดไป

    • a"ต่อท้าย"เคอร์เซอร์

    • <CR> รันคำสั่ง

    เมื่อใช้ Surround.vim คำสั่งด้านบนจะกลายเป็น

    :'<,'>norm ^wvees"<CR>
    

7
สำหรับขั้นตอนที่ 4 และ 5 ฉันจะแนะนำการกดปุ่มgvที่จะได้รับกลับมาเลือกภาพก่อนหน้านี้ของคุณและจากนั้น2eย้ายแนวนอนอาจจะมี (ยิ่งเส้นมากยิ่งมีค่ามากgv!)
joeytwiddle

4
surround.vim ใช้ขนาดเล็กsในโหมดปกติ แต่มีขนาดใหญ่Sในโหมดภาพดังนั้นในขั้นตอนที่ 3 ของวิธีการแบบ surround.vim การกดแป้นพิมพ์ควรเป็นS"
joeytwiddle

1
จุดที่ 3 ของ visual-block + Surround.vim ควรเป็นS"ไม่ใช่s"
zool

1
แทนโหมดภาพบล็อกขั้นตอนที่ 5 และ 6 .คุณสามารถวางเคอร์เซอร์หลังคำที่สามและกด
Jonas

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

30

นี่เป็นโซลูชันนอกกรอบที่ดีที่ให้ไว้ข้างต้น แต่เรายังสามารถลองใช้ปลั๊กอินบางตัวที่มีเคอร์เซอร์หลายตัวเช่น Sublime

ฉันคิดว่าสิ่งนี้ดูมีแนวโน้ม:

ดูเหมือนถูกทิ้งร้างมาระยะหนึ่ง แต่มีส่วนร่วมในปี 2014

มันค่อนข้างทรงพลังแม้ว่าฉันจะใช้เวลาสักครู่ในการทำความคุ้นเคยกับการไหล (ซึ่งค่อนข้างคล้าย Sublime แต่ก็ยังคงเป็นกิริยาเหมือน Vim)

จากประสบการณ์ของฉันหากคุณติดตั้งปลั๊กอินอื่น ๆ ไว้มากมายคุณอาจพบกับความขัดแย้ง!

มีบางส่วนพยายามที่คุณลักษณะนี้:

โปรดอย่าลังเลที่จะแก้ไขหากคุณสังเกตเห็นสิ่งเหล่านี้อยู่ระหว่างการปรับปรุง


ดูเหมือนว่าgithub.com/osyo-manga/vim-overจะมีการใช้งานมากที่สุดในขณะนี้
Wernight

ยอดเยี่ยมนั่นคือสิ่งที่ฉันกำลังมองหา
Alexandre Bourlier

1
หลังจากการทดสอบส่วนใหญ่แล้วhlissner / vim-multieditดูเหมือนว่าAFAIACที่ดีที่สุด
Alexandre Bourlier

1
ตรวจสอบmg979 / vim-visual-multiเพื่อทดแทนvim-multiple-cursors
Mushex Antaranian

29

มีหลายวิธีในการทำให้สำเร็จในกลุ่ม ฉันไม่รู้ว่าอันไหนคล้ายกับ Sublime Text มากที่สุด


คนแรกจะใช้โหมดแทรกหลายเส้น วางเคอร์เซอร์ไว้ที่ "a" ตัวที่สองในบรรทัดแรกกดCtrl-Vเลือกทุกบรรทัดจากนั้นกดIและใส่ doublequote การกด<esc>จะเป็นการดำเนินการซ้ำในทุกบรรทัด


อันที่สองคือผ่านมาโคร qaวางเคอร์เซอร์บนตัวอักษรตัวแรกและเริ่มต้นการบันทึกแมโครด้วย ไปทางขวาของคุณด้วยllllเข้าสู่โหมดแทรกด้วย aวาง doublequote ออกจากโหมดแทรกแล้วกลับไปที่จุดเริ่มต้นของแถวด้วย<home>(หรือเทียบเท่า) กดjเพื่อเลื่อนลงหนึ่งแถว qหยุดการบันทึกด้วย จากนั้นเล่นมาโครซ้ำด้วย@a. หลายครั้ง.


วิธีการใด ๆ ข้างต้นได้ผลสำหรับคุณหรือไม่?


15

หากคุณใช้คำสั่ง "global" คุณสามารถทำซ้ำสิ่งที่ทำได้ทางออนไลน์กี่บรรทัดก็ได้

:g/<search>/.<your ex command>

ตัวอย่าง:

:g/foo/.s/bar/baz/g

คำสั่งดังกล่าวค้นหาบรรทัดทั้งหมดที่มี foo และแทนที่แถบที่เกิดขึ้นทั้งหมดในบรรทัดนั้นด้วย baz

:g/.*/

จะทำในทุกบรรทัด


1
สิ่งนี้มีประโยชน์มากฉันไม่รู้เลย ดูเหมือนการผสมผสานคำสั่งที่ทรงพลังและชาญฉลาด
0xc0de

เพื่อความสะดวกฉันเขียนฟังก์ชั่นเล็ก ๆ น้อย ๆ ที่ใช้คำใต้เคอร์เซอร์ (หรือคำที่เลือกด้วยสายตา) แจ้งให้เปลี่ยนจากนั้นเรียกใช้:gคำสั่งที่อธิบายไว้ที่นี่ ฉันชอบใช้/gcเพื่อขอ "การยืนยัน" เพื่อที่ฉันจะได้ตีyหรือnสำหรับการเปลี่ยนแต่ละครั้งหรือaเปลี่ยนทั้งหมด
joeytwiddle

11
Ctrl-v ................ start visual block selection
6j .................... go down 6 lines
I" .................... inserts " at the beginning
<Esc><Esc> ............ finishes start
2fdl. ................. second 'd' l (goes right) . (repeats insertion)

ในขั้นตอนที่ 3 Iไม่สามารถเข้าสู่โหมดแทรกคุณรู้หรือไม่ว่าเหตุใดจึงเกิดขึ้น
Ninja

ลองโหลดกลุ่มโดยไม่มีปลั๊กอิน: vim -u NONEและลองดำเนินการตามที่ต้องการอีกครั้งอาจเป็นแผนที่หรือปลั๊กอินบางตัวเปลี่ยนพฤติกรรมของกลุ่มของคุณ
SergioAraujo

6

ฉันไม่แน่ใจว่าvimกำลังทำอะไรอยู่ แต่มันเป็นเอฟเฟกต์ที่น่าสนใจ วิธีที่คุณอธิบายสิ่งที่คุณต้องการฟังดูเหมือนการทำงานของมาโคร ( :help macro) สิ่งนี้จะทำสิ่งที่คุณต้องการด้วยมาโคร (เริ่มต้นในโหมดปกติ):

  1. qa: บันทึกมาโครเพื่อaลงทะเบียน
  2. 0w: ไปที่0จุดเริ่มต้นของบรรทัดwกระโดดหนึ่งคำ
  3. i"<Esc>: เข้าสู่โหมดแทรกแทรก"และกลับสู่โหมดปกติ
  4. 2e: ข้ามไปที่ท้ายคำที่สอง
  5. a"<Esc>: ผนวกก".
  6. jq ย้ายไปที่บรรทัดถัดไปและสิ้นสุดการบันทึกมาโคร

นำมารวมกัน: qa0wi"<Esc>2ea"<Esc>

ตอนนี้คุณสามารถรันมาโครที่มีแมโครที่ผ่านมาซ้ำด้วย@a @@หากต้องการนำไปใช้กับไฟล์ที่เหลือให้ทำสิ่ง99@aที่สมมติว่าคุณมีไม่เกิน 99 บรรทัดการเรียกใช้แมโครจะสิ้นสุดเมื่อถึงจุดสิ้นสุดของไฟล์

นี่คือวิธีบรรลุสิ่งที่คุณต้องการvisual-block-mode(เริ่มในโหมดปกติ):

  1. นำทางไปยังตำแหน่งที่คุณต้องการให้ใบเสนอราคาแรกอยู่
  2. ป้อนvisual-block-modeเลือกบรรทัดที่คุณต้องการให้มีผลGเพื่อไปที่ด้านล่างของไฟล์
  3. I"<Esc>hit
  4. "ย้ายไปยังจุดต่อไปที่คุณต้องการแทรก
  5. คุณต้องการทำซ้ำสิ่งที่คุณเพิ่งทำไปเพื่อให้ง่าย.พอเพียง

4
ไม่ต้อง 99 @ ก. หากคุณต้องการเรียกใช้มาโครในทุกบรรทัดของไฟล์ให้ลอง:% norm! @a
Rook

ไม่มีจุด (เป็นเพียงส่วนท้ายของประโยคไม่ใช่ส่วนหนึ่งของคำสั่ง)
Rook

9999@aอาจจะน่าเกลียด แต่พิมพ์ง่ายกว่ามาก:%norm! @aและไม่ได้รันซ้ำในบรรทัดที่คุณเพิ่งแก้ไข ยังดีที่รู้อยู่แล้ว :)
joeytwiddle

0

วิธีแก้ปัญหาของฉันคือใช้การแมป 2 รายการนี้:

map <leader>n <Esc><Esc>0qq
map <leader>m q:'<,'>-1normal!@q<CR><Down>

วิธีใช้:

  1. เลือกสายของคุณ หากฉันต้องการเลือก 12 บรรทัดถัดไปฉันเพียงแค่กดV12j
  2. กด <leader>n
  3. ทำการเปลี่ยนแปลงของคุณในบรรทัด
  4. ตรวจสอบให้แน่ใจว่าคุณอยู่ในโหมดปกติจากนั้นกด <leader>m

หากต้องการแก้ไขอีกครั้งคุณไม่จำเป็นต้องทำการเลือกอีกครั้ง เพียงแค่กด<leader>nทำการแก้ไขและกด<leader>mเพื่อสมัคร


วิธีการทำงาน:

  • <Esc><Esc>0qq ออกจากการเลือกภาพไปที่จุดเริ่มต้นของบรรทัดและเริ่มบันทึกมาโคร

  • q หยุดบันทึกมาโคร

  • :'<,'>-1normal!@q<CR> จากจุดเริ่มต้นของการเลือกภาพไปจนถึงบรรทัดก่อนสิ้นสุดให้เล่นมาโครในแต่ละบรรทัด

  • <Down> กลับลงไปที่บรรทัดสุดท้าย


คุณสามารถแมปคีย์เดียวกันได้ แต่สำหรับโหมดต่างๆ:

vmap <leader>m <Esc><Esc>0qq
nmap <leader>m q:'<,'>-1normal!@q<CR><Down>

แม้ว่าสิ่งนี้จะทำให้ความสามารถในการแก้ไขอื่น ๆ ยุ่งเหยิง คุณจะต้องเลือกเส้นของคุณใหม่

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