codemirror-rails 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +40 -7
- data/lib/codemirror/rails.rb +2 -0
- data/lib/codemirror/rails/engine.rb +6 -0
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +85 -45
- data/vendor/assets/javascripts/codemirror/modes/clojure.js +207 -0
- data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +42 -25
- data/vendor/assets/javascripts/codemirror/modes/css.js +3 -3
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +4 -0
- data/vendor/assets/javascripts/codemirror/modes/jinja2.js +42 -0
- data/vendor/assets/javascripts/codemirror/modes/lua.js +4 -2
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +230 -0
- data/vendor/assets/javascripts/codemirror/modes/ntriples.js +172 -0
- data/vendor/assets/javascripts/codemirror/modes/pascal.js +138 -0
- data/vendor/assets/javascripts/codemirror/modes/php.js +3 -2
- data/vendor/assets/javascripts/codemirror/modes/python.js +5 -6
- data/vendor/assets/javascripts/codemirror/modes/r.js +9 -2
- data/vendor/assets/javascripts/codemirror/modes/ruby.js +36 -23
- data/vendor/assets/javascripts/codemirror/modes/scheme.js +51 -31
- data/vendor/assets/javascripts/codemirror/modes/xml.js +4 -4
- data/vendor/assets/stylesheets/codemirror.css +1 -0
- data/vendor/assets/stylesheets/codemirror/modes/markdown.css +10 -0
- data/vendor/assets/stylesheets/codemirror/themes/cobalt.css +17 -0
- data/vendor/assets/stylesheets/codemirror/themes/eclipse.css +24 -0
- metadata +12 -5
@@ -0,0 +1,172 @@
|
|
1
|
+
/**********************************************************
|
2
|
+
* This script provides syntax highlighting support for
|
3
|
+
* the Ntriples format.
|
4
|
+
* Ntriples format specification:
|
5
|
+
* http://www.w3.org/TR/rdf-testcases/#ntriples
|
6
|
+
***********************************************************/
|
7
|
+
|
8
|
+
/*
|
9
|
+
The following expression defines the defined ASF grammar transitions.
|
10
|
+
|
11
|
+
pre_subject ->
|
12
|
+
{
|
13
|
+
( writing_subject_uri | writing_bnode_uri )
|
14
|
+
-> pre_predicate
|
15
|
+
-> writing_predicate_uri
|
16
|
+
-> pre_object
|
17
|
+
-> writing_object_uri | writing_object_bnode |
|
18
|
+
(
|
19
|
+
writing_object_literal
|
20
|
+
-> writing_literal_lang | writing_literal_type
|
21
|
+
)
|
22
|
+
-> post_object
|
23
|
+
-> BEGIN
|
24
|
+
} otherwise {
|
25
|
+
-> ERROR
|
26
|
+
}
|
27
|
+
*/
|
28
|
+
CodeMirror.defineMode("ntriples", function() {
|
29
|
+
|
30
|
+
Location = {
|
31
|
+
PRE_SUBJECT : 0,
|
32
|
+
WRITING_SUB_URI : 1,
|
33
|
+
WRITING_BNODE_URI : 2,
|
34
|
+
PRE_PRED : 3,
|
35
|
+
WRITING_PRED_URI : 4,
|
36
|
+
PRE_OBJ : 5,
|
37
|
+
WRITING_OBJ_URI : 6,
|
38
|
+
WRITING_OBJ_BNODE : 7,
|
39
|
+
WRITING_OBJ_LITERAL : 8,
|
40
|
+
WRITING_LIT_LANG : 9,
|
41
|
+
WRITING_LIT_TYPE : 10,
|
42
|
+
POST_OBJ : 11,
|
43
|
+
ERROR : 12
|
44
|
+
};
|
45
|
+
function transitState(currState, c) {
|
46
|
+
var currLocation = currState.location;
|
47
|
+
var ret;
|
48
|
+
|
49
|
+
// Opening.
|
50
|
+
if (currLocation == Location.PRE_SUBJECT && c == '<') ret = Location.WRITING_SUB_URI;
|
51
|
+
else if(currLocation == Location.PRE_SUBJECT && c == '_') ret = Location.WRITING_BNODE_URI;
|
52
|
+
else if(currLocation == Location.PRE_PRED && c == '<') ret = Location.WRITING_PRED_URI;
|
53
|
+
else if(currLocation == Location.PRE_OBJ && c == '<') ret = Location.WRITING_OBJ_URI;
|
54
|
+
else if(currLocation == Location.PRE_OBJ && c == '_') ret = Location.WRITING_OBJ_BNODE;
|
55
|
+
else if(currLocation == Location.PRE_OBJ && c == '"') ret = Location.WRITING_OBJ_LITERAL;
|
56
|
+
|
57
|
+
// Closing.
|
58
|
+
else if(currLocation == Location.WRITING_SUB_URI && c == '>') ret = Location.PRE_PRED;
|
59
|
+
else if(currLocation == Location.WRITING_BNODE_URI && c == ' ') ret = Location.PRE_PRED;
|
60
|
+
else if(currLocation == Location.WRITING_PRED_URI && c == '>') ret = Location.PRE_OBJ;
|
61
|
+
else if(currLocation == Location.WRITING_OBJ_URI && c == '>') ret = Location.POST_OBJ;
|
62
|
+
else if(currLocation == Location.WRITING_OBJ_BNODE && c == ' ') ret = Location.POST_OBJ;
|
63
|
+
else if(currLocation == Location.WRITING_OBJ_LITERAL && c == '"') ret = Location.POST_OBJ;
|
64
|
+
else if(currLocation == Location.WRITING_LIT_LANG && c == ' ') ret = Location.POST_OBJ;
|
65
|
+
else if(currLocation == Location.WRITING_LIT_TYPE && c == '>') ret = Location.POST_OBJ;
|
66
|
+
|
67
|
+
// Closing typed and language literal.
|
68
|
+
else if(currLocation == Location.WRITING_OBJ_LITERAL && c == '@') ret = Location.WRITING_LIT_LANG;
|
69
|
+
else if(currLocation == Location.WRITING_OBJ_LITERAL && c == '^') ret = Location.WRITING_LIT_TYPE;
|
70
|
+
|
71
|
+
// Spaces.
|
72
|
+
else if( c == ' ' &&
|
73
|
+
(
|
74
|
+
currLocation == Location.PRE_SUBJECT ||
|
75
|
+
currLocation == Location.PRE_PRED ||
|
76
|
+
currLocation == Location.PRE_OBJ ||
|
77
|
+
currLocation == Location.POST_OBJ
|
78
|
+
)
|
79
|
+
) ret = currLocation;
|
80
|
+
|
81
|
+
// Reset.
|
82
|
+
else if(currLocation == Location.POST_OBJ && c == '.') ret = Location.PRE_SUBJECT;
|
83
|
+
|
84
|
+
// Error
|
85
|
+
else ret = Location.ERROR;
|
86
|
+
|
87
|
+
currState.location=ret;
|
88
|
+
}
|
89
|
+
|
90
|
+
untilSpace = function(c) { return c != ' '; };
|
91
|
+
untilEndURI = function(c) { return c != '>'; };
|
92
|
+
return {
|
93
|
+
startState: function() {
|
94
|
+
return {
|
95
|
+
location : Location.PRE_SUBJECT,
|
96
|
+
uris : [],
|
97
|
+
anchors : [],
|
98
|
+
bnodes : [],
|
99
|
+
langs : [],
|
100
|
+
types : []
|
101
|
+
};
|
102
|
+
},
|
103
|
+
token: function(stream, state) {
|
104
|
+
var ch = stream.next();
|
105
|
+
if(ch == '<') {
|
106
|
+
transitState(state, ch);
|
107
|
+
var parsedURI = '';
|
108
|
+
stream.eatWhile( function(c) { if( c != '#' && c != '>' ) { parsedURI += c; return true; } return false;} );
|
109
|
+
state.uris.push(parsedURI);
|
110
|
+
if( stream.match('#', false) ) return 'variable';
|
111
|
+
stream.next();
|
112
|
+
transitState(state, '>');
|
113
|
+
return 'variable';
|
114
|
+
}
|
115
|
+
if(ch == '#') {
|
116
|
+
var parsedAnchor = '';
|
117
|
+
stream.eatWhile(function(c) { if(c != '>' && c != ' ') { parsedAnchor+= c; return true; } return false});
|
118
|
+
state.anchors.push(parsedAnchor);
|
119
|
+
return 'variable-2';
|
120
|
+
}
|
121
|
+
if(ch == '>') {
|
122
|
+
transitState(state, '>');
|
123
|
+
return 'variable';
|
124
|
+
}
|
125
|
+
if(ch == '_') {
|
126
|
+
transitState(state, ch);
|
127
|
+
var parsedBNode = '';
|
128
|
+
stream.eatWhile(function(c) { if( c != ' ' ) { parsedBNode += c; return true; } return false;});
|
129
|
+
state.bnodes.push(parsedBNode);
|
130
|
+
stream.next();
|
131
|
+
transitState(state, ' ');
|
132
|
+
return 'builtin';
|
133
|
+
}
|
134
|
+
if(ch == '"') {
|
135
|
+
transitState(state, ch);
|
136
|
+
stream.eatWhile( function(c) { return c != '"'; } );
|
137
|
+
stream.next();
|
138
|
+
if( stream.peek() != '@' && stream.peek() != '^' ) {
|
139
|
+
transitState(state, '"');
|
140
|
+
}
|
141
|
+
return 'string';
|
142
|
+
}
|
143
|
+
if( ch == '@' ) {
|
144
|
+
transitState(state, '@');
|
145
|
+
var parsedLang = '';
|
146
|
+
stream.eatWhile(function(c) { if( c != ' ' ) { parsedLang += c; return true; } return false;});
|
147
|
+
state.langs.push(parsedLang);
|
148
|
+
stream.next();
|
149
|
+
transitState(state, ' ');
|
150
|
+
return 'string-2';
|
151
|
+
}
|
152
|
+
if( ch == '^' ) {
|
153
|
+
stream.next();
|
154
|
+
transitState(state, '^');
|
155
|
+
var parsedType = '';
|
156
|
+
stream.eatWhile(function(c) { if( c != '>' ) { parsedType += c; return true; } return false;} );
|
157
|
+
state.types.push(parsedType);
|
158
|
+
stream.next();
|
159
|
+
transitState(state, '>');
|
160
|
+
return 'variable';
|
161
|
+
}
|
162
|
+
if( ch == ' ' ) {
|
163
|
+
transitState(state, ch);
|
164
|
+
}
|
165
|
+
if( ch == '.' ) {
|
166
|
+
transitState(state, ch);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
};
|
170
|
+
});
|
171
|
+
|
172
|
+
CodeMirror.defineMIME("text/n-triples", "ntriples");
|
@@ -0,0 +1,138 @@
|
|
1
|
+
CodeMirror.defineMode("pascal", function(config) {
|
2
|
+
function words(str) {
|
3
|
+
var obj = {}, words = str.split(" ");
|
4
|
+
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
|
5
|
+
return obj;
|
6
|
+
}
|
7
|
+
var keywords = words("and array begin case const div do downto else end file for forward integer " +
|
8
|
+
"boolean char function goto if in label mod nil not of or packed procedure " +
|
9
|
+
"program record repeat set string then to type until var while with");
|
10
|
+
var blockKeywords = words("case do else for if switch while struct then of");
|
11
|
+
var atoms = {"null": true};
|
12
|
+
|
13
|
+
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
|
14
|
+
var curPunc;
|
15
|
+
|
16
|
+
function tokenBase(stream, state) {
|
17
|
+
var ch = stream.next();
|
18
|
+
if (ch == "#" && state.startOfLine) {
|
19
|
+
stream.skipToEnd();
|
20
|
+
return "meta";
|
21
|
+
}
|
22
|
+
if (ch == '"' || ch == "'") {
|
23
|
+
state.tokenize = tokenString(ch);
|
24
|
+
return state.tokenize(stream, state);
|
25
|
+
}
|
26
|
+
if (ch == "(" && stream.eat("*")) {
|
27
|
+
state.tokenize = tokenComment;
|
28
|
+
return tokenComment(stream, state);
|
29
|
+
}
|
30
|
+
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
|
31
|
+
curPunc = ch;
|
32
|
+
return null
|
33
|
+
}
|
34
|
+
if (/\d/.test(ch)) {
|
35
|
+
stream.eatWhile(/[\w\.]/);
|
36
|
+
return "number";
|
37
|
+
}
|
38
|
+
if (ch == "/") {
|
39
|
+
if (stream.eat("/")) {
|
40
|
+
stream.skipToEnd();
|
41
|
+
return "comment";
|
42
|
+
}
|
43
|
+
}
|
44
|
+
if (isOperatorChar.test(ch)) {
|
45
|
+
stream.eatWhile(isOperatorChar);
|
46
|
+
return "operator";
|
47
|
+
}
|
48
|
+
stream.eatWhile(/[\w\$_]/);
|
49
|
+
var cur = stream.current();
|
50
|
+
if (keywords.propertyIsEnumerable(cur)) {
|
51
|
+
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
52
|
+
return "keyword";
|
53
|
+
}
|
54
|
+
if (atoms.propertyIsEnumerable(cur)) return "atom";
|
55
|
+
return "word";
|
56
|
+
}
|
57
|
+
|
58
|
+
function tokenString(quote) {
|
59
|
+
return function(stream, state) {
|
60
|
+
var escaped = false, next, end = false;
|
61
|
+
while ((next = stream.next()) != null) {
|
62
|
+
if (next == quote && !escaped) {end = true; break;}
|
63
|
+
escaped = !escaped && next == "\\";
|
64
|
+
}
|
65
|
+
if (end || !escaped) state.tokenize = null;
|
66
|
+
return "string";
|
67
|
+
};
|
68
|
+
}
|
69
|
+
|
70
|
+
function tokenComment(stream, state) {
|
71
|
+
var maybeEnd = false, ch;
|
72
|
+
while (ch = stream.next()) {
|
73
|
+
if (ch == ")" && maybeEnd) {
|
74
|
+
state.tokenize = null;
|
75
|
+
break;
|
76
|
+
}
|
77
|
+
maybeEnd = (ch == "*");
|
78
|
+
}
|
79
|
+
return "comment";
|
80
|
+
}
|
81
|
+
|
82
|
+
function Context(indented, column, type, align, prev) {
|
83
|
+
this.indented = indented;
|
84
|
+
this.column = column;
|
85
|
+
this.type = type;
|
86
|
+
this.align = align;
|
87
|
+
this.prev = prev;
|
88
|
+
}
|
89
|
+
function pushContext(state, col, type) {
|
90
|
+
return state.context = new Context(state.indented, col, type, null, state.context);
|
91
|
+
}
|
92
|
+
function popContext(state) {
|
93
|
+
var t = state.context.type;
|
94
|
+
if (t == ")" || t == "]" )
|
95
|
+
state.indented = state.context.indented;
|
96
|
+
return state.context = state.context.prev;
|
97
|
+
}
|
98
|
+
|
99
|
+
// Interface
|
100
|
+
|
101
|
+
return {
|
102
|
+
startState: function(basecolumn) {
|
103
|
+
return {
|
104
|
+
tokenize: null,
|
105
|
+
context: new Context((basecolumn || 0) - config.indentUnit, 0, "top", false),
|
106
|
+
indented: 0,
|
107
|
+
startOfLine: true
|
108
|
+
};
|
109
|
+
},
|
110
|
+
|
111
|
+
token: function(stream, state) {
|
112
|
+
var ctx = state.context;
|
113
|
+
if (stream.sol()) {
|
114
|
+
if (ctx.align == null) ctx.align = false;
|
115
|
+
state.indented = stream.indentation();
|
116
|
+
state.startOfLine = true;
|
117
|
+
}
|
118
|
+
if (stream.eatSpace()) return null;
|
119
|
+
curPunc = null;
|
120
|
+
var style = (state.tokenize || tokenBase)(stream, state);
|
121
|
+
if (style == "comment" || style == "meta") return style;
|
122
|
+
if (ctx.align == null) ctx.align = true;
|
123
|
+
|
124
|
+
if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
|
125
|
+
else if (curPunc == "[") pushContext(state, stream.column(), "]");
|
126
|
+
else if (curPunc == "(") pushContext(state, stream.column(), ")");
|
127
|
+
else if (curPunc == ctx.type) popContext(state);
|
128
|
+
else if ( ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
|
129
|
+
pushContext(state, stream.column(), "statement");
|
130
|
+
state.startOfLine = false;
|
131
|
+
return style;
|
132
|
+
},
|
133
|
+
|
134
|
+
electricChars: "{}"
|
135
|
+
};
|
136
|
+
});
|
137
|
+
|
138
|
+
CodeMirror.defineMIME("text/x-pascal", "pascal");
|
@@ -16,9 +16,10 @@
|
|
16
16
|
keywords: keywords("abstract and array as break case catch cfunction class clone const continue declare " +
|
17
17
|
"default do else elseif enddeclare endfor endforeach endif endswitch endwhile extends " +
|
18
18
|
"final for foreach function global goto if implements interface instanceof namespace " +
|
19
|
-
"new or private protected public static switch throw try use var while xor return"
|
19
|
+
"new or private protected public static switch throw try use var while xor return" +
|
20
|
+
"die echo empty exit eval include include_once isset list require require_once print unset"),
|
20
21
|
blockKeywords: keywords("catch do else elseif for foreach if switch try while"),
|
21
|
-
atoms: keywords("true false null"),
|
22
|
+
atoms: keywords("true false null TRUE FALSE NULL"),
|
22
23
|
multiLineStrings: true,
|
23
24
|
hooks: {
|
24
25
|
"$": function(stream, state) {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
CodeMirror.defineMode("python", function(conf) {
|
1
|
+
CodeMirror.defineMode("python", function(conf, parserConf) {
|
2
2
|
var ERRORCLASS = 'error';
|
3
3
|
|
4
4
|
function wordRegexp(words) {
|
@@ -29,7 +29,7 @@ CodeMirror.defineMode("python", function(conf) {
|
|
29
29
|
'open', 'range', 'zip'],
|
30
30
|
'keywords': ['nonlocal']};
|
31
31
|
|
32
|
-
if (!!
|
32
|
+
if (!!parserConf.version && parseInt(parserConf.version, 10) === 3) {
|
33
33
|
commonkeywords = commonkeywords.concat(py3.keywords);
|
34
34
|
commontypes = commontypes.concat(py3.types);
|
35
35
|
var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i");
|
@@ -147,10 +147,9 @@ CodeMirror.defineMode("python", function(conf) {
|
|
147
147
|
}
|
148
148
|
|
149
149
|
function tokenStringFactory(delimiter) {
|
150
|
-
while ('rub'.indexOf(delimiter
|
150
|
+
while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
|
151
151
|
delimiter = delimiter.substr(1);
|
152
152
|
}
|
153
|
-
var delim_re = new RegExp(delimiter);
|
154
153
|
var singleline = delimiter.length == 1;
|
155
154
|
var OUTCLASS = 'string';
|
156
155
|
|
@@ -162,7 +161,7 @@ CodeMirror.defineMode("python", function(conf) {
|
|
162
161
|
if (singleline && stream.eol()) {
|
163
162
|
return OUTCLASS;
|
164
163
|
}
|
165
|
-
} else if (stream.match(
|
164
|
+
} else if (stream.match(delimiter)) {
|
166
165
|
state.tokenize = tokenBase;
|
167
166
|
return OUTCLASS;
|
168
167
|
} else {
|
@@ -170,7 +169,7 @@ CodeMirror.defineMode("python", function(conf) {
|
|
170
169
|
}
|
171
170
|
}
|
172
171
|
if (singleline) {
|
173
|
-
if (
|
172
|
+
if (parserConf.singleLineStringErrors) {
|
174
173
|
return ERRORCLASS;
|
175
174
|
} else {
|
176
175
|
state.tokenize = tokenBase;
|
@@ -46,6 +46,8 @@ CodeMirror.defineMode("r", function(config) {
|
|
46
46
|
return "variable-2";
|
47
47
|
} else if (ch == "<" && stream.eat("-")) {
|
48
48
|
return "arrow";
|
49
|
+
} else if (ch == "=" && state.ctx.argList) {
|
50
|
+
return "arg-is";
|
49
51
|
} else if (opChars.test(ch)) {
|
50
52
|
if (ch == "$") return "dollar";
|
51
53
|
stream.eatWhile(opChars);
|
@@ -98,7 +100,8 @@ CodeMirror.defineMode("r", function(config) {
|
|
98
100
|
ctx: {type: "top",
|
99
101
|
indent: -config.indentUnit,
|
100
102
|
align: false},
|
101
|
-
indent: 0
|
103
|
+
indent: 0,
|
104
|
+
afterIdent: false};
|
102
105
|
},
|
103
106
|
|
104
107
|
token: function(stream, state) {
|
@@ -113,10 +116,14 @@ CodeMirror.defineMode("r", function(config) {
|
|
113
116
|
var ctype = state.ctx.type;
|
114
117
|
if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && ctype == "block") pop(state);
|
115
118
|
if (curPunc == "{") push(state, "}", stream);
|
116
|
-
else if (curPunc == "(")
|
119
|
+
else if (curPunc == "(") {
|
120
|
+
push(state, ")", stream);
|
121
|
+
if (state.afterIdent) state.ctx.argList = true;
|
122
|
+
}
|
117
123
|
else if (curPunc == "[") push(state, "]", stream);
|
118
124
|
else if (curPunc == "block") push(state, "block", stream);
|
119
125
|
else if (curPunc == ctype) pop(state);
|
126
|
+
state.afterIdent = style == "variable" || style == "keyword";
|
120
127
|
return style;
|
121
128
|
},
|
122
129
|
|
@@ -19,28 +19,29 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
|
|
19
19
|
var curPunc;
|
20
20
|
|
21
21
|
function chain(newtok, stream, state) {
|
22
|
-
state.tokenize
|
22
|
+
state.tokenize.push(newtok);
|
23
23
|
return newtok(stream, state);
|
24
24
|
}
|
25
25
|
|
26
26
|
function tokenBase(stream, state) {
|
27
27
|
curPunc = null;
|
28
28
|
if (stream.sol() && stream.match("=begin") && stream.eol()) {
|
29
|
-
state.tokenize
|
29
|
+
state.tokenize.push(readBlockComment);
|
30
30
|
return "comment";
|
31
31
|
}
|
32
32
|
if (stream.eatSpace()) return null;
|
33
33
|
var ch = stream.next();
|
34
34
|
if (ch == "`" || ch == "'" || ch == '"' || ch == "/") {
|
35
|
-
return chain(readQuoted(ch, "string"), stream, state);
|
35
|
+
return chain(readQuoted(ch, "string", ch == '"'), stream, state);
|
36
36
|
} else if (ch == "%") {
|
37
|
-
var style;
|
37
|
+
var style, embed = false;
|
38
38
|
if (stream.eat("s")) style = "atom";
|
39
|
-
else if (stream.eat(/[
|
39
|
+
else if (stream.eat(/[WQ]/)) { style = "string"; embed = true; }
|
40
|
+
else if (stream.eat(/[wxqr]/)) style = "string";
|
40
41
|
var delim = stream.eat(/[^\w\s]/);
|
41
42
|
if (!delim) return "operator";
|
42
43
|
if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
|
43
|
-
return chain(
|
44
|
+
return chain(readQuoted(delim, style, embed, true), stream, state);
|
44
45
|
} else if (ch == "#") {
|
45
46
|
stream.skipToEnd();
|
46
47
|
return "comment";
|
@@ -65,8 +66,8 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
|
|
65
66
|
else stream.next();
|
66
67
|
return "string";
|
67
68
|
} else if (ch == ":") {
|
68
|
-
if (stream.eat("'")) return chain(readQuoted("'", "atom"), stream, state);
|
69
|
-
if (stream.eat('"')) return chain(readQuoted('"', "atom"), stream, state);
|
69
|
+
if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
|
70
|
+
if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
|
70
71
|
stream.eatWhile(/[\w\?]/);
|
71
72
|
return "atom";
|
72
73
|
} else if (ch == "@") {
|
@@ -97,12 +98,31 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
|
|
97
98
|
}
|
98
99
|
}
|
99
100
|
|
100
|
-
function
|
101
|
+
function tokenBaseUntilBrace() {
|
102
|
+
var depth = 1;
|
103
|
+
return function(stream, state) {
|
104
|
+
if (stream.peek() == "}") {
|
105
|
+
depth--;
|
106
|
+
if (depth == 0) {
|
107
|
+
state.tokenize.pop();
|
108
|
+
return state.tokenize[state.tokenize.length-1](stream, state);
|
109
|
+
}
|
110
|
+
} else if (stream.peek() == "{") {
|
111
|
+
depth++;
|
112
|
+
}
|
113
|
+
return tokenBase(stream, state);
|
114
|
+
};
|
115
|
+
}
|
116
|
+
function readQuoted(quote, style, embed, unescaped) {
|
101
117
|
return function(stream, state) {
|
102
118
|
var escaped = false, ch;
|
103
119
|
while ((ch = stream.next()) != null) {
|
104
|
-
if (ch == quote && !escaped) {
|
105
|
-
state.tokenize
|
120
|
+
if (ch == quote && (unescaped || !escaped)) {
|
121
|
+
state.tokenize.pop();
|
122
|
+
break;
|
123
|
+
}
|
124
|
+
if (embed && ch == "#" && !escaped && stream.eat("{")) {
|
125
|
+
state.tokenize.push(tokenBaseUntilBrace(arguments.callee));
|
106
126
|
break;
|
107
127
|
}
|
108
128
|
escaped = !escaped && ch == "\\";
|
@@ -110,30 +130,23 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
|
|
110
130
|
return style;
|
111
131
|
};
|
112
132
|
}
|
113
|
-
function readPercentQuoted(quote, style) {
|
114
|
-
return function(stream, state) {
|
115
|
-
if (stream.skipTo(quote)) {stream.next(); state.tokenize = tokenBase;}
|
116
|
-
else stream.skipToEnd();
|
117
|
-
return style;
|
118
|
-
};
|
119
|
-
}
|
120
133
|
function readHereDoc(phrase) {
|
121
134
|
return function(stream, state) {
|
122
|
-
if (stream.match(phrase)) state.tokenize
|
135
|
+
if (stream.match(phrase)) state.tokenize.pop();
|
123
136
|
else stream.skipToEnd();
|
124
137
|
return "string";
|
125
138
|
};
|
126
139
|
}
|
127
140
|
function readBlockComment(stream, state) {
|
128
141
|
if (stream.sol() && stream.match("=end") && stream.eol())
|
129
|
-
state.tokenize
|
142
|
+
state.tokenize.pop();
|
130
143
|
stream.skipToEnd();
|
131
144
|
return "comment";
|
132
145
|
}
|
133
146
|
|
134
147
|
return {
|
135
148
|
startState: function() {
|
136
|
-
return {tokenize: tokenBase,
|
149
|
+
return {tokenize: [tokenBase],
|
137
150
|
indented: 0,
|
138
151
|
context: {type: "top", indented: -config.indentUnit},
|
139
152
|
continuedLine: false,
|
@@ -143,7 +156,7 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
|
|
143
156
|
|
144
157
|
token: function(stream, state) {
|
145
158
|
if (stream.sol()) state.indented = stream.indentation();
|
146
|
-
var style = state.tokenize(stream, state), kwtype;
|
159
|
+
var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
|
147
160
|
if (style == "ident") {
|
148
161
|
var word = stream.current();
|
149
162
|
style = keywords.propertyIsEnumerable(stream.current()) ? "keyword"
|
@@ -168,7 +181,7 @@ CodeMirror.defineMode("ruby", function(config, parserConfig) {
|
|
168
181
|
},
|
169
182
|
|
170
183
|
indent: function(state, textAfter) {
|
171
|
-
if (state.tokenize != tokenBase) return 0;
|
184
|
+
if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0;
|
172
185
|
var firstChar = textAfter && textAfter.charAt(0);
|
173
186
|
var ct = state.context;
|
174
187
|
var closing = ct.type == matching[firstChar] ||
|