codemirror-rails 3.20 → 3.21
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.
- checksums.yaml +4 -4
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +240 -135
- data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +6 -2
- data/vendor/assets/javascripts/codemirror/addons/comment/continuecomment.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/dialog/dialog.js +1 -0
- data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +5 -3
- data/vendor/assets/javascripts/codemirror/addons/edit/closetag.js +10 -6
- data/vendor/assets/javascripts/codemirror/addons/edit/continuelist.js +2 -0
- data/vendor/assets/javascripts/codemirror/addons/edit/matchbrackets.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/fold/comment-fold.js +3 -1
- data/vendor/assets/javascripts/codemirror/addons/fold/foldcode.js +13 -2
- data/vendor/assets/javascripts/codemirror/addons/fold/foldgutter.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/fold/indent-fold.js +2 -2
- data/vendor/assets/javascripts/codemirror/addons/fold/xml-fold.js +6 -0
- data/vendor/assets/javascripts/codemirror/addons/hint/anyword-hint.js +3 -5
- data/vendor/assets/javascripts/codemirror/addons/hint/css-hint.js +29 -33
- data/vendor/assets/javascripts/codemirror/addons/hint/javascript-hint.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/hint/pig-hint.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/hint/python-hint.js +1 -5
- data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +58 -9
- data/vendor/assets/javascripts/codemirror/addons/hint/sql-hint.js +58 -17
- data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +5 -5
- data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +6 -1
- data/vendor/assets/javascripts/codemirror/addons/mode/multiplex.js +5 -3
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode-standalone.js +26 -11
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.node.js +22 -11
- data/vendor/assets/javascripts/codemirror/addons/search/search.js +22 -9
- data/vendor/assets/javascripts/codemirror/addons/search/searchcursor.js +48 -24
- data/vendor/assets/javascripts/codemirror/addons/selection/active-line.js +15 -9
- data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +3 -3
- data/vendor/assets/javascripts/codemirror/addons/wrap/hardwrap.js +21 -9
- data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +12 -1
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +110 -28
- data/vendor/assets/javascripts/codemirror/modes/clike.js +28 -9
- data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +3 -4
- data/vendor/assets/javascripts/codemirror/modes/css.js +341 -297
- data/vendor/assets/javascripts/codemirror/modes/erlang.js +302 -179
- data/vendor/assets/javascripts/codemirror/modes/gfm.js +10 -5
- data/vendor/assets/javascripts/codemirror/modes/gherkin.js +45 -50
- data/vendor/assets/javascripts/codemirror/modes/haml.js +0 -4
- data/vendor/assets/javascripts/codemirror/modes/haskell.js +5 -3
- data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +0 -2
- data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +0 -2
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +43 -30
- data/vendor/assets/javascripts/codemirror/modes/jinja2.js +13 -3
- data/vendor/assets/javascripts/codemirror/modes/less.js +7 -6
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +231 -45
- data/vendor/assets/javascripts/codemirror/modes/{ocaml.js → mllike.js} +88 -13
- data/vendor/assets/javascripts/codemirror/modes/pegjs.js +5 -9
- data/vendor/assets/javascripts/codemirror/modes/php.js +6 -7
- data/vendor/assets/javascripts/codemirror/modes/python.js +6 -0
- data/vendor/assets/javascripts/codemirror/modes/r.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/rpm-spec.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/ruby.js +3 -1
- data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +4 -2
- data/vendor/assets/javascripts/codemirror/modes/smartymixed.js +0 -2
- data/vendor/assets/javascripts/codemirror/modes/sql.js +5 -4
- data/vendor/assets/javascripts/codemirror/modes/xml.js +87 -100
- data/vendor/assets/stylesheets/codemirror/themes/mbo.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/midnight.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/pastel-on-dark.css +49 -0
- data/vendor/assets/stylesheets/codemirror/themes/the-matrix.css +1 -1
- metadata +3 -2
|
@@ -1,45 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
1
|
+
/*jshint unused:true, eqnull:true, curly:true, bitwise:true */
|
|
2
|
+
/*jshint undef:true, latedef:true, trailing:true */
|
|
3
|
+
/*global CodeMirror:true */
|
|
4
|
+
|
|
5
|
+
// erlang mode.
|
|
6
|
+
// tokenizer -> token types -> CodeMirror styles
|
|
7
|
+
// tokenizer maintains a parse stack
|
|
8
|
+
// indenter uses the parse stack
|
|
9
|
+
|
|
10
|
+
// TODO indenter:
|
|
11
|
+
// bit syntax
|
|
12
|
+
// old guard/bif/conversion clashes (e.g. "float/1")
|
|
13
|
+
// type/spec/opaque
|
|
9
14
|
|
|
10
15
|
CodeMirror.defineMIME("text/x-erlang", "erlang");
|
|
11
16
|
|
|
12
17
|
CodeMirror.defineMode("erlang", function(cmCfg) {
|
|
18
|
+
"use strict";
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
state.in_record = (type == "record");
|
|
17
|
-
|
|
18
|
-
// erlang -> CodeMirror tag
|
|
19
|
-
switch (type) {
|
|
20
|
-
case "atom": return "atom";
|
|
21
|
-
case "attribute": return "attribute";
|
|
22
|
-
case "boolean": return "special";
|
|
23
|
-
case "builtin": return "builtin";
|
|
24
|
-
case "comment": return "comment";
|
|
25
|
-
case "fun": return "meta";
|
|
26
|
-
case "function": return "tag";
|
|
27
|
-
case "guard": return "property";
|
|
28
|
-
case "keyword": return "keyword";
|
|
29
|
-
case "macro": return "variable-2";
|
|
30
|
-
case "number": return "number";
|
|
31
|
-
case "operator": return "operator";
|
|
32
|
-
case "record": return "bracket";
|
|
33
|
-
case "string": return "string";
|
|
34
|
-
case "type": return "def";
|
|
35
|
-
case "variable": return "variable";
|
|
36
|
-
case "error": return "error";
|
|
37
|
-
case "separator": return null;
|
|
38
|
-
case "open_paren": return null;
|
|
39
|
-
case "close_paren": return null;
|
|
40
|
-
default: return null;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
20
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
21
|
+
// constants
|
|
43
22
|
|
|
44
23
|
var typeWords = [
|
|
45
24
|
"-type", "-spec", "-export_type", "-opaque"];
|
|
@@ -48,23 +27,23 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
|
|
|
48
27
|
"after","begin","catch","case","cond","end","fun","if",
|
|
49
28
|
"let","of","query","receive","try","when"];
|
|
50
29
|
|
|
51
|
-
var separatorRE
|
|
30
|
+
var separatorRE = /[\->,;]/;
|
|
52
31
|
var separatorWords = [
|
|
53
|
-
"->",";","
|
|
32
|
+
"->",";",","];
|
|
54
33
|
|
|
55
|
-
var
|
|
34
|
+
var operatorAtomWords = [
|
|
56
35
|
"and","andalso","band","bnot","bor","bsl","bsr","bxor",
|
|
57
36
|
"div","not","or","orelse","rem","xor"];
|
|
58
37
|
|
|
59
|
-
var
|
|
60
|
-
var
|
|
61
|
-
"+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-","!"];
|
|
38
|
+
var operatorSymbolRE = /[\+\-\*\/<>=\|:!]/;
|
|
39
|
+
var operatorSymbolWords = [
|
|
40
|
+
"=","+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-","!"];
|
|
62
41
|
|
|
63
|
-
var openParenRE
|
|
42
|
+
var openParenRE = /[<\(\[\{]/;
|
|
64
43
|
var openParenWords = [
|
|
65
44
|
"<<","(","[","{"];
|
|
66
45
|
|
|
67
|
-
var closeParenRE
|
|
46
|
+
var closeParenRE = /[>\)\]\}]/;
|
|
68
47
|
var closeParenWords = [
|
|
69
48
|
"}","]",")",">>"];
|
|
70
49
|
|
|
@@ -99,23 +78,25 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
|
|
|
99
78
|
"term_to_binary","time","throw","tl","trunc","tuple_size",
|
|
100
79
|
"tuple_to_list","unlink","unregister","whereis"];
|
|
101
80
|
|
|
102
|
-
// [Ø-Þ] [À-Ö]
|
|
103
|
-
// [ß-ö] [ø-ÿ]
|
|
81
|
+
// upper case: [A-Z] [Ø-Þ] [À-Ö]
|
|
82
|
+
// lower case: [a-z] [ß-ö] [ø-ÿ]
|
|
104
83
|
var anumRE = /[\w@Ø-ÞÀ-Öß-öø-ÿ]/;
|
|
105
84
|
var escapesRE =
|
|
106
85
|
/[0-7]{1,3}|[bdefnrstv\\"']|\^[a-zA-Z]|x[0-9a-zA-Z]{2}|x{[0-9a-zA-Z]+}/;
|
|
107
86
|
|
|
108
|
-
|
|
87
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
88
|
+
// tokenizer
|
|
109
89
|
|
|
90
|
+
function tokenizer(stream,state) {
|
|
110
91
|
// in multi-line string
|
|
111
92
|
if (state.in_string) {
|
|
112
|
-
state.in_string =
|
|
93
|
+
state.in_string = (!doubleQuote(stream));
|
|
113
94
|
return rval(state,stream,"string");
|
|
114
95
|
}
|
|
115
96
|
|
|
116
97
|
// in multi-line atom
|
|
117
98
|
if (state.in_atom) {
|
|
118
|
-
state.in_atom =
|
|
99
|
+
state.in_atom = (!singleQuote(stream));
|
|
119
100
|
return rval(state,stream,"atom");
|
|
120
101
|
}
|
|
121
102
|
|
|
@@ -125,9 +106,9 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
|
|
|
125
106
|
}
|
|
126
107
|
|
|
127
108
|
// attributes and type specs
|
|
128
|
-
if (
|
|
109
|
+
if (!peekToken(state) &&
|
|
129
110
|
stream.match(/-\s*[a-zß-öø-ÿ][\wØ-ÞÀ-Öß-öø-ÿ]*/)) {
|
|
130
|
-
if (
|
|
111
|
+
if (is_member(stream.current(),typeWords)) {
|
|
131
112
|
return rval(state,stream,"type");
|
|
132
113
|
}else{
|
|
133
114
|
return rval(state,stream,"attribute");
|
|
@@ -142,32 +123,43 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
|
|
|
142
123
|
return rval(state,stream,"comment");
|
|
143
124
|
}
|
|
144
125
|
|
|
126
|
+
// colon
|
|
127
|
+
if (ch == ":") {
|
|
128
|
+
return rval(state,stream,"colon");
|
|
129
|
+
}
|
|
130
|
+
|
|
145
131
|
// macro
|
|
146
132
|
if (ch == '?') {
|
|
133
|
+
stream.eatSpace();
|
|
147
134
|
stream.eatWhile(anumRE);
|
|
148
135
|
return rval(state,stream,"macro");
|
|
149
136
|
}
|
|
150
137
|
|
|
151
138
|
// record
|
|
152
139
|
if (ch == "#") {
|
|
140
|
+
stream.eatSpace();
|
|
153
141
|
stream.eatWhile(anumRE);
|
|
154
142
|
return rval(state,stream,"record");
|
|
155
143
|
}
|
|
156
144
|
|
|
157
145
|
// dollar escape
|
|
158
|
-
if (
|
|
146
|
+
if (ch == "$") {
|
|
159
147
|
if (stream.next() == "\\" && !stream.match(escapesRE)) {
|
|
160
148
|
return rval(state,stream,"error");
|
|
161
149
|
}
|
|
162
150
|
return rval(state,stream,"number");
|
|
163
151
|
}
|
|
164
152
|
|
|
153
|
+
// dot
|
|
154
|
+
if (ch == ".") {
|
|
155
|
+
return rval(state,stream,"dot");
|
|
156
|
+
}
|
|
157
|
+
|
|
165
158
|
// quoted atom
|
|
166
159
|
if (ch == '\'') {
|
|
167
160
|
if (!(state.in_atom = (!singleQuote(stream)))) {
|
|
168
161
|
if (stream.match(/\s*\/\s*[0-9]/,false)) {
|
|
169
162
|
stream.match(/\s*\/\s*[0-9]/,true);
|
|
170
|
-
popToken(state);
|
|
171
163
|
return rval(state,stream,"fun"); // 'f'/0 style fun
|
|
172
164
|
}
|
|
173
165
|
if (stream.match(/\s*\(/,false) || stream.match(/\s*:/,false)) {
|
|
@@ -195,34 +187,37 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
|
|
|
195
187
|
|
|
196
188
|
if (stream.match(/\s*\/\s*[0-9]/,false)) {
|
|
197
189
|
stream.match(/\s*\/\s*[0-9]/,true);
|
|
198
|
-
popToken(state);
|
|
199
190
|
return rval(state,stream,"fun"); // f/0 style fun
|
|
200
191
|
}
|
|
201
192
|
|
|
202
193
|
var w = stream.current();
|
|
203
194
|
|
|
204
|
-
if (
|
|
205
|
-
pushToken(state,stream);
|
|
195
|
+
if (is_member(w,keywordWords)) {
|
|
206
196
|
return rval(state,stream,"keyword");
|
|
197
|
+
}else if (is_member(w,operatorAtomWords)) {
|
|
198
|
+
return rval(state,stream,"operator");
|
|
207
199
|
}else if (stream.match(/\s*\(/,false)) {
|
|
208
200
|
// 'put' and 'erlang:put' are bifs, 'foo:put' is not
|
|
209
|
-
if (
|
|
210
|
-
(
|
|
201
|
+
if (is_member(w,bifWords) &&
|
|
202
|
+
((peekToken(state).token != ":") ||
|
|
203
|
+
(peekToken(state,2).token == "erlang"))) {
|
|
211
204
|
return rval(state,stream,"builtin");
|
|
212
|
-
}else if (
|
|
205
|
+
}else if (is_member(w,guardWords)) {
|
|
213
206
|
return rval(state,stream,"guard");
|
|
214
207
|
}else{
|
|
215
208
|
return rval(state,stream,"function");
|
|
216
209
|
}
|
|
217
|
-
}else if (
|
|
210
|
+
}else if (is_member(w,operatorAtomWords)) {
|
|
218
211
|
return rval(state,stream,"operator");
|
|
219
|
-
}else if (stream
|
|
212
|
+
}else if (lookahead(stream) == ":") {
|
|
220
213
|
if (w == "erlang") {
|
|
221
214
|
return rval(state,stream,"builtin");
|
|
222
215
|
} else {
|
|
223
216
|
return rval(state,stream,"function");
|
|
224
217
|
}
|
|
225
|
-
}else if (
|
|
218
|
+
}else if (is_member(w,["true","false"])) {
|
|
219
|
+
return rval(state,stream,"boolean");
|
|
220
|
+
}else if (is_member(w,["true","false"])) {
|
|
226
221
|
return rval(state,stream,"boolean");
|
|
227
222
|
}else{
|
|
228
223
|
return rval(state,stream,"atom");
|
|
@@ -234,15 +229,25 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
|
|
|
234
229
|
var radixRE = /[0-9a-zA-Z]/; // 36#zZ style int
|
|
235
230
|
if (digitRE.test(ch)) {
|
|
236
231
|
stream.eatWhile(digitRE);
|
|
237
|
-
if (stream.eat('#')) {
|
|
238
|
-
stream.eatWhile(radixRE)
|
|
239
|
-
|
|
240
|
-
if (stream.eat('.')) { // float
|
|
241
|
-
stream.eatWhile(digitRE);
|
|
232
|
+
if (stream.eat('#')) { // 36#aZ style integer
|
|
233
|
+
if (!stream.eatWhile(radixRE)) {
|
|
234
|
+
stream.backUp(1); //"36#" - syntax error
|
|
242
235
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
stream.
|
|
236
|
+
} else if (stream.eat('.')) { // float
|
|
237
|
+
if (!stream.eatWhile(digitRE)) {
|
|
238
|
+
stream.backUp(1); // "3." - probably end of function
|
|
239
|
+
} else {
|
|
240
|
+
if (stream.eat(/[eE]/)) { // float with exponent
|
|
241
|
+
if (stream.eat(/[-+]/)) {
|
|
242
|
+
if (!stream.eatWhile(digitRE)) {
|
|
243
|
+
stream.backUp(2); // "2e-" - syntax error
|
|
244
|
+
}
|
|
245
|
+
} else {
|
|
246
|
+
if (!stream.eatWhile(digitRE)) {
|
|
247
|
+
stream.backUp(1); // "2e" - syntax error
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
246
251
|
}
|
|
247
252
|
}
|
|
248
253
|
return rval(state,stream,"number"); // normal integer
|
|
@@ -250,50 +255,35 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
|
|
|
250
255
|
|
|
251
256
|
// open parens
|
|
252
257
|
if (nongreedy(stream,openParenRE,openParenWords)) {
|
|
253
|
-
pushToken(state,stream);
|
|
254
258
|
return rval(state,stream,"open_paren");
|
|
255
259
|
}
|
|
256
260
|
|
|
257
261
|
// close parens
|
|
258
262
|
if (nongreedy(stream,closeParenRE,closeParenWords)) {
|
|
259
|
-
pushToken(state,stream);
|
|
260
263
|
return rval(state,stream,"close_paren");
|
|
261
264
|
}
|
|
262
265
|
|
|
263
266
|
// separators
|
|
264
267
|
if (greedy(stream,separatorRE,separatorWords)) {
|
|
265
|
-
// distinguish between "." as terminator and record field operator
|
|
266
|
-
if (!state.in_record) {
|
|
267
|
-
pushToken(state,stream);
|
|
268
|
-
}
|
|
269
268
|
return rval(state,stream,"separator");
|
|
270
269
|
}
|
|
271
270
|
|
|
272
271
|
// operators
|
|
273
|
-
if (greedy(stream,
|
|
272
|
+
if (greedy(stream,operatorSymbolRE,operatorSymbolWords)) {
|
|
274
273
|
return rval(state,stream,"operator");
|
|
275
274
|
}
|
|
276
275
|
|
|
277
276
|
return rval(state,stream,null);
|
|
278
277
|
}
|
|
279
278
|
|
|
280
|
-
|
|
281
|
-
|
|
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
|
-
|
|
279
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
280
|
+
// utilities
|
|
291
281
|
function nongreedy(stream,re,words) {
|
|
292
282
|
if (stream.current().length == 1 && re.test(stream.current())) {
|
|
293
283
|
stream.backUp(1);
|
|
294
284
|
while (re.test(stream.peek())) {
|
|
295
285
|
stream.next();
|
|
296
|
-
if (
|
|
286
|
+
if (is_member(stream.current(),words)) {
|
|
297
287
|
return true;
|
|
298
288
|
}
|
|
299
289
|
}
|
|
@@ -308,7 +298,7 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
|
|
|
308
298
|
stream.next();
|
|
309
299
|
}
|
|
310
300
|
while (0 < stream.current().length) {
|
|
311
|
-
if (
|
|
301
|
+
if (is_member(stream.current(),words)) {
|
|
312
302
|
return true;
|
|
313
303
|
}else{
|
|
314
304
|
stream.backUp(1);
|
|
@@ -339,144 +329,277 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
|
|
|
339
329
|
return false;
|
|
340
330
|
}
|
|
341
331
|
|
|
342
|
-
function
|
|
332
|
+
function lookahead(stream) {
|
|
333
|
+
var m = stream.match(/([\n\s]+|%[^\n]*\n)*(.)/,false);
|
|
334
|
+
return m ? m.pop() : "";
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function is_member(element,list) {
|
|
343
338
|
return (-1 < list.indexOf(element));
|
|
344
339
|
}
|
|
345
340
|
|
|
346
|
-
|
|
347
|
-
function myIndent(state,textAfter) {
|
|
348
|
-
var indent = cmCfg.indentUnit;
|
|
349
|
-
var token = (peekToken(state)).token;
|
|
350
|
-
var wordAfter = takewhile(textAfter,/[^a-z]/);
|
|
341
|
+
function rval(state,stream,type) {
|
|
351
342
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
return
|
|
360
|
-
|
|
361
|
-
return
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
return
|
|
374
|
-
|
|
375
|
-
return
|
|
343
|
+
// parse stack
|
|
344
|
+
pushToken(state,realToken(type,stream));
|
|
345
|
+
|
|
346
|
+
// map erlang token type to CodeMirror style class
|
|
347
|
+
// erlang -> CodeMirror tag
|
|
348
|
+
switch (type) {
|
|
349
|
+
case "atom": return "atom";
|
|
350
|
+
case "attribute": return "attribute";
|
|
351
|
+
case "boolean": return "special";
|
|
352
|
+
case "builtin": return "builtin";
|
|
353
|
+
case "close_paren": return null;
|
|
354
|
+
case "colon": return null;
|
|
355
|
+
case "comment": return "comment";
|
|
356
|
+
case "dot": return null;
|
|
357
|
+
case "error": return "error";
|
|
358
|
+
case "fun": return "meta";
|
|
359
|
+
case "function": return "tag";
|
|
360
|
+
case "guard": return "property";
|
|
361
|
+
case "keyword": return "keyword";
|
|
362
|
+
case "macro": return "variable-2";
|
|
363
|
+
case "number": return "number";
|
|
364
|
+
case "open_paren": return null;
|
|
365
|
+
case "operator": return "operator";
|
|
366
|
+
case "record": return "bracket";
|
|
367
|
+
case "separator": return null;
|
|
368
|
+
case "string": return "string";
|
|
369
|
+
case "type": return "def";
|
|
370
|
+
case "variable": return "variable";
|
|
371
|
+
default: return null;
|
|
376
372
|
}
|
|
377
373
|
}
|
|
378
374
|
|
|
379
|
-
function
|
|
380
|
-
|
|
381
|
-
|
|
375
|
+
function aToken(tok,col,ind,typ) {
|
|
376
|
+
return {token: tok,
|
|
377
|
+
column: col,
|
|
378
|
+
indent: ind,
|
|
379
|
+
type: typ};
|
|
382
380
|
}
|
|
383
381
|
|
|
384
|
-
function
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
382
|
+
function realToken(type,stream) {
|
|
383
|
+
return aToken(stream.current(),
|
|
384
|
+
stream.column(),
|
|
385
|
+
stream.indentation(),
|
|
386
|
+
type);
|
|
388
387
|
}
|
|
389
388
|
|
|
390
|
-
function
|
|
391
|
-
return
|
|
389
|
+
function fakeToken(type) {
|
|
390
|
+
return aToken(type,0,0,type);
|
|
392
391
|
}
|
|
393
392
|
|
|
394
393
|
function peekToken(state,depth) {
|
|
395
394
|
var len = state.tokenStack.length;
|
|
396
395
|
var dep = (depth ? depth : 1);
|
|
396
|
+
|
|
397
397
|
if (len < dep) {
|
|
398
|
-
return
|
|
398
|
+
return false;
|
|
399
399
|
}else{
|
|
400
400
|
return state.tokenStack[len-dep];
|
|
401
401
|
}
|
|
402
402
|
}
|
|
403
403
|
|
|
404
|
-
function pushToken(state,
|
|
405
|
-
var token = stream.current();
|
|
406
|
-
var prev_token = peekToken(state).token;
|
|
404
|
+
function pushToken(state,token) {
|
|
407
405
|
|
|
408
|
-
if (token == ".") {
|
|
409
|
-
state.tokenStack =
|
|
410
|
-
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
return false;
|
|
406
|
+
if (!(token.type == "comment" || token.type == "whitespace")) {
|
|
407
|
+
state.tokenStack = maybe_drop_pre(state.tokenStack,token);
|
|
408
|
+
state.tokenStack = maybe_drop_post(state.tokenStack);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
function maybe_drop_pre(s,token) {
|
|
413
|
+
var last = s.length-1;
|
|
414
|
+
|
|
415
|
+
if (0 < last && s[last].type === "record" && token.type === "dot") {
|
|
416
|
+
s.pop();
|
|
417
|
+
}else if (0 < last && s[last].type === "group") {
|
|
418
|
+
s.pop();
|
|
419
|
+
s.push(token);
|
|
423
420
|
}else{
|
|
424
|
-
|
|
425
|
-
return true;
|
|
421
|
+
s.push(token);
|
|
426
422
|
}
|
|
423
|
+
return s;
|
|
427
424
|
}
|
|
428
425
|
|
|
429
|
-
function
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
426
|
+
function maybe_drop_post(s) {
|
|
427
|
+
var last = s.length-1;
|
|
428
|
+
|
|
429
|
+
if (s[last].type === "dot") {
|
|
430
|
+
return [];
|
|
431
|
+
}
|
|
432
|
+
if (s[last].type === "fun" && s[last-1].token === "fun") {
|
|
433
|
+
return s.slice(0,last-1);
|
|
434
|
+
}
|
|
435
|
+
switch (s[s.length-1].token) {
|
|
436
|
+
case "}": return d(s,{g:["{"]});
|
|
437
|
+
case "]": return d(s,{i:["["]});
|
|
438
|
+
case ")": return d(s,{i:["("]});
|
|
439
|
+
case ">>": return d(s,{i:["<<"]});
|
|
440
|
+
case "end": return d(s,{i:["begin","case","fun","if","receive","try"]});
|
|
441
|
+
case ",": return d(s,{e:["begin","try","when","->",
|
|
442
|
+
",","(","[","{","<<"]});
|
|
443
|
+
case "->": return d(s,{r:["when"],
|
|
444
|
+
m:["try","if","case","receive"]});
|
|
445
|
+
case ";": return d(s,{E:["case","fun","if","receive","try","when"]});
|
|
446
|
+
case "catch":return d(s,{e:["try"]});
|
|
447
|
+
case "of": return d(s,{e:["case"]});
|
|
448
|
+
case "after":return d(s,{e:["receive","try"]});
|
|
449
|
+
default: return s;
|
|
433
450
|
}
|
|
434
451
|
}
|
|
435
452
|
|
|
436
|
-
function
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
453
|
+
function d(stack,tt) {
|
|
454
|
+
// stack is a stack of Token objects.
|
|
455
|
+
// tt is an object; {type:tokens}
|
|
456
|
+
// type is a char, tokens is a list of token strings.
|
|
457
|
+
// The function returns (possibly truncated) stack.
|
|
458
|
+
// It will descend the stack, looking for a Token such that Token.token
|
|
459
|
+
// is a member of tokens. If it does not find that, it will normally (but
|
|
460
|
+
// see "E" below) return stack. If it does find a match, it will remove
|
|
461
|
+
// all the Tokens between the top and the matched Token.
|
|
462
|
+
// If type is "m", that is all it does.
|
|
463
|
+
// If type is "i", it will also remove the matched Token and the top Token.
|
|
464
|
+
// If type is "g", like "i", but add a fake "group" token at the top.
|
|
465
|
+
// If type is "r", it will remove the matched Token, but not the top Token.
|
|
466
|
+
// If type is "e", it will keep the matched Token but not the top Token.
|
|
467
|
+
// If type is "E", it behaves as for type "e", except if there is no match,
|
|
468
|
+
// in which case it will return an empty stack.
|
|
469
|
+
|
|
470
|
+
for (var type in tt) {
|
|
471
|
+
var len = stack.length-1;
|
|
472
|
+
var tokens = tt[type];
|
|
473
|
+
for (var i = len-1; -1 < i ; i--) {
|
|
474
|
+
if (is_member(stack[i].token,tokens)) {
|
|
475
|
+
var ss = stack.slice(0,i);
|
|
476
|
+
switch (type) {
|
|
477
|
+
case "m": return ss.concat(stack[i]).concat(stack[len]);
|
|
478
|
+
case "r": return ss.concat(stack[len]);
|
|
479
|
+
case "i": return ss;
|
|
480
|
+
case "g": return ss.concat(fakeToken("group"));
|
|
481
|
+
case "E": return ss.concat(stack[i]);
|
|
482
|
+
case "e": return ss.concat(stack[i]);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
441
486
|
}
|
|
487
|
+
return (type == "E" ? [] : stack);
|
|
442
488
|
}
|
|
443
489
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
490
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
491
|
+
// indenter
|
|
492
|
+
|
|
493
|
+
function indenter(state,textAfter) {
|
|
494
|
+
var t;
|
|
495
|
+
var unit = cmCfg.indentUnit;
|
|
496
|
+
var wordAfter = wordafter(textAfter);
|
|
497
|
+
var currT = peekToken(state,1);
|
|
498
|
+
var prevT = peekToken(state,2);
|
|
499
|
+
|
|
500
|
+
if (state.in_string || state.in_atom) {
|
|
501
|
+
return CodeMirror.Pass;
|
|
502
|
+
}else if (!prevT) {
|
|
503
|
+
return 0;
|
|
504
|
+
}else if (currT.token == "when") {
|
|
505
|
+
return currT.column+unit;
|
|
506
|
+
}else if (wordAfter === "when" && prevT.type === "function") {
|
|
507
|
+
return prevT.indent+unit;
|
|
508
|
+
}else if (wordAfter === "(" && currT.token === "fun") {
|
|
509
|
+
return currT.column+3;
|
|
510
|
+
}else if (wordAfter === "catch" && (t = getToken(state,["try"]))) {
|
|
511
|
+
return t.column;
|
|
512
|
+
}else if (is_member(wordAfter,["end","after","of"])) {
|
|
513
|
+
t = getToken(state,["begin","case","fun","if","receive","try"]);
|
|
514
|
+
return t ? t.column : CodeMirror.Pass;
|
|
515
|
+
}else if (is_member(wordAfter,closeParenWords)) {
|
|
516
|
+
t = getToken(state,openParenWords);
|
|
517
|
+
return t ? t.column : CodeMirror.Pass;
|
|
518
|
+
}else if (is_member(currT.token,[",","|","||"]) ||
|
|
519
|
+
is_member(wordAfter,[",","|","||"])) {
|
|
520
|
+
t = postcommaToken(state);
|
|
521
|
+
return t ? t.column+t.token.length : unit;
|
|
522
|
+
}else if (currT.token == "->") {
|
|
523
|
+
if (is_member(prevT.token, ["receive","case","if","try"])) {
|
|
524
|
+
return prevT.column+unit+unit;
|
|
525
|
+
}else{
|
|
526
|
+
return prevT.column+unit;
|
|
527
|
+
}
|
|
528
|
+
}else if (is_member(currT.token,openParenWords)) {
|
|
529
|
+
return currT.column+currT.token.length;
|
|
530
|
+
}else{
|
|
531
|
+
t = defaultToken(state);
|
|
532
|
+
return truthy(t) ? t.column+unit : 0;
|
|
460
533
|
}
|
|
461
534
|
}
|
|
462
535
|
|
|
536
|
+
function wordafter(str) {
|
|
537
|
+
var m = str.match(/,|[a-z]+|\}|\]|\)|>>|\|+|\(/);
|
|
538
|
+
|
|
539
|
+
return truthy(m) && (m.index === 0) ? m[0] : "";
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
function postcommaToken(state) {
|
|
543
|
+
var objs = state.tokenStack.slice(0,-1);
|
|
544
|
+
var i = getTokenIndex(objs,"type",["open_paren"]);
|
|
545
|
+
|
|
546
|
+
return truthy(objs[i]) ? objs[i] : false;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
function defaultToken(state) {
|
|
550
|
+
var objs = state.tokenStack;
|
|
551
|
+
var stop = getTokenIndex(objs,"type",["open_paren","separator","keyword"]);
|
|
552
|
+
var oper = getTokenIndex(objs,"type",["operator"]);
|
|
553
|
+
|
|
554
|
+
if (truthy(stop) && truthy(oper) && stop < oper) {
|
|
555
|
+
return objs[stop+1];
|
|
556
|
+
} else if (truthy(stop)) {
|
|
557
|
+
return objs[stop];
|
|
558
|
+
} else {
|
|
559
|
+
return false;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
function getToken(state,tokens) {
|
|
564
|
+
var objs = state.tokenStack;
|
|
565
|
+
var i = getTokenIndex(objs,"token",tokens);
|
|
566
|
+
|
|
567
|
+
return truthy(objs[i]) ? objs[i] : false;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
function getTokenIndex(objs,propname,propvals) {
|
|
571
|
+
|
|
572
|
+
for (var i = objs.length-1; -1 < i ; i--) {
|
|
573
|
+
if (is_member(objs[i][propname],propvals)) {
|
|
574
|
+
return i;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
function truthy(x) {
|
|
581
|
+
return (x !== false) && (x != null);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
585
|
+
// this object defines the mode
|
|
586
|
+
|
|
463
587
|
return {
|
|
464
588
|
startState:
|
|
465
589
|
function() {
|
|
466
590
|
return {tokenStack: [],
|
|
467
|
-
in_record: false,
|
|
468
591
|
in_string: false,
|
|
469
592
|
in_atom: false};
|
|
470
593
|
},
|
|
471
594
|
|
|
472
595
|
token:
|
|
473
596
|
function(stream, state) {
|
|
474
|
-
return
|
|
597
|
+
return tokenizer(stream, state);
|
|
475
598
|
},
|
|
476
599
|
|
|
477
600
|
indent:
|
|
478
601
|
function(state, textAfter) {
|
|
479
|
-
return
|
|
602
|
+
return indenter(state,textAfter);
|
|
480
603
|
},
|
|
481
604
|
|
|
482
605
|
lineComment: "%"
|