codemirror-rails 2.2.1 → 2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/README.md +8 -0
  2. data/codemirror-rails.gemspec +1 -1
  3. data/lib/codemirror/rails/version.rb +2 -2
  4. data/vendor/assets/javascripts/codemirror.js +842 -422
  5. data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +2 -2
  6. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +722 -32
  7. data/vendor/assets/javascripts/codemirror/modes/clike.js +31 -9
  8. data/vendor/assets/javascripts/codemirror/modes/clojure.js +14 -14
  9. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +59 -37
  10. data/vendor/assets/javascripts/codemirror/modes/css.js +1 -1
  11. data/vendor/assets/javascripts/codemirror/modes/diff.js +24 -5
  12. data/vendor/assets/javascripts/codemirror/modes/ecl.js +203 -0
  13. data/vendor/assets/javascripts/codemirror/modes/erlang.js +251 -0
  14. data/vendor/assets/javascripts/codemirror/modes/gfm.js +40 -4
  15. data/vendor/assets/javascripts/codemirror/modes/go.js +170 -0
  16. data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +1 -1
  17. data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +4 -2
  18. data/vendor/assets/javascripts/codemirror/modes/javascript.js +10 -9
  19. data/vendor/assets/javascripts/codemirror/modes/less.js +232 -0
  20. data/vendor/assets/javascripts/codemirror/modes/markdown.js +52 -49
  21. data/vendor/assets/javascripts/codemirror/modes/mysql.js +188 -0
  22. data/vendor/assets/javascripts/codemirror/modes/pascal.js +2 -46
  23. data/vendor/assets/javascripts/codemirror/modes/perl.js +1 -1
  24. data/vendor/assets/javascripts/codemirror/modes/php.js +55 -25
  25. data/vendor/assets/javascripts/codemirror/modes/pig.js +172 -0
  26. data/vendor/assets/javascripts/codemirror/modes/properties.js +63 -0
  27. data/vendor/assets/javascripts/codemirror/modes/python.js +37 -32
  28. data/vendor/assets/javascripts/codemirror/modes/rpm-spec.js +1 -1
  29. data/vendor/assets/javascripts/codemirror/modes/rst.js +1 -1
  30. data/vendor/assets/javascripts/codemirror/modes/ruby.js +14 -14
  31. data/vendor/assets/javascripts/codemirror/modes/rust.js +36 -15
  32. data/vendor/assets/javascripts/codemirror/modes/scheme.js +74 -46
  33. data/vendor/assets/javascripts/codemirror/modes/shell.js +103 -0
  34. data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +16 -16
  35. data/vendor/assets/javascripts/codemirror/modes/smarty.js +148 -0
  36. data/vendor/assets/javascripts/codemirror/modes/stex.js +21 -6
  37. data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +55 -45
  38. data/vendor/assets/javascripts/codemirror/modes/tiki.js +316 -0
  39. data/vendor/assets/javascripts/codemirror/modes/vbscript.js +26 -0
  40. data/vendor/assets/javascripts/codemirror/modes/verilog.js +194 -0
  41. data/vendor/assets/javascripts/codemirror/modes/xml.js +89 -16
  42. data/vendor/assets/javascripts/codemirror/modes/xmlpure.js +5 -0
  43. data/vendor/assets/javascripts/codemirror/modes/xquery.js +448 -0
  44. data/vendor/assets/javascripts/codemirror/utils/closetag.js +146 -0
  45. data/vendor/assets/javascripts/codemirror/utils/dialog.js +63 -0
  46. data/vendor/assets/javascripts/codemirror/utils/foldcode.js +196 -0
  47. data/vendor/assets/javascripts/codemirror/utils/formatting.js +297 -0
  48. data/vendor/assets/javascripts/codemirror/utils/javascript-hint.js +134 -0
  49. data/vendor/assets/javascripts/codemirror/utils/loadmode.js +51 -0
  50. data/vendor/assets/javascripts/codemirror/utils/match-highlighter.js +44 -0
  51. data/vendor/assets/javascripts/codemirror/utils/multiplex.js +72 -0
  52. data/vendor/assets/javascripts/codemirror/{overlay.js → utils/overlay.js} +3 -2
  53. data/vendor/assets/javascripts/codemirror/utils/pig-hint.js +123 -0
  54. data/vendor/assets/javascripts/codemirror/utils/runmode.js +49 -0
  55. data/vendor/assets/javascripts/codemirror/utils/search.js +118 -0
  56. data/vendor/assets/javascripts/codemirror/utils/searchcursor.js +117 -0
  57. data/vendor/assets/javascripts/codemirror/utils/simple-hint.js +72 -0
  58. data/vendor/assets/stylesheets/codemirror.css +69 -5
  59. data/vendor/assets/stylesheets/codemirror/modes/tiddlywiki.css +14 -21
  60. data/vendor/assets/stylesheets/codemirror/modes/tiki.css +26 -0
  61. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +81 -0
  62. data/vendor/assets/stylesheets/codemirror/themes/blackboard.css +25 -0
  63. data/vendor/assets/stylesheets/codemirror/themes/cobalt.css +1 -1
  64. data/vendor/assets/stylesheets/codemirror/themes/eclipse.css +1 -1
  65. data/vendor/assets/stylesheets/codemirror/themes/elegant.css +2 -2
  66. data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +21 -0
  67. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +44 -0
  68. data/vendor/assets/stylesheets/codemirror/themes/monokai.css +1 -1
  69. data/vendor/assets/stylesheets/codemirror/themes/neat.css +3 -3
  70. data/vendor/assets/stylesheets/codemirror/themes/night.css +1 -1
  71. data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +2 -2
  72. data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +27 -0
  73. data/vendor/assets/stylesheets/codemirror/themes/xq-dark.css +46 -0
  74. data/vendor/assets/stylesheets/codemirror/utils/dialog.css +23 -0
  75. data/vendor/assets/stylesheets/codemirror/utils/simple-hint.css +16 -0
  76. metadata +41 -10
  77. data/vendor/assets/javascripts/codemirror/runmode.js +0 -27
  78. data/vendor/assets/stylesheets/codemirror/modes/clike.css +0 -7
  79. data/vendor/assets/stylesheets/codemirror/modes/markdown.css +0 -10
  80. data/vendor/assets/stylesheets/codemirror/modes/rst.css +0 -75
  81. data/vendor/assets/stylesheets/codemirror/themes/default.css +0 -19
