Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: Source/devtools/front_end/cm/python.js

Issue 354833004: DevTools: [CodeMirror] roll CodeMirror to version @e20d175 (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: address comments Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/devtools/front_end/cm/php.js ('k') | Source/devtools/front_end/cm/shell.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 CodeMirror.defineMode("python", function(conf, parserConf) { 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 var ERRORCLASS = 'error'; 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 function wordRegexp(words) { 4 (function(mod) {
5 return new RegExp("^((" + words.join(")|(") + "))\\b"); 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 } 6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 function wordRegexp(words) {
15 return new RegExp("^((" + words.join(")|(") + "))\\b");
16 }
17
18 var wordOperators = wordRegexp(["and", "or", "not", "is", "in"]);
19 var commonKeywords = ["as", "assert", "break", "class", "continue",
20 "def", "del", "elif", "else", "except", "finally",
21 "for", "from", "global", "if", "import",
22 "lambda", "pass", "raise", "return",
23 "try", "while", "with", "yield"];
24 var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callab le", "chr",
25 "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
26 "enumerate", "eval", "filter", "float", "format", "froze nset",
27 "getattr", "globals", "hasattr", "hash", "help", "hex", "id",
28 "input", "int", "isinstance", "issubclass", "iter", "len ",
29 "list", "locals", "map", "max", "memoryview", "min", "ne xt",
30 "object", "oct", "open", "ord", "pow", "property", "rang e",
31 "repr", "reversed", "round", "set", "setattr", "slice",
32 "sorted", "staticmethod", "str", "sum", "super", "tuple" ,
33 "type", "vars", "zip", "__import__", "NotImplemented",
34 "Ellipsis", "__debug__"];
35 var py2 = {builtins: ["apply", "basestring", "buffer", "cmp", "coerce", "execf ile",
36 "file", "intern", "long", "raw_input", "reduce", "reload ",
37 "unichr", "unicode", "xrange", "False", "True", "None"],
38 keywords: ["exec", "print"]};
39 var py3 = {builtins: ["ascii", "bytes", "exec", "print"],
40 keywords: ["nonlocal", "False", "True", "None"]};
41
42 CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonB uiltins));
43
44 function top(state) {
45 return state.scopes[state.scopes.length - 1];
46 }
47
48 CodeMirror.defineMode("python", function(conf, parserConf) {
49 var ERRORCLASS = "error";
7 50
8 var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/ %&|\\^~<>!]"); 51 var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/ %&|\\^~<>!]");
9 var singleDelimiters = parserConf.singleDelimiters || new RegExp('^[\\(\\)\\ [\\]\\{\\}@,:`=;\\.]'); 52 var singleDelimiters = parserConf.singleDelimiters || new RegExp("^[\\(\\)\\ [\\]\\{\\}@,:`=;\\.]");
10 var doubleOperators = parserConf.doubleOperators || new RegExp("^((==)|(!=)| (<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))"); 53 var doubleOperators = parserConf.doubleOperators || new RegExp("^((==)|(!=)| (<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
11 var doubleDelimiters = parserConf.doubleDelimiters || new RegExp("^((\\+=)|( \\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))"); 54 var doubleDelimiters = parserConf.doubleDelimiters || new RegExp("^((\\+=)|( \\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
12 var tripleDelimiters = parserConf.tripleDelimiters || new RegExp("^((//=)|(> >=)|(<<=)|(\\*\\*=))"); 55 var tripleDelimiters = parserConf.tripleDelimiters || new RegExp("^((//=)|(> >=)|(<<=)|(\\*\\*=))");
13 var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9 ]*"); 56 var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9 ]*");
14 57 var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
15 var wordOperators = wordRegexp(['and', 'or', 'not', 'is', 'in']); 58
16 var commonkeywords = ['as', 'assert', 'break', 'class', 'continue', 59 var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
17 'def', 'del', 'elif', 'else', 'except', 'finally',
18 'for', 'from', 'global', 'if', 'import',
19 'lambda', 'pass', 'raise', 'return',
20 'try', 'while', 'with', 'yield'];
21 var commonBuiltins = ['abs', 'all', 'any', 'bin', 'bool', 'bytearray', 'call able', 'chr',
22 'classmethod', 'compile', 'complex', 'delattr', 'dict' , 'dir', 'divmod',
23 'enumerate', 'eval', 'filter', 'float', 'format', 'fro zenset',
24 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex' , 'id',
25 'input', 'int', 'isinstance', 'issubclass', 'iter', 'l en',
26 'list', 'locals', 'map', 'max', 'memoryview', 'min', ' next',
27 'object', 'oct', 'open', 'ord', 'pow', 'property', 'ra nge',
28 'repr', 'reversed', 'round', 'set', 'setattr', 'slice' ,
29 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tupl e',
30 'type', 'vars', 'zip', '__import__', 'NotImplemented',
31 'Ellipsis', '__debug__'];
32 var py2 = {'builtins': ['apply', 'basestring', 'buffer', 'cmp', 'coerce', 'e xecfile',
33 'file', 'intern', 'long', 'raw_input', 'reduce', 're load',
34 'unichr', 'unicode', 'xrange', 'False', 'True', 'Non e'],
35 'keywords': ['exec', 'print']};
36 var py3 = {'builtins': ['ascii', 'bytes', 'exec', 'print'],
37 'keywords': ['nonlocal', 'False', 'True', 'None']};
38
39 if(parserConf.extra_keywords != undefined){ 60 if(parserConf.extra_keywords != undefined){
40 commonkeywords = commonkeywords.concat(parserConf.extra_keywords); 61 myKeywords = myKeywords.concat(parserConf.extra_keywords);
41 } 62 }
42 if(parserConf.extra_builtins != undefined){ 63 if(parserConf.extra_builtins != undefined){
43 commonBuiltins = commonBuiltins.concat(parserConf.extra_builtins); 64 myBuiltins = myBuiltins.concat(parserConf.extra_builtins);
44 } 65 }
45 if (!!parserConf.version && parseInt(parserConf.version, 10) === 3) { 66 if (parserConf.version && parseInt(parserConf.version, 10) == 3) {
46 commonkeywords = commonkeywords.concat(py3.keywords); 67 myKeywords = myKeywords.concat(py3.keywords);
47 commonBuiltins = commonBuiltins.concat(py3.builtins); 68 myBuiltins = myBuiltins.concat(py3.builtins);
48 var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i" ); 69 var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i");
49 } else { 70 } else {
50 commonkeywords = commonkeywords.concat(py2.keywords); 71 myKeywords = myKeywords.concat(py2.keywords);
51 commonBuiltins = commonBuiltins.concat(py2.builtins); 72 myBuiltins = myBuiltins.concat(py2.builtins);
52 var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"])) ", "i"); 73 var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
53 } 74 }
54 var keywords = wordRegexp(commonkeywords); 75 var keywords = wordRegexp(myKeywords);
55 var builtins = wordRegexp(commonBuiltins); 76 var builtins = wordRegexp(myBuiltins);
56
57 var indentInfo = null;
58 77
59 // tokenizers 78 // tokenizers
60 function tokenBase(stream, state) { 79 function tokenBase(stream, state) {
61 // Handle scope changes 80 // Handle scope changes
62 if (stream.sol()) { 81 if (stream.sol() && top(state).type == "py") {
63 var scopeOffset = state.scopes[0].offset; 82 var scopeOffset = top(state).offset;
64 if (stream.eatSpace()) {
65 var lineOffset = stream.indentation();
66 if (lineOffset > scopeOffset) {
67 indentInfo = 'indent';
68 } else if (lineOffset < scopeOffset) {
69 indentInfo = 'dedent';
70 }
71 return null;
72 } else {
73 if (scopeOffset > 0) {
74 dedent(stream, state);
75 }
76 }
77 }
78 if (stream.eatSpace()) { 83 if (stream.eatSpace()) {
79 return null; 84 var lineOffset = stream.indentation();
80 } 85 if (lineOffset > scopeOffset)
81 86 pushScope(stream, state, "py");
82 var ch = stream.peek(); 87 else if (lineOffset < scopeOffset && dedent(stream, state))
83 88 state.errorToken = true;
84 // Handle Comments 89 return null;
85 if (ch === '#') { 90 } else {
86 stream.skipToEnd(); 91 var style = tokenBaseInner(stream, state);
87 return 'comment'; 92 if (scopeOffset > 0 && dedent(stream, state))
88 } 93 style += " " + ERRORCLASS;
89 94 return style;
90 // Handle Number Literals 95 }
91 if (stream.match(/^[0-9\.]/, false)) { 96 }
92 var floatLiteral = false; 97 return tokenBaseInner(stream, state);
93 // Floats 98 }
94 if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; } 99
95 if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; } 100 function tokenBaseInner(stream, state) {
96 if (stream.match(/^\.\d+/)) { floatLiteral = true; } 101 if (stream.eatSpace()) return null;
97 if (floatLiteral) { 102
98 // Float literals may be "imaginary" 103 var ch = stream.peek();
99 stream.eat(/J/i); 104
100 return 'number'; 105 // Handle Comments
101 } 106 if (ch == "#") {
102 // Integers 107 stream.skipToEnd();
103 var intLiteral = false; 108 return "comment";
104 // Hex 109 }
105 if (stream.match(/^0x[0-9a-f]+/i)) { intLiteral = true; } 110
106 // Binary 111 // Handle Number Literals
107 if (stream.match(/^0b[01]+/i)) { intLiteral = true; } 112 if (stream.match(/^[0-9\.]/, false)) {
108 // Octal 113 var floatLiteral = false;
109 if (stream.match(/^0o[0-7]+/i)) { intLiteral = true; } 114 // Floats
110 // Decimal 115 if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
111 if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) { 116 if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
112 // Decimal literals may be "imaginary" 117 if (stream.match(/^\.\d+/)) { floatLiteral = true; }
113 stream.eat(/J/i); 118 if (floatLiteral) {
114 // TODO - Can you have imaginary longs? 119 // Float literals may be "imaginary"
115 intLiteral = true; 120 stream.eat(/J/i);
116 } 121 return "number";
117 // Zero by itself with no other piece of number. 122 }
118 if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; } 123 // Integers
119 if (intLiteral) { 124 var intLiteral = false;
120 // Integer literals may be "long" 125 // Hex
121 stream.eat(/L/i); 126 if (stream.match(/^0x[0-9a-f]+/i)) intLiteral = true;
122 return 'number'; 127 // Binary
123 } 128 if (stream.match(/^0b[01]+/i)) intLiteral = true;
124 } 129 // Octal
125 130 if (stream.match(/^0o[0-7]+/i)) intLiteral = true;
126 // Handle Strings 131 // Decimal
127 if (stream.match(stringPrefixes)) { 132 if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
128 state.tokenize = tokenStringFactory(stream.current()); 133 // Decimal literals may be "imaginary"
129 return state.tokenize(stream, state); 134 stream.eat(/J/i);
130 } 135 // TODO - Can you have imaginary longs?
131 136 intLiteral = true;
132 // Handle operators and Delimiters 137 }
133 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) { 138 // Zero by itself with no other piece of number.
134 return null; 139 if (stream.match(/^0(?![\dx])/i)) intLiteral = true;
135 } 140 if (intLiteral) {
136 if (stream.match(doubleOperators) 141 // Integer literals may be "long"
137 || stream.match(singleOperators) 142 stream.eat(/L/i);
138 || stream.match(wordOperators)) { 143 return "number";
139 return 'operator'; 144 }
140 } 145 }
141 if (stream.match(singleDelimiters)) { 146
142 return null; 147 // Handle Strings
143 } 148 if (stream.match(stringPrefixes)) {
144 149 state.tokenize = tokenStringFactory(stream.current());
145 if (stream.match(keywords)) { 150 return state.tokenize(stream, state);
146 return 'keyword'; 151 }
147 } 152
148 153 // Handle operators and Delimiters
149 if (stream.match(builtins)) { 154 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
150 return 'builtin'; 155 return null;
151 } 156
152 157 if (stream.match(doubleOperators)
153 if (stream.match(identifiers)) { 158 || stream.match(singleOperators)
154 if (state.lastToken == 'def' || state.lastToken == 'class') { 159 || stream.match(wordOperators))
155 return 'def'; 160 return "operator";
156 } 161
157 return 'variable'; 162 if (stream.match(singleDelimiters))
158 } 163 return null;
159 164
160 // Handle non-detected items 165 if (stream.match(keywords))
161 stream.next(); 166 return "keyword";
162 return ERRORCLASS; 167
168 if (stream.match(builtins))
169 return "builtin";
170
171 if (stream.match(/^(self|cls)\b/))
172 return "variable-2";
173
174 if (stream.match(identifiers)) {
175 if (state.lastToken == "def" || state.lastToken == "class")
176 return "def";
177 return "variable";
178 }
179
180 // Handle non-detected items
181 stream.next();
182 return ERRORCLASS;
163 } 183 }
164 184
165 function tokenStringFactory(delimiter) { 185 function tokenStringFactory(delimiter) {
166 while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) { 186 while ("rub".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
167 delimiter = delimiter.substr(1); 187 delimiter = delimiter.substr(1);
168 } 188
169 var singleline = delimiter.length == 1; 189 var singleline = delimiter.length == 1;
170 var OUTCLASS = 'string'; 190 var OUTCLASS = "string";
171 191
172 function tokenString(stream, state) { 192 function tokenString(stream, state) {
173 while (!stream.eol()) { 193 while (!stream.eol()) {
174 stream.eatWhile(/[^'"\\]/); 194 stream.eatWhile(/[^'"\\]/);
175 if (stream.eat('\\')) { 195 if (stream.eat("\\")) {
176 stream.next(); 196 stream.next();
177 if (singleline && stream.eol()) { 197 if (singleline && stream.eol())
178 return OUTCLASS; 198 return OUTCLASS;
179 } 199 } else if (stream.match(delimiter)) {
180 } else if (stream.match(delimiter)) { 200 state.tokenize = tokenBase;
181 state.tokenize = tokenBase;
182 return OUTCLASS;
183 } else {
184 stream.eat(/['"]/);
185 }
186 }
187 if (singleline) {
188 if (parserConf.singleLineStringErrors) {
189 return ERRORCLASS;
190 } else {
191 state.tokenize = tokenBase;
192 }
193 }
194 return OUTCLASS; 201 return OUTCLASS;
195 } 202 } else {
196 tokenString.isString = true; 203 stream.eat(/['"]/);
197 return tokenString; 204 }
198 } 205 }
199 206 if (singleline) {
200 function indent(stream, state, type) { 207 if (parserConf.singleLineStringErrors)
201 type = type || 'py'; 208 return ERRORCLASS;
202 var indentUnit = 0; 209 else
203 if (type === 'py') { 210 state.tokenize = tokenBase;
204 if (state.scopes[0].type !== 'py') { 211 }
205 state.scopes[0].offset = stream.indentation(); 212 return OUTCLASS;
206 return; 213 }
207 } 214 tokenString.isString = true;
208 for (var i = 0; i < state.scopes.length; ++i) { 215 return tokenString;
209 if (state.scopes[i].type === 'py') { 216 }
210 indentUnit = state.scopes[i].offset + conf.indentUnit; 217
211 break; 218 function pushScope(stream, state, type) {
212 } 219 var offset = 0, align = null;
213 } 220 if (type == "py") {
214 } else { 221 while (top(state).type != "py")
215 indentUnit = stream.column() + stream.current().length; 222 state.scopes.pop();
216 } 223 }
217 state.scopes.unshift({ 224 offset = top(state).offset + (type == "py" ? conf.indentUnit : hangingInde nt);
218 offset: indentUnit, 225 if (type != "py" && !stream.match(/^(\s|#.*)*$/, false))
219 type: type 226 align = stream.column() + 1;
220 }); 227 state.scopes.push({offset: offset, type: type, align: align});
221 } 228 }
222 229
223 function dedent(stream, state, type) { 230 function dedent(stream, state) {
224 type = type || 'py'; 231 var indented = stream.indentation();
225 if (state.scopes.length == 1) return; 232 while (top(state).offset > indented) {
226 if (state.scopes[0].type === 'py') { 233 if (top(state).type != "py") return true;
227 var _indent = stream.indentation(); 234 state.scopes.pop();
228 var _indent_index = -1; 235 }
229 for (var i = 0; i < state.scopes.length; ++i) { 236 return top(state).offset != indented;
230 if (_indent === state.scopes[i].offset) {
231 _indent_index = i;
232 break;
233 }
234 }
235 if (_indent_index === -1) {
236 return true;
237 }
238 while (state.scopes[0].offset !== _indent) {
239 state.scopes.shift();
240 }
241 return false;
242 } else {
243 if (type === 'py') {
244 state.scopes[0].offset = stream.indentation();
245 return false;
246 } else {
247 if (state.scopes[0].type != type) {
248 return true;
249 }
250 state.scopes.shift();
251 return false;
252 }
253 }
254 } 237 }
255 238
256 function tokenLexer(stream, state) { 239 function tokenLexer(stream, state) {
257 indentInfo = null; 240 var style = state.tokenize(stream, state);
258 var style = state.tokenize(stream, state); 241 var current = stream.current();
242
243 // Handle '.' connected identifiers
244 if (current == ".") {
245 style = stream.match(identifiers, false) ? null : ERRORCLASS;
246 if (style == null && state.lastStyle == "meta") {
247 // Apply 'meta' style to '.' connected identifiers when
248 // appropriate.
249 style = "meta";
250 }
251 return style;
252 }
253
254 // Handle decorators
255 if (current == "@")
256 return stream.match(identifiers, false) ? "meta" : ERRORCLASS;
257
258 if ((style == "variable" || style == "builtin")
259 && state.lastStyle == "meta")
260 style = "meta";
261
262 // Handle scope changes.
263 if (current == "pass" || current == "return")
264 state.dedent += 1;
265
266 if (current == "lambda") state.lambda = true;
267 if (current == ":" && !state.lambda && top(state).type == "py")
268 pushScope(stream, state, "py");
269
270 var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1;
271 if (delimiter_index != -1)
272 pushScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1) );
273
274 delimiter_index = "])}".indexOf(current);
275 if (delimiter_index != -1) {
276 if (top(state).type == current) state.scopes.pop();
277 else return ERRORCLASS;
278 }
279 if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
280 if (state.scopes.length > 1) state.scopes.pop();
281 state.dedent -= 1;
282 }
283
284 return style;
285 }
286
287 var external = {
288 startState: function(basecolumn) {
289 return {
290 tokenize: tokenBase,
291 scopes: [{offset: basecolumn || 0, type: "py", align: null}],
292 lastStyle: null,
293 lastToken: null,
294 lambda: false,
295 dedent: 0
296 };
297 },
298
299 token: function(stream, state) {
300 var addErr = state.errorToken;
301 if (addErr) state.errorToken = false;
302 var style = tokenLexer(stream, state);
303
304 state.lastStyle = style;
305
259 var current = stream.current(); 306 var current = stream.current();
260 307 if (current && style)
261 // Handle '.' connected identifiers 308 state.lastToken = current;
262 if (current === '.') { 309
263 style = stream.match(identifiers, false) ? null : ERRORCLASS; 310 if (stream.eol() && state.lambda)
264 if (style === null && state.lastStyle === 'meta') { 311 state.lambda = false;
265 // Apply 'meta' style to '.' connected identifiers when 312 return addErr ? style + " " + ERRORCLASS : style;
266 // appropriate. 313 },
267 style = 'meta'; 314
268 } 315 indent: function(state, textAfter) {
269 return style; 316 if (state.tokenize != tokenBase)
270 } 317 return state.tokenize.isString ? CodeMirror.Pass : 0;
271 318
272 // Handle decorators 319 var scope = top(state);
273 if (current === '@') { 320 var closing = textAfter && textAfter.charAt(0) == scope.type;
274 return stream.match(identifiers, false) ? 'meta' : ERRORCLASS; 321 if (scope.align != null)
275 } 322 return scope.align - (closing ? 1 : 0);
276 323 else if (closing && state.scopes.length > 1)
277 if ((style === 'variable' || style === 'builtin') 324 return state.scopes[state.scopes.length - 2].offset;
278 && state.lastStyle === 'meta') { 325 else
279 style = 'meta'; 326 return scope.offset;
280 } 327 },
281 328
282 // Handle scope changes. 329 lineComment: "#",
283 if (current === 'pass' || current === 'return') { 330 fold: "indent"
284 state.dedent += 1;
285 }
286 if (current === 'lambda') state.lambda = true;
287 if ((current === ':' && !state.lambda && state.scopes[0].type == 'py')
288 || indentInfo === 'indent') {
289 indent(stream, state);
290 }
291 var delimiter_index = '[({'.indexOf(current);
292 if (delimiter_index !== -1) {
293 indent(stream, state, '])}'.slice(delimiter_index, delimiter_index+1 ));
294 }
295 if (indentInfo === 'dedent') {
296 if (dedent(stream, state)) {
297 return ERRORCLASS;
298 }
299 }
300 delimiter_index = '])}'.indexOf(current);
301 if (delimiter_index !== -1) {
302 if (dedent(stream, state, current)) {
303 return ERRORCLASS;
304 }
305 }
306 if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'py') {
307 if (state.scopes.length > 1) state.scopes.shift();
308 state.dedent -= 1;
309 }
310
311 return style;
312 }
313
314 var external = {
315 startState: function(basecolumn) {
316 return {
317 tokenize: tokenBase,
318 scopes: [{offset:basecolumn || 0, type:'py'}],
319 lastStyle: null,
320 lastToken: null,
321 lambda: false,
322 dedent: 0
323 };
324 },
325
326 token: function(stream, state) {
327 var style = tokenLexer(stream, state);
328
329 state.lastStyle = style;
330
331 var current = stream.current();
332 if (current && style) {
333 state.lastToken = current;
334 }
335
336 if (stream.eol() && state.lambda) {
337 state.lambda = false;
338 }
339 return style;
340 },
341
342 indent: function(state) {
343 if (state.tokenize != tokenBase) {
344 return state.tokenize.isString ? CodeMirror.Pass : 0;
345 }
346
347 return state.scopes[0].offset;
348 },
349
350 lineComment: "#",
351 fold: "indent"
352 }; 331 };
353 return external; 332 return external;
354 }); 333 });
355 334
356 CodeMirror.defineMIME("text/x-python", "python"); 335 CodeMirror.defineMIME("text/x-python", "python");
357 336
358 (function() { 337 var words = function(str) { return str.split(" "); };
359 "use strict";
360 var words = function(str){return str.split(' ');};
361 338
362 CodeMirror.defineMIME("text/x-cython", { 339 CodeMirror.defineMIME("text/x-cython", {
363 name: "python", 340 name: "python",
364 extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+ 341 extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
365 "extern gil include nogil property public"+ 342 "extern gil include nogil property public"+
366 "readonly struct union DEF IF ELIF ELSE") 343 "readonly struct union DEF IF ELIF ELSE")
367 }); 344 });
368 })(); 345
346 });
OLDNEW
« no previous file with comments | « Source/devtools/front_end/cm/php.js ('k') | Source/devtools/front_end/cm/shell.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698