vim: ทำต่อแมโครหลังจากเกิดข้อผิดพลาดใน submacro หรือไม่


15

ฉันกำลังดำเนินการตกแต่งซอร์สโค้ดบางส่วนโดยใช้ vim {1}

ฉันได้สร้างมาโครมาโครสองตัวที่ทำตามแต่ละขั้นตอน: ลบ whilespace ต่อท้าย, ลบบรรทัดว่างหลังจาก{, ลบบรรทัดว่างก่อนหน้า{, สิ่งนั้น

ตอนนี้ฉันต้องการสร้างแมโครที่เรียกใช้แมโครแต่ละตัวตามลำดับ อย่างไรก็ตามเมื่อแมโครแบบเรียกซ้ำตัวแรกสิ้นสุดลง (เนื่องจากไม่สามารถหาข้อผิดพลาดการจับคู่ -> การจับคู่อีกต่อไปได้) มาโคร "wrapper" ของฉันก็จะยุติเช่นกัน

มีวิธีทำให้แมโครเป็นกลุ่มดำเนินต่อไปหลังจากที่ submacro สร้างข้อผิดพลาดหรือไม่

{1}ฉันรู้เกี่ยวกับการฟอร์แมตอัตโนมัติ ฉันอาจใช้มันกับปัญหาปัจจุบันของฉัน ฉันแค่กล่าวถึงการจัดรูปแบบแหล่งที่มาใหม่เพื่อประโยชน์ของตัวอย่าง อย่าโพสต์คำตอบใด ๆ เกี่ยวกับแหล่งที่มาสวยงามนี้หรือว่า คำถามไม่ได้เกี่ยวกับการจัดรูปแบบโค้ดต่อ seแต่เกี่ยวกับ vim macros

ตัวอย่าง:

  • มาโคร 1 - ตัดช่องว่างต่อท้าย - qw/\s\+$d$@wq
  • มาโคร 2 - การลบบรรทัดว่างก่อน} - qe/\n\n *}dd@eq
  • Wrapper Macro - แท็บใหม่, มาโคร 1, มาโคร 2 - qr:retab@w@eq

เมื่อฉันเรียกใช้ wrapper - @r- มันจะทำการ retab จากนั้นเรียกใช้ Macro 1 จนกว่าจะไม่พบช่องว่างที่ต่อท้ายอีกต่อไปจากนั้นให้ยุติ ( โดยไม่เรียกใช้แมโคร 2)

ชี้แจง:

สิ่งที่ฉันกำลังมองหาคือวิธีการเรียกใช้ submacro เพื่อที่ว่าเมื่อ submacro นั้นสิ้นสุดลงมาโครการโทรยังคงดำเนินต่อไป

คำตอบ:


12

ฉันแนะนำให้คุณใช้:try"ซับ" ข้อผิดพลาดของ submacro

นี่คือตัวอย่างที่โง่:

:let @a='f|dt|@a'
:let @q=':try|exe "norm! @a"|endtry^Mj0@q'
@q

มาโคร wrapper ของคุณจะมีลักษณะดังนี้:

let @r=':retab^M:try|exe "norm! @w"|endtry|try|exe "norm! @e"|endtry^M'

ในขณะที่ garyjohn จัดให้มีการแก้ปัญหาไม่ได้มีข้อผิดพลาดใน submacro นี้เป็นคำตอบเดียวที่จริงไม่จัดการกับข้อผิดพลาดดังกล่าว ฉันต้องขอโทษด้วย ฉันไม่ได้ตรวจสอบคำตอบของคุณในเวลาที่คุณจะได้รับรางวัล (หมดอายุแล้ว) ... :-(
DevSolar

26

หากคำสั่งที่ล้มเหลวเป็นการทดแทนที่ไม่พบรูปแบบของมันเช่น

:%s/foo/bar/

เมื่อfooไม่มีอยู่ในบัฟเฟอร์คุณสามารถเพิ่มการeตั้งค่าสถานะเพื่อละเว้นข้อผิดพลาดนั้นเช่น

:%s/foo/bar/e

ดู

:help :s_flags

คุณสามารถบอกได้เป็นกลุ่มที่จะเพิกเฉยต่อข้อผิดพลาดจากบางส่วนนี้: :silent!คำสั่งอดีตโดยก่อนหน้านี้พวกเขาด้วย ดู

:help :silent


แก้ไขต่อจากการเพิ่มตัวอย่างคำถาม

Macro 1 และ Macro 2 ทั้งแบบเรียกซ้ำและไม่มีกลไกชัดเจนใด ๆ สำหรับการยกเลิกการเรียกซ้ำ ฉันเดาว่าหนึ่งในการทดสอบภายในของ Vim สำหรับการเรียกซ้ำแบบไม่ จำกัด กำลังถูกเรียกใช้ซึ่งสร้างข้อผิดพลาด หากมาโคร 1 สร้างข้อผิดพลาดดังกล่าวแล้วข้อผิดพลาดที่จะยุติการดำเนินการของ Wrapper @wขวามาโครหลัง

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

qw:%s/\s\+$//^Mq
qe:%s/\n\n *}/\r}/^Mq

