Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/ShExBy/shex_roo.../lib64/python2..../idlelib
File: PyParse.py
import re
[0] Fix | Delete
import sys
[1] Fix | Delete
[2] Fix | Delete
# Reason last stmt is continued (or C_NONE if it's not).
[3] Fix | Delete
(C_NONE, C_BACKSLASH, C_STRING_FIRST_LINE,
[4] Fix | Delete
C_STRING_NEXT_LINES, C_BRACKET) = range(5)
[5] Fix | Delete
[6] Fix | Delete
if 0: # for throwaway debugging output
[7] Fix | Delete
def dump(*stuff):
[8] Fix | Delete
sys.__stdout__.write(" ".join(map(str, stuff)) + "\n")
[9] Fix | Delete
[10] Fix | Delete
# Find what looks like the start of a popular stmt.
[11] Fix | Delete
[12] Fix | Delete
_synchre = re.compile(r"""
[13] Fix | Delete
^
[14] Fix | Delete
[ \t]*
[15] Fix | Delete
(?: while
[16] Fix | Delete
| else
[17] Fix | Delete
| def
[18] Fix | Delete
| return
[19] Fix | Delete
| assert
[20] Fix | Delete
| break
[21] Fix | Delete
| class
[22] Fix | Delete
| continue
[23] Fix | Delete
| elif
[24] Fix | Delete
| try
[25] Fix | Delete
| except
[26] Fix | Delete
| raise
[27] Fix | Delete
| import
[28] Fix | Delete
| yield
[29] Fix | Delete
)
[30] Fix | Delete
\b
[31] Fix | Delete
""", re.VERBOSE | re.MULTILINE).search
[32] Fix | Delete
[33] Fix | Delete
# Match blank line or non-indenting comment line.
[34] Fix | Delete
[35] Fix | Delete
_junkre = re.compile(r"""
[36] Fix | Delete
[ \t]*
[37] Fix | Delete
(?: \# \S .* )?
[38] Fix | Delete
\n
[39] Fix | Delete
""", re.VERBOSE).match
[40] Fix | Delete
[41] Fix | Delete
# Match any flavor of string; the terminating quote is optional
[42] Fix | Delete
# so that we're robust in the face of incomplete program text.
[43] Fix | Delete
[44] Fix | Delete
_match_stringre = re.compile(r"""
[45] Fix | Delete
\""" [^"\\]* (?:
[46] Fix | Delete
(?: \\. | "(?!"") )
[47] Fix | Delete
[^"\\]*
[48] Fix | Delete
)*
[49] Fix | Delete
(?: \""" )?
[50] Fix | Delete
[51] Fix | Delete
| " [^"\\\n]* (?: \\. [^"\\\n]* )* "?
[52] Fix | Delete
[53] Fix | Delete
| ''' [^'\\]* (?:
[54] Fix | Delete
(?: \\. | '(?!'') )
[55] Fix | Delete
[^'\\]*
[56] Fix | Delete
)*
[57] Fix | Delete
(?: ''' )?
[58] Fix | Delete
[59] Fix | Delete
| ' [^'\\\n]* (?: \\. [^'\\\n]* )* '?
[60] Fix | Delete
""", re.VERBOSE | re.DOTALL).match
[61] Fix | Delete
[62] Fix | Delete
# Match a line that starts with something interesting;
[63] Fix | Delete
# used to find the first item of a bracket structure.
[64] Fix | Delete
[65] Fix | Delete
_itemre = re.compile(r"""
[66] Fix | Delete
[ \t]*
[67] Fix | Delete
[^\s#\\] # if we match, m.end()-1 is the interesting char
[68] Fix | Delete
""", re.VERBOSE).match
[69] Fix | Delete
[70] Fix | Delete
# Match start of stmts that should be followed by a dedent.
[71] Fix | Delete
[72] Fix | Delete
_closere = re.compile(r"""
[73] Fix | Delete
\s*
[74] Fix | Delete
(?: return
[75] Fix | Delete
| break
[76] Fix | Delete
| continue
[77] Fix | Delete
| raise
[78] Fix | Delete
| pass
[79] Fix | Delete
)
[80] Fix | Delete
\b
[81] Fix | Delete
""", re.VERBOSE).match
[82] Fix | Delete
[83] Fix | Delete
# Chew up non-special chars as quickly as possible. If match is
[84] Fix | Delete
# successful, m.end() less 1 is the index of the last boring char
[85] Fix | Delete
# matched. If match is unsuccessful, the string starts with an
[86] Fix | Delete
# interesting char.
[87] Fix | Delete
[88] Fix | Delete
_chew_ordinaryre = re.compile(r"""
[89] Fix | Delete
[^[\](){}#'"\\]+
[90] Fix | Delete
""", re.VERBOSE).match
[91] Fix | Delete
[92] Fix | Delete
# Build translation table to map uninteresting chars to "x", open
[93] Fix | Delete
# brackets to "(", and close brackets to ")".
[94] Fix | Delete
[95] Fix | Delete
_tran = ['x'] * 256
[96] Fix | Delete
for ch in "({[":
[97] Fix | Delete
_tran[ord(ch)] = '('
[98] Fix | Delete
for ch in ")}]":
[99] Fix | Delete
_tran[ord(ch)] = ')'
[100] Fix | Delete
for ch in "\"'\\\n#":
[101] Fix | Delete
_tran[ord(ch)] = ch
[102] Fix | Delete
_tran = ''.join(_tran)
[103] Fix | Delete
del ch
[104] Fix | Delete
[105] Fix | Delete
try:
[106] Fix | Delete
UnicodeType = type(unicode(""))
[107] Fix | Delete
except NameError:
[108] Fix | Delete
UnicodeType = None
[109] Fix | Delete
[110] Fix | Delete
class Parser:
[111] Fix | Delete
[112] Fix | Delete
def __init__(self, indentwidth, tabwidth):
[113] Fix | Delete
self.indentwidth = indentwidth
[114] Fix | Delete
self.tabwidth = tabwidth
[115] Fix | Delete
[116] Fix | Delete
def set_str(self, str):
[117] Fix | Delete
assert len(str) == 0 or str[-1] == '\n'
[118] Fix | Delete
if type(str) is UnicodeType:
[119] Fix | Delete
# The parse functions have no idea what to do with Unicode, so
[120] Fix | Delete
# replace all Unicode characters with "x". This is "safe"
[121] Fix | Delete
# so long as the only characters germane to parsing the structure
[122] Fix | Delete
# of Python are 7-bit ASCII. It's *necessary* because Unicode
[123] Fix | Delete
# strings don't have a .translate() method that supports
[124] Fix | Delete
# deletechars.
[125] Fix | Delete
uniphooey = str
[126] Fix | Delete
str = []
[127] Fix | Delete
push = str.append
[128] Fix | Delete
for raw in map(ord, uniphooey):
[129] Fix | Delete
push(raw < 127 and chr(raw) or "x")
[130] Fix | Delete
str = "".join(str)
[131] Fix | Delete
self.str = str
[132] Fix | Delete
self.study_level = 0
[133] Fix | Delete
[134] Fix | Delete
# Return index of a good place to begin parsing, as close to the
[135] Fix | Delete
# end of the string as possible. This will be the start of some
[136] Fix | Delete
# popular stmt like "if" or "def". Return None if none found:
[137] Fix | Delete
# the caller should pass more prior context then, if possible, or
[138] Fix | Delete
# if not (the entire program text up until the point of interest
[139] Fix | Delete
# has already been tried) pass 0 to set_lo.
[140] Fix | Delete
#
[141] Fix | Delete
# This will be reliable iff given a reliable is_char_in_string
[142] Fix | Delete
# function, meaning that when it says "no", it's absolutely
[143] Fix | Delete
# guaranteed that the char is not in a string.
[144] Fix | Delete
[145] Fix | Delete
def find_good_parse_start(self, is_char_in_string=None,
[146] Fix | Delete
_synchre=_synchre):
[147] Fix | Delete
str, pos = self.str, None
[148] Fix | Delete
[149] Fix | Delete
if not is_char_in_string:
[150] Fix | Delete
# no clue -- make the caller pass everything
[151] Fix | Delete
return None
[152] Fix | Delete
[153] Fix | Delete
# Peek back from the end for a good place to start,
[154] Fix | Delete
# but don't try too often; pos will be left None, or
[155] Fix | Delete
# bumped to a legitimate synch point.
[156] Fix | Delete
limit = len(str)
[157] Fix | Delete
for tries in range(5):
[158] Fix | Delete
i = str.rfind(":\n", 0, limit)
[159] Fix | Delete
if i < 0:
[160] Fix | Delete
break
[161] Fix | Delete
i = str.rfind('\n', 0, i) + 1 # start of colon line
[162] Fix | Delete
m = _synchre(str, i, limit)
[163] Fix | Delete
if m and not is_char_in_string(m.start()):
[164] Fix | Delete
pos = m.start()
[165] Fix | Delete
break
[166] Fix | Delete
limit = i
[167] Fix | Delete
if pos is None:
[168] Fix | Delete
# Nothing looks like a block-opener, or stuff does
[169] Fix | Delete
# but is_char_in_string keeps returning true; most likely
[170] Fix | Delete
# we're in or near a giant string, the colorizer hasn't
[171] Fix | Delete
# caught up enough to be helpful, or there simply *aren't*
[172] Fix | Delete
# any interesting stmts. In any of these cases we're
[173] Fix | Delete
# going to have to parse the whole thing to be sure, so
[174] Fix | Delete
# give it one last try from the start, but stop wasting
[175] Fix | Delete
# time here regardless of the outcome.
[176] Fix | Delete
m = _synchre(str)
[177] Fix | Delete
if m and not is_char_in_string(m.start()):
[178] Fix | Delete
pos = m.start()
[179] Fix | Delete
return pos
[180] Fix | Delete
[181] Fix | Delete
# Peeking back worked; look forward until _synchre no longer
[182] Fix | Delete
# matches.
[183] Fix | Delete
i = pos + 1
[184] Fix | Delete
while 1:
[185] Fix | Delete
m = _synchre(str, i)
[186] Fix | Delete
if m:
[187] Fix | Delete
s, i = m.span()
[188] Fix | Delete
if not is_char_in_string(s):
[189] Fix | Delete
pos = s
[190] Fix | Delete
else:
[191] Fix | Delete
break
[192] Fix | Delete
return pos
[193] Fix | Delete
[194] Fix | Delete
# Throw away the start of the string. Intended to be called with
[195] Fix | Delete
# find_good_parse_start's result.
[196] Fix | Delete
[197] Fix | Delete
def set_lo(self, lo):
[198] Fix | Delete
assert lo == 0 or self.str[lo-1] == '\n'
[199] Fix | Delete
if lo > 0:
[200] Fix | Delete
self.str = self.str[lo:]
[201] Fix | Delete
[202] Fix | Delete
# As quickly as humanly possible <wink>, find the line numbers (0-
[203] Fix | Delete
# based) of the non-continuation lines.
[204] Fix | Delete
# Creates self.{goodlines, continuation}.
[205] Fix | Delete
[206] Fix | Delete
def _study1(self):
[207] Fix | Delete
if self.study_level >= 1:
[208] Fix | Delete
return
[209] Fix | Delete
self.study_level = 1
[210] Fix | Delete
[211] Fix | Delete
# Map all uninteresting characters to "x", all open brackets
[212] Fix | Delete
# to "(", all close brackets to ")", then collapse runs of
[213] Fix | Delete
# uninteresting characters. This can cut the number of chars
[214] Fix | Delete
# by a factor of 10-40, and so greatly speed the following loop.
[215] Fix | Delete
str = self.str
[216] Fix | Delete
str = str.translate(_tran)
[217] Fix | Delete
str = str.replace('xxxxxxxx', 'x')
[218] Fix | Delete
str = str.replace('xxxx', 'x')
[219] Fix | Delete
str = str.replace('xx', 'x')
[220] Fix | Delete
str = str.replace('xx', 'x')
[221] Fix | Delete
str = str.replace('\nx', '\n')
[222] Fix | Delete
# note that replacing x\n with \n would be incorrect, because
[223] Fix | Delete
# x may be preceded by a backslash
[224] Fix | Delete
[225] Fix | Delete
# March over the squashed version of the program, accumulating
[226] Fix | Delete
# the line numbers of non-continued stmts, and determining
[227] Fix | Delete
# whether & why the last stmt is a continuation.
[228] Fix | Delete
continuation = C_NONE
[229] Fix | Delete
level = lno = 0 # level is nesting level; lno is line number
[230] Fix | Delete
self.goodlines = goodlines = [0]
[231] Fix | Delete
push_good = goodlines.append
[232] Fix | Delete
i, n = 0, len(str)
[233] Fix | Delete
while i < n:
[234] Fix | Delete
ch = str[i]
[235] Fix | Delete
i = i+1
[236] Fix | Delete
[237] Fix | Delete
# cases are checked in decreasing order of frequency
[238] Fix | Delete
if ch == 'x':
[239] Fix | Delete
continue
[240] Fix | Delete
[241] Fix | Delete
if ch == '\n':
[242] Fix | Delete
lno = lno + 1
[243] Fix | Delete
if level == 0:
[244] Fix | Delete
push_good(lno)
[245] Fix | Delete
# else we're in an unclosed bracket structure
[246] Fix | Delete
continue
[247] Fix | Delete
[248] Fix | Delete
if ch == '(':
[249] Fix | Delete
level = level + 1
[250] Fix | Delete
continue
[251] Fix | Delete
[252] Fix | Delete
if ch == ')':
[253] Fix | Delete
if level:
[254] Fix | Delete
level = level - 1
[255] Fix | Delete
# else the program is invalid, but we can't complain
[256] Fix | Delete
continue
[257] Fix | Delete
[258] Fix | Delete
if ch == '"' or ch == "'":
[259] Fix | Delete
# consume the string
[260] Fix | Delete
quote = ch
[261] Fix | Delete
if str[i-1:i+2] == quote * 3:
[262] Fix | Delete
quote = quote * 3
[263] Fix | Delete
firstlno = lno
[264] Fix | Delete
w = len(quote) - 1
[265] Fix | Delete
i = i+w
[266] Fix | Delete
while i < n:
[267] Fix | Delete
ch = str[i]
[268] Fix | Delete
i = i+1
[269] Fix | Delete
[270] Fix | Delete
if ch == 'x':
[271] Fix | Delete
continue
[272] Fix | Delete
[273] Fix | Delete
if str[i-1:i+w] == quote:
[274] Fix | Delete
i = i+w
[275] Fix | Delete
break
[276] Fix | Delete
[277] Fix | Delete
if ch == '\n':
[278] Fix | Delete
lno = lno + 1
[279] Fix | Delete
if w == 0:
[280] Fix | Delete
# unterminated single-quoted string
[281] Fix | Delete
if level == 0:
[282] Fix | Delete
push_good(lno)
[283] Fix | Delete
break
[284] Fix | Delete
continue
[285] Fix | Delete
[286] Fix | Delete
if ch == '\\':
[287] Fix | Delete
assert i < n
[288] Fix | Delete
if str[i] == '\n':
[289] Fix | Delete
lno = lno + 1
[290] Fix | Delete
i = i+1
[291] Fix | Delete
continue
[292] Fix | Delete
[293] Fix | Delete
# else comment char or paren inside string
[294] Fix | Delete
[295] Fix | Delete
else:
[296] Fix | Delete
# didn't break out of the loop, so we're still
[297] Fix | Delete
# inside a string
[298] Fix | Delete
if (lno - 1) == firstlno:
[299] Fix | Delete
# before the previous \n in str, we were in the first
[300] Fix | Delete
# line of the string
[301] Fix | Delete
continuation = C_STRING_FIRST_LINE
[302] Fix | Delete
else:
[303] Fix | Delete
continuation = C_STRING_NEXT_LINES
[304] Fix | Delete
continue # with outer loop
[305] Fix | Delete
[306] Fix | Delete
if ch == '#':
[307] Fix | Delete
# consume the comment
[308] Fix | Delete
i = str.find('\n', i)
[309] Fix | Delete
assert i >= 0
[310] Fix | Delete
continue
[311] Fix | Delete
[312] Fix | Delete
assert ch == '\\'
[313] Fix | Delete
assert i < n
[314] Fix | Delete
if str[i] == '\n':
[315] Fix | Delete
lno = lno + 1
[316] Fix | Delete
if i+1 == n:
[317] Fix | Delete
continuation = C_BACKSLASH
[318] Fix | Delete
i = i+1
[319] Fix | Delete
[320] Fix | Delete
# The last stmt may be continued for all 3 reasons.
[321] Fix | Delete
# String continuation takes precedence over bracket
[322] Fix | Delete
# continuation, which beats backslash continuation.
[323] Fix | Delete
if (continuation != C_STRING_FIRST_LINE
[324] Fix | Delete
and continuation != C_STRING_NEXT_LINES and level > 0):
[325] Fix | Delete
continuation = C_BRACKET
[326] Fix | Delete
self.continuation = continuation
[327] Fix | Delete
[328] Fix | Delete
# Push the final line number as a sentinel value, regardless of
[329] Fix | Delete
# whether it's continued.
[330] Fix | Delete
assert (continuation == C_NONE) == (goodlines[-1] == lno)
[331] Fix | Delete
if goodlines[-1] != lno:
[332] Fix | Delete
push_good(lno)
[333] Fix | Delete
[334] Fix | Delete
def get_continuation_type(self):
[335] Fix | Delete
self._study1()
[336] Fix | Delete
return self.continuation
[337] Fix | Delete
[338] Fix | Delete
# study1 was sufficient to determine the continuation status,
[339] Fix | Delete
# but doing more requires looking at every character. study2
[340] Fix | Delete
# does this for the last interesting statement in the block.
[341] Fix | Delete
# Creates:
[342] Fix | Delete
# self.stmt_start, stmt_end
[343] Fix | Delete
# slice indices of last interesting stmt
[344] Fix | Delete
# self.stmt_bracketing
[345] Fix | Delete
# the bracketing structure of the last interesting stmt;
[346] Fix | Delete
# for example, for the statement "say(boo) or die", stmt_bracketing
[347] Fix | Delete
# will be [(0, 0), (3, 1), (8, 0)]. Strings and comments are
[348] Fix | Delete
# treated as brackets, for the matter.
[349] Fix | Delete
# self.lastch
[350] Fix | Delete
# last non-whitespace character before optional trailing
[351] Fix | Delete
# comment
[352] Fix | Delete
# self.lastopenbracketpos
[353] Fix | Delete
# if continuation is C_BRACKET, index of last open bracket
[354] Fix | Delete
[355] Fix | Delete
def _study2(self):
[356] Fix | Delete
if self.study_level >= 2:
[357] Fix | Delete
return
[358] Fix | Delete
self._study1()
[359] Fix | Delete
self.study_level = 2
[360] Fix | Delete
[361] Fix | Delete
# Set p and q to slice indices of last interesting stmt.
[362] Fix | Delete
str, goodlines = self.str, self.goodlines
[363] Fix | Delete
i = len(goodlines) - 1
[364] Fix | Delete
p = len(str) # index of newest line
[365] Fix | Delete
while i:
[366] Fix | Delete
assert p
[367] Fix | Delete
# p is the index of the stmt at line number goodlines[i].
[368] Fix | Delete
# Move p back to the stmt at line number goodlines[i-1].
[369] Fix | Delete
q = p
[370] Fix | Delete
for nothing in range(goodlines[i-1], goodlines[i]):
[371] Fix | Delete
# tricky: sets p to 0 if no preceding newline
[372] Fix | Delete
p = str.rfind('\n', 0, p-1) + 1
[373] Fix | Delete
# The stmt str[p:q] isn't a continuation, but may be blank
[374] Fix | Delete
# or a non-indenting comment line.
[375] Fix | Delete
if _junkre(str, p):
[376] Fix | Delete
i = i-1
[377] Fix | Delete
else:
[378] Fix | Delete
break
[379] Fix | Delete
if i == 0:
[380] Fix | Delete
# nothing but junk!
[381] Fix | Delete
assert p == 0
[382] Fix | Delete
q = p
[383] Fix | Delete
self.stmt_start, self.stmt_end = p, q
[384] Fix | Delete
[385] Fix | Delete
# Analyze this stmt, to find the last open bracket (if any)
[386] Fix | Delete
# and last interesting character (if any).
[387] Fix | Delete
lastch = ""
[388] Fix | Delete
stack = [] # stack of open bracket indices
[389] Fix | Delete
push_stack = stack.append
[390] Fix | Delete
bracketing = [(p, 0)]
[391] Fix | Delete
while p < q:
[392] Fix | Delete
# suck up all except ()[]{}'"#\\
[393] Fix | Delete
m = _chew_ordinaryre(str, p, q)
[394] Fix | Delete
if m:
[395] Fix | Delete
# we skipped at least one boring char
[396] Fix | Delete
newp = m.end()
[397] Fix | Delete
# back up over totally boring whitespace
[398] Fix | Delete
i = newp - 1 # index of last boring char
[399] Fix | Delete
while i >= p and str[i] in " \t\n":
[400] Fix | Delete
i = i-1
[401] Fix | Delete
if i >= p:
[402] Fix | Delete
lastch = str[i]
[403] Fix | Delete
p = newp
[404] Fix | Delete
if p >= q:
[405] Fix | Delete
break
[406] Fix | Delete
[407] Fix | Delete
ch = str[p]
[408] Fix | Delete
[409] Fix | Delete
if ch in "([{":
[410] Fix | Delete
push_stack(p)
[411] Fix | Delete
bracketing.append((p, len(stack)))
[412] Fix | Delete
lastch = ch
[413] Fix | Delete
p = p+1
[414] Fix | Delete
continue
[415] Fix | Delete
[416] Fix | Delete
if ch in ")]}":
[417] Fix | Delete
if stack:
[418] Fix | Delete
del stack[-1]
[419] Fix | Delete
lastch = ch
[420] Fix | Delete
p = p+1
[421] Fix | Delete
bracketing.append((p, len(stack)))
[422] Fix | Delete
continue
[423] Fix | Delete
[424] Fix | Delete
if ch == '"' or ch == "'":
[425] Fix | Delete
# consume string
[426] Fix | Delete
# Note that study1 did this with a Python loop, but
[427] Fix | Delete
# we use a regexp here; the reason is speed in both
[428] Fix | Delete
# cases; the string may be huge, but study1 pre-squashed
[429] Fix | Delete
# strings to a couple of characters per line. study1
[430] Fix | Delete
# also needed to keep track of newlines, and we don't
[431] Fix | Delete
# have to.
[432] Fix | Delete
bracketing.append((p, len(stack)+1))
[433] Fix | Delete
lastch = ch
[434] Fix | Delete
p = _match_stringre(str, p, q).end()
[435] Fix | Delete
bracketing.append((p, len(stack)))
[436] Fix | Delete
continue
[437] Fix | Delete
[438] Fix | Delete
if ch == '#':
[439] Fix | Delete
# consume comment and trailing newline
[440] Fix | Delete
bracketing.append((p, len(stack)+1))
[441] Fix | Delete
p = str.find('\n', p, q) + 1
[442] Fix | Delete
assert p > 0
[443] Fix | Delete
bracketing.append((p, len(stack)))
[444] Fix | Delete
continue
[445] Fix | Delete
[446] Fix | Delete
assert ch == '\\'
[447] Fix | Delete
p = p+1 # beyond backslash
[448] Fix | Delete
assert p < q
[449] Fix | Delete
if str[p] != '\n':
[450] Fix | Delete
# the program is invalid, but can't complain
[451] Fix | Delete
lastch = ch + str[p]
[452] Fix | Delete
p = p+1 # beyond escaped char
[453] Fix | Delete
[454] Fix | Delete
# end while p < q:
[455] Fix | Delete
[456] Fix | Delete
self.lastch = lastch
[457] Fix | Delete
if stack:
[458] Fix | Delete
self.lastopenbracketpos = stack[-1]
[459] Fix | Delete
self.stmt_bracketing = tuple(bracketing)
[460] Fix | Delete
[461] Fix | Delete
# Assuming continuation is C_BRACKET, return the number
[462] Fix | Delete
# of spaces the next line should be indented.
[463] Fix | Delete
[464] Fix | Delete
def compute_bracket_indent(self):
[465] Fix | Delete
self._study2()
[466] Fix | Delete
assert self.continuation == C_BRACKET
[467] Fix | Delete
j = self.lastopenbracketpos
[468] Fix | Delete
str = self.str
[469] Fix | Delete
n = len(str)
[470] Fix | Delete
origi = i = str.rfind('\n', 0, j) + 1
[471] Fix | Delete
j = j+1 # one beyond open bracket
[472] Fix | Delete
# find first list item; set i to start of its line
[473] Fix | Delete
while j < n:
[474] Fix | Delete
m = _itemre(str, j)
[475] Fix | Delete
if m:
[476] Fix | Delete
j = m.end() - 1 # index of first interesting char
[477] Fix | Delete
extra = 0
[478] Fix | Delete
break
[479] Fix | Delete
else:
[480] Fix | Delete
# this line is junk; advance to next line
[481] Fix | Delete
i = j = str.find('\n', j) + 1
[482] Fix | Delete
else:
[483] Fix | Delete
# nothing interesting follows the bracket;
[484] Fix | Delete
# reproduce the bracket line's indentation + a level
[485] Fix | Delete
j = i = origi
[486] Fix | Delete
while str[j] in " \t":
[487] Fix | Delete
j = j+1
[488] Fix | Delete
extra = self.indentwidth
[489] Fix | Delete
return len(str[i:j].expandtabs(self.tabwidth)) + extra
[490] Fix | Delete
[491] Fix | Delete
# Return number of physical lines in last stmt (whether or not
[492] Fix | Delete
# it's an interesting stmt! this is intended to be called when
[493] Fix | Delete
# continuation is C_BACKSLASH).
[494] Fix | Delete
[495] Fix | Delete
def get_num_lines_in_stmt(self):
[496] Fix | Delete
self._study1()
[497] Fix | Delete
goodlines = self.goodlines
[498] Fix | Delete
return goodlines[-1] - goodlines[-2]
[499] Fix | Delete
12
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function