codemirror-rails 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. data/codemirror-rails-0.0.0.gem +0 -0
  2. data/codemirror-rails-0.1.gem +0 -0
  3. data/lib/codemirror/rails/version.rb +2 -2
  4. data/vendor/assets/javascripts/codemirror.js +122 -63
  5. data/vendor/assets/javascripts/codemirror/modes/clike.js +221 -0
  6. data/vendor/assets/javascripts/codemirror/modes/css.js +124 -0
  7. data/vendor/assets/javascripts/codemirror/modes/diff.js +13 -0
  8. data/vendor/assets/javascripts/codemirror/modes/haskell.js +242 -0
  9. data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +79 -0
  10. data/vendor/assets/javascripts/codemirror/modes/javascript.js +348 -0
  11. data/vendor/assets/javascripts/codemirror/modes/lua.js +138 -0
  12. data/vendor/assets/javascripts/codemirror/modes/php.js +111 -0
  13. data/vendor/assets/javascripts/codemirror/modes/plsql.js +217 -0
  14. data/vendor/assets/javascripts/codemirror/modes/python.js +321 -0
  15. data/vendor/assets/javascripts/codemirror/modes/rst.js +333 -0
  16. data/vendor/assets/javascripts/codemirror/modes/scheme.js +181 -0
  17. data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +122 -0
  18. data/vendor/assets/javascripts/codemirror/modes/stex.js +167 -0
  19. data/vendor/assets/javascripts/codemirror/modes/xml.js +227 -0
  20. data/vendor/assets/javascripts/codemirror/modes/yaml.js +95 -0
  21. data/vendor/assets/javascripts/codemirror/overlay.js +51 -0
  22. data/vendor/assets/javascripts/codemirror/runmode.js +27 -0
  23. data/vendor/assets/stylesheets/codemirror.css +3 -0
  24. data/vendor/assets/stylesheets/codemirror/modes/clike.css +7 -0
  25. data/vendor/assets/stylesheets/codemirror/modes/diff.css +3 -0
  26. data/vendor/assets/stylesheets/codemirror/modes/rst.css +75 -0
  27. metadata +25 -3
  28. data/codemirror-rails-0.1.1.gem +0 -0
