2

I'm trying to match a new line character on a Vim syntax file, I can make it work when I use the patern within Vim but when I put it in my syntax file it doesn't highlight when I have a new line and when it should.

The regex part that I use for new line match is: \_s (also tried with \n with: \(\n\|\s\))

The patern: [,(]\(\_s*\w\+:\)\?\_s*\zs\w\+

Simplified version of the patern: [,(]\_s*\zs\w\+ (same for the example and the purpose of the question)

Syntax file code inside .vim/syntax/python.vim:

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

Here is a sample test file to reproduce try: 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"
)

When I use Vim integrated search ( /[,(]\_s*\zs\w\+ ) I get thoses matches:

  matched_by_all    matched_by_all
    matched_by_all
    matched_only_by_vim_search


    matched_only_by_vim_search
    

So everything works has expected

When I use syntax syn match with the same regex I get different matches (less match):

  matched_by_all    matched_by_all
    matched_by_all






Has you can see when there is a ( or , on the same line it will match, but not if it's a new line.

So my question is: How to get the same match in my syntax file ?

  • 1
    Please stick to one question per post. I’ve removed the second; you can find in the edit history if you’d like to repost it as a new question. Thank you for including screenshots of what matched; please also include the original text where relevant—it would be nice to have a sample to copy/paste/test, which images make hard to do. – D. Ben Knoble Sep 29 at 12:49
  • Is it better now ? I thought the question were related since they both are matching issues concerning Vim's syntax. I'm probably missing something about how Vim deal with syntax but couldn't find it in the doc – ndfg201 Sep 29 at 13:11
  • 1
    The screenshots were fine! I just wanted to also include the original text. Up to you how you prefer to structure the question to read. I removed the second question since it was only marginally related (syntax) and had to do with a completely different part of that syntax (class definition versus function params) – D. Ben Knoble Sep 29 at 13:26
1

Looks like vim syntax match regexp engine doesn't like \zs and \_s. If you remove \zs you can see matches:

enter image description here

I would go with another approach:

  1. define transparent function call region that contains function parameters
  2. define contained function paramenter
syn region pythonFunctionCall start='\k\+\_s*(\zs' end='\ze)' contains=pythonFunctionParam transparent keepend
syn match pythonFunctionParam '\k\+\(\s*=\s*[^,]\+\)\?' contained
hi link pythonFunctionParam Error

NOTE: pythonFunctionParam is just a simple example you can tune.

enter image description here

| improve this answer | |
1

There is an explicit exception to how \zs works in a syntax match in that it must match on the same line as the pattern starts.

See :help syn-multi-line:

The patterns can include "\n" to match an end-of-line. Mostly this works as expected, but there are a few exceptions.

When using a start pattern with an offset, the start of the match is not allowed to start in a following line. The highlighting can start in a following line though. Using the \zs item also requires that the start of the match doesn't move to another line.

You can work around that by using a zero-width look-behind match instead:

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

But note that this kind of match tends to be more expensive. If you use one, try to limit its scope. The syntax engine in Vim also offers other mechanisms that can help you narrow down your matches, for example you can match certain groups only when they occur inside specific other groups, this might help implement this kind of syntax using simpler matches.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.