มีวิธีการและเหตุการณ์ใน autocmd หรือไม่


21

ผมอยากจะเรียกautocmd ทั้งสองเหตุการณ์ที่เกิดขึ้น autocmdแต่ไม่ใช่ในลักษณะที่จะทำมักจะเป็นเช่นถ้าเหตุการณ์ใดเหตุการณ์หนึ่งที่เกิดขึ้นแล้วเรียก ฉันต้องการที่จะเรียกมันถ้าเหตุการณ์ทั้งสองเกิดขึ้น

ตัวอย่างเช่น:
วิธีปกติในการทำ

autocmd BufWrite,BufRead *.c *.py *.h :call StripTrailingWhitespaces()

รหัสนี้จะเรียก StripTrailingWhiteSpaces () บน BufWrite หรือ BufRead

ฉันต้องการทำสิ่งที่ชอบ:

autocmd Filetype c,cpp,python AND BufWrite :call StripTrailingWhiteSpaces()

ในคำอื่น ๆ เรียกautcmdเมื่อชนิดของไฟล์เป็นหนึ่งใน c, cpp, python และการเขียนในบัฟเฟอร์นี้เกิดขึ้น

ความช่วยเหลือใด ๆ ที่ชื่นชม

คำตอบ:


14

คำสั่ง autocommand จะถูกดำเนินการเมื่อมีเหตุการณ์หนึ่งเกิดขึ้น คุณต้องการให้คำสั่งถูกเรียกใช้งานหลังจากมีลำดับเหตุการณ์เกิดขึ้น วิธีหนึ่งในการทำเช่นนี้:

autocmd FileType c,cpp,python
    \ autocmd BufWritePre <buffer> call StripTrailingWhiteSpaces()

<buffer>รูปแบบที่ทำให้เกิด autocommand ที่จะถูกเรียกเมื่อบัฟเฟอร์ปัจจุบันเป็นลายลักษณ์อักษร ดู

:help autocmd-buflocal

ปรับปรุง

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

augroup TrailSpace
    autocmd FileType c,cpp,python
        \ autocmd! TrailSpace BufWritePost <buffer> call SkipTrailingWhiteSpaces()
augroup END

โซลูชันอื่นซึ่งคล้ายกับคำตอบที่โพสต์โดย lcd047 ที่ถูกลบไปแล้วในตอนนี้คือการรับรู้ว่าเมื่อเกิดเหตุการณ์ FileType ตัวเลือก 'filetype' จะถูกตั้งค่า จากนั้นคุณสามารถกำหนดเงื่อนไขการตอบสนองต่อเหตุการณ์ BufWritePost ตามค่าของ 'filetype' ดังตัวอย่างต่อไปนี้ มันมีข้อได้เปรียบเหนือโซลูชันอื่น ๆ ที่มีเพียงรายการสร้างอัตโนมัติเท่านั้น

autocmd BufWritePre * if count(['c','cpp','python'],&filetype)
    \ | call SkipTrailingWhiteSpaces()
    \ | endif

จะเกิดอะไรขึ้นถ้าฉันต้องการรันสิ่งนี้กับไฟล์ทั้งหมดที่เปิดอยู่ในปัจจุบันเช่นฉันเรียกใช้: wa
flashburn

หากไฟล์ถูกเปิดด้วยประเภทไฟล์ที่ถูกต้องFileTypeautocmd ในคำตอบจะตั้งค่า autocmd ( BufWritePre) ตัวที่สองไว้แล้วเพื่อเริ่มทำงานเมื่อคุณบันทึกไฟล์
VanLaser

1
FileTypeautocmd ข้างต้นจะไฟสำหรับทุกไฟล์ที่คุณเปิดกับ filetype ที่ถูกต้องและการตั้งค่าพินัยกรรมบัฟเฟอร์ท้องถิ่นเหตุการณ์สำหรับแต่ละไฟล์เหล่านั้น ดังนั้นหากคุณเรียกใช้:waกลุ่มจะเรียกใช้กิจกรรมที่ลงทะเบียนไว้สำหรับบัฟเฟอร์แต่ละรายการก่อนบันทึกลงในไฟล์
VanLaser

1
ดังนั้นหากคุณเปิดไฟล์ Python 5 ไฟล์คุณจะมี 5 autocmdวินาทีแทนที่จะเป็นไฟล์เดียวทุกไฟล์จะถูกเขียน จากนั้นถ้าพูดว่า 3 ไฟล์เหล่านี้ถูกซ่อนจากนั้นแสดงอีกครั้งFileTypeรับการทริกเกอร์อีกครั้งเพื่อให้คุณได้ 3 autocmdวินาทีมากขึ้นเมื่อเขียน นี่ยอดเยี่ยมฉันสงสัยว่าทำไมฉันถึงไม่ได้แก้ปัญหาด้วยวิธีนี้ :)
lcd047

1
ประสิทธิภาพไม่ใช่ปัญหา การรันฟังก์ชั่นstripTrailingWhiteSpaces()หลาย ๆ ครั้งกับไฟล์เดียวกันอาจมีผลที่ตามมาโดยไม่ได้ตั้งใจ ยิ่งautocmdคุณมีเหตุการณ์เดียวกันสำหรับไฟล์เดียวกันมากเท่าไหร่ก็จะยิ่งมีแนวโน้มที่จะเกิดปัญหาการแข่งขันมากขึ้นเท่านั้น ลองค้นหาคลังเก็บ vim_dev เพื่อรับแนวคิด จากนั้นอีกครั้งฉันรู้อะไรมันอาจจะได้ผลสำหรับคุณใช่ไหม
lcd047

4

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

function StripTrailingWhiteSpacesIfReady(event) abort
  if !exists('b:events_for_whitespace')
    let b:events_for_whitespace = {}
  endif
  let b:events_for_whitespace[a:event] = 1
  if has_key(b:events_for_whitespace, 'FileType') && has_key(b:events_for_whitespace, 'Buf')
    " Strip trailing whitespace
    %s/\m\s\+$//
  endif
endfunction
autocmd Filetype c,cpp,python call StripTrailingWhiteSpacesIfReady('FileType')
autocmd BufWrite,BufRead * StripTrailingWhiteSpacesIfReady('Buf')
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.