โดยที่^Mพิมพ์คีย์ Enter หรือ Return ของคุณ ฉันไม่ได้ทดสอบสิ่งเหล่านี้ใน Wrapper Macro ของคุณ แต่ฉันคิดว่าคุณจะสามารถแก้ไขข้อผิดพลาดที่ฉันทำ


มันไม่ใช่การทดแทนในกรณีของฉัน แต่เป็นการค้นหาง่าย ๆ(เช่น/foo) ในขณะ:silent!ที่เคล็ดลับของ submacro แบบเรียกซ้ำไม่ได้ยกเลิกแมโคร wrapper แต่ตอนนี้ submacro ไม่ยุติเลย ... และฉันสงสัยว่าการทำให้มันยุติอีกครั้งจะยุติแมโครตัวห่ออีกด้วย ดูเหมือนว่าฉันติดอยู่ : - \
DevSolar

เป็นการยากที่จะพูดสิ่งที่อาจผิดโดยไม่เห็นมาโครที่คุณใช้อยู่หรือเป็นตัวอย่างง่ายๆที่แสดงถึงปัญหาเดียวกัน
garyjohn

เพิ่มตัวอย่าง
DevSolar

2

สิ่งที่ใช้ได้ผลสำหรับฉันคือการรวมกันของ @Peter Rincker และ @garyjohn ฉันเพิ่งเจอปัญหาแปลก ๆ

nnoremap <leader>rt :silent! %s/\s\+$//e<CR>
let @r='\rt'
let @t=':try|silent! exe "norm! @r"|endtry|w^M'

ฉันคิดว่าsilent!ใน<leader>rtและอักขระไพพ์ระหว่างendtryและwมีกุญแจ - เพียงแค่มีการแบ่งบรรทัดหลังจากendtryล้มเหลว การtryทำงานเมื่อฉันเพิ่งป้อนพวกเขา แต่เมื่อทำงานเป็นแมโครข้อผิดพลาดเกี่ยวกับข้อความค้นหาไม่พบจะถูกยกขึ้น


1

ฉันสร้างมาโครได้ทันทีเมื่อฉันต้องทำงานซ้ำ ๆ ในหลาย ๆ ไฟล์ ในกรณีของฉันฉันมี NERDtree ( http://www.vim.org/scripts/script.php?script_id=1658 ) ติดตั้งใน VIM ซึ่งสร้างvsplitหน้าต่างและด้านซ้ายฉันมีรายการไฟล์ทั้งหมดใน ไดเรกทอรีปัจจุบัน ในตัวอย่างหนึ่งฉันต้องการค้นหาอินสแตนซ์แรกของสตริงMY_TESTในไฟล์แล้วลบหากมีคำนำหน้าระบุว่าCUSTOM_PREFIX-จากบรรทัดนั้นบันทึกไฟล์จากนั้นย้ายไปยังส่วนถัดไป

นี่คือวิธีที่ฉันมีมาโครนี้ทำงานกับไฟล์ประมาณ 2000 ไฟล์ในไดเรกทอรีปัจจุบัน ฉันสามารถเขียนสคริปต์ทุบตีเพื่อทำสิ่งนี้ แต่ใน VIM นั้นเร็วกว่าในกรณีของฉัน +คีย์หมายถึงการกดงิ้ว

# Start recording a macro sequence to register 'A'

q,a

# Search silently for the string "MY_TEST"; DO NOT report an error
# if the string could not be found.
:silent! /MY_TEST


# Replace, on just the current line, the string "CUSTOM_PREFIX-", with
# nothing (ie: delete it), and suppress any warning messages if the
# string could not be found on the current line.
:s/CUSTOM_PREFIX-//e


# Now issue some UI commands. CTRL-W then and arrow key lets you hope
# between tabs/splits/windows within vim.

CTRL+ W,

# Scroll down to the next file in the list in NERDtree



# Open the next file

ENTER

# End the macro

q

# Run the macro a thousand times in VIM

1,000 @,,a

หวังว่านี่จะช่วยได้!

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