@@ -0,0 +1,79 @@
1
+ CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
2
+ var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
3
+ var jsMode = CodeMirror.getMode(config, "javascript");
4
+ var cssMode = CodeMirror.getMode(config, "css");
5
+
6
+ function html(stream, state) {
7
+ var style = htmlMode.token(stream, state.htmlState);
8
+ if (style == "tag" && stream.current() == ">" && state.htmlState.context) {
9
+ if (/^script$/i.test(state.htmlState.context.tagName)) {
10
+ state.token = javascript;
11
+ state.localState = jsMode.startState(htmlMode.indent(state.htmlState, ""));
12
+ state.mode = "javascript";
13
+ }
14
+ else if (/^style$/i.test(state.htmlState.context.tagName)) {
15
+ state.token = css;
16
+ state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
17
+ state.mode = "css";
18
+ }
19
+ }
20
+ return style;
21
+ }
22
+ function maybeBackup(stream, pat, style) {
23
+ var cur = stream.current();
24
+ var close = cur.search(pat);
25
+ if (close > -1) stream.backUp(cur.length - close);
26
+ return style;
27
+ }
28
+ function javascript(stream, state) {
29
+ if (stream.match(/^<\/\s*script\s*>/i, false)) {
30
+ state.token = html;
31
+ state.curState = null;
32
+ state.mode = "html";
33
+ return html(stream, state);
34
+ }
35
+ return maybeBackup(stream, /<\/\s*script\s*>/,
36
+ jsMode.token(stream, state.localState));
37
+ }
38
+ function css(stream, state) {
39
+ if (stream.match(/^<\/\s*style\s*>/i, false)) {
40
+ state.token = html;
41
+ state.localState = null;
42
+ state.mode = "html";
43
+ return html(stream, state);
44
+ }
45
+ return maybeBackup(stream, /<\/\s*style\s*>/,
46
+ cssMode.token(stream, state.localState));
47
+ }
48
+
49
+ return {
50
+ startState: function() {
51
+ var state = htmlMode.startState();
52
+ return {token: html, localState: null, mode: "html", htmlState: state};
53
+ },
54
+
55
+ copyState: function(state) {
56
+ if (state.localState)
57
+ var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);
58
+ return {token: state.token, localState: local, mode: state.mode,
59
+ htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
60
+ },
61
+
62
+ token: function(stream, state) {
63
+ return state.token(stream, state);
64
+ },
65
+
66
+ indent: function(state, textAfter) {
67
+ if (state.token == html || /^\s*<\//.test(textAfter))
68
+ return htmlMode.indent(state.htmlState, textAfter);
69
+ else if (state.token == javascript)
70
+ return jsMode.indent(state.localState, textAfter);
71
+ else
72
+ return cssMode.indent(state.localState, textAfter);
73
+ },
74
+
75
+ electricChars: "/{}:"
76
+ }
77
+ });
78
+
79
+ CodeMirror.defineMIME("text/html", "htmlmixed");
@@ -0,0 +1,348 @@
1
+ CodeMirror.defineMode("javascript", function(config, parserConfig) {
2
+ var indentUnit = config.indentUnit;
3
+ var jsonMode = parserConfig.json;
4
+
5
+ // Tokenizer
6
+
7
+ var keywords = function(){
8
+ function kw(type) {return {type: type, style: "keyword"};}
9
+ var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
10
+ var operator = kw("operator"), atom = {type: "atom", style: "atom"};
11
+ return {
12
+ "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
13
+ "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
14
+ "var": kw("var"), "function": kw("function"), "catch": kw("catch"),
15
+ "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
16
+ "in": operator, "typeof": operator, "instanceof": operator,
17
+ "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
18
+ };
19
+ }();
20
+
21
+ var isOperatorChar = /[+\-*&%=<>!?|]/;
22
+
23
+ function chain(stream, state, f) {
24
+ state.tokenize = f;
25
+ return f(stream, state);
26
+ }
27
+
28
+ function nextUntilUnescaped(stream, end) {
29
+ var escaped = false, next;
30
+ while ((next = stream.next()) != null) {
31
+ if (next == end && !escaped)
32
+ return false;
33
+ escaped = !escaped && next == "\\";
34
+ }
35
+ return escaped;
36
+ }
37
+
38
+ // Used as scratch variables to communicate multiple values without
39
+ // consing up tons of objects.
40
+ var type, content;
41
+ function ret(tp, style, cont) {
42
+ type = tp; content = cont;
43
+ return style;
44
+ }
45
+
46
+ function jsTokenBase(stream, state) {
47
+ var ch = stream.next();
48
+ if (ch == '"' || ch == "'")
49
+ return chain(stream, state, jsTokenString(ch));
50
+ else if (/[\[\]{}\(\),;\:\.]/.test(ch))
51
+ return ret(ch);
52
+ else if (ch == "0" && stream.eat(/x/i)) {
53
+ stream.eatWhile(/[\da-f]/i);
54
+ return ret("number", "atom");
55
+ }
56
+ else if (/\d/.test(ch)) {
57
+ stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/);
58
+ return ret("number", "atom");
59
+ }
60
+ else if (ch == "/") {
61
+ if (stream.eat("*")) {
62
+ return chain(stream, state, jsTokenComment);
63
+ }
64
+ else if (stream.eat("/")) {
65
+ stream.skipToEnd();
66
+ return ret("comment", "comment");
67
+ }
68
+ else if (state.reAllowed) {
69
+ nextUntilUnescaped(stream, "/");
70
+ stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
71
+ return ret("regexp", "string");
72
+ }
73
+ else {
74
+ stream.eatWhile(isOperatorChar);
75
+ return ret("operator", null, stream.current());
76
+ }
77
+ }
78
+ else if (isOperatorChar.test(ch)) {
79
+ stream.eatWhile(isOperatorChar);
80
+ return ret("operator", null, stream.current());
81
+ }
82
+ else {
83
+ stream.eatWhile(/[\w\$_]/);
84
+ var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
85
+ return known ? ret(known.type, known.style, word) :
86
+ ret("variable", "variable", word);
87
+ }
88
+ }
89
+
90
+ function jsTokenString(quote) {
91
+ return function(stream, state) {
92
+ if (!nextUntilUnescaped(stream, quote))
93
+ state.tokenize = jsTokenBase;
94
+ return ret("string", "string");
95
+ };
96
+ }
97
+
98
+ function jsTokenComment(stream, state) {
99
+ var maybeEnd = false, ch;
100
+ while (ch = stream.next()) {
101
+ if (ch == "/" && maybeEnd) {
102
+ state.tokenize = jsTokenBase;
103
+ break;
104
+ }
105
+ maybeEnd = (ch == "*");
106
+ }
107
+ return ret("comment", "comment");
108
+ }
109
+
110
+ // Parser
111
+
112
+ var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
113
+
114
+ function JSLexical(indented, column, type, align, prev, info) {
115
+ this.indented = indented;
116
+ this.column = column;
117
+ this.type = type;
118
+ this.prev = prev;
119
+ this.info = info;
120
+ if (align != null) this.align = align;
121
+ }
122
+
123
+ function inScope(state, varname) {
124
+ for (var v = state.localVars; v; v = v.next)
125
+ if (v.name == varname) return true;
126
+ }
127
+
128
+ function parseJS(state, style, type, content, stream) {
129
+ var cc = state.cc;
130
+ // Communicate our context to the combinators.
131
+ // (Less wasteful than consing up a hundred closures on every call.)
132
+ cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
133
+
134
+ if (!state.lexical.hasOwnProperty("align"))
135
+ state.lexical.align = true;
136
+
137
+ while(true) {
138
+ var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
139
+ if (combinator(type, content)) {
140
+ while(cc.length && cc[cc.length - 1].lex)
141
+ cc.pop()();
142
+ if (cx.marked) return cx.marked;
143
+ if (type == "variable" && inScope(state, content)) return "variable-2";
144
+ return style;
145
+ }
146
+ }
147
+ }
148
+
149
+ // Combinator utils
150
+
151
+ var cx = {state: null, column: null, marked: null, cc: null};
152
+ function pass() {
153
+ for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
154
+ }
155
+ function cont() {
156
+ pass.apply(null, arguments);
157
+ return true;
158
+ }
159
+ function register(varname) {
160
+ var state = cx.state;
161
+ if (state.context) {
162
+ cx.marked = "def";
163
+ for (var v = state.localVars; v; v = v.next)
164
+ if (v.name == varname) return;
165
+ state.localVars = {name: varname, next: state.localVars};
166
+ }
167
+ }
168
+
169
+ // Combinators
170
+
171
+ var defaultVars = {name: "this", next: {name: "arguments"}};
172
+ function pushcontext() {
173
+ if (!cx.state.context) cx.state.localVars = defaultVars;
174
+ cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
175
+ }
176
+ function popcontext() {
177
+ cx.state.localVars = cx.state.context.vars;
178
+ cx.state.context = cx.state.context.prev;
179
+ }
180
+ function pushlex(type, info) {
181
+ var result = function() {
182
+ var state = cx.state;
183
+ state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info)
184
+ };
185
+ result.lex = true;
186
+ return result;
187
+ }
188
+ function poplex() {
189
+ var state = cx.state;
190
+ if (state.lexical.prev) {
191
+ if (state.lexical.type == ")")
192
+ state.indented = state.lexical.indented;
193
+ state.lexical = state.lexical.prev;
194
+ }
195
+ }
196
+ poplex.lex = true;
197
+
198
+ function expect(wanted) {
199
+ return function expecting(type) {
200
+ if (type == wanted) return cont();
201
+ else if (wanted == ";") return pass();
202
+ else return cont(arguments.callee);
203
+ };
204
+ }
205
+
206
+ function statement(type) {
207
+ if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
208
+ if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
209
+ if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
210
+ if (type == "{") return cont(pushlex("}"), block, poplex);
211
+ if (type == ";") return cont();
212
+ if (type == "function") return cont(functiondef);
213
+ if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
214
+ poplex, statement, poplex);
215
+ if (type == "variable") return cont(pushlex("stat"), maybelabel);
216
+ if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
217
+ block, poplex, poplex);
218
+ if (type == "case") return cont(expression, expect(":"));
219
+ if (type == "default") return cont(expect(":"));
220
+ if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
221
+ statement, poplex, popcontext);
222
+ return pass(pushlex("stat"), expression, expect(";"), poplex);
223
+ }
224
+ function expression(type) {
225
+ if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
226
+ if (type == "function") return cont(functiondef);
227
+ if (type == "keyword c") return cont(expression);
228
+ if (type == "(") return cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator);
229
+ if (type == "operator") return cont(expression);
230
+ if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
231
+ if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
232
+ return cont();
233
+ }
234
+ function maybeoperator(type, value) {
235
+ if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
236
+ if (type == "operator") return cont(expression);
237
+ if (type == ";") return;
238
+ if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
239
+ if (type == ".") return cont(property, maybeoperator);
240
+ if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
241
+ }
242
+ function maybelabel(type) {
243
+ if (type == ":") return cont(poplex, statement);
244
+ return pass(maybeoperator, expect(";"), poplex);
245
+ }
246
+ function property(type) {
247
+ if (type == "variable") {cx.marked = "property"; return cont();}
248
+ }
249
+ function objprop(type) {
250
+ if (type == "variable") cx.marked = "property";
251
+ if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
252
+ }
253
+ function commasep(what, end) {
254
+ function proceed(type) {
255
+ if (type == ",") return cont(what, proceed);
256
+ if (type == end) return cont();
257
+ return cont(expect(end));
258
+ }
259
+ return function commaSeparated(type) {
260
+ if (type == end) return cont();
261
+ else return pass(what, proceed);
262
+ };
263
+ }
264
+ function block(type) {
265
+ if (type == "}") return cont();
266
+ return pass(statement, block);
267
+ }
268
+ function vardef1(type, value) {
269
+ if (type == "variable"){register(value); return cont(vardef2);}
270
+ return cont();
271
+ }
272
+ function vardef2(type, value) {
273
+ if (value == "=") return cont(expression, vardef2);
274
+ if (type == ",") return cont(vardef1);
275
+ }
276
+ function forspec1(type) {
277
+ if (type == "var") return cont(vardef1, forspec2);
278
+ if (type == ";") return pass(forspec2);
279
+ if (type == "variable") return cont(formaybein);
280
+ return pass(forspec2);
281
+ }
282
+ function formaybein(type, value) {
283
+ if (value == "in") return cont(expression);
284
+ return cont(maybeoperator, forspec2);
285
+ }
286
+ function forspec2(type, value) {
287
+ if (type == ";") return cont(forspec3);
288
+ if (value == "in") return cont(expression);
289
+ return cont(expression, expect(";"), forspec3);
290
+ }
291
+ function forspec3(type) {
292
+ if (type != ")") cont(expression);
293
+ }
294
+ function functiondef(type, value) {
295
+ if (type == "variable") {register(value); return cont(functiondef);}
296
+ if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
297
+ }
298
+ function funarg(type, value) {
299
+ if (type == "variable") {register(value); return cont();}
300
+ }
301
+
302
+ // Interface
303
+
304
+ return {
305
+ startState: function(basecolumn) {
306
+ return {
307
+ tokenize: jsTokenBase,
308
+ reAllowed: true,
309
+ cc: [],
310
+ lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
311
+ localVars: null,
312
+ context: null,
313
+ indented: 0
314
+ };
315
+ },
316
+
317
+ token: function(stream, state) {
318
+ if (stream.sol()) {
319
+ if (!state.lexical.hasOwnProperty("align"))
320
+ state.lexical.align = false;
321
+ state.indented = stream.indentation();
322
+ }
323
+ if (stream.eatSpace()) return null;
324
+ var style = state.tokenize(stream, state);
325
+ if (type == "comment") return style;
326
+ state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/);
327
+ return parseJS(state, style, type, content, stream);
328
+ },
329
+
330
+ indent: function(state, textAfter) {
331
+ if (state.tokenize != jsTokenBase) return 0;
332
+ var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
333
+ type = lexical.type, closing = firstChar == type;
334
+ if (type == "vardef") return lexical.indented + 4;
335
+ else if (type == "form" && firstChar == "{") return lexical.indented;
336
+ else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
337
+ else if (lexical.info == "switch" && !closing)
338
+ return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
339
+ else if (lexical.align) return lexical.column + (closing ? 0 : 1);
340
+ else return lexical.indented + (closing ? 0 : indentUnit);
341
+ },
342
+
343
+ electricChars: ":{}"
344
+ };
345
+ });
346
+
347
+ CodeMirror.defineMIME("text/javascript", "javascript");
348
+ CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
@@ -0,0 +1,138 @@
1
+ // LUA mode. Ported to CodeMirror 2 from Franciszek Wawrzak's
2
+ // CodeMirror 1 mode.
3
+ // highlights keywords, strings, comments (no leveling supported! ("[==[")), tokens, basic indenting
4
+
5
+ CodeMirror.defineMode("lua", function(config, parserConfig) {
6
+ var indentUnit = config.indentUnit;
7
+
8
+ function prefixRE(words) {
9
+ return new RegExp("^(?:" + words.join("|") + ")", "i");
10
+ }
11
+ function wordRE(words) {
12
+ return new RegExp("^(?:" + words.join("|") + ")$", "i");
13
+ }
14
+ var specials = wordRE(parserConfig.specials || []);
15
+
16
+ // long list of standard functions from lua manual
17
+ var builtins = wordRE([
18
+ "_G","_VERSION","assert","collectgarbage","dofile","error","getfenv","getmetatable","ipairs","load",
19
+ "loadfile","loadstring","module","next","pairs","pcall","print","rawequal","rawget","rawset","require",
20
+ "select","setfenv","setmetatable","tonumber","tostring","type","unpack","xpcall",
21
+
22
+ "coroutine.create","coroutine.resume","coroutine.running","coroutine.status","coroutine.wrap","coroutine.yield",
23
+
24
+ "debug.debug","debug.getfenv","debug.gethook","debug.getinfo","debug.getlocal","debug.getmetatable",
25
+ "debug.getregistry","debug.getupvalue","debug.setfenv","debug.sethook","debug.setlocal","debug.setmetatable",
26
+ "debug.setupvalue","debug.traceback",
27
+
28
+ "close","flush","lines","read","seek","setvbuf","write",
29
+
30
+ "io.close","io.flush","io.input","io.lines","io.open","io.output","io.popen","io.read","io.stderr","io.stdin",
31
+ "io.stdout","io.tmpfile","io.type","io.write",
32
+
33
+ "math.abs","math.acos","math.asin","math.atan","math.atan2","math.ceil","math.cos","math.cosh","math.deg",
34
+ "math.exp","math.floor","math.fmod","math.frexp","math.huge","math.ldexp","math.log","math.log10","math.max",
35
+ "math.min","math.modf","math.pi","math.pow","math.rad","math.random","math.randomseed","math.sin","math.sinh",
36
+ "math.sqrt","math.tan","math.tanh",
37
+
38
+ "os.clock","os.date","os.difftime","os.execute","os.exit","os.getenv","os.remove","os.rename","os.setlocale",
39
+ "os.time","os.tmpname",
40
+
41
+ "package.cpath","package.loaded","package.loaders","package.loadlib","package.path","package.preload",
42
+ "package.seeall",
43
+
44
+ "string.byte","string.char","string.dump","string.find","string.format","string.gmatch","string.gsub",
45
+ "string.len","string.lower","string.match","string.rep","string.reverse","string.sub","string.upper",
46
+
47
+ "table.concat","table.insert","table.maxn","table.remove","table.sort"
48
+ ]);
49
+ var keywords = wordRE(["and","break","elseif","false","nil","not","or","return",
50
+ "true","function", "end", "if", "then", "else", "do",
51
+ "while", "repeat", "until", "for", "in", "local" ]);
52
+
53
+ var indentTokens = wordRE(["function", "if","repeat","for","while", "\\(", "{"]);
54
+ var dedentTokens = wordRE(["end", "until", "\\)", "}"]);
55
+ var dedentPartial = prefixRE(["end", "until", "\\)", "}", "else", "elseif"]);
56
+
57
+ function readBracket(stream) {
58
+ var level = 0;
59
+ while (stream.eat("=")) ++level;
60
+ stream.eat("[");
61
+ return level;
62
+ }
63
+
64
+ function normal(stream, state) {
65
+ var ch = stream.next();
66
+ if (ch == "-" && stream.eat("-")) {
67
+ if (stream.eat("["))
68
+ return (state.cur = bracketed(readBracket(stream), "comment"))(stream, state);
69
+ stream.skipToEnd();
70
+ return "comment";
71
+ }
72
+ if (ch == "\"" || ch == "'")
73
+ return (state.cur = string(ch))(stream, state);
74
+ if (ch == "[" && /[\[=]/.test(stream.peek()))
75
+ return (state.cur = bracketed(readBracket(stream), "string"))(stream, state);
76
+ if (/\d/.test(ch)) {
77
+ stream.eatWhile(/[\w.%]/);
78
+ return "number";
79
+ }
80
+ if (/[\w_]/.test(ch)) {
81
+ stream.eatWhile(/[\w\\\-_.]/);
82
+ return "variable";
83
+ }
84
+ return null;
85
+ }
86
+
87
+ function bracketed(level, style) {
88
+ return function(stream, state) {
89
+ var curlev = null, ch;
90
+ while ((ch = stream.next()) != null) {
91
+ if (curlev == null) {if (ch == "]") curlev = 0;}
92
+ else if (ch == "=") ++curlev;
93
+ else if (ch == "]" && curlev == level) { state.cur = normal; break; }
94
+ else curlev = null;
95
+ }
96
+ return style;
97
+ };
98
+ }
99
+
100
+ function string(quote) {
101
+ return function(stream, state) {
102
+ var escaped = false, ch;
103
+ while ((ch = stream.next()) != null) {
104
+ if (ch == quote && !escaped) break;
105
+ escaped = !escaped && ch == "\\";
106
+ }
107
+ if (!escaped) state.cur = normal;
108
+ return "string";
109
+ };
110
+ }
111
+
112
+ return {
113
+ startState: function(basecol) {
114
+ return {basecol: basecol || 0, indentDepth: 0, cur: normal};
115
+ },
116
+
117
+ token: function(stream, state) {
118
+ if (stream.eatSpace()) return null;
119
+ var style = state.cur(stream, state);
120
+ var word = stream.current();
121
+ if (style == "variable") {
122
+ if (keywords.test(word)) style = "keyword";
123
+ else if (builtins.test(word)) style = "builtin";
124
+ else if (specials.test(word)) style = "variable-2";
125
+ }
126
+ if (indentTokens.test(word)) ++state.indentDepth;
127
+ else if (dedentTokens.test(word)) --state.indentDepth;
128
+ return style;
129
+ },
130
+
131
+ indent: function(state, textAfter) {
132
+ var closing = dedentPartial.test(textAfter);
133
+ return state.basecol + indentUnit * (state.indentDepth - (closing ? 1 : 0));
134
+ }
135
+ };
136
+ });
137
+
138
+ CodeMirror.defineMIME("text/x-lua", "lua");