Skip to content

Commit 595f6be

Browse files
committed
fixed colourising of multiline strings
1 parent 1370bbf commit 595f6be

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

bpython/cli.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,11 @@
5252
from ConfigParser import ConfigParser, NoSectionError, NoOptionError
5353

5454
# These are used for syntax hilighting.
55-
from pygments import highlight
55+
from pygments import format
5656
from pygments.lexers import PythonLexer
57+
from pygments.token import Token
5758
from bpython.formatter import BPythonFormatter
59+
from itertools import chain
5860

5961
# This for import completion
6062
from bpython import importcompletion
@@ -119,8 +121,6 @@ def readlines(self, x):
119121
#
120122
# Tab completion does not work if not at the end of the line.
121123
#
122-
# Triple-quoted strings over multiple lines are not colourised correctly.
123-
#
124124
# Numerous optimisations can be made but it seems to do all the lookup stuff
125125
# fast enough on even my crappy server so I'm not too bothered about that
126126
# at the moment.
@@ -162,6 +162,18 @@ def make_colours():
162162
return c
163163

164164

165+
def next_token_inside_string(s, inside_string):
166+
"""Given a code string s and an initial state inside_string, return
167+
whether the next token will be inside a string or not."""
168+
for token, value in PythonLexer().get_tokens(s):
169+
if token is Token.String and value in ['"""', "'''", '"', "'"]:
170+
if not inside_string:
171+
inside_string = value
172+
elif value == inside_string:
173+
inside_string = False
174+
return inside_string
175+
176+
165177
class Interpreter(code.InteractiveInterpreter):
166178

167179
def __init__(self):
@@ -188,6 +200,7 @@ def showsyntaxerror(self, filename=None):
188200
sys.last_type = type
189201
sys.last_value = value
190202
if filename and type is SyntaxError:
203+
self.inside_string = False
191204
# Work hard to stuff the correct filename in the exception
192205
try:
193206
msg, (dummy_filename, lineno, offset, line) = value
@@ -296,6 +309,7 @@ def __init__(self, scr, interp, statusbar=None, idle=None):
296309
self.matches = []
297310
self.argspec = None
298311
self.s = ''
312+
self.inside_string = False
299313
self.list_win_visible = False
300314
self._C = {}
301315
sys.stdin = FakeStdin(self)
@@ -1377,6 +1391,9 @@ def lf(self):
13771391
for _ in range(self.cpos):
13781392
self.mvc(-1)
13791393

1394+
self.inside_string = next_token_inside_string(self.s,
1395+
self.inside_string)
1396+
13801397
self.echo("\n")
13811398

13821399
def addstr(self, s):
@@ -1398,7 +1415,16 @@ def print_line(self, s, clr=False):
13981415
clr = True
13991416

14001417
if OPTS.syntax:
1401-
o = highlight(s, PythonLexer(), BPythonFormatter())
1418+
if self.inside_string:
1419+
# A string started in another line is continued in this
1420+
# line
1421+
tokens = PythonLexer().get_tokens(self.inside_string + s)
1422+
token, value = tokens.next()
1423+
if token is Token.String.Doc:
1424+
tokens = chain([(Token.String, value[3:])], tokens)
1425+
else:
1426+
tokens = PythonLexer().get_tokens(s)
1427+
o = format(tokens, BPythonFormatter())
14021428
else:
14031429
o = s
14041430

0 commit comments

Comments
 (0)