codemirror-rails 3.15 → 3.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +59 -29
  4. data/vendor/assets/javascripts/codemirror/addons/comment/continuecomment.js +44 -0
  5. data/vendor/assets/javascripts/codemirror/addons/display/fullscreen.js +30 -0
  6. data/vendor/assets/javascripts/codemirror/addons/edit/continuecomment.js +1 -1
  7. data/vendor/assets/javascripts/codemirror/addons/fold/brace-fold.js +3 -3
  8. data/vendor/assets/javascripts/codemirror/addons/fold/comment-fold.js +40 -0
  9. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +7 -10
  10. data/vendor/assets/javascripts/codemirror/addons/scroll/scrollpastend.js +34 -0
  11. data/vendor/assets/javascripts/codemirror/addons/search/match-highlighter.js +4 -1
  12. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +5 -0
  13. data/vendor/assets/javascripts/codemirror/modes/css.js +21 -19
  14. data/vendor/assets/javascripts/codemirror/modes/erlang.js +122 -102
  15. data/vendor/assets/javascripts/codemirror/modes/javascript.js +3 -2
  16. data/vendor/assets/javascripts/codemirror/modes/python.js +12 -4
  17. data/vendor/assets/javascripts/codemirror/modes/rst.js +20 -21
  18. data/vendor/assets/javascripts/codemirror/modes/velocity.js +54 -12
  19. data/vendor/assets/javascripts/codemirror/modes/xml.js +1 -1
  20. data/vendor/assets/javascripts/codemirror/modes/xquery.js +5 -1
  21. data/vendor/assets/javascripts/codemirror/modes/yaml.js +8 -8
  22. data/vendor/assets/stylesheets/codemirror.css +1 -0
  23. data/vendor/assets/stylesheets/codemirror/addons/display/fullscreen.css +6 -0
  24. data/vendor/assets/stylesheets/codemirror/themes/3024-day.css +1 -0
  25. data/vendor/assets/stylesheets/codemirror/themes/3024-night.css +1 -0
  26. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +1 -1
  27. data/vendor/assets/stylesheets/codemirror/themes/base16-dark.css +1 -0
  28. data/vendor/assets/stylesheets/codemirror/themes/base16-light.css +1 -0
  29. data/vendor/assets/stylesheets/codemirror/themes/blackboard.css +3 -0
  30. data/vendor/assets/stylesheets/codemirror/themes/cobalt.css +3 -0
  31. data/vendor/assets/stylesheets/codemirror/themes/eclipse.css +2 -4
  32. data/vendor/assets/stylesheets/codemirror/themes/elegant.css +3 -0
  33. data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +11 -2
  34. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +3 -0
  35. data/vendor/assets/stylesheets/codemirror/themes/midnight.css +2 -2
  36. data/vendor/assets/stylesheets/codemirror/themes/monokai.css +1 -0
  37. data/vendor/assets/stylesheets/codemirror/themes/neat.css +3 -0
  38. data/vendor/assets/stylesheets/codemirror/themes/night.css +3 -0
  39. data/vendor/assets/stylesheets/codemirror/themes/paraiso-dark.css +34 -0
  40. data/vendor/assets/stylesheets/codemirror/themes/paraiso-light.css +34 -0
  41. data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +2 -0
  42. data/vendor/assets/stylesheets/codemirror/themes/solarized.css +2 -7
  43. data/vendor/assets/stylesheets/codemirror/themes/the-matrix.css +26 -0
  44. data/vendor/assets/stylesheets/codemirror/themes/tomorrow-night-eighties.css +1 -0
  45. data/vendor/assets/stylesheets/codemirror/themes/twilight.css +2 -0
  46. data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +3 -0
  47. data/vendor/assets/stylesheets/codemirror/themes/xq-dark.css +4 -1
  48. data/vendor/assets/stylesheets/codemirror/themes/xq-light.css +1 -1
  49. metadata +10 -2