@@ -0,0 +1,63 @@
1
+ CodeMirror.defineMode("properties", function() {
2
+ return {
3
+ token: function(stream, state) {
4
+ var sol = stream.sol() || state.afterSection;
5
+ var eol = stream.eol();
6
+
7
+ state.afterSection = false;
8
+
9
+ if (sol) {
10
+ if (state.nextMultiline) {
11
+ state.inMultiline = true;
12
+ state.nextMultiline = false;
13
+ } else {
14
+ state.position = "def";
15
+ }
16
+ }
17
+
18
+ if (eol && ! state.nextMultiline) {
19
+ state.inMultiline = false;
20
+ state.position = "def";
21
+ }
22
+
23
+ if (sol) {
24
+ while(stream.eatSpace());
25
+ }
26
+
27
+ var ch = stream.next();
28
+
29
+ if (sol && (ch === "#" || ch === "!" || ch === ";")) {
30
+ state.position = "comment";
31
+ stream.skipToEnd();
32
+ return "comment";
33
+ } else if (sol && ch === "[") {
34
+ state.afterSection = true;
35
+ stream.skipTo("]"); stream.eat("]");
36
+ return "header";
37
+ } else if (ch === "=" || ch === ":") {
38
+ state.position = "quote";
39
+ return null;
40
+ } else if (ch === "\\" && state.position === "quote") {
41
+ if (stream.next() !== "u") { // u = Unicode sequence \u1234
42
+ // Multiline value
43
+ state.nextMultiline = true;
44
+ }
45
+ }
46
+
47
+ return state.position;
48
+ },
49
+
50
+ startState: function() {
51
+ return {
52
+ position : "def", // Current position, "def", "quote" or "comment"
53
+ nextMultiline : false, // Is the next line multiline value
54
+ inMultiline : false, // Is the current line a multiline value
55
+ afterSection : false // Did we just open a section
56
+ };
57
+ }
58
+
59
+ };
60
+ });
61
+
62
+ CodeMirror.defineMIME("text/x-properties", "properties");
63
+ CodeMirror.defineMIME("text/x-ini", "properties");
@@ -18,28 +18,35 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
18
18
  'for', 'from', 'global', 'if', 'import',
