Skip to content

Commit 8692c37

Browse files
committed
Merge "Add support for Python 3.6 f-string literal and underscore in numbers."
hdima#60
2 parents 69760cb + eb44ea7 commit 8692c37

File tree

2 files changed

+37
-15
lines changed

2 files changed

+37
-15
lines changed

syntax/python.vim

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ else
186186
syn match pythonStatement "\<async\s\+for\>" display
187187
endif
188188

189+
syn cluster pythonExpression contains=pythonStatement,pythonRepeat,pythonConditional,pythonOperator,pythonNumber,pythonHexNumber,pythonOctNumber,pythonBinNumber,pythonFloat,pythonString,pythonBytes,pythonBoolean,pythonBuiltinObj,pythonBuiltinFunc
190+
189191
"
190192
" Decorators (new in Python 2.4)
191193
"
@@ -276,6 +278,11 @@ else
276278
syn region pythonString start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,@Spell
277279
syn region pythonString start=+"""+ end=+"""+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,pythonDocTest2,pythonSpaceError,@Spell
278280
syn region pythonString start=+'''+ end=+'''+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,pythonDocTest,pythonSpaceError,@Spell
281+
282+
syn region pythonFString start=+[fF]'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,@Spell
283+
syn region pythonFString start=+[fF]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,@Spell
284+
syn region pythonFString start=+[fF]"""+ end=+"""+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,pythonDocTest2,pythonSpaceError,@Spell
285+
syn region pythonFString start=+[fF]'''+ end=+'''+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,pythonDocTest,pythonSpaceError,@Spell
279286
endif
280287

281288
if s:Python2Syntax()
@@ -326,8 +333,9 @@ if s:Enabled("g:python_highlight_string_format")
326333
syn match pythonStrFormat "{{\|}}" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString
327334
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
328335
else
329-
syn match pythonStrFormat "{{\|}}" contained containedin=pythonString,pythonRawString
330-
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
336+
syn match pythonStrFormat "{{\|}}" contained containedin=pythonString,pythonRawString,pythonFString
337+
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
338+
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
331339
endif
332340
endif
333341

@@ -370,28 +378,34 @@ if s:Python2Syntax()
370378

371379
syn match pythonOctError "\<0[oO]\=\o*[8-9]\d*[lL]\=\>" display
372380
syn match pythonBinError "\<0[bB][01]*[2-9]\d*[lL]\=\>" display
381+
382+
syn match pythonFloat "\.\d\+\%([eE][+-]\=\d\+\)\=[jJ]\=\>" display
383+
syn match pythonFloat "\<\d\+[eE][+-]\=\d\+[jJ]\=\>" display
384+
syn match pythonFloat "\<\d\+\.\d*\%([eE][+-]\=\d\+\)\=[jJ]\=" display
373385
else
374386
syn match pythonHexError "\<0[xX]\x*[g-zG-Z]\x*\>" display
375387
syn match pythonOctError "\<0[oO]\=\o*\D\+\d*\>" display
376388
syn match pythonBinError "\<0[bB][01]*\D\+\d*\>" display
377389

378-
syn match pythonHexNumber "\<0[xX]\x\+\>" display
379-
syn match pythonOctNumber "\<0[oO]\o\+\>" display
380-
syn match pythonBinNumber "\<0[bB][01]\+\>" display
390+
syn match pythonHexNumber "\<0[xX][_0-9a-fA-F]*\x\>" display
391+
syn match pythonOctNumber "\<0[oO][_0-7]*\o\>" display
392+
syn match pythonBinNumber "\<0[bB][_01]*[01]\>" display
381393

382-
syn match pythonNumberError "\<\d\+\D\>" display
383-
syn match pythonNumberError "\<0\d\+\>" display
394+
syn match pythonNumberError "\<\d[_0-9]*\D\>" display
395+
syn match pythonNumberError "\<0[_0-9]\+\>" display
396+
syn match pythonNumberError "\<\d[_0-9]*_\>" display
384397
syn match pythonNumber "\<\d\>" display
385-
syn match pythonNumber "\<[1-9]\d\+\>" display
386-
syn match pythonNumber "\<\d\+[jJ]\>" display
398+
syn match pythonNumber "\<[1-9][_0-9]*\d\>" display
399+
syn match pythonNumber "\<\d[jJ]\>" display
400+
syn match pythonNumber "\<[1-9][_0-9]*\d[jJ]\>" display
387401

388402
syn match pythonOctError "\<0[oO]\=\o*[8-9]\d*\>" display
389403
syn match pythonBinError "\<0[bB][01]*[2-9]\d*\>" display
390-
endif
391404

392-
syn match pythonFloat "\.\d\+\%([eE][+-]\=\d\+\)\=[jJ]\=\>" display
393-
syn match pythonFloat "\<\d\+[eE][+-]\=\d\+[jJ]\=\>" display
394-
syn match pythonFloat "\<\d\+\.\d*\%([eE][+-]\=\d\+\)\=[jJ]\=" display
405+
syn match pythonFloat "\.\d\%([_0-9]*\d\)\=\%([eE][+-]\=\d\%([_0-9]*\d\)\=\)\=[jJ]\=\>" display
406+
syn match pythonFloat "\<\d\%([_0-9]*\d\)\=[eE][+-]\=\d\%([_0-9]*\d\)\=[jJ]\=\>" display
407+
syn match pythonFloat "\<\d\%([_0-9]*\d\)\=\.\d\%([_0-9]*\d\)\=\%([eE][+-]\=\d\%([_0-9]*\d\)\=\)\=[jJ]\=" display
408+
endif
395409

396410
"
397411
" Builtin objects and types
@@ -536,6 +550,8 @@ if version >= 508 || !exists("did_python_syn_inits")
536550
HiLink pythonBytesError Error
537551
HiLink pythonBytesEscape Special
538552
HiLink pythonBytesEscapeError Error
553+
HiLink pythonFString String
554+
HiLink pythonStrInterpRegion Special
539555
endif
540556

541557
HiLink pythonStrFormatting Special

test.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,13 @@ async def Test
6161

6262
# Numbers
6363

64-
0 1 2 9 10 0x1f .3 12.34 0j 0j 34.2E-3 0b10 0o77 1023434 0x0
64+
0 1 2 9 10 0x1f .3 12.34 0j 124j 34.2E-3 0b10 0o77 1023434 0x0
65+
1_1 1_1.2_2 1_2j 0x_1f 0x1_f 34_56e-3 34_56e+3_1 0o7_7
6566

6667
# Erroneous numbers
6768

68-
077 100L 0xfffffffL 0L 08 0xk 0x 0b102 0o78 0o123LaB
69+
077 100L 0xfffffffL 0L 08 0xk 0x 0b102 0o78 0o123LaB
70+
0_ 0_1 0_x1f 0x1f_ 0_b77 0b77_ .2_ 1_j
6971

7072
# Strings
7173

@@ -103,6 +105,10 @@ async def Test
103105
"${test} ${test ${test}aname $$$ $test+nope"
104106
b"${test} ${test ${test}aname $$$ $test+nope"
105107

108+
f"{var}...{arr[123]} normal {var['{'] // 0xff} \"xzcb\" 'xzcb' {var['}'] + 1} text"
109+
f"{expr1 if True or False else expr2} wow {','.join(c.lower() for c in 'asdf')}"
110+
f"hello {expr:.2f} yes {(lambda: 0b1)():#03x} lol {var!r}"
111+
106112
# Doctests.
107113

108114
"""

0 commit comments

Comments
 (0)