codemirror-rails 2.24 → 2.32

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 (90) hide show
  1. data/.gitignore +1 -0
  2. data/Rakefile +19 -0
  3. data/codemirror-rails.gemspec +6 -1
  4. data/lib/codemirror/rails/version.rb +2 -2
  5. data/test/dummy/README.rdoc +261 -0
  6. data/test/dummy/Rakefile +7 -0
  7. data/test/dummy/app/assets/javascripts/application.js +15 -0
  8. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  9. data/test/dummy/app/controllers/application_controller.rb +3 -0
  10. data/test/dummy/app/helpers/application_helper.rb +2 -0
  11. data/test/dummy/app/mailers/.gitkeep +0 -0
  12. data/test/dummy/app/models/.gitkeep +0 -0
  13. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  14. data/test/dummy/config.ru +4 -0
  15. data/test/dummy/config/application.rb +56 -0
  16. data/test/dummy/config/boot.rb +10 -0
  17. data/test/dummy/config/environment.rb +5 -0
  18. data/test/dummy/config/environments/development.rb +37 -0
  19. data/test/dummy/config/environments/production.rb +67 -0
  20. data/test/dummy/config/environments/test.rb +37 -0
  21. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  22. data/test/dummy/config/initializers/inflections.rb +15 -0
  23. data/test/dummy/config/initializers/mime_types.rb +5 -0
  24. data/test/dummy/config/initializers/secret_token.rb +7 -0
  25. data/test/dummy/config/initializers/session_store.rb +8 -0
  26. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  27. data/test/dummy/config/locales/en.yml +5 -0
  28. data/test/dummy/config/routes.rb +58 -0
  29. data/test/dummy/lib/assets/.gitkeep +0 -0
  30. data/test/dummy/log/.gitkeep +0 -0
  31. data/test/dummy/public/404.html +26 -0
  32. data/test/dummy/public/422.html +26 -0
  33. data/test/dummy/public/500.html +25 -0
  34. data/test/dummy/public/favicon.ico +0 -0
  35. data/test/dummy/script/rails +6 -0
  36. data/test/integration/codemirror_rails_integration_test.rb +13 -0
  37. data/test/test_helper.rb +13 -0
  38. data/vendor/assets/javascripts/codemirror.js +381 -197
  39. data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +1 -1
  40. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +649 -94
  41. data/vendor/assets/javascripts/codemirror/modes/clike.js +53 -7
  42. data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +12 -7
  43. data/vendor/assets/javascripts/codemirror/modes/diff.js +24 -5
  44. data/vendor/assets/javascripts/codemirror/modes/ecl.js +2 -2
  45. data/vendor/assets/javascripts/codemirror/modes/erlang.js +463 -0
  46. data/vendor/assets/javascripts/codemirror/modes/gfm.js +38 -2
  47. data/vendor/assets/javascripts/codemirror/modes/go.js +1 -1
  48. data/vendor/assets/javascripts/codemirror/modes/groovy.js +1 -1
  49. data/vendor/assets/javascripts/codemirror/modes/haxe.js +432 -0
  50. data/vendor/assets/javascripts/codemirror/modes/javascript.js +1 -1
  51. data/vendor/assets/javascripts/codemirror/modes/less.js +93 -93
  52. data/vendor/assets/javascripts/codemirror/modes/markdown.js +29 -6
  53. data/vendor/assets/javascripts/codemirror/modes/mysql.js +6 -8
  54. data/vendor/assets/javascripts/codemirror/modes/ocaml.js +114 -0
  55. data/vendor/assets/javascripts/codemirror/modes/pascal.js +1 -1
  56. data/vendor/assets/javascripts/codemirror/modes/pig.js +2 -2
  57. data/vendor/assets/javascripts/codemirror/modes/plsql.js +2 -2
  58. data/vendor/assets/javascripts/codemirror/modes/python.js +13 -16
  59. data/vendor/assets/javascripts/codemirror/modes/ruby.js +3 -8
  60. data/vendor/assets/javascripts/codemirror/modes/scheme.js +74 -46
  61. data/vendor/assets/javascripts/codemirror/modes/shell.js +22 -7
  62. data/vendor/assets/javascripts/codemirror/modes/stex.js +7 -5
  63. data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +14 -14
  64. data/vendor/assets/javascripts/codemirror/modes/vb.js +260 -0
  65. data/vendor/assets/javascripts/codemirror/modes/verilog.js +1 -1
  66. data/vendor/assets/javascripts/codemirror/modes/xml.js +2 -1
  67. data/vendor/assets/javascripts/codemirror/modes/xquery.js +3 -3
  68. data/vendor/assets/javascripts/codemirror/utils/closetag.js +24 -34
  69. data/vendor/assets/javascripts/codemirror/utils/dialog.js +5 -1
  70. data/vendor/assets/javascripts/codemirror/utils/foldcode.js +10 -5
  71. data/vendor/assets/javascripts/codemirror/utils/formatting.js +8 -3
  72. data/vendor/assets/javascripts/codemirror/utils/loadmode.js +2 -1
  73. data/vendor/assets/javascripts/codemirror/utils/match-highlighter.js +1 -1
  74. data/vendor/assets/javascripts/codemirror/utils/multiplex.js +81 -0
  75. data/vendor/assets/javascripts/codemirror/utils/overlay.js +2 -1
  76. data/vendor/assets/javascripts/codemirror/utils/pig-hint.js +123 -0
  77. data/vendor/assets/javascripts/codemirror/utils/search.js +16 -12
  78. data/vendor/assets/javascripts/codemirror/utils/searchcursor.js +1 -1
  79. data/vendor/assets/javascripts/codemirror/utils/simple-hint.js +4 -0
  80. data/vendor/assets/javascripts/codemirror/utils/xml-hint.js +137 -0
  81. data/vendor/assets/stylesheets/codemirror.css +59 -4
  82. data/vendor/assets/stylesheets/codemirror/modes/tiddlywiki.css +14 -21
  83. data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +1 -2
  84. data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +21 -0
  85. data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +2 -3
  86. data/vendor/assets/stylesheets/codemirror/themes/night.css +1 -1
  87. data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +27 -0
  88. data/vendor/assets/stylesheets/codemirror/utils/dialog.css +4 -0
  89. metadata +98 -5
  90. data/vendor/assets/javascripts/codemirror/modes/rpm-spec.css +0 -5
