codemirror-rails 3.15 → 3.16

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 (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: