From f3e6bffa6eecdf974822931cb5208cdccb4e3ab9 Mon Sep 17 00:00:00 2001 From: Victor Petrovykh Date: Wed, 10 Oct 2018 18:40:48 -0400 Subject: [PATCH] Scope `from`, `import`, and `as` the same way in imports. Use `keyword.control.import.python` scope for `from`, `import`, and `as` keywords when they appear as part of an import statement. Use `keyword.control.flow.python` scope for `from` and `as` if they appear elsewhere. Issue: #123. --- grammars/MagicPython.cson | 64 +++++-- grammars/MagicPython.tmLanguage | 82 +++++++-- grammars/src/MagicPython.syntax.yaml | 46 +++-- test/atom-spec/python-spec.js | 261 ++++++++++++++++++++++++++- test/expressions/keywords.py | 4 +- test/statements/from1.py | 33 ++++ test/statements/import1.py | 4 +- test/statements/import6.py | 2 +- test/statements/import7.py | 2 +- test/statements/import8.py | 48 +++++ test/statements/import9.py | 67 +++++++ 11 files changed, 557 insertions(+), 56 deletions(-) create mode 100644 test/statements/from1.py create mode 100644 test/statements/import8.py create mode 100644 test/statements/import9.py diff --git a/grammars/MagicPython.cson b/grammars/MagicPython.cson index c3f182d4..d04da619 100644 --- a/grammars/MagicPython.cson +++ b/grammars/MagicPython.cson @@ -259,12 +259,32 @@ repository: name: "storage.type.function.python" match: "\\b((async\\s+)?\\s*def)\\b" } + { + name: "keyword.control.flow.python" + comment: ''' + if `as` is eventually followed by `:` or line continuation + it's probably control flow like: + with foo as bar, \\ + Foo as Bar: + try: + do_stuff() + except Exception as e: + pass + + ''' + match: "\\b(?match \b((async\s+)?\s*def)\b + + name + keyword.control.flow.python + comment + if `as` is eventually followed by `:` or line continuation +it's probably control flow like: + with foo as bar, \ + Foo as Bar: + try: + do_stuff() + except Exception as e: + pass + + match + \b(?<!\.)as\b(?=.*[:\\]) + + + name + keyword.control.import.python + comment + other legal use of `as` is in an import + match + \b(?<!\.)as\b + name keyword.control.flow.python match (?x) \b(?<!\.)( - as | async | continue | del | assert | break | finally | for + async | continue | del | assert | break | finally | for | from | elif | else | if | except | pass | raise | return | try | while | with )\b @@ -1531,39 +1555,63 @@ import comment - Import statements + Import statements used to correctly mark `from`, `import`, and `as` patterns - match - (?x) - \s* \b(from) \s*(\.+)\s* (import\b)? - - captures + begin + \b(?<!\.)(from)\b(?=.+import) + end + $|(?=import) + beginCaptures 1 name keyword.control.import.python - 2 + + patterns + name punctuation.separator.period.python + match + \.+ - 3 + + include + #expression + + + + + begin + \b(?<!\.)(import)\b + end + $ + beginCaptures + + 1 name keyword.control.import.python - - - name - keyword.control.import.python - match - \b(?<!\.)import\b + patterns + + + name + keyword.control.import.python + match + \b(?<!\.)as\b + + + include + #expression + + @@ -2836,13 +2884,13 @@ indirectly through syntactic constructs (?x) \b(?: ( - and | as | assert | async | await | break | class | continue | def + and | assert | async | await | break | class | continue | def | del | elif | else | except | finally | for | from | global | if | in | is | (?<=\.)lambda | lambda(?=\s*[\.=]) | nonlocal | not | or | pass | raise | return | try | while | with | yield ) | ( - import + as | import ) )\b diff --git a/grammars/src/MagicPython.syntax.yaml b/grammars/src/MagicPython.syntax.yaml index 2be48ca1..e7623f32 100644 --- a/grammars/src/MagicPython.syntax.yaml +++ b/grammars/src/MagicPython.syntax.yaml @@ -359,11 +359,25 @@ repository: patterns: - name: storage.type.function.python match: \b((async\s+)?\s*def)\b + - name: keyword.control.flow.python + comment: | + if `as` is eventually followed by `:` or line continuation + it's probably control flow like: + with foo as bar, \ + Foo as Bar: + try: + do_stuff() + except Exception as e: + pass + match: \b(?