@@ -1,6 +1,7 @@
1
1
  CodeMirror.defineMode("clike", function(config, parserConfig) {
2
2
  var indentUnit = config.indentUnit,
3
3
  keywords = parserConfig.keywords || {},
4
+ builtin = parserConfig.builtin || {},
4
5
  blockKeywords = parserConfig.blockKeywords || {},
5
6
  atoms = parserConfig.atoms || {},
6
7
  hooks = parserConfig.hooks || {},
@@ -47,8 +48,12 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
47
48
  if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
48
49
  return "keyword";
49
50
  }
51
+ if (builtin.propertyIsEnumerable(cur)) {
52
+ if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
53
+ return "builtin";
54
+ }
50
55
  if (atoms.propertyIsEnumerable(cur)) return "atom";
51
- return "word";
56
+ return "variable";
52
57
  }
53
58
 
54
59
  function tokenString(quote) {
@@ -211,14 +216,18 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
211
216
  });
212
217
  CodeMirror.defineMIME("text/x-csharp", {
213
218
  name: "clike",
214
- keywords: words("abstract as base bool break byte case catch char checked class const continue decimal" +
215
- " default delegate do double else enum event explicit extern finally fixed float for" +
216
- " foreach goto if implicit in int interface internal is lock long namespace new object" +
217
- " operator out override params private protected public readonly ref return sbyte sealed short" +
218
- " sizeof stackalloc static string struct switch this throw try typeof uint ulong unchecked" +
219
- " unsafe ushort using virtual void volatile while add alias ascending descending dynamic from get" +
219
+ keywords: words("abstract as base break case catch checked class const continue" +
220
+ " default delegate do else enum event explicit extern finally fixed for" +
221
+ " foreach goto if implicit in interface internal is lock namespace new" +
222
+ " operator out override params private protected public readonly ref return sealed" +
223
+ " sizeof stackalloc static struct switch this throw try typeof unchecked" +
224
+ " unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
220
225
  " global group into join let orderby partial remove select set value var yield"),
221
226
  blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
227
+ builtin: words("Boolean Byte Char DateTime DateTimeOffset Decimal Double" +
228
+ " Guid Int16 Int32 Int64 Object SByte Single String TimeSpan UInt16 UInt32" +
229
+ " UInt64 bool byte char decimal double short int long object" +
230
+ " sbyte float string ushort uint ulong"),
222
231
  atoms: words("true false null"),
223
232
  hooks: {
224
233
  "@": function(stream, state) {
@@ -231,4 +240,41 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
231
240
  }
232
241
  }
233
242
  });
243
+ CodeMirror.defineMIME("text/x-scala", {
244
+ name: "clike",
245
+ keywords: words(
246
+
247
+ /* scala */
248
+ "abstract case catch class def do else extends false final finally for forSome if " +
249
+ "implicit import lazy match new null object override package private protected return " +
250
+ "sealed super this throw trait try trye type val var while with yield _ : = => <- <: " +
251
+ "<% >: # @ " +
252
+
253
+ /* package scala */
254
+ "assert assume require print println printf readLine readBoolean readByte readShort " +
255
+ "readChar readInt readLong readFloat readDouble " +
256
+
257
+ "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
258
+ "Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " +
259
+ "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
260
+ "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
261
+ "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector :: #:: " +
262
+
263
+ /* package java.lang */
264
+ "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
265
+ "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
266
+ "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
267
+ "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
268
+
269
+
270
+ ),
271
+ blockKeywords: words("catch class do else finally for forSome if match switch try while"),
272
+ atoms: words("true false null"),
273
+ hooks: {
274
+ "@": function(stream, state) {
275
+ stream.eatWhile(/[\w\$_]/);
276
+ return "meta";
277
+ }
278
+ }
279
+ });
234
280
  }());
