Browse Source

Merge "Add support for Python 3.6 f-string literal and underscore in numbers."

https://github.com/hdima/python-syntax/pull/60
lilydjwg 7 years ago
parent
commit
8692c37f91
2 changed files with 37 additions and 15 deletions
  1. 29
    13
      syntax/python.vim
  2. 8
    2
      test.py

+ 29
- 13
syntax/python.vim View File

@@ -186,6 +186,8 @@ else
186 186
   syn match   pythonStatement   "\<async\s\+for\>" display
187 187
 endif
188 188
 
189
+syn cluster pythonExpression contains=pythonStatement,pythonRepeat,pythonConditional,pythonOperator,pythonNumber,pythonHexNumber,pythonOctNumber,pythonBinNumber,pythonFloat,pythonString,pythonBytes,pythonBoolean,pythonBuiltinObj,pythonBuiltinFunc
190
+
189 191
 "
190 192
 " Decorators (new in Python 2.4)
191 193
 "
@@ -276,6 +278,11 @@ else
276 278
   syn region pythonString   start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,@Spell
277 279
   syn region pythonString   start=+"""+ end=+"""+ keepend contains=pythonBytesEscape,pythonBytesEscapeError,pythonUniEscape,pythonUniEscapeError,pythonDocTest2,pythonSpaceError,@Spell
278 280
   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
279 286
 endif
280 287
 
281 288
 if s:Python2Syntax()
@@ -326,8 +333,9 @@ if s:Enabled("g:python_highlight_string_format")
326 333
     syn match pythonStrFormat "{{\|}}" contained containedin=pythonString,pythonUniString,pythonUniRawString,pythonRawString
327 334
     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
328 335
   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
331 339
   endif
332 340
 endif
333 341
 
@@ -370,28 +378,34 @@ if s:Python2Syntax()
370 378
 
371 379
   syn match   pythonOctError	"\<0[oO]\=\o*[8-9]\d*[lL]\=\>" display
372 380
   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
373 385
 else
374 386
   syn match   pythonHexError	"\<0[xX]\x*[g-zG-Z]\x*\>" display
375 387
   syn match   pythonOctError	"\<0[oO]\=\o*\D\+\d*\>" display
376 388
   syn match   pythonBinError	"\<0[bB][01]*\D\+\d*\>" display
377 389
 
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
381 393
 
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
384 397
   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
387 401
 
388 402
   syn match   pythonOctError	"\<0[oO]\=\o*[8-9]\d*\>" display
389 403
   syn match   pythonBinError	"\<0[bB][01]*[2-9]\d*\>" display
390
-endif
391 404
 
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
395 409
 
396 410
 "
397 411
 " Builtin objects and types
@@ -536,6 +550,8 @@ if version >= 508 || !exists("did_python_syn_inits")
536 550
     HiLink pythonBytesError         Error
537 551
     HiLink pythonBytesEscape        Special
538 552
     HiLink pythonBytesEscapeError   Error
553
+    HiLink pythonFString            String
554
+    HiLink pythonStrInterpRegion    Special
539 555
   endif
540 556
 
541 557
   HiLink pythonStrFormatting    Special

+ 8
- 2
test.py View File

@@ -61,11 +61,13 @@ RuntimeWarning FutureWarning ImportWarning UnicodeWarning
61 61
 
62 62
 # Numbers
63 63
 
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
65 66
 
66 67
 # Erroneous numbers
67 68
 
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
69 71
 
70 72
 # Strings
71 73
 
@@ -103,6 +105,10 @@ b"{0.name!r:b} {0[n]} {name!s:  } {{test}} {{}} {} {.__len__:s}"
103 105
 "${test} ${test ${test}aname $$$ $test+nope"
104 106
 b"${test} ${test ${test}aname $$$ $test+nope"
105 107
 
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
+
106 112
 # Doctests.
107 113
 
108 114
 """