From 84f5cf9ce6438ac40512a05426d943497921ee96 Mon Sep 17 00:00:00 2001 From: Jan Hermann Date: Wed, 13 Jan 2016 16:24:07 +0100 Subject: [PATCH 01/19] narrow decorator match to exclude matrix multiplication --- syntax/python.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syntax/python.vim b/syntax/python.vim index e963628..fe84e6e 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -190,7 +190,7 @@ endif " Decorators (new in Python 2.4) " -syn match pythonDecorator "@" display nextgroup=pythonDottedName skipwhite +syn match pythonDecorator "\(^\s*\)\@<=@" 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 From ddbd84e7b8b437bc926ac28850b2ca8068488a93 Mon Sep 17 00:00:00 2001 From: Jan Hermann Date: Mon, 18 Jan 2016 14:34:22 +0100 Subject: [PATCH 02/19] More efficient regex --- syntax/python.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syntax/python.vim b/syntax/python.vim index fe84e6e..71c4b4f 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -190,7 +190,7 @@ endif " Decorators (new in Python 2.4) " -syn match pythonDecorator "\(^\s*\)\@<=@" 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 From 60a7b5c3d2e23d52175b855a84a91bc8aca58c24 Mon Sep 17 00:00:00 2001 From: Alois Mahdal Date: Fri, 27 Feb 2015 04:28:15 +0100 Subject: [PATCH 03/19] Mark None as Python builtin object along with True and False More specifically, they are "built-in constants": https://docs.python.org/2/library/constants.html#built-in-consts --- syntax/python.vim | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/syntax/python.vim b/syntax/python.vim index e963628..4bb9cd9 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -176,9 +176,9 @@ 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 keyword pythonBuiltinObj None True False syn match pythonFunction "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained syn keyword pythonStatement await syn match pythonStatement "\" nextgroup=pythonFunction skipwhite @@ -399,8 +399,7 @@ syn match pythonFloat "\<\d\+\.\d*\%([eE][+-]\=\d\+\)\=[jJ]\=" display 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__ From e07541aa596f4036c8d1f78b259e2318b88641bc Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Fri, 25 Nov 2016 22:54:18 +0900 Subject: [PATCH 04/19] Add support for Python 3.6 f-string literal and underscore in numbers. --- syntax/python.vim | 42 +++++++++++++++++++++++++++++------------- test.py | 10 ++++++++-- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/syntax/python.vim b/syntax/python.vim index e963628..e26ebba 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -186,6 +186,8 @@ else syn match pythonStatement "\" display endif +syn cluster pythonExpression contains=pythonStatement,pythonRepeat,pythonConditional,pythonOperator,pythonNumber,pythonHexNumber,pythonOctNumber,pythonBinNumber,pythonFloat,pythonString,pythonBytes,pythonBoolean,pythonBuiltinObj,pythonBuiltinFunc + " " Decorators (new in Python 2.4) " @@ -276,6 +278,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() @@ -326,8 +333,9 @@ if s:Enabled("g:python_highlight_string_format") 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 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 "{{\|}}" contained containedin=pythonString,pythonRawString,pythonFString + 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 start="{"he=e+1,rs=e+1 end="\%(![rsa]\)\=\%(:\%({\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)}\|\%([^}]\=[<>=^]\)\=[ +-]\=#\=0\=\d*,\=\%(\.\d\+\)\=[bcdeEfFgGnosxX%]\=\)\=\)\=}"hs=s-1,re=s-1 extend contained containedin=pythonFString contains=pythonStrInterpRegion,@pythonExpression endif endif @@ -370,28 +378,34 @@ if s:Python2Syntax() 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 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\+\D\>" display - syn match pythonNumberError "\<0\d\+\>" display + syn match pythonNumberError "\<\d[_0-9]*\D\>" display + syn match pythonNumberError "\<0[_0-9]\+\>" display + syn match pythonNumberError "\<\%(_[_0-9]\+\|[_0-9]\+_\)\>" display syn match pythonNumber "\<\d\>" display - syn match pythonNumber "\<[1-9]\d\+\>" display - syn match pythonNumber "\<\d\+[jJ]\>" 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 -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 + 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 " " Builtin objects and types @@ -536,6 +550,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 diff --git a/test.py b/test.py index df81a9a..1042622 100644 --- a/test.py +++ b/test.py @@ -61,11 +61,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 0_x1f 0x1f_ 0_b77 0b77_ ._2 .2_ 1_j # Strings @@ -103,6 +105,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. """ From eb44ea7304700d4272c0b64990e35744fda0a4b4 Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Fri, 25 Nov 2016 23:44:02 +0900 Subject: [PATCH 05/19] Fix pythonNumberError patterns to exclude legitimate identifiers. * "_0" is a valid identifier! --- syntax/python.vim | 2 +- test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/syntax/python.vim b/syntax/python.vim index e26ebba..0e032f9 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -393,7 +393,7 @@ else syn match pythonNumberError "\<\d[_0-9]*\D\>" display syn match pythonNumberError "\<0[_0-9]\+\>" display - syn match pythonNumberError "\<\%(_[_0-9]\+\|[_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 diff --git a/test.py b/test.py index 1042622..a97dd59 100644 --- a/test.py +++ b/test.py @@ -67,7 +67,7 @@ async def Test # Erroneous numbers 077 100L 0xfffffffL 0L 08 0xk 0x 0b102 0o78 0o123LaB -0_ 0_1 _0 0_x1f 0x1f_ 0_b77 0b77_ ._2 .2_ 1_j +0_ 0_1 0_x1f 0x1f_ 0_b77 0b77_ .2_ 1_j # Strings From 738e118831485a7c564ac2350e7cdafa80fdaecb Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Fri, 9 Dec 2016 14:53:23 +0800 Subject: [PATCH 06/19] support for async keyword --- syntax/python.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syntax/python.vim b/syntax/python.vim index a504956..79ffdb1 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -180,7 +180,7 @@ else syn match pythonStatement "\" display syn keyword pythonBuiltinObj None True False syn match pythonFunction "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained - syn keyword pythonStatement await + syn keyword pythonStatement await async syn match pythonStatement "\" nextgroup=pythonFunction skipwhite syn match pythonStatement "\" display syn match pythonStatement "\" display From 31f669d00d549f8a45c282b063e3be3e333518fa Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Fri, 2 Jun 2017 11:49:10 +0900 Subject: [PATCH 07/19] Improve builtin-func highlighting * Make them highlighted only when used as in the global namespace. (e.g., `id` in `something.id` is not highlighted) * Also add self and cls to builtin objects --- syntax/python.vim | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/syntax/python.vim b/syntax/python.vim index 79ffdb1..c36172a 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -415,7 +415,7 @@ if s:Enabled("g:python_highlight_builtin_objs") if s:Python2Syntax() syn keyword pythonBuiltinObj None False True endif - syn keyword pythonBuiltinObj Ellipsis NotImplemented + syn keyword pythonBuiltinObj Ellipsis NotImplemented self cls syn keyword pythonBuiltinObj __debug__ __doc__ __file__ __name__ __package__ endif @@ -425,28 +425,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(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' if s:Enabled("g:python_print_as_function") - syn keyword pythonBuiltinFunc print + syn match pythonBuiltinFunc '\v(\.)@' endif else - syn keyword pythonBuiltinFunc ascii exec memoryview print + syn match pythonBuiltinFunc '\v(\.)@' endif - syn keyword pythonBuiltinFunc __import__ abs all any - syn keyword pythonBuiltinFunc bin bool bytearray bytes - syn keyword pythonBuiltinFunc chr classmethod cmp compile complex - syn keyword pythonBuiltinFunc delattr dict dir divmod enumerate eval - syn keyword pythonBuiltinFunc filter float format frozenset getattr - syn keyword pythonBuiltinFunc globals hasattr hash hex id - syn keyword pythonBuiltinFunc input int isinstance - syn keyword pythonBuiltinFunc issubclass iter len list locals map max - syn keyword pythonBuiltinFunc min next object oct open ord - syn keyword pythonBuiltinFunc pow property range - syn keyword pythonBuiltinFunc repr reversed round set setattr - syn keyword pythonBuiltinFunc slice sorted staticmethod str sum super tuple - syn keyword pythonBuiltinFunc type vars zip + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' endif " From 43f3542282a86a52d36848965b08aade6b27263e Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Fri, 2 Jun 2017 13:28:25 +0900 Subject: [PATCH 08/19] Improve builtin-func and highlight type annotations in func args * Builtin-functions are highlighted only when used as global functions. * Annotations in type-only variable definitions and assignment statements are not supported yet due to potential conflicts with dictionary expressions. * Uses a custom syntax highlight def "Optional" (in my setup, it applies italic style.) * Taken from purpleP/python-syntax commits and customized. --- syntax/python.vim | 139 +++++++++++++++++++++++++++++----------------- 1 file changed, 89 insertions(+), 50 deletions(-) diff --git a/syntax/python.vim b/syntax/python.vim index c36172a..3d67e0a 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -163,9 +163,19 @@ 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 "\v[a-zA-Z_][a-zA-Z0-9_]*" nextgroup=FunctionParameters syn keyword pythonException try except finally syn keyword pythonOperator and in is not or +" TODO: contain pythonTypeAnno in assignments and non-assigning variable type defs +syn match pythonTypeAnno ":\s*[a-zA-Z0-9_\[\],\s]\+" display contained contains=pythonType +syn keyword pythonType Any AnyStr Callable ClassVar Tuple Union Optional Type TypeVar 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 + syn match pythonStatement "\" display syn match pythonImport "\" display @@ -179,13 +189,39 @@ else syn keyword pythonStatement as nonlocal syn match pythonStatement "\" display syn keyword pythonBuiltinObj None True False - syn match pythonFunction "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained + syn match pythonFunction "[a-zA-Z_][a-zA-Z0-9_]*" nextgroup=FunctionParameters display contained syn keyword pythonStatement await async syn match pythonStatement "\" nextgroup=pythonFunction skipwhite syn match pythonStatement "\" display syn match pythonStatement "\" display endif +syn region FunctionParameters start='(' end=')' display contains= + \ FunctionParameters, + \ pythonRepeat, + \ pythonConditional, + \ pythonComment, + \ pythonOperator, + \ pythonNumber, + \ pythonNumberError, + \ pythonFloat, + \ pythonHexNumber, + \ pythonStatement, + \ pythonOctNumber, + \ pythonString, + \ pythonRawString, + \ pythonUniString, + \ pythonExClass, + \ pythonUniRawString, + \ pythonNumber, + \ pythonRawString, + \ pythonBytes, + \ pythonBuiltinObj, + \ pythonNone, + \ pythonBuiltinFunc, + \ pythonTypeAnno, + \ pythonBoolean nextgroup=pythonRaiseFromStatement display contained + syn cluster pythonExpression contains=pythonStatement,pythonRepeat,pythonConditional,pythonOperator,pythonNumber,pythonHexNumber,pythonOctNumber,pythonBinNumber,pythonFloat,pythonString,pythonBytes,pythonBoolean,pythonBuiltinObj,pythonBuiltinFunc " @@ -425,28 +461,28 @@ endif if s:Enabled("g:python_highlight_builtin_funcs") if s:Python2Syntax() - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters if s:Enabled("g:python_print_as_function") - syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters endif else - syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@' nextgroup=FunctionParameters endif - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' - syn match pythonBuiltinFunc '\v(\.)@' + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters endif " @@ -455,39 +491,39 @@ endif if s:Enabled("g:python_highlight_exceptions") if s:Python2Syntax() - syn keyword pythonExClass StandardError + syn keyword pythonExClass StandardError nextgroup=FunctionParameters 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=FunctionParameters + syn keyword pythonExClass ConnectionError BrokenPipeError nextgroup=FunctionParameters + syn keyword pythonExClass ConnectionAbortedError ConnectionRefusedError nextgroup=FunctionParameters + syn keyword pythonExClass ConnectionResetError FileExistsError nextgroup=FunctionParameters + syn keyword pythonExClass FileNotFoundError InterruptedError nextgroup=FunctionParameters + syn keyword pythonExClass IsADirectoryError NotADirectoryError nextgroup=FunctionParameters + syn keyword pythonExClass PermissionError ProcessLookupError TimeoutError nextgroup=FunctionParameters + + syn keyword pythonExClass ResourceWarning nextgroup=FunctionParameters 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=FunctionParameters + syn keyword pythonExClass Exception ArithmeticError nextgroup=FunctionParameters + syn keyword pythonExClass LookupError EnvironmentError nextgroup=FunctionParameters + + syn keyword pythonExClass AssertionError AttributeError BufferError EOFError nextgroup=FunctionParameters + syn keyword pythonExClass FloatingPointError GeneratorExit IOError nextgroup=FunctionParameters + syn keyword pythonExClass ImportError IndexError KeyError nextgroup=FunctionParameters + syn keyword pythonExClass KeyboardInterrupt MemoryError NameError nextgroup=FunctionParameters + syn keyword pythonExClass NotImplementedError OSError OverflowError nextgroup=FunctionParameters + syn keyword pythonExClass ReferenceError RuntimeError StopIteration nextgroup=FunctionParameters + syn keyword pythonExClass SyntaxError IndentationError TabError nextgroup=FunctionParameters + syn keyword pythonExClass SystemError SystemExit TypeError nextgroup=FunctionParameters + syn keyword pythonExClass UnboundLocalError UnicodeError nextgroup=FunctionParameters + syn keyword pythonExClass UnicodeEncodeError UnicodeDecodeError nextgroup=FunctionParameters + syn keyword pythonExClass UnicodeTranslateError ValueError VMSError nextgroup=FunctionParameters + syn keyword pythonExClass WindowsError ZeroDivisionError nextgroup=FunctionParameters + + syn keyword pythonExClass Warning UserWarning BytesWarning DeprecationWarning nextgroup=FunctionParameters + syn keyword pythonExClass PendingDepricationWarning SyntaxWarning nextgroup=FunctionParameters + syn keyword pythonExClass RuntimeWarning FutureWarning nextgroup=FunctionParameters + syn keyword pythonExClass ImportWarning UnicodeWarning nextgroup=FunctionParameters endif if s:Enabled("g:python_slow_sync") @@ -577,6 +613,9 @@ if version >= 508 || !exists("did_python_syn_inits") HiLink pythonExClass Structure + HiLink pythonTypeAnno Optional + HiLink pythonType Special + delcommand HiLink endif From f544d3c90b4eeb2912082fba3f0e5b26e2d29651 Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Fri, 2 Jun 2017 16:14:23 +0900 Subject: [PATCH 09/19] Fully implement type annotation support --- syntax/python.vim | 272 ++++++++++++++++++++++++---------------------- test.py | 38 +++++-- 2 files changed, 174 insertions(+), 136 deletions(-) diff --git a/syntax/python.vim b/syntax/python.vim index 3d67e0a..b55a1f7 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -163,13 +163,17 @@ 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 "\v[a-zA-Z_][a-zA-Z0-9_]*" nextgroup=FunctionParameters +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 -" TODO: contain pythonTypeAnno in assignments and non-assigning variable type defs -syn match pythonTypeAnno ":\s*[a-zA-Z0-9_\[\],\s]\+" display contained contains=pythonType -syn keyword pythonType Any AnyStr Callable ClassVar Tuple Union Optional Type TypeVar contained +syn region pythonDictSetExpr matchgroup=pythonDictSetExpr start='{' end='}' contains=@pythonExpression +syn region pythonFuncArgs matchgroup=pythonFuncArgs start='(' end=')' contained contains=pythonTypeAnno,@pythonExpression + +syn match pythonTypeAnno ":\s*\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"hs=s+1 display contained contains=pythonType nextgroup=pythonTypeArgs +syn match pythonTypeAnnoReturn "->\s*\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*:"hs=s+2,he=e-1 display contains=pythonType nextgroup=pythonTypeArgs +syn region pythonTypeArgs matchgroup=pythonTypeArgs start='\[' end='\]' display contained contains=pythonType,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 @@ -189,15 +193,17 @@ else syn keyword pythonStatement as nonlocal syn match pythonStatement "\" display syn keyword pythonBuiltinObj None True False - syn match pythonFunction "[a-zA-Z_][a-zA-Z0-9_]*" nextgroup=FunctionParameters display contained + syn match pythonFunction "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" nextgroup=pythonFuncArgs display contained syn keyword pythonStatement await async - syn match pythonStatement "\" nextgroup=pythonFunction skipwhite + syn match pythonStatement "\" display nextgroup=pythonFunction skipwhite syn match pythonStatement "\" display syn match pythonStatement "\" display endif -syn region FunctionParameters start='(' end=')' display contains= - \ FunctionParameters, +syn cluster pythonExpression contains= + \ pythonFuncArgs, + \ pythonDictSetExpr, + \ pythonStatement, \ pythonRepeat, \ pythonConditional, \ pythonComment, @@ -206,29 +212,37 @@ syn region FunctionParameters start='(' end=')' display contains= \ pythonNumberError, \ pythonFloat, \ pythonHexNumber, - \ pythonStatement, \ pythonOctNumber, + \ pythonBytes, \ pythonString, \ pythonRawString, \ pythonUniString, - \ pythonExClass, \ pythonUniRawString, + \ pythonFString, + \ pythonExClass, + \ pythonBuiltinObj, + \ pythonBuiltinFunc + +syn cluster pythonFExpression contains= + \ pythonStatement, + \ pythonRepeat, + \ pythonConditional, + \ pythonOperator, \ pythonNumber, - \ pythonRawString, + \ pythonHexNumber, + \ pythonOctNumber, + \ pythonBinNumber, + \ pythonFloat, + \ pythonString, \ pythonBytes, \ pythonBuiltinObj, - \ pythonNone, - \ pythonBuiltinFunc, - \ pythonTypeAnno, - \ pythonBoolean nextgroup=pythonRaiseFromStatement display contained - -syn cluster pythonExpression contains=pythonStatement,pythonRepeat,pythonConditional,pythonOperator,pythonNumber,pythonHexNumber,pythonOctNumber,pythonBinNumber,pythonFloat,pythonString,pythonBytes,pythonBoolean,pythonBuiltinObj,pythonBuiltinFunc + \ pythonBuiltinFunc " " Decorators (new in Python 2.4) " -syn match pythonDecorator "^\s*\zs@" 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 @@ -240,31 +254,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 " @@ -279,10 +293,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 @@ -355,11 +369,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 @@ -367,31 +381,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,pythonFString 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 start="{"he=e+1,rs=e+1 end="\%(![rsa]\)\=\%(:\%({\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)}\|\%([^}]\=[<>=^]\)\=[ +-]\=#\=0\=\d*,\=\%(\.\d\+\)\=[bcdeEfFgGnosxX%]\=\)\=\)\=}"hs=s-1,re=s-1 extend contained containedin=pythonFString contains=pythonStrInterpRegion,@pythonExpression + syn region pythonStrInterpRegion start="{"he=e+1,rs=e+1 end="\%(![rsa]\)\=\%(:\%({\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)}\|\%([^}]\=[<>=^]\)\=[ +-]\=#\=0\=\d*,\=\%(\.\d\+\)\=[bcdeEfFgGnosxX%]\=\)\=\)\=}"hs=s-1,re=s-1 extend contained containedin=pythonFString contains=pythonStrInterpRegion,@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 " @@ -399,48 +413,48 @@ 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 + 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 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 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 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 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 + 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 " @@ -449,10 +463,10 @@ endif if s:Enabled("g:python_highlight_builtin_objs") if s:Python2Syntax() - syn keyword pythonBuiltinObj None False True + syn keyword pythonBuiltinObj None False True endif - syn keyword pythonBuiltinObj Ellipsis NotImplemented self cls - syn keyword pythonBuiltinObj __debug__ __doc__ __file__ __name__ __package__ + syn keyword pythonBuiltinObj Ellipsis NotImplemented self cls + syn keyword pythonBuiltinObj __debug__ __doc__ __file__ __name__ __package__ endif " @@ -461,28 +475,28 @@ endif if s:Enabled("g:python_highlight_builtin_funcs") if s:Python2Syntax() - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + 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 match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs endif else - syn match pythonBuiltinFunc '\v(\.)@' nextgroup=FunctionParameters + syn match pythonBuiltinFunc '\v(\.)@' nextgroup=pythonFuncArgs endif - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters - syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=FunctionParameters + 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 " @@ -491,39 +505,39 @@ endif if s:Enabled("g:python_highlight_exceptions") if s:Python2Syntax() - syn keyword pythonExClass StandardError nextgroup=FunctionParameters + syn keyword pythonExClass StandardError nextgroup=pythonFuncArgs else - syn keyword pythonExClass BlockingIOError ChildProcessError nextgroup=FunctionParameters - syn keyword pythonExClass ConnectionError BrokenPipeError nextgroup=FunctionParameters - syn keyword pythonExClass ConnectionAbortedError ConnectionRefusedError nextgroup=FunctionParameters - syn keyword pythonExClass ConnectionResetError FileExistsError nextgroup=FunctionParameters - syn keyword pythonExClass FileNotFoundError InterruptedError nextgroup=FunctionParameters - syn keyword pythonExClass IsADirectoryError NotADirectoryError nextgroup=FunctionParameters - syn keyword pythonExClass PermissionError ProcessLookupError TimeoutError nextgroup=FunctionParameters - - syn keyword pythonExClass ResourceWarning nextgroup=FunctionParameters + 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 nextgroup=FunctionParameters - syn keyword pythonExClass Exception ArithmeticError nextgroup=FunctionParameters - syn keyword pythonExClass LookupError EnvironmentError nextgroup=FunctionParameters - - syn keyword pythonExClass AssertionError AttributeError BufferError EOFError nextgroup=FunctionParameters - syn keyword pythonExClass FloatingPointError GeneratorExit IOError nextgroup=FunctionParameters - syn keyword pythonExClass ImportError IndexError KeyError nextgroup=FunctionParameters - syn keyword pythonExClass KeyboardInterrupt MemoryError NameError nextgroup=FunctionParameters - syn keyword pythonExClass NotImplementedError OSError OverflowError nextgroup=FunctionParameters - syn keyword pythonExClass ReferenceError RuntimeError StopIteration nextgroup=FunctionParameters - syn keyword pythonExClass SyntaxError IndentationError TabError nextgroup=FunctionParameters - syn keyword pythonExClass SystemError SystemExit TypeError nextgroup=FunctionParameters - syn keyword pythonExClass UnboundLocalError UnicodeError nextgroup=FunctionParameters - syn keyword pythonExClass UnicodeEncodeError UnicodeDecodeError nextgroup=FunctionParameters - syn keyword pythonExClass UnicodeTranslateError ValueError VMSError nextgroup=FunctionParameters - syn keyword pythonExClass WindowsError ZeroDivisionError nextgroup=FunctionParameters - - syn keyword pythonExClass Warning UserWarning BytesWarning DeprecationWarning nextgroup=FunctionParameters - syn keyword pythonExClass PendingDepricationWarning SyntaxWarning nextgroup=FunctionParameters - syn keyword pythonExClass RuntimeWarning FutureWarning nextgroup=FunctionParameters - syn keyword pythonExClass ImportWarning UnicodeWarning nextgroup=FunctionParameters + 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") @@ -606,14 +620,14 @@ 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 pythonTypeAnnoReturn Optional + HiLink pythonTypeArgs Optional HiLink pythonType Special delcommand HiLink diff --git a/test.py b/test.py index a97dd59..561df34 100644 --- a/test.py +++ b/test.py @@ -23,19 +23,43 @@ async def Test async with async for +# Type annotations + +def myfunc(a: str, something_other, + b: Callable[[str, str], int]) -> Any: + myval: float + mygood: Optional[int, Any] = b('wow', 'oops') + 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']) + + # 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. From f5284a836c1c9350dcb0e0a1300db58ac47f4cb7 Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Sat, 3 Jun 2017 00:17:57 +0900 Subject: [PATCH 10/19] Add default italic style for type annotation * It is recommended to override it in colorschemes. --- syntax/python.vim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/syntax/python.vim b/syntax/python.vim index b55a1f7..44ca189 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -631,6 +631,9 @@ if version >= 508 || !exists("did_python_syn_inits") 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" From d47e205ccdad734422715778da70960bb626ac44 Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Sat, 3 Jun 2017 00:26:10 +0900 Subject: [PATCH 11/19] Fix highlighting function return type annotation --- syntax/python.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syntax/python.vim b/syntax/python.vim index 44ca189..c4e6bd2 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -171,7 +171,7 @@ syn region pythonDictSetExpr matchgroup=pythonDictSetExpr start='{' end='}' cont syn region pythonFuncArgs matchgroup=pythonFuncArgs start='(' end=')' contained contains=pythonTypeAnno,@pythonExpression syn match pythonTypeAnno ":\s*\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"hs=s+1 display contained contains=pythonType nextgroup=pythonTypeArgs -syn match pythonTypeAnnoReturn "->\s*\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*:"hs=s+2,he=e-1 display contains=pythonType nextgroup=pythonTypeArgs +syn match pythonTypeAnnoReturn "->\s*\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"hs=s+2,he=e-1 display contains=pythonType nextgroup=pythonTypeArgs syn region pythonTypeArgs matchgroup=pythonTypeArgs start='\[' end='\]' display contained contains=pythonType,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 From 0e3ba78aad712de2e198a611d06ddeaec938a9ca Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Mon, 5 Jun 2017 00:43:04 +0900 Subject: [PATCH 12/19] Fix lambda and list/slices broken after type annotation support --- syntax/python.vim | 12 ++++++++++-- test.py | 9 ++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/syntax/python.vim b/syntax/python.vim index c4e6bd2..f866139 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -154,7 +154,6 @@ syn keyword pythonStatement break continue del syn keyword pythonStatement exec 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 @@ -166,12 +165,15 @@ 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:]]\|_\)*"hs=s+2,he=e-1 display contains=pythonType nextgroup=pythonTypeArgs +syn match pythonTypeAnnoReturn "->\s*\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contains=pythonType nextgroup=pythonTypeArgs syn region pythonTypeArgs matchgroup=pythonTypeArgs start='\[' end='\]' display contained contains=pythonType,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 @@ -203,6 +205,8 @@ endif syn cluster pythonExpression contains= \ pythonFuncArgs, \ pythonDictSetExpr, + \ pythonListSliceExpr, + \ pythonLambdaExpr, \ pythonStatement, \ pythonRepeat, \ pythonConditional, @@ -225,6 +229,9 @@ syn cluster pythonExpression contains= syn cluster pythonFExpression contains= \ pythonStatement, + \ pythonDictSetExpr, + \ pythonListSliceExpr, + \ pythonLambdaExpr, \ pythonRepeat, \ pythonConditional, \ pythonOperator, @@ -559,6 +566,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 diff --git a/test.py b/test.py index 561df34..256aa03 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 @@ -29,6 +32,7 @@ def myfunc(a: str, something_other, b: Callable[[str, str], int]) -> Any: myval: float mygood: Optional[int, Any] = b('wow', 'oops') + myarr: Sequence[int] = origarr[aa:bb] mykey = a wow = { mykey: this_should_not_be_type_anno[Any], @@ -39,6 +43,9 @@ def myfunc(a: str, something_other, '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. From 260521b9380114765021ec15d900f4785c7a55f9 Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Mon, 5 Jun 2017 00:54:01 +0900 Subject: [PATCH 13/19] Fix bugs in f-string literals --- syntax/python.vim | 15 +++++++-------- test.py | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/syntax/python.vim b/syntax/python.vim index f866139..3694a2b 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -165,8 +165,7 @@ 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 "\=^]\)\=[ +-]\=#\=0\=\d*,\=\%(\.\d\+\)\=[bcdeEfFgGnosxX%]\=\)\=\)\=}" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString else - syn match pythonStrFormat "{{\|}}" contained containedin=pythonString,pythonRawString,pythonFString + 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 region pythonStrInterpRegion start="{"he=e+1,rs=e+1 end="\%(![rsa]\)\=\%(:\%({\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)}\|\%([^}]\=[<>=^]\)\=[ +-]\=#\=0\=\d*,\=\%(\.\d\+\)\=[bcdeEfFgGnosxX%]\=\)\=\)\=}"hs=s-1,re=s-1 extend contained containedin=pythonFString contains=pythonStrInterpRegion,@pythonFExpression + syn region pythonStrInterpRegion matchgroup=pythonStrInterpRegion start="{" end="}" extend contained containedin=pythonFString contains=@pythonFExpression endif endif diff --git a/test.py b/test.py index 256aa03..64203ca 100644 --- a/test.py +++ b/test.py @@ -32,7 +32,7 @@ def myfunc(a: str, something_other, b: Callable[[str, str], int]) -> Any: myval: float mygood: Optional[int, Any] = b('wow', 'oops') - myarr: Sequence[int] = origarr[aa:bb] + myarr: Sequence[int] = origarr[aa:bb] + (lambda: x)() mykey = a wow = { mykey: this_should_not_be_type_anno[Any], From e257b1d89ec5e384b24ee0c426bcca3f25a3248e Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Mon, 5 Jun 2017 11:12:25 +0900 Subject: [PATCH 14/19] Final retouch for README and options --- README.rst | 5 ++++- syntax/python.vim | 23 ++++++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) 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 3694a2b..ce914b9 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") @@ -171,15 +172,19 @@ syn region pythonDictSetExpr matchgroup=pythonDictSetExpr start='{' end='}' cont syn region pythonListSliceExpr matchgroup=pythonListSliceExpr start='\[' end='\]' contains=@pythonExpression syn region pythonFuncArgs matchgroup=pythonFuncArgs start='(' end=')' contained contains=pythonTypeAnno,@pythonExpression -syn match pythonTypeAnno ":\s*\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"hs=s+1 display contained contains=pythonType nextgroup=pythonTypeArgs -syn match pythonTypeAnnoReturn "->\s*\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contains=pythonType nextgroup=pythonTypeArgs -syn region pythonTypeArgs matchgroup=pythonTypeArgs start='\[' end='\]' display contained contains=pythonType,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 +if !s:Python2Syntax() + if s:Enabled("g:python_highlight_type_annotations") + syn match pythonTypeAnno ":\s*\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"hs=s+1 display contained contains=pythonType nextgroup=pythonTypeArgs + syn match pythonTypeAnnoReturn "->\s*\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contains=pythonType nextgroup=pythonTypeArgs + syn region pythonTypeArgs matchgroup=pythonTypeArgs start='\[' end='\]' display contained contains=pythonType,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 From daf7366c8d48228c8e7bdcd45b2f60f3286baf9d Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Mon, 5 Jun 2017 14:58:44 +0900 Subject: [PATCH 15/19] Add support for runtime-resolved type annotations in strings --- syntax/python.vim | 6 +++--- test.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/syntax/python.vim b/syntax/python.vim index ce914b9..f035636 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -174,9 +174,9 @@ syn region pythonFuncArgs matchgroup=pythonFuncArgs start='(' end=')' cont if !s:Python2Syntax() if s:Enabled("g:python_highlight_type_annotations") - syn match pythonTypeAnno ":\s*\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"hs=s+1 display contained contains=pythonType nextgroup=pythonTypeArgs - syn match pythonTypeAnnoReturn "->\s*\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contains=pythonType nextgroup=pythonTypeArgs - syn region pythonTypeArgs matchgroup=pythonTypeArgs start='\[' end='\]' display contained contains=pythonType,pythonTypeArgs + syn match pythonTypeAnno @:\s*['"]\?\([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\([^[:cntrl:][:punct:][:space:]]\|_\)*['"]\?@hs=s+1 display contained contains=pythonType,pythonString nextgroup=pythonTypeArgs + syn match pythonTypeAnnoReturn @->\s*['"]\?\([^[: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 diff --git a/test.py b/test.py index 64203ca..6e32abe 100644 --- a/test.py +++ b/test.py @@ -29,7 +29,7 @@ async def Test # Type annotations def myfunc(a: str, something_other, - b: Callable[[str, str], int]) -> Any: + b: Callable[[str, str], int]) -> 'runtime_resolved_type': myval: float mygood: Optional[int, Any] = b('wow', 'oops') myarr: Sequence[int] = origarr[aa:bb] + (lambda: x)() From 4f194e77311703837dfcbf39a9ca223344951378 Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Fri, 9 Jun 2017 15:04:31 +0900 Subject: [PATCH 16/19] Fix highlighting dotted names in type annotations. --- syntax/python.vim | 6 +++--- test.py | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/syntax/python.vim b/syntax/python.vim index f035636..ab71026 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -166,7 +166,7 @@ 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:]]\|_\)*['"]\?@ display contains=pythonType,pythonString nextgroup=pythonTypeArgs + syn match pythonTypeAnno @:\s*['"]\?\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\%(\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\)*['"]\?@hs=s+1 display contained contains=pythonType,pythonString nextgroup=pythonTypeArgs + syn match pythonTypeAnnoReturn @->\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 diff --git a/test.py b/test.py index 6e32abe..d19a6f7 100644 --- a/test.py +++ b/test.py @@ -29,7 +29,8 @@ async def Test # Type annotations def myfunc(a: str, something_other, - b: Callable[[str, str], int]) -> 'runtime_resolved_type': + 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)() From 559e3e2a3fbacfc6f2cd9c412d97644a5069fb20 Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Mon, 26 Jun 2017 15:45:01 +0900 Subject: [PATCH 17/19] Fix typo-bug in highlights of Python 3 builtin functions. --- syntax/python.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syntax/python.vim b/syntax/python.vim index ab71026..7fa0242 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -493,7 +493,7 @@ if s:Enabled("g:python_highlight_builtin_funcs") syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs endif else - syn match pythonBuiltinFunc '\v(\.)@' nextgroup=pythonFuncArgs + syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs syn match pythonBuiltinFunc '\v(\.)@\ze\(' nextgroup=pythonFuncArgs From ac5499b832d0e6b9ed64872ffee61a66ab619c89 Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Mon, 26 Jun 2017 15:47:49 +0900 Subject: [PATCH 18/19] Fix highlighting of exec() as builtin function in Python 3 --- syntax/python.vim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/syntax/python.vim b/syntax/python.vim index 7fa0242..5abc239 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -152,7 +152,10 @@ 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 with From 09357048aced6245f7bd41431b59d761d855d2d0 Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Wed, 3 Jan 2018 17:56:16 +0900 Subject: [PATCH 19/19] Add support for union operator ("|") in annotation * An example to use this style: tarfaret library --- syntax/python.vim | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/syntax/python.vim b/syntax/python.vim index 5abc239..1c5ea66 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -173,11 +173,12 @@ 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 @@ -209,6 +210,8 @@ else syn match pythonStatement "\" display endif +syn cluster pythonTypeExpression contains=pythonTypeAnno,pythonTypeUnion,pythonTypeArgs + syn cluster pythonExpression contains= \ pythonFuncArgs, \ pythonDictSetExpr, @@ -641,6 +644,7 @@ if version >= 508 || !exists("did_python_syn_inits") HiLink pythonExClass Structure HiLink pythonTypeAnno Optional + HiLink pythonTypeUnion Optional HiLink pythonTypeAnnoReturn Optional HiLink pythonTypeArgs Optional HiLink pythonType Special