@@ -10,11 +10,12 @@ CodeMirror.defineMode('coffeescript', function(conf) {
10
10
  }
11
11
 
12
12
  var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\?]");
13
- var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
13
+ var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\},:`=;\\.]');
14
14
  var doubleOperators = new RegExp("^((\->)|(\=>)|(\\+\\+)|(\\+\\=)|(\\-\\-)|(\\-\\=)|(\\*\\*)|(\\*\\=)|(\\/\\/)|(\\/\\=)|(==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//))");
15
15
  var doubleDelimiters = new RegExp("^((\\.\\.)|(\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
16
16
  var tripleDelimiters = new RegExp("^((\\.\\.\\.)|(//=)|(>>=)|(<<=)|(\\*\\*=))");
17
17
  var identifiers = new RegExp("^[_A-Za-z$][_A-Za-z$0-9]*");
18
+ var properties = new RegExp("^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*");
18
19
 
19
20
  var wordOperators = wordRegexp(['and', 'or', 'not',
20
21
  'is', 'isnt', 'in',
@@ -60,6 +61,12 @@ CodeMirror.defineMode('coffeescript', function(conf) {
60
61
 
61
62
  var ch = stream.peek();
62
63
 
64
+ // Handle docco title comment (single line)
65
+ if (stream.match("####")) {
66
+ stream.skipToEnd();
67
+ return 'comment';
68
+ }
69
+
63
70
  // Handle multi line comments
64
71
  if (stream.match("###")) {
65
72
  state.tokenize = longComment;
@@ -151,6 +158,10 @@ CodeMirror.defineMode('coffeescript', function(conf) {
151
158
  if (stream.match(identifiers)) {
152
159
  return 'variable';
153
160
  }
161
+
162
+ if (stream.match(properties)) {
163
+ return 'property';
164
+ }
154
165
 
155
166
  // Handle non-detected items
156
167
  stream.next();
@@ -255,12 +266,6 @@ CodeMirror.defineMode('coffeescript', function(conf) {
255
266
  }
256
267
  }
257
268
 
258
- // Handle properties
259
- if (current === '@') {
260
- stream.eat('@');
261
- return 'keyword';
262
- }
263
-
264
269
  // Handle scope changes.
265
270
  if (current === 'return') {
266
271
  state.dedent += 1;
@@ -1,11 +1,30 @@
1
1
  CodeMirror.defineMode("diff", function() {
2
+
3
+ var TOKEN_NAMES = {
4
+ '+': 'tag',
5
+ '-': 'string',
6
+ '@': 'meta'
7
+ };
8
+
2
9
  return {
3
10
  token: function(stream) {
4
- var ch = stream.next();
5
- stream.skipToEnd();
6
- if (ch == "+") return "plus";
7
- if (ch == "-") return "minus";
8
- if (ch == "@") return "rangeinfo";
11
+ var tw_pos = stream.string.search(/[\t ]+?$/);
12
+
13
+ if (!stream.sol() || tw_pos === 0) {
14
+ stream.skipToEnd();
15
+ return ("error " + (
16
+ TOKEN_NAMES[stream.string.charAt(0)] || '')).replace(/ $/, '');
17
+ }
18
+
19
+ var token_name = TOKEN_NAMES[stream.peek()] || stream.skipToEnd();
20
+
21
+ if (tw_pos === -1) {
22
+ stream.skipToEnd();
23
+ } else {
24
+ stream.pos = tw_pos;
25
+ }
26
+
27
+ return token_name;
9
28
  }
10
29
  };
11
30
  });
@@ -100,7 +100,7 @@ CodeMirror.defineMode("ecl", function(config) {
100
100
  }
101
101
  }
102
102
  if (atoms.propertyIsEnumerable(cur)) return "atom";
103
- return "word";
103
+ return null;
104
104
  }
105
105
 
106
106
  function tokenString(quote) {
@@ -200,4 +200,4 @@ CodeMirror.defineMode("ecl", function(config) {
200
200
  };
201
201
  });
202
202
 
203
- CodeMirror.defineMIME("text/x-ecl");
203
+ CodeMirror.defineMIME("text/x-ecl", "ecl");
@@ -0,0 +1,463 @@
1
+ // block; "begin", "case", "fun", "if", "receive", "try": closed by "end"
2
+ // block internal; "after", "catch", "of"
3
+ // guard; "when", closed by "->"
4
+ // "->" opens a clause, closed by ";" or "."
5
+ // "<<" opens a binary, closed by ">>"
6
+ // "," appears in arglists, lists, tuples and terminates lines of code
7
+ // "." resets indentation to 0
8
+ // obsolete; "cond", "let", "query"
9
+
10
+ CodeMirror.defineMIME("text/x-erlang", "erlang");
11
+
12
+ CodeMirror.defineMode("erlang", function(cmCfg, modeCfg) {
13
+
14
+ function rval(state,stream,type) {
15
+ // distinguish between "." as terminator and record field operator
16
+ if (type == "record") {
17
+ state.context = "record";
18
+ }else{
19
+ state.context = false;
20
+ }
21
+
22
+ // remember last significant bit on last line for indenting
23
+ if (type != "whitespace" && type != "comment") {
24
+ state.lastToken = stream.current();
25
+ }
26
+ // erlang -> CodeMirror tag
27
+ switch (type) {
28
+ case "atom": return "atom";
29
+ case "attribute": return "attribute";
30
+ case "builtin": return "builtin";
31
+ case "comment": return "comment";
32
+ case "fun": return "meta";
33
+ case "function": return "tag";
34
+ case "guard": return "property";
35
+ case "keyword": return "keyword";
36
+ case "macro": return "variable-2";
37
+ case "number": return "number";
38
+ case "operator": return "operator";
39
+ case "record": return "bracket";
40
+ case "string": return "string";
41
+ case "type": return "def";
42
+ case "variable": return "variable";
43
+ case "error": return "error";
44
+ case "separator": return null;
45
+ case "open_paren": return null;
46
+ case "close_paren": return null;
47
+ default: return null;
48
+ }
49
+ }
50
+
51
+ var typeWords = [
52
+ "-type", "-spec", "-export_type", "-opaque"];
53
+
54
+ var keywordWords = [
55
+ "after","begin","catch","case","cond","end","fun","if",
56
+ "let","of","query","receive","try","when"];
57
+
58
+ var separatorWords = [
59
+ "->",";",":",".",","];
60
+
61
+ var operatorWords = [
62
+ "and","andalso","band","bnot","bor","bsl","bsr","bxor",
63
+ "div","not","or","orelse","rem","xor"];
64
+
65
+ var symbolWords = [
66
+ "+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-"];
67
+
68
+ var openParenWords = [
69
+ "<<","(","[","{"];
70
+
71
+ var closeParenWords = [
72
+ "}","]",")",">>"];
73
+
74
+ var guardWords = [
75
+ "is_atom","is_binary","is_bitstring","is_boolean","is_float",
76
+ "is_function","is_integer","is_list","is_number","is_pid",
77
+ "is_port","is_record","is_reference","is_tuple",
78
+ "atom","binary","bitstring","boolean","function","integer","list",
79
+ "number","pid","port","record","reference","tuple"];
80
+
81
+ var bifWords = [
82
+ "abs","adler32","adler32_combine","alive","apply","atom_to_binary",
83
+ "atom_to_list","binary_to_atom","binary_to_existing_atom",
84
+ "binary_to_list","binary_to_term","bit_size","bitstring_to_list",
85
+ "byte_size","check_process_code","contact_binary","crc32",
86
+ "crc32_combine","date","decode_packet","delete_module",
87
+ "disconnect_node","element","erase","exit","float","float_to_list",
88
+ "garbage_collect","get","get_keys","group_leader","halt","hd",
89
+ "integer_to_list","internal_bif","iolist_size","iolist_to_binary",
90
+ "is_alive","is_atom","is_binary","is_bitstring","is_boolean",
91
+ "is_float","is_function","is_integer","is_list","is_number","is_pid",
92
+ "is_port","is_process_alive","is_record","is_reference","is_tuple",
93
+ "length","link","list_to_atom","list_to_binary","list_to_bitstring",
94
+ "list_to_existing_atom","list_to_float","list_to_integer",
95
+ "list_to_pid","list_to_tuple","load_module","make_ref","module_loaded",
96
+ "monitor_node","node","node_link","node_unlink","nodes","notalive",
97
+ "now","open_port","pid_to_list","port_close","port_command",
98
+ "port_connect","port_control","pre_loaded","process_flag",
99
+ "process_info","processes","purge_module","put","register",
100
+ "registered","round","self","setelement","size","spawn","spawn_link",
101
+ "spawn_monitor","spawn_opt","split_binary","statistics",
102
+ "term_to_binary","time","throw","tl","trunc","tuple_size",
103
+ "tuple_to_list","unlink","unregister","whereis"];
104
+
105
+ // ignored for indenting purposes
106
+ var ignoreWords = [
107
+ ",", ":", "catch", "after", "of", "cond", "let", "query"];
108
+
109
+
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 = /[\->\.,:;]/;
119
+
120
+ function isMember(element,list) {
121
+ return (-1 < list.indexOf(element));
122
+ }
123
+
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;
132
+ }
133
+ }
134
+
135
+ function tokenize(stream, state) {
136
+ if (stream.eatSpace()) {
137
+ return rval(state,stream,"whitespace");
138
+ }
139
+
140
+ // 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
+ }
150
+ }
151
+ stream.backUp(1);
152
+ }
153
+
154
+ var ch = stream.next();
155
+
156
+ // comment
157
+ if (ch == '%') {
158
+ stream.skipToEnd();
159
+ return rval(state,stream,"comment");
160
+ }
161
+
162
+ // macro
163
+ if (ch == '?') {
164
+ stream.eatWhile(anumRE);
165
+ return rval(state,stream,"macro");
166
+ }
167
+
168
+ // record
169
+ if ( ch == "#") {
170
+ stream.eatWhile(anumRE);
171
+ return rval(state,stream,"record");
172
+ }
173
+
174
+ // char
175
+ if ( ch == "$") {
176
+ if (stream.next() == "\\") {
177
+ if (!stream.eatWhile(octitRE)) {
178
+ stream.next();
179
+ }
180
+ }
181
+ return rval(state,stream,"string");
182
+ }
183
+
184
+ // quoted atom
185
+ if (ch == '\'') {
186
+ if (singleQuote(stream)) {
187
+ return rval(state,stream,"atom");
188
+ }else{
189
+ return rval(state,stream,"error");
190
+ }
191
+ }
192
+
193
+ // string
194
+ if (ch == '"') {
195
+ if (doubleQuote(stream)) {
196
+ return rval(state,stream,"string");
197
+ }else{
198
+ return rval(state,stream,"error");
199
+ }
200
+ }
201
+
202
+ // variable
203
+ if (largeRE.test(ch)) {
204
+ stream.eatWhile(anumRE);
205
+ return rval(state,stream,"variable");
206
+ }
207
+
208
+ // atom/keyword/BIF/function
209
+ if (smallRE.test(ch)) {
210
+ stream.eatWhile(anumRE);
211
+
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
+ }
220
+ }
221
+
222
+ var w = stream.current();
223
+
224
+ if (isMember(w,keywordWords)) {
225
+ pushToken(state,stream);
226
+ return rval(state,stream,"keyword");
227
+ }
228
+ if (stream.peek() == "(") {
229
+ // 'put' and 'erlang:put' are bifs, 'foo:put' is not
230
+ if (isMember(w,bifWords) &&
231
+ (!isPrev(stream,":") || isPrev(stream,"erlang:"))) {
232
+ return rval(state,stream,"builtin");
233
+ }else{
234
+ return rval(state,stream,"function");
235
+ }
236
+ }
237
+ if (isMember(w,guardWords)) {
238
+ return rval(state,stream,"guard");
239
+ }
240
+ if (isMember(w,operatorWords)) {
241
+ return rval(state,stream,"operator");
242
+ }
243
+ if (stream.peek() == ":") {
244
+ if (w == "erlang") {
245
+ return rval(state,stream,"builtin");
246
+ } else {
247
+ return rval(state,stream,"function");
248
+ }
249
+ }
250
+ return rval(state,stream,"atom");
251
+ }
252
+
253
+ // number
254
+ if (digitRE.test(ch)) {
255
+ stream.eatWhile(digitRE);
256
+ if (stream.eat('#')) {
257
+ stream.eatWhile(digitRE); // 16#10 style integer
258
+ } else {
259
+ if (stream.eat('.')) { // float
260
+ stream.eatWhile(digitRE);
261
+ }
262
+ if (stream.eat(/[eE]/)) {
263
+ stream.eat(/[-+]/); // float with exponent
264
+ stream.eatWhile(digitRE);
265
+ }
266
+ }
267
+ return rval(state,stream,"number"); // normal integer
268
+ }
269
+
270
+ // open parens
271
+ if (nongreedy(stream,openParenRE,openParenWords)) {
272
+ pushToken(state,stream);
273
+ return rval(state,stream,"open_paren");
274
+ }
275
+
276
+ // close parens
277
+ if (nongreedy(stream,closeParenRE,closeParenWords)) {
278
+ pushToken(state,stream);
279
+ return rval(state,stream,"close_paren");
280
+ }
281
+
282
+ // separators
283
+ if (greedy(stream,sepRE,separatorWords)) {
284
+ // distinguish between "." as terminator and record field operator
285
+ if (state.context == false) {
286
+ pushToken(state,stream);
287
+ }
288
+ return rval(state,stream,"separator");
289
+ }
290
+
291
+ // operators
292
+ if (greedy(stream,symbolRE,symbolWords)) {
293
+ return rval(state,stream,"operator");
294
+ }
295
+
296
+ return rval(state,stream,null);
297
+ }
298
+
299
+ function nongreedy(stream,re,words) {
300
+ if (stream.current().length == 1 && re.test(stream.current())) {
301
+ stream.backUp(1);
302
+ while (re.test(stream.peek())) {
303
+ stream.next();
304
+ if (isMember(stream.current(),words)) {
305
+ return true;
306
+ }
307
+ }
308
+ stream.backUp(stream.current().length-1);
309
+ }
310
+ return false;
311
+ }
312
+
313
+ function greedy(stream,re,words) {
314
+ if (stream.current().length == 1 && re.test(stream.current())) {
315
+ while (re.test(stream.peek())) {
316
+ stream.next();
317
+ }
318
+ while (0 < stream.current().length) {
319
+ if (isMember(stream.current(),words)) {
320
+ return true;
321
+ }else{
322
+ stream.backUp(1);
323
+ }
324
+ }
325
+ stream.next();
326
+ }
327
+ return false;
328
+ }
329
+
330
+ function doubleQuote(stream) {
331
+ return quote(stream, '"', '\\');
332
+ }
333
+
334
+ function singleQuote(stream) {
335
+ return quote(stream,'\'','\\');
336
+ }
337
+
338
+ function quote(stream,quoteChar,escapeChar) {
339
+ while (!stream.eol()) {
340
+ var ch = stream.next();
341
+ if (ch == quoteChar) {
342
+ return true;
343
+ }else if (ch == escapeChar) {
344
+ stream.next();
345
+ }
346
+ }
347
+ return false;
348
+ }
349
+
350
+ function Token(stream) {
351
+ this.token = stream ? stream.current() : "";
352
+ this.column = stream ? stream.column() : 0;
353
+ this.indent = stream ? stream.indentation() : 0;
354
+ }
355
+
356
+ function myIndent(state,textAfter) {
357
+ var indent = cmCfg.indentUnit;
358
+ var outdentWords = ["after","catch"];
359
+ var token = (peekToken(state)).token;
360
+ var wordAfter = takewhile(textAfter,/[^a-z]/);
361
+
362
+ if (isMember(token,openParenWords)) {
363
+ return (peekToken(state)).column+token.length;
364
+ }else if (token == "." || token == ""){
365
+ return 0;
366
+ }else if (token == "->") {
367
+ if (wordAfter == "end") {
368
+ return peekToken(state,2).column;
369
+ }else if (peekToken(state,2).token == "fun") {
370
+ return peekToken(state,2).column+indent;
371
+ }else{
372
+ return (peekToken(state)).indent+indent;
373
+ }
374
+ }else if (isMember(wordAfter,outdentWords)) {
375
+ return (peekToken(state)).indent;
376
+ }else{
377
+ return (peekToken(state)).column+indent;
378
+ }
379
+ }
380
+
381
+ function takewhile(str,re) {
382
+ var m = str.match(re);
383
+ return m ? str.slice(0,m.index) : str;
384
+ }
385
+
386
+ function popToken(state) {
387
+ return state.tokenStack.pop();
388
+ }
389
+
390
+ function peekToken(state,depth) {
391
+ var len = state.tokenStack.length;
392
+ var dep = (depth ? depth : 1);
393
+ if (len < dep) {
394
+ return new Token;
395
+ }else{
396
+ return state.tokenStack[len-dep];
397
+ }
398
+ }
399
+
400
+ function pushToken(state,stream) {
401
+ var token = stream.current();
402
+ var prev_token = peekToken(state).token;
403
+ if (isMember(token,ignoreWords)) {
404
+ return false;
405
+ }else if (drop_both(prev_token,token)) {
406
+ popToken(state);
407
+ return false;
408
+ }else if (drop_first(prev_token,token)) {
409
+ popToken(state);
410
+ return pushToken(state,stream);
411
+ }else{
412
+ state.tokenStack.push(new Token(stream));
413
+ return true;
414
+ }
415
+ }
416
+
417
+ function drop_first(open, close) {
418
+ switch (open+" "+close) {
419
+ case "when ->": return true;
420
+ case "-> end": return true;
421
+ case "-> .": return true;
422
+ case ". .": return true;
423
+ default: return false;
424
+ }
425
+ }
426
+
427
+ function drop_both(open, close) {
428
+ switch (open+" "+close) {
429
+ case "( )": return true;
430
+ case "[ ]": return true;
431
+ case "{ }": return true;
432
+ case "<< >>": return true;
433
+ case "begin end": return true;
434
+ case "case end": return true;
435
+ case "fun end": return true;
436
+ case "if end": return true;
437
+ case "receive end": return true;
438
+ case "try end": return true;
439
+ case "-> ;": return true;
440
+ default: return false;
441
+ }
442
+ }
443
+
444
+ return {
445
+ startState:
446
+ function() {
447
+ return {tokenStack: [],
448
+ context: false,
449
+ lastToken: null};
450
+ },
451
+
452
+ token:
453
+ function(stream, state) {
454
+ return tokenize(stream, state);
455
+ },
456
+
457
+ indent:
458
+ function(state, textAfter) {
459
+ // console.log(state.tokenStack);
460
+ return myIndent(state,textAfter);
461
+ }
462
+ };
463
+ });