|
53 | 53 | var doubleDelimiters = parserConf.doubleDelimiters || /^(\+=|\-=|\*=|%=|\/=|&=|\|=|\^=)/; |
54 | 54 | var tripleDelimiters = parserConf.tripleDelimiters || /^(\/\/=|>>=|<<=|\*\*=)/; |
55 | 55 |
|
56 | | - if (parserConf.version && parseInt(parserConf.version, 10) == 3){ |
| 56 | + if (parserConf.version && parseInt(parserConf.version, 10) == 3) { |
57 | 57 | // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator |
58 | 58 | var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!@]/; |
59 | 59 | var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/; |
|
65 | 65 | var hangingIndent = parserConf.hangingIndent || conf.indentUnit; |
66 | 66 |
|
67 | 67 | var myKeywords = commonKeywords, myBuiltins = commonBuiltins; |
68 | | - if(parserConf.extra_keywords != undefined){ |
| 68 | + if (parserConf.extra_keywords != undefined) |
69 | 69 | myKeywords = myKeywords.concat(parserConf.extra_keywords); |
70 | | - } |
71 | | - if(parserConf.extra_builtins != undefined){ |
| 70 | + |
| 71 | + if (parserConf.extra_builtins != undefined) |
72 | 72 | myBuiltins = myBuiltins.concat(parserConf.extra_builtins); |
73 | | - } |
| 73 | + |
74 | 74 | if (parserConf.version && parseInt(parserConf.version, 10) == 3) { |
75 | 75 | myKeywords = myKeywords.concat(py3.keywords); |
76 | 76 | myBuiltins = myBuiltins.concat(py3.builtins); |
|
87 | 87 | function tokenBase(stream, state) { |
88 | 88 | // Handle scope changes |
89 | 89 | if (stream.sol() && top(state).type == "py") { |
| 90 | + state.indent = stream.indentation() |
90 | 91 | var scopeOffset = top(state).offset; |
91 | 92 | if (stream.eatSpace()) { |
92 | 93 | var lineOffset = stream.indentation(); |
93 | 94 | if (lineOffset > scopeOffset) |
94 | | - pushScope(stream, state, "py"); |
| 95 | + pushPyScope(state); |
95 | 96 | else if (lineOffset < scopeOffset && dedent(stream, state)) |
96 | 97 | state.errorToken = true; |
97 | 98 | return null; |
|
224 | 225 | return tokenString; |
225 | 226 | } |
226 | 227 |
|
227 | | - function pushScope(stream, state, type) { |
228 | | - var offset = 0, align = null; |
229 | | - if (type == "py") { |
230 | | - while (top(state).type != "py") |
231 | | - state.scopes.pop(); |
232 | | - } |
233 | | - offset = top(state).offset + (type == "py" ? conf.indentUnit : hangingIndent); |
234 | | - if (type != "py" && !stream.match(/^(\s|#.*)*$/, false)) |
235 | | - align = stream.column() + 1; |
236 | | - state.scopes.push({offset: offset, type: type, align: align}); |
| 228 | + function pushPyScope(state) { |
| 229 | + while (top(state).type != "py") state.scopes.pop() |
| 230 | + state.scopes.push({offset: top(state).offset + conf.indentUnit, |
| 231 | + type: "py", |
| 232 | + align: null}) |
| 233 | + } |
| 234 | + |
| 235 | + function pushBracketScope(stream, state, type) { |
| 236 | + var align = stream.match(/^([\s\[\{\(]|#.*)*$/, false) ? null : stream.column() + 1 |
| 237 | + state.scopes.push({offset: state.indent + hangingIndent, |
| 238 | + type: type, |
| 239 | + align: align}) |
237 | 240 | } |
238 | 241 |
|
239 | 242 | function dedent(stream, state) { |
|
250 | 253 | var current = stream.current(); |
251 | 254 |
|
252 | 255 | // Handle decorators |
253 | | - if (current == "@"){ |
254 | | - if(parserConf.version && parseInt(parserConf.version, 10) == 3){ |
255 | | - return stream.match(identifiers, false) ? "meta" : "operator"; |
256 | | - } else { |
257 | | - return stream.match(identifiers, false) ? "meta" : ERRORCLASS; |
258 | | - } |
| 256 | + if (current == "@") { |
| 257 | + if (parserConf.version && parseInt(parserConf.version, 10) == 3) |
| 258 | + return stream.match(identifiers, false) ? "meta" : "operator"; |
| 259 | + else |
| 260 | + return stream.match(identifiers, false) ? "meta" : ERRORCLASS; |
259 | 261 | } |
260 | 262 |
|
261 | 263 | if ((style == "variable" || style == "builtin") |
|
268 | 270 |
|
269 | 271 | if (current == "lambda") state.lambda = true; |
270 | 272 | if (current == ":" && !state.lambda && top(state).type == "py") |
271 | | - pushScope(stream, state, "py"); |
| 273 | + pushPyScope(state); |
272 | 274 |
|
273 | 275 | var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1; |
274 | 276 | if (delimiter_index != -1) |
275 | | - pushScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1)); |
| 277 | + pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1)); |
276 | 278 |
|
277 | 279 | delimiter_index = "])}".indexOf(current); |
278 | 280 | if (delimiter_index != -1) { |
279 | | - if (top(state).type == current) state.scopes.pop(); |
| 281 | + if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent |
280 | 282 | else return ERRORCLASS; |
281 | 283 | } |
282 | 284 | if (state.dedent > 0 && stream.eol() && top(state).type == "py") { |
|
292 | 294 | return { |
293 | 295 | tokenize: tokenBase, |
294 | 296 | scopes: [{offset: basecolumn || 0, type: "py", align: null}], |
| 297 | + indent: basecolumn || 0, |
295 | 298 | lastToken: null, |
296 | 299 | lambda: false, |
297 | 300 | dedent: 0 |
|
316 | 319 | if (state.tokenize != tokenBase) |
317 | 320 | return state.tokenize.isString ? CodeMirror.Pass : 0; |
318 | 321 |
|
319 | | - var scope = top(state); |
320 | | - var closing = textAfter && textAfter.charAt(0) == scope.type; |
| 322 | + var scope = top(state), closing = scope.type == textAfter.charAt(0) |
321 | 323 | if (scope.align != null) |
322 | | - return scope.align - (closing ? 1 : 0); |
323 | | - else if (closing && state.scopes.length > 1) |
324 | | - return state.scopes[state.scopes.length - 2].offset; |
| 324 | + return scope.align - (closing ? 1 : 0) |
325 | 325 | else |
326 | | - return scope.offset; |
| 326 | + return scope.offset - (closing ? hangingIndent : 0) |
327 | 327 | }, |
328 | 328 |
|
| 329 | + electricInput: /^\s*[\}\]\)]$/, |
329 | 330 | closeBrackets: {triples: "'\""}, |
330 | 331 | lineComment: "#", |
331 | 332 | fold: "indent" |
|
0 commit comments