170 'expr-inside-fstring': [ |
170 'expr-inside-fstring': [ |
171 (r'[{([]', Punctuation, 'expr-inside-fstring-inner'), |
171 (r'[{([]', Punctuation, 'expr-inside-fstring-inner'), |
172 # without format specifier |
172 # without format specifier |
173 (r'(=\s*)?' # debug (https://bugs.python.org/issue36817) |
173 (r'(=\s*)?' # debug (https://bugs.python.org/issue36817) |
174 r'(\![sraf])?' # conversion |
174 r'(\![sraf])?' # conversion |
175 r'}', String.Interpol, '#pop'), |
175 r'\}', String.Interpol, '#pop'), |
176 # with format specifier |
176 # with format specifier |
177 # we'll catch the remaining '}' in the outer scope |
177 # we'll catch the remaining '}' in the outer scope |
178 (r'(=\s*)?' # debug (https://bugs.python.org/issue36817) |
178 (r'(=\s*)?' # debug (https://bugs.python.org/issue36817) |
179 r'(\![sraf])?' # conversion |
179 r'(\![sraf])?' # conversion |
180 r':', String.Interpol, '#pop'), |
180 r':', String.Interpol, '#pop'), |
181 (r'[^\S]+', Text), # allow new lines |
181 (r'\s+', Text), # allow new lines |
182 include('expr'), |
182 include('expr'), |
183 ], |
183 ], |
184 'expr-inside-fstring-inner': [ |
184 'expr-inside-fstring-inner': [ |
185 (r'[{([]', Punctuation, 'expr-inside-fstring-inner'), |
185 (r'[{([]', Punctuation, 'expr-inside-fstring-inner'), |
186 (r'[])}]', Punctuation, '#pop'), |
186 (r'[])}]', Punctuation, '#pop'), |
187 (r'[^\S]+', Text), # allow new lines |
187 (r'\s+', Text), # allow new lines |
188 include('expr'), |
188 include('expr'), |
189 ], |
189 ], |
190 'expr-keywords': [ |
190 'expr-keywords': [ |
191 # Based on https://docs.python.org/3/reference/expressions.html |
191 # Based on https://docs.python.org/3/reference/expressions.html |
192 (words(( |
192 (words(( |
205 (words(('True', 'False', 'None'), suffix=r'\b'), Keyword.Constant), |
205 (words(('True', 'False', 'None'), suffix=r'\b'), Keyword.Constant), |
206 ], |
206 ], |
207 'builtins': [ |
207 'builtins': [ |
208 (words(( |
208 (words(( |
209 '__import__', 'abs', 'all', 'any', 'bin', 'bool', 'bytearray', |
209 '__import__', 'abs', 'all', 'any', 'bin', 'bool', 'bytearray', |
210 'bytes', 'chr', 'classmethod', 'cmp', 'compile', 'complex', |
210 'bytes', 'chr', 'classmethod', 'compile', 'complex', |
211 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'filter', |
211 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'filter', |
212 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', |
212 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', |
213 'hash', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', |
213 'hash', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', |
214 'iter', 'len', 'list', 'locals', 'map', 'max', 'memoryview', |
214 'iter', 'len', 'list', 'locals', 'map', 'max', 'memoryview', |
215 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', |
215 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', |
315 (r'None\b', Name.Builtin.Pseudo, '#pop'), |
315 (r'None\b', Name.Builtin.Pseudo, '#pop'), |
316 (uni_name, Name.Namespace), |
316 (uni_name, Name.Namespace), |
317 default('#pop'), |
317 default('#pop'), |
318 ], |
318 ], |
319 'fstringescape': [ |
319 'fstringescape': [ |
320 ('{{', String.Escape), |
320 (r'\{\{', String.Escape), |
321 ('}}', String.Escape), |
321 (r'\}\}', String.Escape), |
322 include('stringescape'), |
322 include('stringescape'), |
323 ], |
323 ], |
324 'stringescape': [ |
324 'stringescape': [ |
325 (r'\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|' |
325 (r'\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|' |
326 r'U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})', String.Escape) |
326 r'U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})', String.Escape) |
644 curtb = '' |
644 curtb = '' |
645 tbindex = 0 |
645 tbindex = 0 |
646 tb = 0 |
646 tb = 0 |
647 for match in line_re.finditer(text): |
647 for match in line_re.finditer(text): |
648 line = match.group() |
648 line = match.group() |
649 if line.startswith(u'>>> ') or line.startswith(u'... '): |
649 if line.startswith('>>> ') or line.startswith('... '): |
650 tb = 0 |
650 tb = 0 |
651 insertions.append((len(curcode), |
651 insertions.append((len(curcode), |
652 [(0, Generic.Prompt, line[:4])])) |
652 [(0, Generic.Prompt, line[:4])])) |
653 curcode += line[4:] |
653 curcode += line[4:] |
654 elif line.rstrip() == u'...' and not tb: |
654 elif line.rstrip() == '...' and not tb: |
655 # only a new >>> prompt can end an exception block |
655 # only a new >>> prompt can end an exception block |
656 # otherwise an ellipsis in place of the traceback frames |
656 # otherwise an ellipsis in place of the traceback frames |
657 # will be mishandled |
657 # will be mishandled |
658 insertions.append((len(curcode), |
658 insertions.append((len(curcode), |
659 [(0, Generic.Prompt, u'...')])) |
659 [(0, Generic.Prompt, '...')])) |
660 curcode += line[3:] |
660 curcode += line[3:] |
661 else: |
661 else: |
662 if curcode: |
662 if curcode: |
663 for item in do_insertions( |
663 yield from do_insertions( |
664 insertions, pylexer.get_tokens_unprocessed(curcode)): |
664 insertions, pylexer.get_tokens_unprocessed(curcode)) |
665 yield item |
|
666 curcode = '' |
665 curcode = '' |
667 insertions = [] |
666 insertions = [] |
668 if (line.startswith(u'Traceback (most recent call last):') or |
667 if (line.startswith('Traceback (most recent call last):') or |
669 re.match(u' File "[^"]+", line \\d+\\n$', line)): |
668 re.match(' File "[^"]+", line \\d+\\n$', line)): |
670 tb = 1 |
669 tb = 1 |
671 curtb = line |
670 curtb = line |
672 tbindex = match.start() |
671 tbindex = match.start() |
673 elif line == 'KeyboardInterrupt\n': |
672 elif line == 'KeyboardInterrupt\n': |
674 yield match.start(), Name.Class, line |
673 yield match.start(), Name.Class, line |
675 elif tb: |
674 elif tb: |
676 curtb += line |
675 curtb += line |
677 if not (line.startswith(' ') or line.strip() == u'...'): |
676 if not (line.startswith(' ') or line.strip() == '...'): |
678 tb = 0 |
677 tb = 0 |
679 for i, t, v in tblexer.get_tokens_unprocessed(curtb): |
678 for i, t, v in tblexer.get_tokens_unprocessed(curtb): |
680 yield tbindex+i, t, v |
679 yield tbindex+i, t, v |
681 curtb = '' |
680 curtb = '' |
682 else: |
681 else: |
683 yield match.start(), Generic.Output, line |
682 yield match.start(), Generic.Output, line |
684 if curcode: |
683 if curcode: |
685 for item in do_insertions(insertions, |
684 yield from do_insertions(insertions, |
686 pylexer.get_tokens_unprocessed(curcode)): |
685 pylexer.get_tokens_unprocessed(curcode)) |
687 yield item |
|
688 if curtb: |
686 if curtb: |
689 for i, t, v in tblexer.get_tokens_unprocessed(curtb): |
687 for i, t, v in tblexer.get_tokens_unprocessed(curtb): |
690 yield tbindex+i, t, v |
688 yield tbindex+i, t, v |
691 |
689 |
692 |
690 |
830 include('name'), |
828 include('name'), |
831 include('numbers'), |
829 include('numbers'), |
832 ], |
830 ], |
833 'keywords': [ |
831 'keywords': [ |
834 (words(( |
832 (words(( |
835 'assert', 'break', 'by', 'continue', 'ctypedef', 'del', 'elif', |
833 'assert', 'async', 'await', 'break', 'by', 'continue', 'ctypedef', 'del', 'elif', |
836 'else', 'except', 'except?', 'exec', 'finally', 'for', 'fused', 'gil', |
834 'else', 'except', 'except?', 'exec', 'finally', 'for', 'fused', 'gil', |
837 'global', 'if', 'include', 'lambda', 'nogil', 'pass', 'print', |
835 'global', 'if', 'include', 'lambda', 'nogil', 'pass', 'print', |
838 'raise', 'return', 'try', 'while', 'yield', 'as', 'with'), suffix=r'\b'), |
836 'raise', 'return', 'try', 'while', 'yield', 'as', 'with'), suffix=r'\b'), |
839 Keyword), |
837 Keyword), |
840 (r'(DEF|IF|ELIF|ELSE)\b', Comment.Preproc), |
838 (r'(DEF|IF|ELIF|ELSE)\b', Comment.Preproc), |