diff --git a/README.md b/README.md index 615218c..6865100 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ let g:python_highlight_all = 1 | `g:python_highlight_space_errors` | Highlight trailing spaces | `0` | | `g:python_highlight_doctests` | Highlight doc-tests | `0` | | `g:python_highlight_class_vars` | Highlight class variables `self` and `cls` | `0` | +| `g:python_highlight_operators` | Highlight all operators | `0` | | `g:python_highlight_all` | Enable all highlight options above, except for previously set. | `0` | | `g:python_highlight_file_headers_as_comments` | Highlight shebang and coding headers as comments | `0` | | `g:python_slow_sync` | Disable for slow machines | `1` | diff --git a/doc/python-syntax.txt b/doc/python-syntax.txt index 9b97d18..c2688f6 100644 --- a/doc/python-syntax.txt +++ b/doc/python-syntax.txt @@ -86,6 +86,9 @@ following command to your `~/.config/nvim/init.vim` or `~/.vimrc`: > `g:python_highlight_class_vars` (default `0`) Highlight class variables `self` and `cls` +`g:python_highlight_operators` (default `0`) + Highlight all operators + `g:python_highlight_all` (default `0`) Enable all highlight options above, except for previously set. diff --git a/syntax/python.vim b/syntax/python.vim index 27681c3..882d9e2 100644 --- a/syntax/python.vim +++ b/syntax/python.vim @@ -53,6 +53,7 @@ if s:Enabled('g:python_highlight_all') call s:EnableByDefault('g:python_highlight_doctests') call s:EnableByDefault('g:python_print_as_function') call s:EnableByDefault('g:python_highlight_class_vars') + call s:EnableByDefault('g:python_highlight_operators') endif " @@ -73,7 +74,6 @@ endif syn keyword pythonRepeat for while syn keyword pythonConditional if elif else syn keyword pythonException try except finally -syn keyword pythonOperator and in is not or " The standard pyrex.vim unconditionally removes the pythonInclude group, so " we provide a dummy group here to avoid crashing pyrex.vim. syn keyword pythonInclude import @@ -83,7 +83,6 @@ syn match pythonRaiseFromStatement '\' syn match pythonImport '^\s*\zsfrom\>' - if s:Python2Syntax() if !s:Enabled('g:python_print_as_function') syn keyword pythonStatement print @@ -100,6 +99,16 @@ else syn cluster pythonExpression contains=pythonStatement,pythonRepeat,pythonConditional,pythonOperator,pythonNumber,pythonHexNumber,pythonOctNumber,pythonBinNumber,pythonFloat,pythonString,pythonBytes,pythonBoolean,pythonBuiltinObj,pythonBuiltinFunc endif + +" +" Operators +" +syn keyword pythonOperator and in is not or +if s:Enabled('g:python_highlight_operators') + syn match pythonOperator '\V=\|-\|+\|*\|@\|/\|%\|&\||\|^\|~\|<\|>\|!=' +endif +syn match pythonError '[$?]\|\([-+@%&|^~]\)\1\{1,}\|\([=*/<>]\)\2\{2,}\|\([-=+*@/%&|^~<>]\)\3\@![-+*@/%&|^~<>]\|[]\+=\{2,}\|[]\{2,}=\+' display + " " Decorators (new in Python 2.4) " @@ -127,10 +136,7 @@ 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\+[^0-9[:space:]]\+\>' display " Mixing spaces and tabs also may be used for pretty formatting multiline " statements @@ -275,34 +281,34 @@ 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 pythonOctNumber '\<0[oO]\o\+[lL]\=\>' display - syn match pythonBinNumber '\<0[bB][01]\+[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 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 pythonOctError '\<0[oO]\=\o*\D\+\d*\>' display + syn match pythonOctError '\<0[oO]\=\o*\D\+\d*\>' display " pythonHexError comes after pythonOctError so that 0xffffl is pythonHexError - syn match pythonHexError '\<0[xX]\x*[g-zG-Z]\x*\>' display - syn match pythonBinError '\<0[bB][01]*\D\+\d*\>' display + syn match pythonHexError '\<0[xX]\x*[g-zG-Z]\x*\>' display + syn match pythonBinError '\<0[bB][01]*\D\+\d*\>' display - syn match pythonHexNumber '\<0[xX][_0-9a-fA-F]*\x\>' display - syn match pythonOctNumber '\<0[oO][_0-7]*\o\>' display - syn match pythonBinNumber '\<0[bB][_01]*[01]\>' display + syn match 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 @@ -314,12 +320,12 @@ else 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 " diff --git a/tests/test.py b/tests/test.py index 964eacd..12b8fc8 100644 --- a/tests/test.py +++ b/tests/test.py @@ -9,7 +9,7 @@ # Keywords. with break continue del exec return pass print raise global assert lambda yield -for while if elif else import as try except finally and in is not or +for while if elif else import as try except finally from test import var as name @@ -66,6 +66,23 @@ async def Test @ декоратор @ декоратор.décorateur +# Operators + +and or in is not += +- + * ** @ / // % +& | ^ ~ << >> +< <= == != >= > + +# Erroneous operators + +$ ? +=== +-- ++ *** @@ /// %% +&& || ^^ ~~ <<< >>> +<== <<= !== !!= >== >>= +%- +- -+ + # Numbers 0 1 2 9 10 0x1f .3 12.34 0j 124j 34.2E-3 0b10 0o77 1023434 0x0 @@ -141,11 +158,10 @@ async def Test Test ''' -# Erroneous symbols or bad variable names. +# Erroneous variable names -$ ? 6xav +6xav -&& || === # Indentation errors.