diff --git a/README.rst b/README.rst index f9cd20d..40fb9f1 100644 --- a/README.rst +++ b/README.rst @@ -24,7 +24,8 @@ Features Changes from the original ``python.vim`` are: -- Added support for Python 3 syntax highlighting +- Added support for Python 3.5/3.6+ syntax highlighting, including f-string + literals and type annotations. - Added ``:Python2Syntax`` and ``:Python3Syntax`` commands which allow to switch between Python 2 and Python 3 syntaxes respectively without reloads/restarts @@ -101,6 +102,8 @@ Options used by the script Highlight builtin objects only ``python_highlight_builtin_funcs`` Highlight builtin functions only +``python_highlight_type_annotations`` + Highlight Python 3.5+ type annotations ``python_highlight_exceptions`` Highlight standard exceptions ``python_highlight_string_formatting`` diff --git a/syntax/python.vim b/syntax/python.vim index e963628..1c5ea66 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -136,6 +136,7 @@ if s:Enabled("g:python_highlight_all") call s:EnableByDefault("g:python_highlight_builtin_objs") call s:EnableByDefault("g:python_highlight_builtin_funcs") endif + call s:EnableByDefault("g:python_highlight_type_annotations") call s:EnableByDefault("g:python_highlight_exceptions") call s:EnableByDefault("g:python_highlight_string_formatting") call s:EnableByDefault("g:python_highlight_string_format") @@ -151,10 +152,12 @@ endif " syn keyword pythonStatement break continue del -syn keyword pythonStatement exec return +if s:Python2Syntax() + syn keyword pythonStatement exec +endif +syn keyword pythonStatement return syn keyword pythonStatement pass raise syn keyword pythonStatement global assert -syn keyword pythonStatement lambda syn keyword pythonStatement with syn keyword pythonStatement def class nextgroup=pythonFunction skipwhite syn keyword pythonRepeat for while @@ -163,8 +166,29 @@ syn keyword pythonConditional if elif else " we provide a dummy group here to avoid crashing pyrex.vim. syn keyword pythonInclude import syn keyword pythonImport import +syn match pythonIdentifier "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" nextgroup=pythonFuncArgs,pythonTypeAnno display syn keyword pythonException try except finally syn keyword pythonOperator and in is not or +syn match pythonLambdaExpr "\\s*['"]\?\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\%(\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\)*['"]\?@ display contains=pythonType,pythonString nextgroup=pythonTypeArgs + syn region pythonTypeArgs matchgroup=pythonTypeArgs start='\[' end='\]' display contained contains=pythonType,pythonString,pythonTypeArgs + syn keyword pythonType Any AnyStr Callable ClassVar Tuple Union Optional Type TypeVar None contained + syn keyword pythonType AbstractSet MutableSet Mapping MutableMapping Sequence MutableSequence ByteString Deque List contained + syn keyword pythonType Set FrozenSet MappingView KeysView ItemsView ValuesView Awaitable Coroutine AsyncIterable contained + syn keyword pythonType AsyncIterator ContextManager Dict DefaultDict Generator AsyncGenerator Text NamedTuple contained + syn keyword pythonType Iterable Iterator Reversible SupportsInt SupportsFloat SupportsAbs SupportsRound Container contained + syn keyword pythonType Hashable Sized Collection contained + endif +endif syn match pythonStatement "\" display syn match pythonImport "\" display @@ -176,21 +200,66 @@ if s:Python2Syntax() syn keyword pythonImport as syn match pythonFunction "[a-zA-Z_][a-zA-Z0-9_]*" display contained else - syn keyword pythonStatement as nonlocal None + syn keyword pythonStatement as nonlocal syn match pythonStatement "\" display - syn keyword pythonBoolean True False - syn match pythonFunction "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained - syn keyword pythonStatement await - syn match pythonStatement "\" nextgroup=pythonFunction skipwhite + syn keyword pythonBuiltinObj None True False + syn match pythonFunction "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" nextgroup=pythonFuncArgs display contained + syn keyword pythonStatement await async + syn match pythonStatement "\" display nextgroup=pythonFunction skipwhite syn match pythonStatement "\" display syn match pythonStatement "\" display endif +syn cluster pythonTypeExpression contains=pythonTypeAnno,pythonTypeUnion,pythonTypeArgs + +syn cluster pythonExpression contains= + \ pythonFuncArgs, + \ pythonDictSetExpr, + \ pythonListSliceExpr, + \ pythonLambdaExpr, + \ pythonStatement, + \ pythonRepeat, + \ pythonConditional, + \ pythonComment, + \ pythonOperator, + \ pythonNumber, + \ pythonNumberError, + \ pythonFloat, + \ pythonHexNumber, + \ pythonOctNumber, + \ pythonBytes, + \ pythonString, + \ pythonRawString, + \ pythonUniString, + \ pythonUniRawString, + \ pythonFString, + \ pythonExClass, + \ pythonBuiltinObj, + \ pythonBuiltinFunc + +syn cluster pythonFExpression contains= + \ pythonStatement, + \ pythonDictSetExpr, + \ pythonListSliceExpr, + \ pythonLambdaExpr, + \ pythonRepeat, + \ pythonConditional, + \ pythonOperator, + \ pythonNumber, + \ pythonHexNumber, + \ pythonOctNumber, + \ pythonBinNumber, + \ pythonFloat, + \ pythonString, + \ pythonBytes, + \ pythonBuiltinObj, + \ pythonBuiltinFunc + " " Decorators (new in Python 2.4) " -syn match pythonDecorator "@" display nextgroup=pythonDottedName skipwhite +syn match pythonDecorator "^\s*\zs@" display nextgroup=pythonDottedName skipwhite if s:Python2Syntax() syn match pythonDottedName "[a-zA-Z_][a-zA-Z0-9_]*\%(\.[a-zA-Z_][a-zA-Z0-9_]*\)*" display contained else @@ -202,31 +271,31 @@ syn match pythonDot "\." display containedin=pythonDottedName " Comments " -syn match pythonComment "#.*$" display contains=pythonTodo,@Spell +syn match pythonComment "#.*$" display contains=pythonTodo,@Spell if !s:Enabled("g:python_highlight_file_headers_as_comments") - syn match pythonRun "\%^#!.*$" - syn match pythonCoding "\%^.*\%(\n.*\)\?#.*coding[:=]\s*[0-9A-Za-z-_.]\+.*$" + syn match pythonRun "\%^#!.*$" + syn match pythonCoding "\%^.*\%(\n.*\)\?#.*coding[:=]\s*[0-9A-Za-z-_.]\+.*$" endif -syn keyword pythonTodo TODO FIXME XXX contained +syn keyword pythonTodo TODO FIXME XXX contained " " Errors " -syn match pythonError "\<\d\+\D\+\>" display -syn match pythonError "[$?]" display -syn match pythonError "[&|]\{2,}" display -syn match pythonError "[=]\{3,}" display +syn match pythonError "\<\d\+\D\+\>" display +syn match pythonError "[$?]" display +syn match pythonError "[&|]\{2,}" display +syn match pythonError "[=]\{3,}" display " Mixing spaces and tabs also may be used for pretty formatting multiline " statements if s:Enabled("g:python_highlight_indent_errors") - syn match pythonIndentError "^\s*\%( \t\|\t \)\s*\S"me=e-1 display + syn match pythonIndentError "^\s*\%( \t\|\t \)\s*\S"me=e-1 display endif " Trailing space errors if s:Enabled("g:python_highlight_space_errors") - syn match pythonSpaceError "\s\+$" display + syn match pythonSpaceError "\s\+$" display endif " @@ -241,10 +310,10 @@ if s:Python2Syntax() syn region pythonString start=+[bB]\='''+ end=+'''+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,pythonDocTest,pythonSpaceError,@Spell else " Python 3 byte strings - syn region pythonBytes start=+[bB]'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonBytesError,pythonBytesContent,@Spell - syn region pythonBytes start=+[bB]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonBytesError,pythonBytesContent,@Spell - syn region pythonBytes start=+[bB]"""+ end=+"""+ keepend contains=pythonBytesError,pythonBytesContent,pythonDocTest2,pythonSpaceError,@Spell - syn region pythonBytes start=+[bB]'''+ end=+'''+ keepend contains=pythonBytesError,pythonBytesContent,pythonDocTest,pythonSpaceError,@Spell + syn region pythonBytes start=+[bB]'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonBytesError,pythonBytesContent,@Spell + syn region pythonBytes start=+[bB]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonBytesError,pythonBytesContent,@Spell + syn region pythonBytes start=+[bB]"""+ end=+"""+ keepend contains=pythonBytesError,pythonBytesContent,pythonDocTest2,pythonSpaceError,@Spell + syn region pythonBytes start=+[bB]'''+ end=+'''+ keepend contains=pythonBytesError,pythonBytesContent,pythonDocTest,pythonSpaceError,@Spell syn match pythonBytesError ".\+" display contained syn match pythonBytesContent "[\u0000-\u00ff]\+" display contained contains=pythonBytesEscape,pythonBytesEscapeError @@ -276,6 +345,11 @@ else syn region pythonString start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,@Spell syn region pythonString start=+"""+ end=+"""+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,pythonDocTest2,pythonSpaceError,@Spell syn region pythonString start=+'''+ end=+'''+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,pythonDocTest,pythonSpaceError,@Spell + + syn region pythonFString start=+[fF]'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,@Spell + syn region pythonFString start=+[fF]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,@Spell + syn region pythonFString start=+[fF]"""+ end=+"""+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,pythonDocTest2,pythonSpaceError,@Spell + syn region pythonFString start=+[fF]'''+ end=+'''+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,pythonDocTest,pythonSpaceError,@Spell endif if s:Python2Syntax() @@ -312,11 +386,11 @@ syn match pythonRawEscape +\\['"]+ display transparent contained if s:Enabled("g:python_highlight_string_formatting") " % operator string formatting if s:Python2Syntax() - syn match pythonStrFormatting "%\%(([^)]\+)\)\=[-#0 +]*\d*\%(\.\d\+\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString - syn match pythonStrFormatting "%[-#0 +]*\%(\*\|\d\+\)\=\%(\.\%(\*\|\d\+\)\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString + syn match pythonStrFormatting "%\%(([^)]\+)\)\=[-#0 +]*\d*\%(\.\d\+\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString + syn match pythonStrFormatting "%[-#0 +]*\%(\*\|\d\+\)\=\%(\.\%(\*\|\d\+\)\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString else - syn match pythonStrFormatting "%\%(([^)]\+)\)\=[-#0 +]*\d*\%(\.\d\+\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonRawString - syn match pythonStrFormatting "%[-#0 +]*\%(\*\|\d\+\)\=\%(\.\%(\*\|\d\+\)\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonRawString + syn match pythonStrFormatting "%\%(([^)]\+)\)\=[-#0 +]*\d*\%(\.\d\+\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonRawString + syn match pythonStrFormatting "%[-#0 +]*\%(\*\|\d\+\)\=\%(\.\%(\*\|\d\+\)\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonRawString endif endif @@ -324,30 +398,31 @@ if s:Enabled("g:python_highlight_string_format") " str.format syntax if s:Python2Syntax() syn match pythonStrFormat "{{\|}}" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString - syn match pythonStrFormat "{\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)\=\%(\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\[\%(\d\+\|[^!:\}]\+\)\]\)*\%(![rsa]\)\=\%(:\%({\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)}\|\%([^}]\=[<>=^]\)\=[ +-]\=#\=0\=\d*,\=\%(\.\d\+\)\=[bcdeEfFgGnosxX%]\=\)\=\)\=}" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString + syn match pythonStrFormat "{\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)\=\%(\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\[\%(\d\+\|[^!:\}]\+\)\]\)*\%(![rsa]\)\=\%(:\%({\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)}\|\%([^}]\=[<>=^]\)\=[ +-]\=#\=0\=\d*,\=\%(\.\d\+\)\=[bcdeEfFgGnosxX%]\=\)\=\)\=}" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString else syn match pythonStrFormat "{{\|}}" contained containedin=pythonString,pythonRawString - syn match pythonStrFormat "{\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)\=\%(\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\[\%(\d\+\|[^!:\}]\+\)\]\)*\%(![rsa]\)\=\%(:\%({\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)}\|\%([^}]\=[<>=^]\)\=[ +-]\=#\=0\=\d*,\=\%(\.\d\+\)\=[bcdeEfFgGnosxX%]\=\)\=\)\=}" contained containedin=pythonString,pythonRawString + syn match pythonStrFormat "{\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)\=\%(\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\[\%(\d\+\|[^!:\}]\+\)\]\)*\%(![rsa]\)\=\%(:\%({\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)}\|\%([^}]\=[<>=^]\)\=[ +-]\=#\=0\=\d*,\=\%(\.\d\+\)\=[bcdeEfFgGnosxX%]\=\)\=\)\=}" contained containedin=pythonString,pythonRawString + syn region pythonStrInterpRegion matchgroup=pythonStrInterpRegion start="{" end="}" extend contained containedin=pythonFString contains=@pythonFExpression endif endif if s:Enabled("g:python_highlight_string_templates") " string.Template format if s:Python2Syntax() - syn match pythonStrTemplate "\$\$" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString - syn match pythonStrTemplate "\${[a-zA-Z_][a-zA-Z0-9_]*}" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString - syn match pythonStrTemplate "\$[a-zA-Z_][a-zA-Z0-9_]*" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString + syn match pythonStrTemplate "\$\$" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString + syn match pythonStrTemplate "\${[a-zA-Z_][a-zA-Z0-9_]*}" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString + syn match pythonStrTemplate "\$[a-zA-Z_][a-zA-Z0-9_]*" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString else - syn match pythonStrTemplate "\$\$" contained containedin=pythonString,pythonRawString - syn match pythonStrTemplate "\${[a-zA-Z_][a-zA-Z0-9_]*}" contained containedin=pythonString,pythonRawString - syn match pythonStrTemplate "\$[a-zA-Z_][a-zA-Z0-9_]*" contained containedin=pythonString,pythonRawString + syn match pythonStrTemplate "\$\$" contained containedin=pythonString,pythonRawString + syn match pythonStrTemplate "\${[a-zA-Z_][a-zA-Z0-9_]*}" contained containedin=pythonString,pythonRawString + syn match pythonStrTemplate "\$[a-zA-Z_][a-zA-Z0-9_]*" contained containedin=pythonString,pythonRawString endif endif if s:Enabled("g:python_highlight_doctests") " DocTests - syn region pythonDocTest start="^\s*>>>" end=+'''+he=s-1 end="^\s*$" contained - syn region pythonDocTest2 start="^\s*>>>" end=+"""+he=s-1 end="^\s*$" contained + syn region pythonDocTest start="^\s*>>>" end=+'''+he=s-1 end="^\s*$" contained + syn region pythonDocTest2 start="^\s*>>>" end=+"""+he=s-1 end="^\s*$" contained endif " @@ -355,55 +430,60 @@ endif " if s:Python2Syntax() - syn match pythonHexError "\<0[xX]\x*[g-zG-Z]\+\x*[lL]\=\>" display - syn match pythonOctError "\<0[oO]\=\o*\D\+\d*[lL]\=\>" display - syn match pythonBinError "\<0[bB][01]*\D\+\d*[lL]\=\>" display + syn match pythonHexError "\<0[xX]\x*[g-zG-Z]\+\x*[lL]\=\>" display + syn match pythonOctError "\<0[oO]\=\o*\D\+\d*[lL]\=\>" display + syn match pythonBinError "\<0[bB][01]*\D\+\d*[lL]\=\>" display - syn match pythonHexNumber "\<0[xX]\x\+[lL]\=\>" display + syn match pythonHexNumber "\<0[xX]\x\+[lL]\=\>" display syn match pythonOctNumber "\<0[oO]\o\+[lL]\=\>" display syn match pythonBinNumber "\<0[bB][01]\+[lL]\=\>" display - syn match pythonNumberError "\<\d\+\D[lL]\=\>" display - syn match pythonNumber "\<\d[lL]\=\>" display - syn match pythonNumber "\<[0-9]\d\+[lL]\=\>" display - syn match pythonNumber "\<\d\+[lLjJ]\>" display + syn match pythonNumberError "\<\d\+\D[lL]\=\>" display + syn match pythonNumber "\<\d[lL]\=\>" display + syn match pythonNumber "\<[0-9]\d\+[lL]\=\>" display + syn match pythonNumber "\<\d\+[lLjJ]\>" display - syn match pythonOctError "\<0[oO]\=\o*[8-9]\d*[lL]\=\>" display - syn match pythonBinError "\<0[bB][01]*[2-9]\d*[lL]\=\>" display + syn match pythonOctError "\<0[oO]\=\o*[8-9]\d*[lL]\=\>" display + syn match pythonBinError "\<0[bB][01]*[2-9]\d*[lL]\=\>" display + + syn match pythonFloat "\.\d\+\%([eE][+-]\=\d\+\)\=[jJ]\=\>" display + syn match pythonFloat "\<\d\+[eE][+-]\=\d\+[jJ]\=\>" display + syn match pythonFloat "\<\d\+\.\d*\%([eE][+-]\=\d\+\)\=[jJ]\=" display else - syn match pythonHexError "\<0[xX]\x*[g-zG-Z]\x*\>" display - syn match pythonOctError "\<0[oO]\=\o*\D\+\d*\>" display - syn match pythonBinError "\<0[bB][01]*\D\+\d*\>" display - - syn match pythonHexNumber "\<0[xX]\x\+\>" display - syn match pythonOctNumber "\<0[oO]\o\+\>" display - syn match pythonBinNumber "\<0[bB][01]\+\>" display - - syn match pythonNumberError "\<\d\+\D\>" display - syn match pythonNumberError "\<0\d\+\>" display - syn match pythonNumber "\<\d\>" display - syn match pythonNumber "\<[1-9]\d\+\>" display - syn match pythonNumber "\<\d\+[jJ]\>" display - - syn match pythonOctError "\<0[oO]\=\o*[8-9]\d*\>" display - syn match pythonBinError "\<0[bB][01]*[2-9]\d*\>" display + syn match pythonHexError "\<0[xX]\x*[g-zG-Z]\x*\>" display + syn match pythonOctError "\<0[oO]\=\o*\D\+\d*\>" display + syn match pythonBinError "\<0[bB][01]*\D\+\d*\>" display + + syn match pythonHexNumber "\<0[xX][_0-9a-fA-F]*\x\>" display + syn match pythonOctNumber "\<0[oO][_0-7]*\o\>" display + syn match pythonBinNumber "\<0[bB][_01]*[01]\>" display + + syn match pythonNumberError "\<\d[_0-9]*\D\>" display + syn match pythonNumberError "\<0[_0-9]\+\>" display + syn match pythonNumberError "\<\d[_0-9]*_\>" display + syn match pythonNumber "\<\d\>" display + syn match pythonNumber "\<[1-9][_0-9]*\d\>" display + syn match pythonNumber "\<\d[jJ]\>" display + syn match pythonNumber "\<[1-9][_0-9]*\d[jJ]\>" display + + syn match pythonOctError "\<0[oO]\=\o*[8-9]\d*\>" display + syn match pythonBinError "\<0[bB][01]*[2-9]\d*\>" display + + syn match pythonFloat "\.\d\%([_0-9]*\d\)\=\%([eE][+-]\=\d\%([_0-9]*\d\)\=\)\=[jJ]\=\>" display + syn match pythonFloat "\<\d\%([_0-9]*\d\)\=[eE][+-]\=\d\%([_0-9]*\d\)\=[jJ]\=\>" display + syn match pythonFloat "\<\d\%([_0-9]*\d\)\=\.\d\%([_0-9]*\d\)\=\%([eE][+-]\=\d\%([_0-9]*\d\)\=\)\=[jJ]\=" display endif -syn match pythonFloat "\.\d\+\%([eE][+-]\=\d\+\)\=[jJ]\=\>" display -syn match pythonFloat "\<\d\+[eE][+-]\=\d\+[jJ]\=\>" display -syn match pythonFloat "\<\d\+\.\d*\%([eE][+-]\=\d\+\)\=[jJ]\=" display - " " Builtin objects and types " if s:Enabled("g:python_highlight_builtin_objs") if s:Python2Syntax() - syn keyword pythonBuiltinObj None - syn keyword pythonBoolean True False + syn keyword pythonBuiltinObj None False True endif - syn keyword pythonBuiltinObj Ellipsis NotImplemented - syn keyword pythonBuiltinObj __debug__ __doc__ __file__ __name__ __package__ + syn keyword pythonBuiltinObj Ellipsis NotImplemented self cls + syn keyword pythonBuiltinObj __debug__ __doc__ __file__ __name__ __package__ endif " @@ -412,28 +492,28 @@ endif if s:Enabled("g:python_highlight_builtin_funcs") if s:Python2Syntax() - syn keyword pythonBuiltinFunc apply basestring buffer callable coerce - syn keyword pythonBuiltinFunc execfile file help intern long raw_input - syn keyword pythonBuiltinFunc reduce reload unichr unicode xrange + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs if s:Enabled("g:python_print_as_function") - syn keyword pythonBuiltinFunc print + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs endif else - syn keyword pythonBuiltinFunc ascii exec memoryview print + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs endif " @@ -442,39 +522,39 @@ endif if s:Enabled("g:python_highlight_exceptions") if s:Python2Syntax() - syn keyword pythonExClass StandardError + syn keyword pythonExClass StandardError nextgroup=pythonFuncArgs else - syn keyword pythonExClass BlockingIOError ChildProcessError - syn keyword pythonExClass ConnectionError BrokenPipeError - syn keyword pythonExClass ConnectionAbortedError ConnectionRefusedError - syn keyword pythonExClass ConnectionResetError FileExistsError - syn keyword pythonExClass FileNotFoundError InterruptedError - syn keyword pythonExClass IsADirectoryError NotADirectoryError - syn keyword pythonExClass PermissionError ProcessLookupError TimeoutError - - syn keyword pythonExClass ResourceWarning + syn keyword pythonExClass BlockingIOError ChildProcessError nextgroup=pythonFuncArgs + syn keyword pythonExClass ConnectionError BrokenPipeError nextgroup=pythonFuncArgs + syn keyword pythonExClass ConnectionAbortedError ConnectionRefusedError nextgroup=pythonFuncArgs + syn keyword pythonExClass ConnectionResetError FileExistsError nextgroup=pythonFuncArgs + syn keyword pythonExClass FileNotFoundError InterruptedError nextgroup=pythonFuncArgs + syn keyword pythonExClass IsADirectoryError NotADirectoryError nextgroup=pythonFuncArgs + syn keyword pythonExClass PermissionError ProcessLookupError TimeoutError nextgroup=pythonFuncArgs + + syn keyword pythonExClass ResourceWarning nextgroup=pythonFuncArgs endif - syn keyword pythonExClass BaseException - syn keyword pythonExClass Exception ArithmeticError - syn keyword pythonExClass LookupError EnvironmentError - - syn keyword pythonExClass AssertionError AttributeError BufferError EOFError - syn keyword pythonExClass FloatingPointError GeneratorExit IOError - syn keyword pythonExClass ImportError IndexError KeyError - syn keyword pythonExClass KeyboardInterrupt MemoryError NameError - syn keyword pythonExClass NotImplementedError OSError OverflowError - syn keyword pythonExClass ReferenceError RuntimeError StopIteration - syn keyword pythonExClass SyntaxError IndentationError TabError - syn keyword pythonExClass SystemError SystemExit TypeError - syn keyword pythonExClass UnboundLocalError UnicodeError - syn keyword pythonExClass UnicodeEncodeError UnicodeDecodeError - syn keyword pythonExClass UnicodeTranslateError ValueError VMSError - syn keyword pythonExClass WindowsError ZeroDivisionError - - syn keyword pythonExClass Warning UserWarning BytesWarning DeprecationWarning - syn keyword pythonExClass PendingDepricationWarning SyntaxWarning - syn keyword pythonExClass RuntimeWarning FutureWarning - syn keyword pythonExClass ImportWarning UnicodeWarning + syn keyword pythonExClass BaseException nextgroup=pythonFuncArgs + syn keyword pythonExClass Exception ArithmeticError nextgroup=pythonFuncArgs + syn keyword pythonExClass LookupError EnvironmentError nextgroup=pythonFuncArgs + + syn keyword pythonExClass AssertionError AttributeError BufferError EOFError nextgroup=pythonFuncArgs + syn keyword pythonExClass FloatingPointError GeneratorExit IOError nextgroup=pythonFuncArgs + syn keyword pythonExClass ImportError IndexError KeyError nextgroup=pythonFuncArgs + syn keyword pythonExClass KeyboardInterrupt MemoryError NameError nextgroup=pythonFuncArgs + syn keyword pythonExClass NotImplementedError OSError OverflowError nextgroup=pythonFuncArgs + syn keyword pythonExClass ReferenceError RuntimeError StopIteration nextgroup=pythonFuncArgs + syn keyword pythonExClass SyntaxError IndentationError TabError nextgroup=pythonFuncArgs + syn keyword pythonExClass SystemError SystemExit TypeError nextgroup=pythonFuncArgs + syn keyword pythonExClass UnboundLocalError UnicodeError nextgroup=pythonFuncArgs + syn keyword pythonExClass UnicodeEncodeError UnicodeDecodeError nextgroup=pythonFuncArgs + syn keyword pythonExClass UnicodeTranslateError ValueError VMSError nextgroup=pythonFuncArgs + syn keyword pythonExClass WindowsError ZeroDivisionError nextgroup=pythonFuncArgs + + syn keyword pythonExClass Warning UserWarning BytesWarning DeprecationWarning nextgroup=pythonFuncArgs + syn keyword pythonExClass PendingDepricationWarning SyntaxWarning nextgroup=pythonFuncArgs + syn keyword pythonExClass RuntimeWarning FutureWarning nextgroup=pythonFuncArgs + syn keyword pythonExClass ImportWarning UnicodeWarning nextgroup=pythonFuncArgs endif if s:Enabled("g:python_slow_sync") @@ -496,6 +576,7 @@ if version >= 508 || !exists("did_python_syn_inits") endif HiLink pythonStatement Statement + HiLink pythonLambdaExpr Statement HiLink pythonImport Include HiLink pythonFunction Function HiLink pythonConditional Conditional @@ -536,6 +617,8 @@ if version >= 508 || !exists("did_python_syn_inits") HiLink pythonBytesError Error HiLink pythonBytesEscape Special HiLink pythonBytesEscapeError Error + HiLink pythonFString String + HiLink pythonStrInterpRegion Special endif HiLink pythonStrFormatting Special @@ -555,14 +638,21 @@ if version >= 508 || !exists("did_python_syn_inits") HiLink pythonHexError Error HiLink pythonBinError Error - HiLink pythonBoolean Boolean - HiLink pythonBuiltinObj Structure HiLink pythonBuiltinFunc Function HiLink pythonExClass Structure + HiLink pythonTypeAnno Optional + HiLink pythonTypeUnion Optional + HiLink pythonTypeAnnoReturn Optional + HiLink pythonTypeArgs Optional + HiLink pythonType Special + delcommand HiLink + + " default style for custom highlight group (may be overriden in colors) + hi Optional gui=italic cterm=italic endif let b:current_syntax = "python" diff --git a/test.py b/test.py index df81a9a..d19a6f7 100644 --- a/test.py +++ b/test.py @@ -8,9 +8,12 @@ # Keywords. -with break continue del exec return pass print raise global assert lambda yield +with break continue del exec return pass print raise global assert yield for while if elif else import from as try except finally and in is not or +lambda: a + 1 +lambda x, y: x + y + yield from def functionname @@ -23,19 +26,48 @@ async def Test async with async for +# Type annotations + +def myfunc(a: str, something_other, + b: Callable[[str, str], int], + c: mypkg.MyType) -> 'runtime_resolved_type': + myval: float + mygood: Optional[int, Any] = b('wow', 'oops') + myarr: Sequence[int] = origarr[aa:bb] + (lambda: x)() + mykey = a + wow = { + mykey: this_should_not_be_type_anno[Any], + 'b': some_data, + } + call_with_dict(a={ + 'a': asdf, + 'b': 'zxcb', + mykey: this_should_not_be_type_anno[Any], + }, b=mydata['a']) + vanilla_lambda = lambda x, y: myval + 1.0 + call_with_lambda(lambda x, y: myval + 1.0) + call_with_slice(mydata[range_start:range_end]) + + # Builtin objects. True False Ellipsis None NotImplemented # Builtin function and types. -__import__ abs all any apply basestring bool buffer callable chr classmethod -cmp coerce compile complex delattr dict dir divmod enumerate eval execfile file -filter float frozenset getattr globals hasattr hash help hex id input int -intern isinstance issubclass iter len list locals long map max min object oct -open ord pow property range raw_input reduce reload repr reversed round set -setattr slice sorted staticmethod str sum super tuple type unichr unicode vars -xrange zip +__import__() abs() all() any() apply() basestring() bool() buffer() callable() chr() classmethod() +cmp() coerce() compile() complex() delattr() dict() dir() divmod() enumerate() eval() execfile() file() +filter() float() frozenset() getattr() globals() hasattr() hash() help() hex() id() input() int() +intern() isinstance() issubclass() iter() len() list() locals() long() map() max() min() object() oct() +open() ord() pow() property() range() raw_input() reduce() reload() repr() reversed() round() set() +setattr() slice() sorted() staticmethod() str() sum() super() tuple() type() unichr() unicode() vars() +xrange() zip() + +when_we_dont_call = a.float +float = when_we_dont_call + +when_we_call = float(x) +when_we_call = min(a, b) # Builtin exceptions and warnings. @@ -61,11 +93,13 @@ async def Test # Numbers -0 1 2 9 10 0x1f .3 12.34 0j 0j 34.2E-3 0b10 0o77 1023434 0x0 +0 1 2 9 10 0x1f .3 12.34 0j 124j 34.2E-3 0b10 0o77 1023434 0x0 +1_1 1_1.2_2 1_2j 0x_1f 0x1_f 34_56e-3 34_56e+3_1 0o7_7 # Erroneous numbers -077 100L 0xfffffffL 0L 08 0xk 0x 0b102 0o78 0o123LaB +077 100L 0xfffffffL 0L 08 0xk 0x 0b102 0o78 0o123LaB +0_ 0_1 0_x1f 0x1f_ 0_b77 0b77_ .2_ 1_j # Strings @@ -103,6 +137,10 @@ async def Test "${test} ${test ${test}aname $$$ $test+nope" b"${test} ${test ${test}aname $$$ $test+nope" +f"{var}...{arr[123]} normal {var['{'] // 0xff} \"xzcb\" 'xzcb' {var['}'] + 1} text" +f"{expr1 if True or False else expr2} wow {','.join(c.lower() for c in 'asdf')}" +f"hello {expr:.2f} yes {(lambda: 0b1)():#03x} lol {var!r}" + # Doctests. """