19
19
  'lambda', 'pass', 'raise', 'return',
20
20
  'try', 'while', 'with', 'yield'];
21
- var commontypes = ['bool', 'classmethod', 'complex', 'dict', 'enumerate',
22
- 'float', 'frozenset', 'int', 'list', 'object',
23
- 'property', 'reversed', 'set', 'slice', 'staticmethod',
24
- 'str', 'super', 'tuple', 'type'];
25
- var py2 = {'types': ['basestring', 'buffer', 'file', 'long', 'unicode',
26
- 'xrange'],
21
+ var commonBuiltins = ['abs', 'all', 'any', 'bin', 'bool', 'bytearray', 'callable', 'chr',
22
+ 'classmethod', 'compile', 'complex', 'delattr', 'dict', 'dir', 'divmod',
23
+ 'enumerate', 'eval', 'filter', 'float', 'format', 'frozenset',
24
+ 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id',
25
+ 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len',
26
+ 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next',
27
+ 'object', 'oct', 'open', 'ord', 'pow', 'property', 'range',
28
+ 'repr', 'reversed', 'round', 'set', 'setattr', 'slice',
29
+ 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple',
30
+ 'type', 'vars', 'zip', '__import__', 'NotImplemented',
31
+ 'Ellipsis', '__debug__'];
32
+ var py2 = {'builtins': ['apply', 'basestring', 'buffer', 'cmp', 'coerce', 'execfile',
33
+ 'file', 'intern', 'long', 'raw_input', 'reduce', 'reload',
34
+ 'unichr', 'unicode', 'xrange', 'False', 'True', 'None'],
27
35
  'keywords': ['exec', 'print']};
28
- var py3 = {'types': ['bytearray', 'bytes', 'filter', 'map', 'memoryview',
29
- 'open', 'range', 'zip'],
30
- 'keywords': ['nonlocal']};
36
+ var py3 = {'builtins': ['ascii', 'bytes', 'exec', 'print'],
37
+ 'keywords': ['nonlocal', 'False', 'True', 'None']};
31
38
 
32
39
  if (!!parserConf.version && parseInt(parserConf.version, 10) === 3) {
33
40
  commonkeywords = commonkeywords.concat(py3.keywords);
34
- commontypes = commontypes.concat(py3.types);
41
+ commonBuiltins = commonBuiltins.concat(py3.builtins);
35
42
  var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i");
36
43
  } else {
37
44
  commonkeywords = commonkeywords.concat(py2.keywords);
38
- commontypes = commontypes.concat(py2.types);
45
+ commonBuiltins = commonBuiltins.concat(py2.builtins);
39
46
  var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
40
47
  }
41
48
  var keywords = wordRegexp(commonkeywords);
42
- var types = wordRegexp(commontypes);
49
+ var builtins = wordRegexp(commonBuiltins);
43
50
 
44
51
  var indentInfo = null;
45
52
 
@@ -129,14 +136,14 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
129
136
  return null;
130
137
  }
131
138
 
132
- if (stream.match(types)) {
133
- return 'builtin';
134
- }
135
-
136
139
  if (stream.match(keywords)) {
137
140
  return 'keyword';
138
141
  }
139
142
 
143
+ if (stream.match(builtins)) {
144
+ return 'builtin';
145
+ }
146
+
140
147
  if (stream.match(identifiers)) {
141
148
  return 'variable';
142
149
  }
@@ -242,32 +249,30 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
242
249
 
243
250
  // Handle '.' connected identifiers
