สามารถสร้างขอบเขตของไวยากรณ์กลุ่มเพื่อสัมผัส / ทับซ้อนได้หรือไม่?


13

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

นี่คือไฟล์ตัวอย่าง:

Some text, unstyled

==================== Log
(Output of git log)

==================== Diff
(Output of diff)

เป้าหมายคือนำไปใช้git.vimกับบันทึกและdiff.vimเพียงส่วนต่างไม่รวมสองหัว 1 นี่คือสิ่งที่ไฟล์ไวยากรณ์ของฉันดูเหมือน:

if exists("b:current_syntax")
    finish
endif

syntax include @gitlog $VIMRUNTIME/syntax/git.vim
syntax region GitLog
    \ start=/^===* Log/
    \ end=/^===* Diff/
    \ contains=@gitlog

syntax include @gitdiff $VIMRUNTIME/syntax/diff.vim
syntax region Diff
    \ start=/^===* Diff/
    \ end=/\n\n/
    \ contains=@gitdiff

let b:current_syntax = "logdiff"

โปรดทราบว่าendในภูมิภาคแรกจะเหมือนกับstartภูมิภาคที่สองอย่างไร มันใช้งานไม่ได้ เห็นได้ชัดว่าไม่พบบริเวณที่สองและไม่ใช้การเน้นไวยากรณ์

ฉันสามารถทำให้มันทำงานโดยคลาย regex ไปend=/^===/และstart=/=== Diff/เพื่อไม่ให้ภูมิภาคสัมผัส แต่โดยเฉพาะอย่างยิ่ง - มันชัดเจนน้อยลงว่าควรจะเริ่มต้นที่ปลายอีกด้าน

มีวิธีให้สองคำจำกัดความภูมิภาคสัมผัสอักขระเดียวกัน (และ / หรือทำให้การจับคู่ขอบพิเศษแทนรวม) หรือฉันติดอยู่กับ loex regex?

1 (ใช่ฉันรู้ว่าgit.vimมีdiff.vimแต่นี่คือแบบฝึกหัดการเรียนรู้)


ฉันคิดว่าสิ่งนี้น่าจะเป็นไปได้ด้วยการใช้ offset "Region End" เพื่อทำให้ขอบเป็นเอกสิทธิ์ (ดู:h :syn-pattern-offset) หรือโดยการเปลี่ยนภูมิภาค GitLog เพื่อขยายไปยังจุดสิ้นสุดของไฟล์และภูมิภาค Diff จะอยู่ในภูมิภาค GitLog ทั้งหมด . อย่างไรก็ตามฉันไม่สามารถใช้วิธีการใดวิธีการหนึ่งต่อไปนี้
รวย

การทดสอบนั้นค่อนข้างยากขึ้นโดยข้อเท็จจริงที่ว่า - ตามที่คุณทราบ - git.vim ไฮไลต์เอาท์พุทที่ต่างออกไปแล้ว อาจเป็นความคิดที่จะเปลี่ยนตัวอย่างของคุณตาม!
รวย

คำตอบ:


4

คุณสามารถบอก Vim regex engine ว่าจะเริ่มการแข่งขันครั้งต่อไปอย่างไร

จนถึงตอนนี้ฉันรู้ว่ามี 2 วิธี:

  1. ใช้\zeเพื่อกำหนดจุดสิ้นสุดของการแข่งขัน:

    syntax region GitLog
        \ start=/^===* Log/
        \ end=/\ze^===* Diff/
        \ contains=@gitlog
    
  2. ใช้ lookahead เชิงบวก\@=ซึ่งเรียกว่าการจับคู่ความกว้างศูนย์ใน Vim:

    syntax region GitLog
        \ start=/^===* Log/
        \ end=/\(^===* Diff\)\@=/
        \ contains=@gitlog
    

ดังนั้นในตอนท้ายของการแข่งขัน "ชี้" ชนิดของ Rewinds จุดเริ่มต้นของ^===* Diffเส้นดังกล่าวว่าregion Diff's startจะเริ่มต้นตรงกับที่^===* Diffสายอีกครั้ง

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