I am trying to come up with a vim syntax for python function call, e.g.

foo(notarg==0, arg2, kwarg='a', kwarg2='b')
dict(a=1, b=2, c=3)

where we want to highlight

  • (i) function name foo, dict
  • (ii) keyword parameters, e.g. kwarg, kwarg2

I know there is a great answer on a similar question. To repeat:

syn region FCall matchgroup=FName start='[[:alpha:]_]\i*\s*(' end=')' contains=FCall,FCallKeyword
syn match FCallKeyword /\i*\ze\s*=[^=]/ contained

Or, alternatively, in my own vim syntax file for python, I could manage to achieve a similar behavior:

syn match   pythonCall   /\<\h\i*\ze\s*(/    contains=pythonBuiltin,pythonBuiltinFunc,pythonBuiltinType
                                           \ nextgroup=pythonCallRegion skipwhite keepend
syn region  pythonCallRegion        contained matchgroup=pythonParamsDelim start=/(/  end=/)/ keepend extend
                                      \ contains=pythonCallComma,pythonCall,@pythonCallArgument,pythonCallArgKeyword
syn match   pythonCallArgKeyword    contained /\h\i*\ze\s*==\@!/

However, the problem is that when a previously existing syntax group (e.g. pythonBuiltinType) matches function name, the entire highlight for keyword arguments would not work:

For example:

dict(a=1, b=2)

where we have the following highlighting rule somewhere (e.g. python-mode)

syn keyword pythonBuiltinType dict ....

Given this, dict matches pythonBuiltinType, but not matches pythonCall. This happens for the both ways I just described. A screenshot:

What did I wrong here? Vim syntax is quite difficult, so your help would be greatly appreciated.

  • 2
    Does this snippet help?
    – user938271
    Dec 28 '18 at 22:04
  • Wow, this works like a charm. Thanks a lot! A key idea is that we kind of "override" the syntax rule defined in other scripts (which is out of control) using the syn list and syn clear trick, in order to make it contained. This is pretty smart. Dec 28 '18 at 22:31
  • 1
    In fact, I wish the original definition of pythonBuiltinType (e.g. from python-mode) had contained, which may give a cleaner solution. Maybe I should try updating all primitive syntax rules. Do you think, however, is there any way to make it work without touching them but playing with additory syntax (e.g. pythonCall)? Dec 28 '18 at 22:34
  • I'm no expert on syntax highlighting, so I can't give you an answer. Maybe someone else will suggest such a solution. I couldn't find a better one because a keyword always has higher priority than a match or region (see :h :syn-keyword), and because the keywords in pythonBuiltinType are not nested: they match at the top level. If they were contained, you could probably override what you want.
    – user938271
    Dec 28 '18 at 22:50
  • 1
    In the future, syntax highlighting could be performed by attaching properties to the text. Here's an excerpt from :h text-prop-intro: Instead of defining patterns to match the text, the highlighting is set by a script, possibly using the output of an external parser. You need a recent version of Vim to read this help file, and I don't think it's ready to replace syntax highlighting yet, because it's very recent and still under development. Maybe keep an eye on it, as it could help fix your issue later.
    – user938271
    Dec 28 '18 at 22:50

Your Answer

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

Browse other questions tagged or ask your own question.