@@ -0,0 +1,34 @@
1
+ (function() {
2
+ "use strict";
3
+
4
+ CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) {
5
+ if (old && old != CodeMirror.Init) {
6
+ cm.off("change", onChange);
7
+ cm.display.lineSpace.parentNode.style.paddingBottom = "";
8
+ cm.state.scrollPastEndPadding = null;
9
+ }
10
+ if (val) {
11
+ cm.on("change", onChange);
12
+ updateBottomMargin(cm);
13
+ }
14
+ });
15
+
16
+ function onChange(cm, change) {
17
+ if (CodeMirror.changeEnd(change).line == cm.lastLine())
18
+ updateBottomMargin(cm);
19
+ }
20
+
21
+ function updateBottomMargin(cm) {
22
+ var padding = "";
23
+ if (cm.lineCount() > 1) {
24
+ var totalH = cm.display.scroller.clientHeight - 30,
25
+ lastLineH = cm.getLineHandle(cm.lastLine()).height;
26
+ padding = (totalH - lastLineH) + "px";
27
+ }
28
+ if (cm.state.scrollPastEndPadding != padding) {
29
+ cm.state.scrollPastEndPadding = padding;
30
+ cm.display.lineSpace.parentNode.style.paddingBottom = padding;
31
+ cm.setSize();
32
+ }
33
+ }
34
+ })();
@@ -15,15 +15,18 @@
15
15
  (function() {
16
16
  var DEFAULT_MIN_CHARS = 2;
17
17
  var DEFAULT_TOKEN_STYLE = "matchhighlight";
18
+ var DEFAULT_DELAY = 100;
18
19
 
19
20
  function State(options) {
20
21
  if (typeof options == "object") {
21
22
  this.minChars = options.minChars;
22
23
  this.style = options.style;
23
24
  this.showToken = options.showToken;
25
+ this.delay = options.delay;
24
26
  }
25
27
  if (this.style == null) this.style = DEFAULT_TOKEN_STYLE;
26
28
  if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS;
29
+ if (this.delay == null) this.delay = DEFAULT_DELAY;
27
30
  this.overlay = this.timeout = null;
28
31
  }
29
32
 
@@ -45,7 +48,7 @@
45
48
  function cursorActivity(cm) {
46
49
  var state = cm.state.matchHighlighter;
47
50
  clearTimeout(state.timeout);
48
- state.timeout = setTimeout(function() {highlightMatches(cm);}, 100);
51
+ state.timeout = setTimeout(function() {highlightMatches(cm);}, state.delay);
49
52
  }
50
53
 
51
54
  function highlightMatches(cm) {
@@ -1104,6 +1104,11 @@
1104
1104
  if (vim.visualLine) {
1105
1105
  if (cursorIsBefore(selectionStart, selectionEnd)) {
1106
1106
  selectionStart.ch = 0;
1107
+
1108
+ var lastLine = cm.lastLine();
1109
+ if (selectionEnd.line > lastLine) {
1110
+ selectionEnd.line = lastLine;
1111
+ }
1107
1112
  selectionEnd.ch = lineLength(cm, selectionEnd.line);
1108
1113
  } else {
1109
1114
  selectionEnd.ch = 0;
@@ -366,8 +366,8 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
366
366
  "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
367
367
  "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
368
368
  "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
369
- "float", "float-offset", "font", "font-feature-settings", "font-family",
370
- "font-kerning", "font-language-override", "font-size", "font-size-adjust",
369
+ "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
370
+ "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
371
371
  "font-stretch", "font-style", "font-synthesis", "font-variant",
372
372
  "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
373
373
  "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
@@ -391,10 +391,12 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
391
391
  "page", "page-break-after", "page-break-before", "page-break-inside",
392
392
  "page-policy", "pause", "pause-after", "pause-before", "perspective",
393
393
  "perspective-origin", "pitch", "pitch-range", "play-during", "position",
394
- "presentation-level", "punctuation-trim", "quotes", "rendering-intent",
395
- "resize", "rest", "rest-after", "rest-before", "richness", "right",
396
- "rotation", "rotation-point", "ruby-align", "ruby-overhang",
397
- "ruby-position", "ruby-span", "size", "speak", "speak-as", "speak-header",
394
+ "presentation-level", "punctuation-trim", "quotes", "region-break-after",
395
+ "region-break-before", "region-break-inside", "region-fragment",
396
+ "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
397
+ "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
398
+ "ruby-position", "ruby-span", "shape-inside", "shape-outside", "size",
399
+ "speak", "speak-as", "speak-header",
398
400
  "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
399
401
  "tab-size", "table-layout", "target", "target-name", "target-new",
400
402
  "target-position", "text-align", "text-align-last", "text-decoration",
@@ -432,7 +434,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
432
434
  "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
433
435
  "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
434
436
  "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
435
- "gold", "goldenrod", "gray", "green", "greenyellow", "honeydew",
437
+ "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
436
438
  "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
437
439
  "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
438
440
  "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
@@ -455,22 +457,22 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
455
457
  "above", "absolute", "activeborder", "activecaption", "afar",
456
458
  "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
457
459
  "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
458
- "arabic-indic", "armenian", "asterisks", "auto", "avoid", "background",
459
- "backwards", "baseline", "below", "bidi-override", "binary", "bengali",
460
- "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
461
- "both", "bottom", "break-all", "break-word", "button", "button-bevel",
460
+ "arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page",
461
+ "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
462
+ "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
463
+ "both", "bottom", "break", "break-all", "break-word", "button", "button-bevel",
462
464
  "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
463
465
  "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
464
466
  "cell", "center", "checkbox", "circle", "cjk-earthly-branch",
465
467
  "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
466
- "col-resize", "collapse", "compact", "condensed", "contain", "content",
468
+ "col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
467
469
  "content-box", "context-menu", "continuous", "copy", "cover", "crop",
468
470
  "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
469
471
  "decimal-leading-zero", "default", "default-button", "destination-atop",
470
472
  "destination-in", "destination-out", "destination-over", "devanagari",
471
473
  "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
472
474
  "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
473
- "element", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
475
+ "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
474
476
  "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
475
477
  "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
476
478
  "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
@@ -486,7 +488,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
486
488
  "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
487
489
  "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
488
490
  "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
489
- "italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer",
491
+ "italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer",
490
492
  "landscape", "lao", "large", "larger", "left", "level", "lighter",
491
493
  "line-through", "linear", "lines", "list-item", "listbox", "listitem",
492
494
  "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
@@ -505,11 +507,11 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
505
507
  "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
506
508
  "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
507
509
  "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
508
- "outside", "overlay", "overline", "padding", "padding-box", "painted",
509
- "paused", "persian", "plus-darker", "plus-lighter", "pointer", "portrait",
510
- "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
511
- "radio", "read-only", "read-write", "read-write-plaintext-only", "relative",
512
- "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
510
+ "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
511
+ "painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer",
512
+ "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
513
+ "radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region",
514
+ "relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
513
515
  "ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
514
516
  "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
515
517
  "searchfield-cancel-button", "searchfield-decoration",
@@ -11,22 +11,15 @@ CodeMirror.defineMIME("text/x-erlang", "erlang");
11
11
 
12
12
  CodeMirror.defineMode("erlang", function(cmCfg) {
13
13
 
14
- function rval(state,stream,type) {
14
+ function rval(state,_stream,type) {
15
15
  // distinguish between "." as terminator and record field operator
16
- if (type == "record") {
17
- state.context = "record";
18
- }else{
19
- state.context = false;
20
- }
16
+ state.in_record = (type == "record");
21
17
 
22
- // remember last significant bit on last line for indenting
23
- if (type != "whitespace" && type != "comment") {
24
- state.lastToken = stream.current();
25
- }
26
18
  // erlang -> CodeMirror tag
27
19
  switch (type) {
28
20
  case "atom": return "atom";
29
21
  case "attribute": return "attribute";
22
+ case "boolean": return "special";
30
23
  case "builtin": return "builtin";
31
24
  case "comment": return "comment";
32
25
  case "fun": return "meta";
@@ -55,6 +48,7 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
55
48
  "after","begin","catch","case","cond","end","fun","if",
56
49
  "let","of","query","receive","try","when"];
57
50
 
51
+ var separatorRE = /[\->\.,:;]/;
58
52
  var separatorWords = [
59
53
  "->",";",":",".",","];
60
54
 
@@ -62,12 +56,15 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
62
56
  "and","andalso","band","bnot","bor","bsl","bsr","bxor",
63
57
  "div","not","or","orelse","rem","xor"];
64
58
 
59
+ var symbolRE = /[\+\-\*\/<>=\|:!]/;
65
60
  var symbolWords = [
66
- "+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-"];
61
+ "+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-","!"];
67
62
 
63
+ var openParenRE = /[<\(\[\{]/;
68
64
  var openParenWords = [
69
65
  "<<","(","[","{"];
70
66
 
67
+ var closeParenRE = /[>\)\]\}]/;
71
68
  var closeParenWords = [
72
69
  "}","]",")",">>"];
73
70
 
@@ -102,53 +99,39 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
102
99
  "term_to_binary","time","throw","tl","trunc","tuple_size",
103
100
  "tuple_to_list","unlink","unregister","whereis"];
104
101
 
105
- // ignored for indenting purposes
106
- var ignoreWords = [
107
- ",", ":", "catch", "after", "of", "cond", "let", "query"];
108
-
102
+ // [Ø-Þ] [À-Ö]
103
+ // [ß-ö] [ø-ÿ]
104
+ var anumRE = /[\w@Ø-ÞÀ-Öß-öø-ÿ]/;
105
+ var escapesRE =
106
+ /[0-7]{1,3}|[bdefnrstv\\"']|\^[a-zA-Z]|x[0-9a-zA-Z]{2}|x{[0-9a-zA-Z]+}/;
109
107
 
110
- var smallRE = /[a-z_]/;
111
- var largeRE = /[A-Z_]/;
112
- var digitRE = /[0-9]/;
113
- var octitRE = /[0-7]/;
114
- var anumRE = /[a-z_A-Z0-9]/;
115
- var symbolRE = /[\+\-\*\/<>=\|:]/;
116
- var openParenRE = /[<\(\[\{]/;
117
- var closeParenRE = /[>\)\]\}]/;
118
- var sepRE = /[\->\.,:;]/;
108
+ function tokenize(stream, state) {
119
109
 
120
- function isMember(element,list) {
121
- return (-1 < list.indexOf(element));
122
- }
110
+ // in multi-line string
111
+ if (state.in_string) {
112
+ state.in_string = (!doubleQuote(stream));
113
+ return rval(state,stream,"string");
114
+ }
123
115
 
124
- function isPrev(stream,string) {
125
- var start = stream.start;
126
- var len = string.length;
127
- if (len <= start) {
128
- var word = stream.string.slice(start-len,start);
129
- return word == string;
130
- }else{
131
- return false;
116
+ // in multi-line atom
117
+ if (state.in_atom) {
118
+ state.in_atom = (!singleQuote(stream));
119
+ return rval(state,stream,"atom");
132
120
  }
133
- }
134
121
 
135
- function tokenize(stream, state) {
122
+ // whitespace
136
123
  if (stream.eatSpace()) {
137
124
  return rval(state,stream,"whitespace");
138
125
  }
139
126
 
140
127
  // attributes and type specs
141
- if ((peekToken(state).token == "" || peekToken(state).token == ".") &&
142
- stream.peek() == '-') {
143
- stream.next();
144
- if (stream.eat(smallRE) && stream.eatWhile(anumRE)) {
145
- if (isMember(stream.current(),typeWords)) {
146
- return rval(state,stream,"type");
147
- }else{
148
- return rval(state,stream,"attribute");
149
- }
128
+ if ((peekToken(state).token == "") &&
129
+ stream.match(/-\s*[a-zß-öø-ÿ][\wØ-ÞÀ-Öß-öø-ÿ]*/)) {
130
+ if (isMember(stream.current(),typeWords)) {
131
+ return rval(state,stream,"type");
132
+ }else{
133
+ return rval(state,stream,"attribute");
150
134
  }
151
- stream.backUp(1);
152
135
  }
153
136
 
154
137
  var ch = stream.next();
@@ -166,57 +149,54 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
166
149
  }
167
150
 
168
151
  // record
169
- if ( ch == "#") {
152
+ if (ch == "#") {
170
153
  stream.eatWhile(anumRE);
171
154
  return rval(state,stream,"record");
172
155
  }
173
156
 
174
- // char
175
- if ( ch == "$") {
176
- if (stream.next() == "\\") {
177
- if (!stream.eatWhile(octitRE)) {
178
- stream.next();
179
- }
157
+ // dollar escape
158
+ if ( ch == "$" ) {
159
+ if (stream.next() == "\\" && !stream.match(escapesRE)) {
160
+ return rval(state,stream,"error");
180
161
  }
181
- return rval(state,stream,"string");
162
+ return rval(state,stream,"number");
182
163
  }
183
164
 
184
165
  // quoted atom
185
166
  if (ch == '\'') {
186
- if (singleQuote(stream)) {
187
- return rval(state,stream,"atom");
188
- }else{
189
- return rval(state,stream,"error");
167
+ if (!(state.in_atom = (!singleQuote(stream)))) {
168
+ if (stream.match(/\s*\/\s*[0-9]/,false)) {
169
+ stream.match(/\s*\/\s*[0-9]/,true);
170
+ popToken(state);
171
+ return rval(state,stream,"fun"); // 'f'/0 style fun
172
+ }
173
+ if (stream.match(/\s*\(/,false) || stream.match(/\s*:/,false)) {
174
+ return rval(state,stream,"function");
175
+ }
190
176
  }
177
+ return rval(state,stream,"atom");
191
178
  }
192
179
 
193
180
  // string
194
181
  if (ch == '"') {
195
- if (doubleQuote(stream)) {
196
- return rval(state,stream,"string");
197
- }else{
198
- return rval(state,stream,"error");
199
- }
182
+ state.in_string = (!doubleQuote(stream));
183
+ return rval(state,stream,"string");
200
184
  }
201
185
 
202
186
  // variable
203
- if (largeRE.test(ch)) {
187
+ if (/[A-Z_Ø-ÞÀ-Ö]/.test(ch)) {
204
188
  stream.eatWhile(anumRE);
205
189
  return rval(state,stream,"variable");
206
190
  }
207
191
 
208
192
  // atom/keyword/BIF/function
209
- if (smallRE.test(ch)) {
193
+ if (/[a-z_ß-öø-ÿ]/.test(ch)) {
210
194
  stream.eatWhile(anumRE);
211
195
 
212
- if (stream.peek() == "/") {
213
- stream.next();
214
- if (stream.eatWhile(digitRE)) {
215
- return rval(state,stream,"fun"); // f/0 style fun
216
- }else{
217
- stream.backUp(1);
218
- return rval(state,stream,"atom");
219
- }
196
+ if (stream.match(/\s*\/\s*[0-9]/,false)) {
197
+ stream.match(/\s*\/\s*[0-9]/,true);
198
+ popToken(state);
199
+ return rval(state,stream,"fun"); // f/0 style fun
220
200
  }
221
201
 
222
202
  var w = stream.current();
@@ -224,37 +204,38 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
224
204
  if (isMember(w,keywordWords)) {
225
205
  pushToken(state,stream);
226
206
  return rval(state,stream,"keyword");
227
- }
228
- if (stream.peek() == "(") {
207
+ }else if (stream.match(/\s*\(/,false)) {
229
208
  // 'put' and 'erlang:put' are bifs, 'foo:put' is not
230
209
  if (isMember(w,bifWords) &&
231
210
  (!isPrev(stream,":") || isPrev(stream,"erlang:"))) {
232
211
  return rval(state,stream,"builtin");
212
+ }else if (isMember(w,guardWords)) {
213
+ return rval(state,stream,"guard");
233
214
  }else{
234
215
  return rval(state,stream,"function");
235
216
  }
236
- }
237
- if (isMember(w,guardWords)) {
238
- return rval(state,stream,"guard");
239
- }
240
- if (isMember(w,operatorWords)) {
217
+ }else if (isMember(w,operatorWords)) {
241
218
  return rval(state,stream,"operator");
242
- }
243
- if (stream.peek() == ":") {
219
+ }else if (stream.match(/\s*:/,false)) {
244
220
  if (w == "erlang") {
245
221
  return rval(state,stream,"builtin");
246
222
  } else {
247
223
  return rval(state,stream,"function");
248
224
  }
225
+ }else if (isMember(w,["true","false"])) {
226
+ return rval(state,stream,"boolean");
227
+ }else{
228
+ return rval(state,stream,"atom");
249
229
  }
250
- return rval(state,stream,"atom");
251
230
  }
252
231
 
253
232
  // number
233
+ var digitRE = /[0-9]/;
234
+ var radixRE = /[0-9a-zA-Z]/; // 36#zZ style int
254
235
  if (digitRE.test(ch)) {
255
236
  stream.eatWhile(digitRE);
256
237
  if (stream.eat('#')) {
257
- stream.eatWhile(digitRE); // 16#10 style integer
238
+ stream.eatWhile(radixRE); // 36#aZ style integer
258
239
  } else {
259
240
  if (stream.eat('.')) { // float
260
241
  stream.eatWhile(digitRE);
@@ -280,9 +261,9 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
280
261
  }
281
262
 
282
263
  // separators
283
- if (greedy(stream,sepRE,separatorWords)) {
264
+ if (greedy(stream,separatorRE,separatorWords)) {
284
265
  // distinguish between "." as terminator and record field operator
285
- if (state.context == false) {
266
+ if (!state.in_record) {
286
267
  pushToken(state,stream);
287
268
  }
288
269
  return rval(state,stream,"separator");
@@ -296,6 +277,17 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
296
277
  return rval(state,stream,null);
297
278
  }
298
279
 
280
+ function isPrev(stream,string) {
281
+ var start = stream.start;
282
+ var len = string.length;
283
+ if (len <= start) {
284
+ var word = stream.string.slice(start-len,start);
285
+ return word == string;
286
+ }else{
287
+ return false;
288
+ }
289
+ }
290
+
299
291
  function nongreedy(stream,re,words) {
300
292
  if (stream.current().length == 1 && re.test(stream.current())) {
301
293
  stream.backUp(1);
@@ -347,31 +339,37 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
347
339
  return false;
348
340
  }
349
341
 
350
- function Token(stream) {
351
- this.token = stream ? stream.current() : "";
352
- this.column = stream ? stream.column() : 0;
353
- this.indent = stream ? stream.indentation() : 0;
342
+ function isMember(element,list) {
343
+ return (-1 < list.indexOf(element));
354
344
  }
355
345
 
346
+ /////////////////////////////////////////////////////////////////////////////
356
347
  function myIndent(state,textAfter) {
357
348
  var indent = cmCfg.indentUnit;
358
- var outdentWords = ["after","catch"];
359
349
  var token = (peekToken(state)).token;
360
350
  var wordAfter = takewhile(textAfter,/[^a-z]/);
361
351
 
362
- if (isMember(token,openParenWords)) {
363
- return (peekToken(state)).column+token.length;
364
- }else if (token == "." || token == ""){
352
+ if (state.in_string || state.in_atom) {
353
+ return CodeMirror.Pass;
354
+ }else if (token == "") {
365
355
  return 0;
356
+ }else if (isMember(token,openParenWords)) {
357
+ return (peekToken(state)).column+token.length;
358
+ }else if (token == "when") {
359
+ return (peekToken(state)).column+token.length+1;
360
+ }else if (token == "fun" && wordAfter == "") {
361
+ return (peekToken(state)).column+token.length;
366
362
  }else if (token == "->") {
367
- if (wordAfter == "end") {
363
+ if (isMember(wordAfter,["end","after","catch"])) {
368
364
  return peekToken(state,2).column;
369
365
  }else if (peekToken(state,2).token == "fun") {
370
366
  return peekToken(state,2).column+indent;
367
+ }else if (peekToken(state,2).token == "") {
368
+ return indent;
371
369
  }else{
372
370
  return (peekToken(state)).indent+indent;
373
371
  }
374
- }else if (isMember(wordAfter,outdentWords)) {
372
+ }else if (isMember(wordAfter,["after","catch","of"])) {
375
373
  return (peekToken(state)).indent;
376
374
  }else{
377
375
  return (peekToken(state)).column+indent;
@@ -383,6 +381,12 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
383
381
  return m ? str.slice(0,m.index) : str;
384
382
  }
385
383
 
384
+ function Token(stream) {
385
+ this.token = stream ? stream.current() : "";
386
+ this.column = stream ? stream.column() : 0;
387
+ this.indent = stream ? stream.indentation() : 0;
388
+ }
389
+
386
390
  function popToken(state) {
387
391
  return state.tokenStack.pop();
388
392
  }
@@ -400,7 +404,13 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
400
404
  function pushToken(state,stream) {
401
405
  var token = stream.current();
402
406
  var prev_token = peekToken(state).token;
403
- if (isMember(token,ignoreWords)) {
407
+
408
+ if (token == ".") {
409
+ state.tokenStack = [];
410
+ return false;
411
+ }else if(isMember(token,[",", ":", "of", "cond", "let", "query"])) {
412
+ return false;
413
+ }else if (drop_last(prev_token,token)) {
404
414
  return false;
405
415
  }else if (drop_both(prev_token,token)) {
406
416
  popToken(state);
@@ -408,18 +418,25 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
408
418
  }else if (drop_first(prev_token,token)) {
409
419
  popToken(state);
410
420
  return pushToken(state,stream);
421
+ }else if (isMember(token,["after","catch"])) {
422
+ return false;
411
423
  }else{
412
424
  state.tokenStack.push(new Token(stream));
413
425
  return true;
414
426
  }
415
427
  }
416
428
 
429
+ function drop_last(open, close) {
430
+ switch(open+" "+close) {
431
+ case "when ;": return true;
432
+ default: return false;
433
+ }
434
+ }
435
+
417
436
  function drop_first(open, close) {
418
437
  switch (open+" "+close) {
419
438
  case "when ->": return true;
420
439
  case "-> end": return true;
421
- case "-> .": return true;
422
- case ". .": return true;
423
440
  default: return false;
424
441
  }
425
442
  }
@@ -436,6 +453,8 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
436
453
  case "if end": return true;
437
454
  case "receive end": return true;
438
455
  case "try end": return true;
456
+ case "-> catch": return true;
457
+ case "-> after": return true;
439
458
  case "-> ;": return true;
440
459
  default: return false;
441
460
  }
@@ -445,8 +464,9 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
445
464
  startState:
446
465
  function() {
447
466
  return {tokenStack: [],
448
- context: false,
449
- lastToken: null};
467
+ in_record: false,
468
+ in_string: false,
469
+ in_atom: false};
450
470
  },
451
471
 
452
472
  token: