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: