Skip to content

Commit

Permalink
[Python] Exit contexts gracefully upon keywords
Browse files Browse the repository at this point in the history
An unclosed function definition (or similar) will no longer cause the
rest of the file to become unreadable but rather only shows
"invalid.illegal" for the first keyword it encounters, upon which it
exits the context normally.
  • Loading branch information
FichteFoll committed Nov 1, 2016
1 parent e4f267b commit 60ee8b1
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
26 changes: 22 additions & 4 deletions Python/Python.sublime-syntax
Expand Up @@ -25,6 +25,7 @@ variables:
identifier: '\b[[:alpha:]_]{{identifier_continue}}*\b'
path: '({{identifier}} *\. *)*{{identifier}}'
sql_indicator: \s*(?:SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER|WITH)\b
illegal_names: (?:and|as|assert|break|class|continue|def|del|elif|else|except|finally|for|from|global|if|import|in|is|lambda|not|or|pass|raise|return|try|while|with|yield)

contexts:
main:
Expand All @@ -42,7 +43,7 @@ contexts:
- include: assignments
- match: ;
scope: punctuation.terminator.statement.python
- include: expressions
- include: line-expressions

inline-statements:
- include: imports
Expand Down Expand Up @@ -209,7 +210,7 @@ contexts:
set: with-body
- include: name

expressions: # Always include this last!
expressions-common:
- include: comments
- include: constants
- include: numbers
Expand All @@ -223,7 +224,6 @@ contexts:
- include: function-calls
- include: item-access
- include: line-continuation
- include: dotted-name
- match: \(
scope: punctuation.section.group.begin.python
push:
Expand All @@ -243,6 +243,19 @@ contexts:
scope: invalid.illegal.stray.brace.curly.python
- include: lists
- include: dictionaries-and-sets

line-expressions: # Always include this last!
- include: expressions-common
- include: dotted-name
# For debugging
# - match: \S
# scope: invalid.illegal.unmatched

expressions: # Always include this last!
# Differs from the line scope in that invalid-name matches will pop the current context
- include: expressions-common
- include: illegal-names-pop
- include: dotted-name
- match: '(\.) *(?={{identifier}})'
captures:
1: punctuation.accessor.python
Expand Down Expand Up @@ -712,9 +725,14 @@ contexts:
- match: "{{identifier}}"

illegal-names:
- match: \b(and|as|assert|break|class|continue|def|del|elif|else|except|finally|for|from|global|if|import|in|is|lambda|not|or|pass|raise|return|try|while|with|yield)\b
- match: \b{{illegal_names}}\b
scope: invalid.illegal.name.python

illegal-names-pop:
- match: \b{{illegal_names}}\b
scope: invalid.illegal.name.python
pop: true

keyword-arguments:
- match: '(?={{identifier}}\s*=(?!=))'
push:
Expand Down
12 changes: 12 additions & 0 deletions Python/syntax_test_python.py
Expand Up @@ -613,3 +613,15 @@ def wrapper(self):
# ^ keyword.operator.assignment.python
foo == bar()
# ^^ keyword.operator.comparison.python


# Pop contexts gracefully
def func(unclosed, parameters: if else
pass
# ^^^^ invalid.illegal.name

# The following function should be matched as normal
# despite the above definition not being closed correctly
def another_func():
#^^ -invalid
pass

0 comments on commit 60ee8b1

Please sign in to comment.