codemirror-rails 0.2.3 → 0.3.0
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/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] ||
|