0

I am trying to more or less reproduce for Python the if0 syntax highlighting of C-like files in Vim where code surrounded by #if 0 and #endif are grayed out (highlighted as Comment). Instead of preprocessor directives, I would like to gray out Python code blocks starting with if 0: or if False:.

Inspired by this question, I came up with the following code which almost works:

syn region pyIfFalse start=/^\(\s*\)if \%(0\+\|False\):\n\+\z(\1\s\+\)\S/ skip=/^\%(\z1\S\|^$\)/ end=/^\z1\@!.*/me=s-1
hi def link pyIfFalse Comment

This results in the following

 if 0: # grayed out (there is a space at the beginning)
   pass
if 0: # not grayed out
  pass

If I replace all if by ef (in the example and in the pattern), both blocks will be grayed out, meaning that the problem must be with the keyword if.

Following this question, one can redefine if as a keyword contained but then it would not be highlighted in regular text so it does not seem like a satisfying solution.

What is quite surprising to me is that the highlighting works for the first block but not the second, with the only difference being a space before the if.

Community
  • 1
  • 1
udscbt
  • 155
  • 1
  • 7
  • As a follow-up, it would be great to be able to detect `if 1: ... else: ...` as is done currently done for C-like files but I feel like Python's indentation rules would make it much more complex. – udscbt Jun 20 '16 at 12:46

1 Answers1

0

The answer lies in :help syn-priority.

  1. When multiple Match or Region items start in the same position, the item defined last has priority.
  2. A Keyword has priority over Match and Region items.
  3. An item that starts in an earlier position has priority over items that start in later positions.

In the third line of the example, the Keyword had priority over the Region (2.) but in the first line, the Region had priority because it started earlier (3.).

A workaround, for lack of a better alternative, is to downgrade the highlighting of if to a Match defined before the Region (1.).

syn clear pythonConditional
syn keyword pythonConditional elif else
syn match pythonIf /\<if\>/
syn region pyIfFalse start=/^\(\s*\)if \%(0\+\|False\):\n\+\z(\1\s\+\)\S/ skip=/^\%(\z1\S\|^$\)/ end=/^\z1\@!.*/me=s-1
hi def link pythonConditional  Conditional
hi def link pythonIf  Conditional
hi def link pyIfFalse Comment
udscbt
  • 155
  • 1
  • 7