vim-python / python-syntax

Python syntax highlighting for Vim
MIT License
438 stars 84 forks source link

Support for PEP 622 structural pattern matching #80

Open wbadart opened 3 years ago

wbadart commented 3 years ago

Hey team- just wanted to start the discussion about PEP 622 since it introduces some new syntax. Any thoughts on what the effort might be to add support? I'm guessing adding the match and case keywords will get us pretty far (and I'd be happy to take a stab at this) but I'd also want to get ahead of any hairy corner cases in the new syntax (e.g. guards, or patterns, ...).

Thanks for your consideration!

kfollstad commented 3 years ago

Hi @wbadart,

I found this repo looking for exactly that, highlighting for current syntax, so thanks for bringing this and the ModuleNotFoundError up.

For what it is worth, what I notice is that the existing syntax file makes no attempt to perform nextgroup checking for other keywords aside from raise, def, and class. The more complicated cases where an elaborate python expression follows such as for if, elif, else, try, except, etc are implemented as just straight keywords with no additional checking. Consequently I don't see why taking the same approach when the case patterns / guards that follow also get quite complicated would not at the least be a great starting point.

char101 commented 2 years ago

Basic support for match/case

diff --git a/syntax/python.vim b/syntax/python.vim
index 2524aba..3d49f51 100644
--- a/syntax/python.vim
+++ b/syntax/python.vim
@@ -81,6 +81,7 @@ if s:Enabled('g:python_highlight_class_vars')
 endif
 syn keyword pythonRepeat        for while
 syn keyword pythonConditional   if elif else
+syn keyword pythonMatch         match case
 syn keyword pythonException     try except finally
 " The standard pyrex.vim unconditionally removes the pythonInclude group, so
 " we provide a dummy group here to avoid crashing pyrex.vim.
@@ -105,7 +106,7 @@ else
     syn match   pythonStatement   '\<async\s\+def\>' nextgroup=pythonFunction skipwhite
     syn match   pythonStatement   '\<async\s\+with\>'
     syn match   pythonStatement   '\<async\s\+for\>'
-    syn cluster pythonExpression contains=pythonStatement,pythonRepeat,pythonConditional,pythonOperator,pythonNumber,pythonHexNumber,pythonOctNumber,pythonBinNumber,pythonFloat,pythonString,pythonFString,pythonRawString,pythonRawFString,pythonBytes,pythonBoolean,pythonNone,pythonSingleton,pythonBuiltinObj,pythonBuiltinFunc,pythonBuiltinType,pythonClassVar
+    syn cluster pythonExpression contains=pythonStatement,pythonRepeat,pythonConditional,pythonMatch,pythonOperator,pythonNumber,pythonHexNumber,pythonOctNumber,pythonBinNumber,pythonFloat,pythonString,pythonFString,pythonRawString,pythonRawFString,pythonBytes,pythonBoolean,pythonNone,pythonSingleton,pythonBuiltinObj,pythonBuiltinFunc,pythonBuiltinType,pythonClassVar
 endif

@@ -434,6 +435,7 @@ if v:version >= 508 || !exists('did_python_syn_inits')
     HiLink pythonFunction         Function
     HiLink pythonFunctionCall     Function
     HiLink pythonConditional      Conditional
+    HiLink pythonMatch            Conditional
     HiLink pythonRepeat           Repeat
     HiLink pythonException        Exception
     HiLink pythonOperator         Operator
GBeauregard commented 2 years ago

This is presumably harder than it seems since the new keywords are "soft" and only keywords in certain contexts.

char101 commented 2 years ago

So match and case can be variable/function/class name outside match expression. Can match pattern have higher priorities? We can make those syntax have higher priorities than match/case syntax.

GBeauregard commented 2 years ago

Yeah, and _ is a soft keyword too. See https://github.com/python/cpython/pull/25851 for what IDLE did.