codemirror-rails 2.2.1 → 2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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");