Đối sánh một phần cú pháp Vim

Sep 29 2020

Tôi đang cố gắng khớp một ký tự dòng mới trên tệp cú pháp Vim, tôi có thể làm cho nó hoạt động khi tôi sử dụng patern trong Vim nhưng khi tôi đặt nó vào tệp cú pháp của mình, nó không đánh dấu khi tôi có một dòng mới và khi nào nó nên.

Phần regex mà tôi sử dụng cho phù hợp với dòng sản phẩm mới là: \_s(cũng đã cố gắng với \nvới: \(\n\|\s\))

Người patern: [,(]\(\_s*\w\+:\)\?\_s*\zs\w\+

Phiên bản đơn giản của patern: [,(]\_s*\zs\w\+(giống với ví dụ và mục đích của câu hỏi)

Mã tệp cú pháp bên trong .vim/syntax/python.vim:

syn match pythonFunctionParam '[,(]\_s*\zs\w\+'
[...]
hi link pythonFunctionParam Error
[...]
let b:current_syntax = 'python'

Đây là một tệp thử nghiệm mẫu để tạo lại thử test.py:

a(matched_by_all=2, matched_by_all="anything")
b(  matched_by_all=3,
    matched_only_by_vim_search='test'
)
c(
    matched_only_by_vim_search=3
    matched_by_none="it's normal"
)

Khi tôi sử dụng tìm kiếm tích hợp Vim ( /[,(]\_s*\zs\w\+), tôi nhận được các kết quả phù hợp:

  matched_by_all    matched_by_all
    matched_by_all
    matched_only_by_vim_search


    matched_only_by_vim_search
    

Vì vậy, mọi thứ hoạt động như mong đợi

Khi tôi sử dụng cú pháp syn matchvới cùng một regex, tôi nhận được các kết quả phù hợp khác nhau (ít khớp hơn):

  matched_by_all    matched_by_all
    matched_by_all






Bạn có thể thấy khi có một (hoặc ,trên cùng một dòng thì nó sẽ khớp, nhưng không phải nếu đó là một dòng mới.

Vì vậy, câu hỏi của tôi là: Làm thế nào để có được kết quả trùng khớp trong tệp cú pháp của tôi?

Trả lời

1 MaximKim Sep 29 2020 at 21:17

Có vẻ như động cơ regexp đối sánh cú pháp vim không thích \zsvà \_s. Nếu xóa, \zsbạn có thể thấy các kết quả phù hợp:

Tôi sẽ đi với một cách tiếp cận khác:

  1. xác định vùng gọi hàm trong suốt có chứa các tham số hàm
  2. xác định tham số hàm chứa
syn region pythonFunctionCall start='\k\+\_s*(\zs' end='\ze)' contains=pythonFunctionParam transparent keepend
syn match pythonFunctionParam '\k\+\(\s*=\s*[^,]\+\)\?' contained
hi link pythonFunctionParam Error

LƯU Ý: pythonFunctionParam chỉ là một ví dụ đơn giản mà bạn có thể điều chỉnh.

1 filbranden Sep 29 2020 at 21:53

Có một ngoại lệ rõ ràng đối với cách \zshoạt động trong đối sánh cú pháp, ở đó nó phải khớp trên cùng một dòng khi bắt đầu mẫu.

Xem :help syn-multi-line:

Các mẫu có thể bao gồm "\ n" để khớp với phần cuối của dòng. Hầu hết điều này hoạt động như mong đợi, nhưng có một vài ngoại lệ.

Khi sử dụng mẫu bắt đầu có độ lệch, phần bắt đầu của trận đấu không được phép bắt đầu ở dòng sau. Tuy nhiên, phần đánh dấu có thể bắt đầu ở một dòng sau. Sử dụng \zsvật phẩm cũng yêu cầu đầu trận đấu không được chuyển sang dòng khác.

Thay vào đó, bạn có thể giải quyết vấn đề đó bằng cách sử dụng đối sánh xem lại chiều rộng bằng không :

syn match pythonFunctionParam '\([,(]\_s*\)\@<=\w\+'

Nhưng lưu ý rằng loại đấu này có xu hướng đắt hơn. Nếu bạn sử dụng một, hãy cố gắng giới hạn phạm vi của nó. Công cụ cú pháp trong Vim cũng cung cấp các cơ chế khác có thể giúp bạn thu hẹp các đối sánh của mình, chẳng hạn như bạn có thể đối sánh các nhóm nhất định chỉ khi chúng xuất hiện bên trong các nhóm cụ thể khác, điều này có thể giúp triển khai loại cú pháp này bằng các đối sánh đơn giản hơn.