neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

python.vim (18807B)


      1 " Vim syntax file
      2 " Language:	Python
      3 " Maintainer:	Zvezdan Petkovic <zpetkovic@acm.org>
      4 " Last Change:	2025 Sep 08
      5 " 2025 Sep 25 by Vim Project: fix wrong type highlighting #18394
      6 " 2025 Dec 03 by Vim Project: highlight t-strings #18679
      7 " 2026 Jan 26 by Vim Project: highlight constants #18922
      8 " Credits:	Neil Schemenauer <nas@python.ca>
      9 "		Dmitry Vasiliev
     10 "		Rob B
     11 "		Jon Parise
     12 "
     13 "		This version is a major rewrite by Zvezdan Petkovic.
     14 "
     15 "		- introduced highlighting of doctests
     16 "		- updated keywords, built-ins, and exceptions
     17 "		- corrected regular expressions for
     18 "
     19 "		  * functions
     20 "		  * decorators
     21 "		  * strings
     22 "		  * escapes
     23 "		  * numbers
     24 "		  * space error
     25 "
     26 "		- corrected synchronization
     27 "		- more highlighting is ON by default, except
     28 "		- space error highlighting is OFF by default
     29 "
     30 " Optional highlighting can be controlled using these variables.
     31 "
     32 "   let python_no_builtin_highlight = 1
     33 "   let python_no_doctest_code_highlight = 1
     34 "   let python_no_doctest_highlight = 1
     35 "   let python_no_exception_highlight = 1
     36 "   let python_no_number_highlight = 1
     37 "   let python_space_error_highlight = 1
     38 "   let python_constant_highlight = 1
     39 "
     40 " All the options above can be switched on together.
     41 "
     42 "   let python_highlight_all = 1
     43 "
     44 " The use of Python 2 compatible syntax highlighting can be enforced.
     45 " The straddling code (Python 2 and 3 compatible), up to Python 3.5,
     46 " will be also supported.
     47 "
     48 "   let python_use_python2_syntax = 1
     49 "
     50 " This option will exclude all modern Python 3.6 or higher features.
     51 "
     52 
     53 " quit when a syntax file was already loaded.
     54 if exists("b:current_syntax")
     55  finish
     56 endif
     57 
     58 " Use of Python 2 and 3.5 or lower requested.
     59 if exists("python_use_python2_syntax")
     60  runtime! syntax/python2.vim
     61  finish
     62 endif
     63 
     64 " We need nocompatible mode in order to continue lines with backslashes.
     65 " Original setting will be restored.
     66 let s:cpo_save = &cpo
     67 set cpo&vim
     68 
     69 if exists("python_no_doctest_highlight")
     70  let python_no_doctest_code_highlight = 1
     71 endif
     72 
     73 if exists("python_highlight_all")
     74  if exists("python_no_builtin_highlight")
     75    unlet python_no_builtin_highlight
     76  endif
     77  if exists("python_no_doctest_code_highlight")
     78    unlet python_no_doctest_code_highlight
     79  endif
     80  if exists("python_no_doctest_highlight")
     81    unlet python_no_doctest_highlight
     82  endif
     83  if exists("python_no_exception_highlight")
     84    unlet python_no_exception_highlight
     85  endif
     86  if exists("python_no_number_highlight")
     87    unlet python_no_number_highlight
     88  endif
     89  let python_space_error_highlight = 1
     90  let python_constant_highlight = 1
     91 endif
     92 
     93 " Keep Python keywords in alphabetical order inside groups for easy
     94 " comparison with the table in the 'Python Language Reference'
     95 " https://docs.python.org/reference/lexical_analysis.html#keywords.
     96 " Groups are in the order presented in NAMING CONVENTIONS in syntax.txt.
     97 " Exceptions come last at the end of each group (class and def below).
     98 "
     99 " The list can be checked using:
    100 "
    101 " python3 -c 'import keyword, pprint; pprint.pprint(keyword.kwlist + keyword.softkwlist, compact=True)'
    102 "
    103 syn keyword pythonBoolean	False True
    104 syn keyword pythonConstant	None
    105 syn keyword pythonStatement	as assert break continue del global
    106 syn keyword pythonStatement	lambda nonlocal pass return with yield
    107 syn keyword pythonStatement	class nextgroup=pythonClass skipwhite
    108 syn keyword pythonStatement	def nextgroup=pythonFunction skipwhite
    109 syn keyword pythonConditional	elif else if
    110 syn keyword pythonRepeat	for while
    111 syn keyword pythonOperator	and in is not or
    112 syn keyword pythonException	except finally raise try
    113 syn keyword pythonInclude	from import
    114 syn keyword pythonAsync		async await
    115 
    116 " Soft keywords
    117 " These keywords do not mean anything unless used in the right context.
    118 " See https://docs.python.org/3/reference/lexical_analysis.html#soft-keywords
    119 " for more on this.
    120 syn match   pythonConditional   "^\s*\zscase\%(\s\+.*:.*$\)\@="
    121 syn match   pythonConditional   "^\s*\zsmatch\%(\s\+.*:\s*\%(#.*\)\=$\)\@="
    122 syn match   pythonStatement     "\<type\ze\s\+\h\w*" nextgroup=pythonType skipwhite
    123 
    124 " These names are special by convention. While they aren't real keywords,
    125 " giving them distinct highlighting provides a nice visual cue.
    126 syn keyword pythonClassVar	self cls
    127 
    128 " Decorators
    129 " A dot must be allowed because of @MyClass.myfunc decorators.
    130 syn match   pythonDecorator	"@" display contained
    131 syn match   pythonDecoratorName	"@\s*\h\%(\w\|\.\)*" display contains=pythonDecorator
    132 
    133 " Python 3.5 introduced the use of the same symbol for matrix multiplication:
    134 " https://www.python.org/dev/peps/pep-0465/.  We now have to exclude the
    135 " symbol from highlighting when used in that context.
    136 " Single line multiplication.
    137 syn match   pythonMatrixMultiply
    138      \ "\%(\w\|[])]\)\s*@"
    139      \ contains=ALLBUT,pythonDecoratorName,pythonDecorator,pythonClass,pythonFunction,pythonType,pythonDoctestValue
    140      \ transparent
    141 " Multiplication continued on the next line after backslash.
    142 syn match   pythonMatrixMultiply
    143      \ "[^\\]\\\s*\n\%(\s*\.\.\.\s\)\=\s\+@"
    144      \ contains=ALLBUT,pythonDecoratorName,pythonDecorator,pythonClass,pythonFunction,pythonType,pythonDoctestValue
    145      \ transparent
    146 " Multiplication in a parenthesized expression over multiple lines with @ at
    147 " the start of each continued line; very similar to decorators and complex.
    148 syn match   pythonMatrixMultiply
    149      \ "^\s*\%(\%(>>>\|\.\.\.\)\s\+\)\=\zs\%(\h\|\%(\h\|[[(]\).\{-}\%(\w\|[])]\)\)\s*\n\%(\s*\.\.\.\s\)\=\s\+@\%(.\{-}\n\%(\s*\.\.\.\s\)\=\s\+@\)*"
    150      \ contains=ALLBUT,pythonDecoratorName,pythonDecorator,pythonClass,pythonFunction,pythonType,pythonDoctestValue
    151      \ transparent
    152 
    153 syn match   pythonClass		"\h\w*" display contained
    154 syn match   pythonFunction	"\h\w*" display contained
    155 syn match   pythonType		"\h\w*" display contained
    156 
    157 syn match   pythonComment	"#.*$" contains=pythonTodo,@Spell
    158 syn keyword pythonTodo		FIXME NOTE NOTES TODO XXX contained
    159 
    160 " Triple-quoted strings can contain doctests.
    161 syn region  pythonString matchgroup=pythonQuotes
    162      \ start=+[uU]\=\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1"
    163      \ contains=pythonEscape,pythonUnicodeEscape,@Spell
    164 syn region  pythonString matchgroup=pythonTripleQuotes
    165      \ start=+[uU]\=\z('''\|"""\)+ skip=+\\["']+ end="\z1" keepend
    166      \ contains=pythonEscape,pythonUnicodeEscape,pythonSpaceError,pythonDoctest,@Spell
    167 syn region  pythonRawString matchgroup=pythonQuotes
    168      \ start=+[rR]\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1"
    169      \ contains=@Spell
    170 syn region  pythonRawString matchgroup=pythonTripleQuotes
    171      \ start=+[rR]\z('''\|"""\)+ end="\z1" keepend
    172      \ contains=pythonSpaceError,pythonDoctest,@Spell
    173 
    174 " Formatted string literals (f-strings)
    175 " https://docs.python.org/3/reference/lexical_analysis.html#f-strings
    176 " Template string literals (t-strings)
    177 " https://docs.python.org/3/reference/lexical_analysis.html#template-string-literals
    178 syn region  pythonFString
    179      \ matchgroup=pythonQuotes
    180      \ start=+\c[FT]\z(['"]\)+
    181      \ end="\z1"
    182      \ skip="\\\\\|\\\z1"
    183      \ contains=pythonFStringField,pythonFStringSkip,pythonEscape,pythonUnicodeEscape,@Spell
    184 syn region  pythonFString
    185      \ matchgroup=pythonTripleQuotes
    186      \ start=+\c[FT]\z('''\|"""\)+
    187      \ end="\z1"
    188      \ keepend
    189      \ contains=pythonFStringField,pythonFStringSkip,pythonEscape,pythonUnicodeEscape,pythonSpaceError,pythonDoctest,@Spell
    190 syn region  pythonRawFString
    191      \ matchgroup=pythonQuotes
    192      \ start=+\c\%([FT]R\|R[FT]\)\z(['"]\)+
    193      \ end="\z1"
    194      \ skip="\\\\\|\\\z1"
    195      \ contains=pythonFStringField,pythonFStringSkip,@Spell
    196 syn region  pythonRawFString
    197      \ matchgroup=pythonTripleQuotes
    198      \ start=+\c\%([FT]R\|R[FT]\)\z('''\|"""\)+
    199      \ end="\z1"
    200      \ keepend
    201      \ contains=pythonFStringField,pythonFStringSkip,pythonSpaceError,pythonDoctest,@Spell
    202 
    203 " Bytes
    204 syn region  pythonBytes
    205      \ matchgroup=pythonQuotes
    206      \ start=+\cB\z(['"]\)+
    207      \ end="\z1"
    208      \ skip="\\\\\|\\\z1"
    209      \ contains=pythonEscape
    210 syn region  pythonBytes
    211      \ matchgroup=pythonTripleQuotes
    212      \ start=+\cB\z('''\|"""\)+
    213      \ end="\z1"
    214      \ keepend
    215      \ contains=pythonEscape
    216 syn region  pythonRawBytes
    217      \ matchgroup=pythonQuotes
    218      \ start=+\c\%(BR\|RB\)\z(['"]\)+
    219      \ end="\z1"
    220      \ skip="\\\\\|\\\z1"
    221 syn region  pythonRawBytes
    222      \ matchgroup=pythonTripleQuotes
    223      \ start=+\c\%(BR\|RB\)\z('''\|"""\)+
    224      \ end="\z1"
    225      \ keepend
    226 
    227 " F-string replacement fields
    228 "
    229 " - Matched parentheses, brackets and braces are skipped
    230 " - A bare = (followed by optional whitespace) enables debugging
    231 " - A bare ! prefixes a conversion field (followed by optional whitespace)
    232 " - A bare : begins a format specification
    233 "     - Matched braces inside a format specification are skipped
    234 "
    235 syn region  pythonFStringField
    236    \ matchgroup=pythonFStringDelimiter
    237    \ start=/{/
    238    \ end=/\%(=\s*\)\=\%(!\a\s*\)\=\%(:\%({\_[^}]*}\|[^{}]*\)\+\)\=}/
    239    \ contained
    240    \ contains=ALLBUT,pythonFStringField,pythonClass,pythonFunction,pythonType,pythonDoctest,pythonDoctestValue,@Spell
    241 syn match   pythonFStringFieldSkip  /(\_[^()]*)\|\[\_[^][]*]\|{\_[^{}]*}/
    242    \ contained
    243    \ contains=ALLBUT,pythonFStringField,pythonClass,pythonFunction,pythonType,pythonDoctest,pythonDoctestValue,@Spell
    244 
    245 " Doubled braces are not replacement fields
    246 syn match   pythonFStringSkip	/{{/ transparent contained contains=NONE
    247 
    248 syn match   pythonEscape	+\\[abfnrtv'"\\]+ contained
    249 syn match   pythonEscape	"\\\o\{1,3}" contained
    250 syn match   pythonEscape	"\\x\x\{2}" contained
    251 syn match   pythonUnicodeEscape	"\%(\\u\x\{4}\|\\U\x\{8}\)" contained
    252 " Python allows case-insensitive Unicode IDs: http://www.unicode.org/charts/
    253 " The specification: https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-4/#G135165
    254 syn match   pythonUnicodeEscape	"\\N{\a\+\%(\%(\s\a\+[[:alnum:]]*\)\|\%(-[[:alnum:]]\+\)\)*}" contained
    255 syn match   pythonEscape	"\\$"
    256 
    257 " It is very important to understand all details before changing the
    258 " regular expressions below or their order.
    259 " The word boundaries are *not* the floating-point number boundaries
    260 " because of a possible leading or trailing decimal point.
    261 " The expressions below ensure that all valid number literals are
    262 " highlighted, and invalid number literals are not.  For example,
    263 "
    264 " - a decimal point in '4.' at the end of a line is highlighted,
    265 " - a second dot in 1.0.0 is not highlighted,
    266 " - 08 is not highlighted,
    267 " - 08e0 or 08j are highlighted,
    268 "
    269 " and so on, as specified in the 'Python Language Reference'.
    270 " https://docs.python.org/reference/lexical_analysis.html#numeric-literals
    271 if !exists("python_no_number_highlight")
    272  " numbers (including complex)
    273  syn match   pythonNumber	"\<0[oO]\%(_\=\o\)\+\>"
    274  syn match   pythonNumber	"\<0[xX]\%(_\=\x\)\+\>"
    275  syn match   pythonNumber	"\<0[bB]\%(_\=[01]\)\+\>"
    276  syn match   pythonNumber	"\<\%([1-9]\%(_\=\d\)*\|0\+\%(_\=0\)*\)\>"
    277  syn match   pythonNumber	"\<\d\%(_\=\d\)*[jJ]\>"
    278  syn match   pythonNumber	"\<\d\%(_\=\d\)*[eE][+-]\=\d\%(_\=\d\)*[jJ]\=\>"
    279  syn match   pythonNumber
    280        \ "\<\d\%(_\=\d\)*\.\%([eE][+-]\=\d\%(_\=\d\)*\)\=[jJ]\=\%(\W\|$\)\@="
    281  syn match   pythonNumber
    282        \ "\%(^\|\W\)\@1<=\%(\d\%(_\=\d\)*\)\=\.\d\%(_\=\d\)*\%([eE][+-]\=\d\%(_\=\d\)*\)\=[jJ]\=\>"
    283 endif
    284 
    285 " Group the built-ins in the order in the 'Python Library Reference' for
    286 " easier comparison.
    287 " https://docs.python.org/library/constants.html
    288 " http://docs.python.org/library/functions.html
    289 " Python built-in functions are in alphabetical order.
    290 "
    291 " The list can be checked using:
    292 "
    293 " python3 -c 'import builtins, pprint; pprint.pprint(dir(builtins), compact=True)'
    294 "
    295 " The constants added by the `site` module are not listed below because they
    296 " should not be used in programs, only in interactive interpreter.
    297 " Similarly for some other attributes and functions `__`-enclosed from the
    298 " output of the above command.
    299 "
    300 if !exists("python_no_builtin_highlight")
    301  " built-in constants
    302  " 'False', 'True', and 'None' are also reserved words in Python 3
    303  syn keyword pythonBoolean	False True
    304  syn keyword pythonConstant	None NotImplemented Ellipsis __debug__
    305  " constants added by the `site` module
    306  syn keyword pythonBuiltin	quit exit copyright credits license
    307  " built-in functions
    308  syn keyword pythonBuiltin	abs all any ascii bin bool breakpoint bytearray
    309  syn keyword pythonBuiltin	bytes callable chr classmethod compile complex
    310  syn keyword pythonBuiltin	delattr dict dir divmod enumerate eval exec
    311  syn keyword pythonBuiltin	filter float format frozenset getattr globals
    312  syn keyword pythonBuiltin	hasattr hash help hex id input int isinstance
    313  syn keyword pythonBuiltin	issubclass iter len list locals map max
    314  syn keyword pythonBuiltin	memoryview min next object oct open ord pow
    315  syn keyword pythonBuiltin	print property range repr reversed round set
    316  syn keyword pythonBuiltin	setattr slice sorted staticmethod str sum super
    317  syn keyword pythonBuiltin	tuple vars zip __import__
    318  " only match `type` as a builtin when it's not followed by an identifier
    319  syn match   pythonBuiltin	"\<type\>\ze\(\s\+\h\w*\)\@!"
    320  " avoid highlighting attributes as builtins
    321  syn match   pythonAttribute	/\.\h\w*/hs=s+1
    322 \ contains=ALLBUT,pythonBuiltin,pythonClass,pythonFunction,pythonType,pythonAsync
    323 \ transparent
    324  " the ellipsis literal `...` can be used in multiple syntactic contexts
    325  syn match   pythonEllipsis	"\.\@1<!\.\.\.\ze\.\@!" display
    326 endif
    327 
    328 " From the 'Python Library Reference' class hierarchy at the bottom.
    329 " http://docs.python.org/library/exceptions.html
    330 if !exists("python_no_exception_highlight")
    331  " builtin base exceptions (used mostly as base classes for other exceptions)
    332  syn keyword pythonExceptions	BaseException Exception
    333  syn keyword pythonExceptions	ArithmeticError BufferError LookupError
    334  " builtin exceptions (actually raised)
    335  syn keyword pythonExceptions	AssertionError AttributeError EOFError
    336  syn keyword pythonExceptions	FloatingPointError GeneratorExit ImportError
    337  syn keyword pythonExceptions	IndentationError IndexError KeyError
    338  syn keyword pythonExceptions	KeyboardInterrupt MemoryError
    339  syn keyword pythonExceptions	ModuleNotFoundError NameError
    340  syn keyword pythonExceptions	NotImplementedError OSError OverflowError
    341  syn keyword pythonExceptions	RecursionError ReferenceError RuntimeError
    342  syn keyword pythonExceptions	StopAsyncIteration StopIteration SyntaxError
    343  syn keyword pythonExceptions	SystemError SystemExit TabError TypeError
    344  syn keyword pythonExceptions	UnboundLocalError UnicodeDecodeError
    345  syn keyword pythonExceptions	UnicodeEncodeError UnicodeError
    346  syn keyword pythonExceptions	UnicodeTranslateError ValueError
    347  syn keyword pythonExceptions	ZeroDivisionError
    348  " builtin exception aliases for OSError
    349  syn keyword pythonExceptions	EnvironmentError IOError WindowsError
    350  " builtin OS exceptions in Python 3
    351  syn keyword pythonExceptions	BlockingIOError BrokenPipeError
    352  syn keyword pythonExceptions	ChildProcessError ConnectionAbortedError
    353  syn keyword pythonExceptions	ConnectionError ConnectionRefusedError
    354  syn keyword pythonExceptions	ConnectionResetError FileExistsError
    355  syn keyword pythonExceptions	FileNotFoundError InterruptedError
    356  syn keyword pythonExceptions	IsADirectoryError NotADirectoryError
    357  syn keyword pythonExceptions	PermissionError ProcessLookupError TimeoutError
    358  " builtin warnings
    359  syn keyword pythonExceptions	BytesWarning DeprecationWarning FutureWarning
    360  syn keyword pythonExceptions	ImportWarning PendingDeprecationWarning
    361  syn keyword pythonExceptions	ResourceWarning RuntimeWarning
    362  syn keyword pythonExceptions	SyntaxWarning UnicodeWarning
    363  syn keyword pythonExceptions	UserWarning Warning
    364 endif
    365 
    366 if exists("python_space_error_highlight")
    367  " trailing whitespace
    368  syn match   pythonSpaceError	display excludenl "\s\+$"
    369  " mixed tabs and spaces
    370  syn match   pythonSpaceError	display " \+\t"
    371  syn match   pythonSpaceError	display "\t\+ "
    372 endif
    373 
    374 " Do not spell doctests inside strings.
    375 " Notice that the end of a string, either ''', or """, will end the contained
    376 " doctest too.  Thus, we do *not* need to have it as an end pattern.
    377 if !exists("python_no_doctest_highlight")
    378  if !exists("python_no_doctest_code_highlight")
    379    syn region pythonDoctest
    380   \ start="^\s*>>>\s" end="^\s*$"
    381   \ contained contains=ALLBUT,pythonDoctest,pythonEllipsis,pythonClass,pythonFunction,pythonType,@Spell
    382    syn region pythonDoctestValue
    383   \ start=+^\s*\%(>>>\s\|\.\.\.\s\|"""\|'''\)\@!\S\++ end="$"
    384   \ contained contains=pythonEllipsis
    385    syn match pythonEllipsis "\%(^\s*\)\@<!\.\@1<!\zs\.\.\.\ze\.\@!" display
    386   \ contained containedin=pythonDoctest
    387  else
    388    syn region pythonDoctest
    389   \ start="^\s*>>>" end="^\s*$"
    390   \ contained contains=@NoSpell
    391  endif
    392 endif
    393 
    394 " Sync at the beginning of (async) function or class definitions.
    395 syn sync match pythonSync grouphere NONE "^\%(def\|class\|async\s\+def\)\s\+\h\w*\s*[(:]"
    396 
    397 " The default highlight links.  Can be overridden later.
    398 hi def link pythonBoolean		Statement
    399 hi def link pythonConstant		Statement
    400 hi def link pythonStatement		Statement
    401 hi def link pythonConditional		Conditional
    402 hi def link pythonRepeat		Repeat
    403 hi def link pythonOperator		Operator
    404 hi def link pythonException		Exception
    405 hi def link pythonInclude		Include
    406 hi def link pythonAsync			Statement
    407 hi def link pythonClassVar		Identifier
    408 hi def link pythonDecorator		Define
    409 hi def link pythonDecoratorName		Function
    410 hi def link pythonClass			Structure
    411 hi def link pythonFunction		Function
    412 hi def link pythonType			Type
    413 hi def link pythonComment		Comment
    414 hi def link pythonTodo			Todo
    415 hi def link pythonString		String
    416 hi def link pythonRawString		String
    417 hi def link pythonFString		String
    418 hi def link pythonRawFString		String
    419 hi def link pythonBytes 		String
    420 hi def link pythonRawBytes 		String
    421 hi def link pythonQuotes		String
    422 hi def link pythonTripleQuotes		pythonQuotes
    423 hi def link pythonEscape		Special
    424 hi def link pythonUnicodeEscape		pythonEscape
    425 hi def link pythonFStringDelimiter	Special
    426 if !exists("python_no_number_highlight")
    427  hi def link pythonNumber		Number
    428 endif
    429 if !exists("python_no_builtin_highlight")
    430  hi! def link pythonBoolean		Function
    431  hi! def link pythonConstant		Function
    432  hi def link pythonBuiltin		Function
    433  hi def link pythonEllipsis		pythonBuiltin
    434 endif
    435 if !exists("python_no_exception_highlight")
    436  hi def link pythonExceptions		Structure
    437 endif
    438 if exists("python_space_error_highlight")
    439  hi def link pythonSpaceError		Error
    440 endif
    441 if !exists("python_no_doctest_highlight")
    442  hi def link pythonDoctest		Special
    443  hi def link pythonDoctestValue	Define
    444 endif
    445 if exists("python_constant_highlight")
    446  hi! def link pythonBoolean		Boolean
    447  hi! def link pythonConstant		Constant
    448 endif
    449 
    450 let b:current_syntax = "python"
    451 
    452 let &cpo = s:cpo_save
    453 unlet s:cpo_save
    454 
    455 " vim:set sw=2 sts=2 ts=8 noet: