Các vùng cú pháp vim có thể được thực hiện để chạm / chồng lấp?


13

Vì vậy, một thời gian trước tôi đã quyết định tìm hiểu thêm về cách các tệp cú pháp của vim hoạt động, bằng cách tạo riêng của tôi. Mục tiêu của tôi là tạo ra một tệp cú pháp đơn giản để chia tệp thành 3 phần dựa trên các dấu phân cách và bao gồm các tệp cú pháp có sẵn cho hai trong ba phần đó.

Đây là một tập tin ví dụ:

Some text, unstyled

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

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

Mục tiêu là chỉ áp dụng git.vimcho nhật ký và diff.vimchỉ khác biệt, không bao gồm hai tiêu đề. 1 Đây là tệp cú pháp của tôi cuối cùng trông như thế nào:

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"

Lưu ý làm thế nào endtrên khu vực đầu tiên giống như starttrên khu vực thứ hai. Điều này không hoạt động; khu vực thứ hai rõ ràng là không được phát hiện và đánh dấu cú pháp không được áp dụng.

Tôi có thể làm cho nó hoạt động bằng cách nới lỏng regex end=/^===/start=/=== Diff/, để các vùng không chạm vào, nhưng không đặc biệt như thế - rõ ràng là người ta phải bắt đầu từ nơi khác kết thúc.

Có cách nào để cho phép hai định nghĩa vùng chạm vào cùng một ký tự (và / hoặc làm cho các cạnh khớp độc quyền thay vì bao gồm) hoặc tôi có bị mắc kẹt với biểu thức chính quy lỏng hơn không?

1 (Có, tôi biết git.vimbao gồm diff.vim, nhưng đây là một bài tập học tập)


Tôi nghĩ điều này có thể bằng cách sử dụng phần bù "Vùng kết thúc" để làm cho các cạnh trở nên độc quyền (xem :h :syn-pattern-offset) hoặc bằng cách thay đổi vùng GitLog để mở rộng đến cuối tệp và vùng Diff nằm hoàn toàn trong vùng GitLog . Mặc dù vậy, tôi không thể làm cho một trong hai phương pháp này hoạt động được.
Giàu

Việc kiểm tra nó đã được thực hiện hơi khó hơn bởi thực tế là - như bạn lưu ý - git.vim đã làm nổi bật đầu ra khác. Có thể là một ý tưởng để thay đổi ví dụ của bạn cho phù hợp!
Giàu

Câu trả lời:


4

Bạn có thể cho Vim regex engine biết nơi bắt đầu trận đấu tiếp theo.

Cho đến nay tôi biết có 2 cách:

  1. Sử dụng \zeđể đặt kết thúc của trận đấu:

    syntax region GitLog
        \ start=/^===* Log/
        \ end=/\ze^===* Diff/
        \ contains=@gitlog
    
  2. Sử dụng giao diện tích cực, \@=được gọi là kết hợp độ rộng 0 trong Vim:

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

Vì vậy, các end-of-match "con trỏ" loại tua lại đến đầu ^===* Diffdòng, như vậy mà region Diff's startsẽ bắt đầu khớp tại ^===* Diffđường một lần nữa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.