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.
- data/.gitignore +1 -0
- data/Rakefile +19 -0
- data/codemirror-rails.gemspec +6 -1
- data/lib/codemirror/rails/version.rb +2 -2
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/mailers/.gitkeep +0 -0
- data/test/dummy/app/models/.gitkeep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +56 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/lib/assets/.gitkeep +0 -0
- data/test/dummy/log/.gitkeep +0 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/integration/codemirror_rails_integration_test.rb +13 -0
- data/test/test_helper.rb +13 -0
- data/vendor/assets/javascripts/codemirror.js +381 -197
- data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +1 -1
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +649 -94
- data/vendor/assets/javascripts/codemirror/modes/clike.js +53 -7
- data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +12 -7
- data/vendor/assets/javascripts/codemirror/modes/diff.js +24 -5
- data/vendor/assets/javascripts/codemirror/modes/ecl.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/erlang.js +463 -0
- data/vendor/assets/javascripts/codemirror/modes/gfm.js +38 -2
- data/vendor/assets/javascripts/codemirror/modes/go.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/groovy.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/haxe.js +432 -0
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/less.js +93 -93
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +29 -6
- data/vendor/assets/javascripts/codemirror/modes/mysql.js +6 -8
- data/vendor/assets/javascripts/codemirror/modes/ocaml.js +114 -0
- data/vendor/assets/javascripts/codemirror/modes/pascal.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/pig.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/plsql.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/python.js +13 -16
- data/vendor/assets/javascripts/codemirror/modes/ruby.js +3 -8
- data/vendor/assets/javascripts/codemirror/modes/scheme.js +74 -46
- data/vendor/assets/javascripts/codemirror/modes/shell.js +22 -7
- data/vendor/assets/javascripts/codemirror/modes/stex.js +7 -5
- data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +14 -14
- data/vendor/assets/javascripts/codemirror/modes/vb.js +260 -0
- data/vendor/assets/javascripts/codemirror/modes/verilog.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/xml.js +2 -1
- data/vendor/assets/javascripts/codemirror/modes/xquery.js +3 -3
- data/vendor/assets/javascripts/codemirror/utils/closetag.js +24 -34
- data/vendor/assets/javascripts/codemirror/utils/dialog.js +5 -1
- data/vendor/assets/javascripts/codemirror/utils/foldcode.js +10 -5
- data/vendor/assets/javascripts/codemirror/utils/formatting.js +8 -3
- data/vendor/assets/javascripts/codemirror/utils/loadmode.js +2 -1
- data/vendor/assets/javascripts/codemirror/utils/match-highlighter.js +1 -1
- data/vendor/assets/javascripts/codemirror/utils/multiplex.js +81 -0
- data/vendor/assets/javascripts/codemirror/utils/overlay.js +2 -1
- data/vendor/assets/javascripts/codemirror/utils/pig-hint.js +123 -0
- data/vendor/assets/javascripts/codemirror/utils/search.js +16 -12
- data/vendor/assets/javascripts/codemirror/utils/searchcursor.js +1 -1
- data/vendor/assets/javascripts/codemirror/utils/simple-hint.js +4 -0
- data/vendor/assets/javascripts/codemirror/utils/xml-hint.js +137 -0
- data/vendor/assets/stylesheets/codemirror.css +59 -4
- data/vendor/assets/stylesheets/codemirror/modes/tiddlywiki.css +14 -21
- data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +1 -2
- data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +21 -0
- data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +2 -3
- data/vendor/assets/stylesheets/codemirror/themes/night.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +27 -0
- data/vendor/assets/stylesheets/codemirror/utils/dialog.css +4 -0
- metadata +98 -5
- 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 "
|
|
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
|
|
215
|
-
" default delegate do
|
|
216
|
-
" foreach goto if implicit in
|
|
217
|
-
" operator out override params private protected public readonly ref return
|
|
218
|
-
" sizeof stackalloc static
|
|
219
|
-
" unsafe
|
|
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
|
|
5
|
-
|
|
6
|
-
if (
|
|
7
|
-
|
|
8
|
-
|
|
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
|
|
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
|
+
});
|