244
251
  if (current === '.') {
245
- style = state.tokenize(stream, state);
246
- current = stream.current();
247
- if (style === 'variable') {
248
- return 'variable';
249
- } else {
250
- return ERRORCLASS;
252
+ style = stream.match(identifiers, false) ? null : ERRORCLASS;
253
+ if (style === null && state.lastToken === 'meta') {
254
+ // Apply 'meta' style to '.' connected identifiers when
255
+ // appropriate.
256
+ style = 'meta';
251
257
  }
258
+ return style;
252
259
  }
253
260
 
254
261
  // Handle decorators
255
262
  if (current === '@') {
256
- style = state.tokenize(stream, state);
257
- current = stream.current();
258
- if (style === 'variable'
259
- || current === '@staticmethod'
260
- || current === '@classmethod') {
261
- return 'meta';
262
- } else {
263
- return ERRORCLASS;
264
- }
263
+ return stream.match(identifiers, false) ? 'meta' : ERRORCLASS;
264
+ }
265
+
266
+ if ((style === 'variable' || style === 'builtin')
267
+ && state.lastToken === 'meta') {
268
+ style = 'meta';
265
269
  }
266
270
 
267
271
  // Handle scope changes.
268
272
  if (current === 'pass' || current === 'return') {
269
273
  state.dedent += 1;
270
274
  }
275
+ if (current === 'lambda') state.lambda = true;
271
276
  if ((current === ':' && !state.lambda && state.scopes[0].type == 'py')
272
277
  || indentInfo === 'indent') {
273
278
  indent(stream, state);
@@ -309,7 +314,7 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
309
314
  token: function(stream, state) {
310
315
  var style = tokenLexer(stream, state);
311
316
 
312
- state.lastToken = {style:style, content: stream.current()};
317
+ state.lastToken = style;
313
318
 
314
319
  if (stream.eol() && stream.lambda) {
315
320
  state.lambda = false;
@@ -14,7 +14,7 @@ CodeMirror.defineMode("spec", function(config, modeConfig) {
14
14
  return {
15
15
  controlFlow: false,
16
16
  macroParameters: false,
17
- section: false,
17
+ section: false
18
18
  };
19
19
  },
20
20
  token: function (stream, state) {
@@ -321,6 +321,6 @@ CodeMirror.defineMode('rst', function(config, options) {
321
321
  return token;
322
322
  }
323
323
  };
324
- });
324
+ }, "python");
325
325
 
326
326
  CodeMirror.defineMIME("text/x-rst", "rst");
@@ -13,7 +13,7 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
13
13
  "require_relative", "extend", "autoload"
14
14
  ]);
15
15
  var indentWords = wordObj(["def", "class", "case", "for", "while", "do", "module", "then",
16
- "unless", "catch", "loop", "proc"]);
16
+ "catch", "loop", "proc", "begin"]);
17
17
  var dedentWords = wordObj(["end", "until"]);
18
18
  var matching = {"[": "]", "{": "}", "(": ")"};
19
19
  var curPunc;
@@ -30,9 +30,10 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
30
30
  return "comment";
31
31
  }
32
32
  if (stream.eatSpace()) return null;
33
- var ch = stream.next();
34
- if (ch == "`" || ch == "'" || ch == '"' || ch == "/") {
35
- return chain(readQuoted(ch, "string", ch == '"'), stream, state);
33
+ var ch = stream.next(), m;
34
+ if (ch == "`" || ch == "'" || ch == '"' ||
35
+ (ch == "/" && !stream.eol() && stream.peek() != " ")) {
36
+ return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
36
37
  } else if (ch == "%") {
37
38
  var style, embed = false;
38
39
  if (stream.eat("s")) style = "atom";
@@ -45,13 +46,8 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
45
46
  } else if (ch == "#") {
46
47
  stream.skipToEnd();
47
48
  return "comment";
48
- } else if (ch == "<" && stream.eat("<")) {
49
- stream.eat("-");
50
- stream.eat(/[\'\"\`]/);
51
- var match = stream.match(/^\w+/);
52
- stream.eat(/[\'\"\`]/);
53
- if (match) return chain(readHereDoc(match[0]), stream, state);
54
- return null;
49
+ } else if (ch == "<" && (m = stream.match(/^<-?[\`\"\']?([a-zA-Z_?]\w*)[\`\"\']?(?:;|$)/))) {
50
+ return chain(readHereDoc(m[1]), stream, state);
55
51
  } else if (ch == "0") {
56
52
  if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/);
57
53
  else if (stream.eat("b")) stream.eatWhile(/[01]/);
@@ -165,7 +161,8 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
165
161
  : "variable";
166
162
  if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
167
163
  else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
168
- else if (word == "if" && stream.column() == stream.indentation()) kwtype = "indent";
164
+ else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
165
+ kwtype = "indent";
169
166
  }
170
167
  if (curPunc || (style && style != "comment")) state.lastTok = word || curPunc || style;
171
168
  if (curPunc == "|") state.varList = !state.varList;
@@ -185,11 +182,14 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
185
182
  var firstChar = textAfter && textAfter.charAt(0);
186
183
  var ct = state.context;
187
184
  var closing = ct.type == matching[firstChar] ||
188
- ct.type == "keyword" && /^(?:end|until|else|elsif|when)\b/.test(textAfter);
185
+ ct.type == "keyword" && /^(?:end|until|else|elsif|when|rescue)\b/.test(textAfter);
189
186
  return ct.indented + (closing ? 0 : config.indentUnit) +
190
187
  (state.continuedLine ? config.indentUnit : 0);
191
- }
188
+ },
189
+ electricChars: "}de" // enD and rescuE
190
+
192
191
  };
193
192
  });
194
193
 
195
194
  CodeMirror.defineMIME("text/x-ruby", "ruby");
195
+
@@ -4,12 +4,12 @@ CodeMirror.defineMode("rust", function() {
4
4
  "if": "if-style", "while": "if-style", "else": "else-style",
5
5
  "do": "else-style", "ret": "else-style", "fail": "else-style",
6
6
  "break": "atom", "cont": "atom", "const": "let", "resource": "fn",
7
- "let": "let", "fn": "fn", "for": "for", "alt": "alt", "obj": "fn",
8
- "lambda": "fn", "type": "type", "tag": "tag", "mod": "mod",
7
+ "let": "let", "fn": "fn", "for": "for", "alt": "alt", "iface": "iface",
8
+ "impl": "impl", "type": "type", "enum": "enum", "mod": "mod",
9
9
  "as": "op", "true": "atom", "false": "atom", "assert": "op", "check": "op",
10
10
  "claim": "op", "native": "ignore", "unsafe": "ignore", "import": "else-style",
11
11
  "export": "else-style", "copy": "op", "log": "op", "log_err": "op",
12
- "use": "op", "bind": "op"
12
+ "use": "op", "bind": "op", "self": "atom"
13
13
  };
14
14
  var typeKeywords = function() {
15
15
  var keywords = {"fn": "fn", "block": "fn", "obj": "obj"};
@@ -169,13 +169,18 @@ CodeMirror.defineMode("rust", function() {
169
169
  };
170
170
  }
171
171
 
172
+ function stat_of(comb, tag) {
173
+ return cont(pushlex("stat", tag), comb, poplex, block);
174
+ }
172
175
  function block(type) {
173
176
  if (type == "}") return cont();
174
- if (type == "let") return cont(pushlex("stat", "let"), letdef1, poplex, block);
175
- if (type == "fn") return cont(pushlex("stat"), fndef, poplex, block);
177
+ if (type == "let") return stat_of(letdef1, "let");
178
+ if (type == "fn") return stat_of(fndef);
176
179
  if (type == "type") return cont(pushlex("stat"), tydef, endstatement, poplex, block);
177
- if (type == "tag") return cont(pushlex("stat"), tagdef, poplex, block);
178
- if (type == "mod") return cont(pushlex("stat"), mod, poplex, block);
180
+ if (type == "enum") return stat_of(enumdef);
181
+ if (type == "mod") return stat_of(mod);
182
+ if (type == "iface") return stat_of(iface);
183
+ if (type == "impl") return stat_of(impl);
179
184
  if (type == "open-attr") return cont(pushlex("]"), commasep(expression, "]"), poplex);
180
185
  if (type == "ignore" || type.match(/[\]\);,]/)) return cont(block);
181
186
  return pass(pushlex("stat"), expression, poplex, endstatement, block);
@@ -253,11 +258,13 @@ CodeMirror.defineMode("rust", function() {
253
258
  return pass();
254
259
  }
255
260
  function fndef(type) {
261
+ if (content == "@" || content == "~") {cx.marked = "keyword"; return cont(fndef);}
256
262
  if (type == "name") {cx.marked = "def"; return cont(fndef);}
257
263
  if (content == "<") return cont(typarams, fndef);
258
264
  if (type == "{") return pass(expression);
259
265
  if (type == "(") return cont(pushlex(")"), commasep(argdef, ")"), poplex, fndef);
260
266
  if (type == "->") return cont(typecx, rtype, valcx, fndef);
267
+ if (type == ";") return cont();
261
268
  return cont(fndef);
262
269
  }
263
270
  function tydef(type) {
@@ -266,27 +273,41 @@ CodeMirror.defineMode("rust", function() {
266
273
  if (content == "=") return cont(typecx, rtype, valcx);
267
274
  return cont(tydef);
268
275
  }
269
- function tagdef(type) {
270
- if (type == "name") {cx.marked = "def"; return cont(tagdef);}
271
- if (content == "<") return cont(typarams, tagdef);
276
+ function enumdef(type) {
277
+ if (type == "name") {cx.marked = "def"; return cont(enumdef);}
278
+ if (content == "<") return cont(typarams, enumdef);
272
279
  if (content == "=") return cont(typecx, rtype, valcx, endstatement);
273
- if (type == "{") return cont(pushlex("}"), typecx, tagblock, valcx, poplex);
274
- return cont(tagdef);
280
+ if (type == "{") return cont(pushlex("}"), typecx, enumblock, valcx, poplex);
281
+ return cont(enumdef);
275
282
  }
276
- function tagblock(type) {
283
+ function enumblock(type) {
277
284
  if (type == "}") return cont();
278
- if (type == "(") return cont(pushlex(")"), commasep(rtype, ")"), poplex, tagblock);
285
+ if (type == "(") return cont(pushlex(")"), commasep(rtype, ")"), poplex, enumblock);
279
286
  if (content.match(/^\w+$/)) cx.marked = "def";
280
- return cont(tagblock);
287
+ return cont(enumblock);
281
288
  }
282
289
  function mod(type) {
283
290
  if (type == "name") {cx.marked = "def"; return cont(mod);}
284
291
  if (type == "{") return cont(pushlex("}"), block, poplex);
285
292
  return pass();
286
293
  }
294
+ function iface(type) {
295
+ if (type == "name") {cx.marked = "def"; return cont(iface);}
296
+ if (content == "<") return cont(typarams, iface);
297
+ if (type == "{") return cont(pushlex("}"), block, poplex);
298
+ return pass();
299
+ }
300
+ function impl(type) {
301
+ if (content == "<") return cont(typarams, impl);
302
+ if (content == "of" || content == "for") {cx.marked = "keyword"; return cont(rtype, impl);}
303
+ if (type == "name") {cx.marked = "def"; return cont(impl);}
304
+ if (type == "{") return cont(pushlex("}"), block, poplex);
305
+ return pass();
306
+ }
287
307
  function typarams(type) {
288
308
  if (content == ">") return cont();
289
309
  if (content == ",") return cont(typarams);
310
+ if (content == ":") return cont(rtype, typarams);
290
311
  return pass(rtype, typarams);
291
312
  }
292
313
  function argdef(type) {
@@ -5,7 +5,7 @@ CodeMirror.defineMode("scheme", function (config, mode) {
5
5
  var BUILTIN = "builtin", COMMENT = "comment", STRING = "string",
6
6
  ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD="keyword";
7
7
  var INDENT_WORD_SKIP = 2, KEYWORDS_SKIP = 1;
8
-
8
+
9
9
  function makeKeywords(str) {
10
10
  var obj = {}, words = str.split(" ");
11
11
  for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
@@ -14,7 +14,6 @@ CodeMirror.defineMode("scheme", function (config, mode) {
14
14
 
15
15
  var keywords = makeKeywords("λ case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci<? char-ci=? char-ci>=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char<? char=? char>=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt #f floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci<? string-ci=? string-ci>=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string<? string=? string>=? string>? string? substring symbol->string symbol? #t tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?");
16
16
  var indentKeys = makeKeywords("define let letrec let* lambda");
17
-
18
17
 
19
18
  function stateStack(indent, type, prev) { // represents a state stack object
20
19
  this.indent = indent;
@@ -29,21 +28,29 @@ CodeMirror.defineMode("scheme", function (config, mode) {
29
28
  function popStack(state) {
30
29
  state.indentStack = state.indentStack.prev;
31
30
  }
32
-
33
- /**
34
- * Scheme numbers are complicated unfortunately.
35
- * Checks if we're looking at a number, which might be possibly a fraction.
36
- * Also checks that it is not part of a longer identifier. Returns true/false accordingly.
37
- */
38
- function isNumber(ch, stream){
39
- if(/[0-9]/.exec(ch) != null){
40
- stream.eatWhile(/[0-9]/);
41
- stream.eat(/\//);
42
- stream.eatWhile(/[0-9]/);
43
- if (stream.eol() || !(/[a-zA-Z\-\_\/]/.exec(stream.peek()))) return true;
44
- stream.backUp(stream.current().length - 1); // undo all the eating
31
+
32
+ var binaryMatcher = new RegExp(/^(?:[-+]i|[-+][01]+#*(?:\/[01]+#*)?i|[-+]?[01]+#*(?:\/[01]+#*)?@[-+]?[01]+#*(?:\/[01]+#*)?|[-+]?[01]+#*(?:\/[01]+#*)?[-+](?:[01]+#*(?:\/[01]+#*)?)?i|[-+]?[01]+#*(?:\/[01]+#*)?)(?=[()\s;"]|$)/i);
33
+ var octalMatcher = new RegExp(/^(?:[-+]i|[-+][0-7]+#*(?:\/[0-7]+#*)?i|[-+]?[0-7]+#*(?:\/[0-7]+#*)?@[-+]?[0-7]+#*(?:\/[0-7]+#*)?|[-+]?[0-7]+#*(?:\/[0-7]+#*)?[-+](?:[0-7]+#*(?:\/[0-7]+#*)?)?i|[-+]?[0-7]+#*(?:\/[0-7]+#*)?)(?=[()\s;"]|$)/i);
34
+ var hexMatcher = new RegExp(/^(?:[-+]i|[-+][\da-f]+#*(?:\/[\da-f]+#*)?i|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?@[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?[-+](?:[\da-f]+#*(?:\/[\da-f]+#*)?)?i|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?)(?=[()\s;"]|$)/i);
35
+ var decimalMatcher = new RegExp(/^(?:[-+]i|[-+](?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)i|[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)@[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)|[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)[-+](?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)?i|(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*))(?=[()\s;"]|$)/i);
36
+
37
+ function isBinaryNumber (stream) {
38
+ return stream.match(binaryMatcher);
39
+ }
40
+
41
+ function isOctalNumber (stream) {
42
+ return stream.match(octalMatcher);
43
+ }
44
+
45
+ function isDecimalNumber (stream, backup) {
46
+ if (backup === true) {
47
+ stream.backUp(1);
45
48
  }
46
- return false;
49
+ return stream.match(decimalMatcher);
50
+ }
51
+
52
+ function isHexNumber (stream) {
53
+ return stream.match(hexMatcher);
47
54
  }
48
55
 
49
56
  return {
@@ -67,13 +74,13 @@ CodeMirror.defineMode("scheme", function (config, mode) {
67
74
  return null;
68
75
  }
69
76
  var returnType = null;
70
-
77
+
71
78
  switch(state.mode){
72
79
  case "string": // multi-line string parsing mode
73
80
  var next, escaped = false;
74
81
  while ((next = stream.next()) != null) {
75
82
  if (next == "\"" && !escaped) {
76
-
83
+
77
84
  state.mode = false;
78
85
  break;
79
86
  }
@@ -85,7 +92,7 @@ CodeMirror.defineMode("scheme", function (config, mode) {
85
92
  var next, maybeEnd = false;
86
93
  while ((next = stream.next()) != null) {
87
94
  if (next == "#" && maybeEnd) {
88
-
95
+
89
96
  state.mode = false;
90
97
  break;
91
98
  }
@@ -106,52 +113,73 @@ CodeMirror.defineMode("scheme", function (config, mode) {
106
113
  }
107
114
  default: // default parsing mode
108
115
  var ch = stream.next();
109
-
116
+
110
117
  if (ch == "\"") {
111
118
  state.mode = "string";
112
119
  returnType = STRING;
113
-
120
+
114
121
  } else if (ch == "'") {
115
122
  returnType = ATOM;
116
123
  } else if (ch == '#') {
117
- if (stream.eat("|")) { // Multi-line comment
124
+ if (stream.eat("|")) { // Multi-line comment
118
125
  state.mode = "comment"; // toggle to comment mode
119
126
  returnType = COMMENT;
120
- } else if (stream.eat(/[tf]/)) { // #t/#f (atom)
127
+ } else if (stream.eat(/[tf]/i)) { // #t/#f (atom)
121
128
  returnType = ATOM;
122
- } else if (stream.eat(';')) { // S-Expr comment
129
+ } else if (stream.eat(';')) { // S-Expr comment
123
130
  state.mode = "s-expr-comment";
124
131
  returnType = COMMENT;
132
+ } else {
133
+ var numTest = null, hasExactness = false, hasRadix = true;
134
+ if (stream.eat(/[ei]/i)) {
135
+ hasExactness = true;
136
+ } else {
137
+ stream.backUp(1); // must be radix specifier
138
+ }
139
+ if (stream.match(/^#b/i)) {
140
+ numTest = isBinaryNumber;
141
+ } else if (stream.match(/^#o/i)) {
142
+ numTest = isOctalNumber;
143
+ } else if (stream.match(/^#x/i)) {
144
+ numTest = isHexNumber;
145
+ } else if (stream.match(/^#d/i)) {
146
+ numTest = isDecimalNumber;
147
+ } else if (stream.match(/^[-+0-9.]/, false)) {
148
+ hasRadix = false;
149
+ numTest = isDecimalNumber;
150
+ // re-consume the intial # if all matches failed
151
+ } else if (!hasExactness) {
152
+ stream.eat('#');
153
+ }
154
+ if (numTest != null) {
155
+ if (hasRadix && !hasExactness) {
156
+ // consume optional exactness after radix
157
+ stream.match(/^#[ei]/i);
158
+ }
159
+ if (numTest(stream))
160
+ returnType = NUMBER;
161
+ }
125
162
  }
126
-
163
+ } else if (/^[-+0-9.]/.test(ch) && isDecimalNumber(stream, true)) { // match non-prefixed number, must be decimal
164
+ returnType = NUMBER;
127
165
  } else if (ch == ";") { // comment
128
166
  stream.skipToEnd(); // rest of the line is a comment
129
167
  returnType = COMMENT;
130
- } else if (ch == "-"){
131
-
132
- if(!isNaN(parseInt(stream.peek()))){
133
- stream.eatWhile(/[\/0-9]/);
134
- returnType = NUMBER;
135
- }else{
136
- returnType = null;
137
- }
138
- } else if (isNumber(ch,stream)){
139
- returnType = NUMBER;
140
168
  } else if (ch == "(" || ch == "[") {
141
169
  var keyWord = ''; var indentTemp = stream.column();
142
170
  /**
143
- Either
171
+ Either
144
172
  (indent-word ..
145
173
  (non-indent-word ..
146
174
  (;something else, bracket, etc.
147
175
  */
148
-
176
+
149
177
  while ((letter = stream.eat(/[^\s\(\[\;\)\]]/)) != null) {
150
178
  keyWord += letter;
151
179
  }
152
-
180
+
153
181
  if (keyWord.length > 0 && indentKeys.propertyIsEnumerable(keyWord)) { // indent-word
154
-
182
+
155
183
  pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
156
184
  } else { // non-indent word
157
185
  // we continue eating the spaces
@@ -165,15 +193,15 @@ CodeMirror.defineMode("scheme", function (config, mode) {
165
193
  }
166
194
  }
167
195
  stream.backUp(stream.current().length - 1); // undo all the eating
168
-
196
+
169
197
  if(typeof state.sExprComment == "number") state.sExprComment++;
170
-
198
+
171
199
  returnType = BRACKET;
172
200
  } else if (ch == ")" || ch == "]") {
173
201
  returnType = BRACKET;
174
202
  if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : "[")) {
175
203
  popStack(state);
176
-
204
+
177
205
  if(typeof state.sExprComment == "number"){
178
206
  if(--state.sExprComment == 0){
179
207
  returnType = COMMENT; // final closing bracket
@@ -182,11 +210,11 @@ CodeMirror.defineMode("scheme", function (config, mode) {
182
210
  }
183
211
  }
184
212
  } else {
185
- stream.eatWhile(/[\w\$_\-]/);
186
-
213
+ stream.eatWhile(/[\w\$_\-!$%&*+\.\/:<=>?@\^~]/);
214
+
187
215
  if (keywords && keywords.propertyIsEnumerable(stream.current())) {
188
216
  returnType = BUILTIN;
189
- }else returnType = null;
217
+ } else returnType = "variable";
190
218
  }
191
219
  }
192
220
  return (typeof state.sExprComment == "number") ? COMMENT : returnType;
@@ -199,4 +227,4 @@ CodeMirror.defineMode("scheme", function (config, mode) {
199
227
  };
200
228
  });
201
229
 
202
- CodeMirror.defineMIME("text/x-scheme", "scheme");
230
+ CodeMirror.defineMIME("text/x-scheme", "scheme");