codemirror-rails 3.13 → 3.14
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 +328 -250
- data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +7 -6
- data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +33 -7
- data/vendor/assets/javascripts/codemirror/addons/edit/matchbrackets.js +14 -10
- data/vendor/assets/javascripts/codemirror/addons/edit/trailingspace.js +15 -0
- data/vendor/assets/javascripts/codemirror/addons/fold/brace-fold.js +70 -17
- data/vendor/assets/javascripts/codemirror/addons/fold/foldcode.js +56 -20
- data/vendor/assets/javascripts/codemirror/addons/fold/xml-fold.js +135 -39
- data/vendor/assets/javascripts/codemirror/addons/hint/html-hint.js +324 -571
- data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +199 -109
- data/vendor/assets/javascripts/codemirror/addons/hint/xml-hint.js +60 -113
- data/vendor/assets/javascripts/codemirror/addons/lint/coffeescript-lint.js +24 -0
- data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +431 -0
- data/vendor/assets/javascripts/codemirror/addons/mode/multiplex.js +7 -1
- data/vendor/assets/javascripts/codemirror/addons/search/match-highlighter.js +46 -20
- data/vendor/assets/javascripts/codemirror/addons/search/search.js +1 -1
- data/vendor/assets/javascripts/codemirror/keymaps/emacs.js +370 -13
- data/vendor/assets/javascripts/codemirror/keymaps/extra.js +43 -0
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +535 -214
- data/vendor/assets/javascripts/codemirror/modes/clike.js +56 -0
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +19 -14
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/ruby.js +67 -16
- data/vendor/assets/javascripts/codemirror/modes/smarty.js +167 -110
- data/vendor/assets/javascripts/codemirror/modes/sql.js +97 -15
- data/vendor/assets/javascripts/codemirror/modes/xml.js +14 -18
- data/vendor/assets/stylesheets/codemirror.css +0 -1
- data/vendor/assets/stylesheets/codemirror/addons/merge/merge.css +82 -0
- metadata +7 -2
@@ -302,4 +302,60 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|
302
302
|
}
|
303
303
|
}
|
304
304
|
});
|
305
|
+
mimes(["x-shader/x-vertex", "x-shader/x-fragment"], {
|
306
|
+
name: "clike",
|
307
|
+
keywords: words("float int bool void " +
|
308
|
+
"vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
|
309
|
+
"mat2 mat3 mat4 " +
|
310
|
+
"sampler1D sampler2D sampler3D samplerCube " +
|
311
|
+
"sampler1DShadow sampler2DShadow" +
|
312
|
+
"const attribute uniform varying " +
|
313
|
+
"break continue discard return " +
|
314
|
+
"for while do if else struct " +
|
315
|
+
"in out inout"),
|
316
|
+
blockKeywords: words("for while do if else struct"),
|
317
|
+
builtin: words("radians degrees sin cos tan asin acos atan " +
|
318
|
+
"pow exp log exp2 sqrt inversesqrt " +
|
319
|
+
"abs sign floor ceil fract mod min max clamp mix step smootstep " +
|
320
|
+
"length distance dot cross normalize ftransform faceforward " +
|
321
|
+
"reflect refract matrixCompMult " +
|
322
|
+
"lessThan lessThanEqual greaterThan greaterThanEqual " +
|
323
|
+
"equal notEqual any all not " +
|
324
|
+
"texture1D texture1DProj texture1DLod texture1DProjLod " +
|
325
|
+
"texture2D texture2DProj texture2DLod texture2DProjLod " +
|
326
|
+
"texture3D texture3DProj texture3DLod texture3DProjLod " +
|
327
|
+
"textureCube textureCubeLod " +
|
328
|
+
"shadow1D shadow2D shadow1DProj shadow2DProj " +
|
329
|
+
"shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
|
330
|
+
"dFdx dFdy fwidth " +
|
331
|
+
"noise1 noise2 noise3 noise4"),
|
332
|
+
atoms: words("true false " +
|
333
|
+
"gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
|
334
|
+
"gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
|
335
|
+
"gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
|
336
|
+
"gl_FogCoord " +
|
337
|
+
"gl_Position gl_PointSize gl_ClipVertex " +
|
338
|
+
"gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
|
339
|
+
"gl_TexCoord gl_FogFragCoord " +
|
340
|
+
"gl_FragCoord gl_FrontFacing " +
|
341
|
+
"gl_FragColor gl_FragData gl_FragDepth " +
|
342
|
+
"gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
|
343
|
+
"gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
|
344
|
+
"gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
|
345
|
+
"gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
|
346
|
+
"gl_ProjectionMatrixInverseTranspose " +
|
347
|
+
"gl_ModelViewProjectionMatrixInverseTranspose " +
|
348
|
+
"gl_TextureMatrixInverseTranspose " +
|
349
|
+
"gl_NormalScale gl_DepthRange gl_ClipPlane " +
|
350
|
+
"gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
|
351
|
+
"gl_FrontLightModelProduct gl_BackLightModelProduct " +
|
352
|
+
"gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
|
353
|
+
"gl_FogParameters " +
|
354
|
+
"gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
|
355
|
+
"gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
|
356
|
+
"gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
|
357
|
+
"gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
|
358
|
+
"gl_MaxDrawBuffers"),
|
359
|
+
hooks: {"#": cppHook}
|
360
|
+
});
|
305
361
|
}());
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
4
4
|
var indentUnit = config.indentUnit;
|
5
|
+
var statementIndent = parserConfig.statementIndent;
|
5
6
|
var jsonMode = parserConfig.json;
|
6
7
|
var isTS = parserConfig.typescript;
|
7
8
|
|
@@ -226,8 +227,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
226
227
|
}
|
227
228
|
function pushlex(type, info) {
|
228
229
|
var result = function() {
|
229
|
-
var state = cx.state;
|
230
|
-
state.lexical
|
230
|
+
var state = cx.state, indent = state.indented;
|
231
|
+
if (state.lexical.type == "stat") indent = state.lexical.indented;
|
232
|
+
state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
|
231
233
|
};
|
232
234
|
result.lex = true;
|
233
235
|
return result;
|
@@ -270,17 +272,18 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
270
272
|
return pass(pushlex("stat"), expression, expect(";"), poplex);
|
271
273
|
}
|
272
274
|
function expression(type) {
|
273
|
-
return expressionInner(type,
|
275
|
+
return expressionInner(type, false);
|
274
276
|
}
|
275
277
|
function expressionNoComma(type) {
|
276
|
-
return expressionInner(type,
|
278
|
+
return expressionInner(type, true);
|
277
279
|
}
|
278
|
-
function expressionInner(type,
|
280
|
+
function expressionInner(type, noComma) {
|
281
|
+
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
|
279
282
|
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
|
280
283
|
if (type == "function") return cont(functiondef);
|
281
|
-
if (type == "keyword c") return cont(maybeexpression);
|
284
|
+
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
|
282
285
|
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
|
283
|
-
if (type == "operator") return cont(expression);
|
286
|
+
if (type == "operator") return cont(noComma ? expressionNoComma : expression);
|
284
287
|
if (type == "[") return cont(pushlex("]"), commasep(expressionNoComma, "]"), poplex, maybeop);
|
285
288
|
if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeop);
|
286
289
|
return cont();
|
@@ -289,9 +292,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
289
292
|
if (type.match(/[;\}\)\],]/)) return pass();
|
290
293
|
return pass(expression);
|
291
294
|
}
|
295
|
+
function maybeexpressionNoComma(type) {
|
296
|
+
if (type.match(/[;\}\)\],]/)) return pass();
|
297
|
+
return pass(expressionNoComma);
|
298
|
+
}
|
292
299
|
|
293
300
|
function maybeoperatorComma(type, value) {
|
294
|
-
if (type == ",") return
|
301
|
+
if (type == ",") return cont(expression);
|
295
302
|
return maybeoperatorNoComma(type, value, maybeoperatorComma);
|
296
303
|
}
|
297
304
|
function maybeoperatorNoComma(type, value, me) {
|
@@ -435,18 +442,16 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
435
442
|
if (state.tokenize != jsTokenBase) return 0;
|
436
443
|
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
|
437
444
|
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
|
445
|
+
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
|
446
|
+
lexical = lexical.prev;
|
438
447
|
var type = lexical.type, closing = firstChar == type;
|
439
|
-
if (parserConfig.statementIndent != null) {
|
440
|
-
if (type == ")" && lexical.prev && lexical.prev.type == "stat") lexical = lexical.prev;
|
441
|
-
if (lexical.type == "stat") return lexical.indented + parserConfig.statementIndent;
|
442
|
-
}
|
443
448
|
|
444
449
|
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0);
|
445
450
|
else if (type == "form" && firstChar == "{") return lexical.indented;
|
446
451
|
else if (type == "form") return lexical.indented + indentUnit;
|
447
452
|
else if (type == "stat")
|
448
|
-
return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? indentUnit : 0);
|
449
|
-
else if (lexical.info == "switch" && !closing)
|
453
|
+
return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
|
454
|
+
else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
|
450
455
|
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
|
451
456
|
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
|
452
457
|
else return lexical.indented + (closing ? 0 : indentUnit);
|
@@ -308,11 +308,11 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
308
308
|
return type;
|
309
309
|
}
|
310
310
|
|
311
|
-
if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/,
|
311
|
+
if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
|
312
312
|
return switchInline(stream, state, inlineElement(linkinline, '>'));
|
313
313
|
}
|
314
314
|
|
315
|
-
if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/,
|
315
|
+
if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
|
316
316
|
return switchInline(stream, state, inlineElement(linkemail, '>'));
|
317
317
|
}
|
318
318
|
|
@@ -10,7 +10,7 @@ CodeMirror.defineMode("ruby", function(config) {
|
|
10
10
|
"redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
|
11
11
|
"until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
|
12
12
|
"caller", "lambda", "proc", "public", "protected", "private", "require", "load",
|
13
|
-
"require_relative", "extend", "autoload"
|
13
|
+
"require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
|
14
14
|
]);
|
15
15
|
var indentWords = wordObj(["def", "class", "case", "for", "while", "do", "module", "then",
|
16
16
|
"catch", "loop", "proc", "begin"]);
|
@@ -31,14 +31,16 @@ CodeMirror.defineMode("ruby", function(config) {
|
|
31
31
|
}
|
32
32
|
if (stream.eatSpace()) return null;
|
33
33
|
var ch = stream.next(), m;
|
34
|
-
if (ch == "`" || ch == "'" || ch == '"'
|
35
|
-
(ch == "/" && !stream.eol() && stream.peek() != " ")) {
|
34
|
+
if (ch == "`" || ch == "'" || ch == '"') {
|
36
35
|
return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
|
36
|
+
} else if (ch == "/" && !stream.eol() && stream.peek() != " ") {
|
37
|
+
return chain(readQuoted(ch, "string-2", true), stream, state);
|
37
38
|
} else if (ch == "%") {
|
38
|
-
var style, embed = false;
|
39
|
+
var style = "string", embed = false;
|
39
40
|
if (stream.eat("s")) style = "atom";
|
40
41
|
else if (stream.eat(/[WQ]/)) { style = "string"; embed = true; }
|
41
|
-
else if (stream.eat(/[
|
42
|
+
else if (stream.eat(/[r]/)) { style = "string-2"; embed = true; }
|
43
|
+
else if (stream.eat(/[wxq]/)) style = "string";
|
42
44
|
var delim = stream.eat(/[^\w\s]/);
|
43
45
|
if (!delim) return "operator";
|
44
46
|
if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
|
@@ -64,18 +66,42 @@ CodeMirror.defineMode("ruby", function(config) {
|
|
64
66
|
} else if (ch == ":") {
|
65
67
|
if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
|
66
68
|
if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
|
67
|
-
|
68
|
-
|
69
|
-
|
69
|
+
|
70
|
+
// :> :>> :< :<< are valid symbols
|
71
|
+
if (stream.eat(/[\<\>]/)) {
|
72
|
+
stream.eat(/[\<\>]/);
|
73
|
+
return "atom";
|
74
|
+
}
|
75
|
+
|
76
|
+
// :+ :- :/ :* :| :& :! are valid symbols
|
77
|
+
if (stream.eat(/[\+\-\*\/\&\|\:\!]/)) {
|
78
|
+
return "atom";
|
79
|
+
}
|
80
|
+
|
81
|
+
// Symbols can't start by a digit
|
82
|
+
if (stream.eat(/[a-zA-Z$@_]/)) {
|
83
|
+
stream.eatWhile(/[\w]/);
|
84
|
+
// Only one ? ! = is allowed and only as the last character
|
85
|
+
stream.eat(/[\?\!\=]/);
|
86
|
+
return "atom";
|
87
|
+
}
|
88
|
+
return "operator";
|
89
|
+
} else if (ch == "@" && stream.match(/^@?[a-zA-Z_]/)) {
|
70
90
|
stream.eat("@");
|
71
|
-
stream.eatWhile(/[\w
|
91
|
+
stream.eatWhile(/[\w]/);
|
72
92
|
return "variable-2";
|
73
93
|
} else if (ch == "$") {
|
74
|
-
stream.
|
75
|
-
|
94
|
+
if (stream.eat(/[a-zA-Z_]/)) {
|
95
|
+
stream.eatWhile(/[\w]/);
|
96
|
+
} else if (stream.eat(/\d/)) {
|
97
|
+
stream.eat(/\d/);
|
98
|
+
} else {
|
99
|
+
stream.next(); // Must be a special global like $: or $!
|
100
|
+
}
|
76
101
|
return "variable-3";
|
77
|
-
} else if (
|
78
|
-
stream.eatWhile(/[\w
|
102
|
+
} else if (/[a-zA-Z_]/.test(ch)) {
|
103
|
+
stream.eatWhile(/[\w]/);
|
104
|
+
stream.eat(/[\?\!]/);
|
79
105
|
if (stream.eat(":")) return "atom";
|
80
106
|
return "ident";
|
81
107
|
} else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
|
@@ -109,17 +135,42 @@ CodeMirror.defineMode("ruby", function(config) {
|
|
109
135
|
return tokenBase(stream, state);
|
110
136
|
};
|
111
137
|
}
|
138
|
+
function tokenBaseOnce() {
|
139
|
+
var alreadyCalled = false;
|
140
|
+
return function(stream, state) {
|
141
|
+
if (alreadyCalled) {
|
142
|
+
state.tokenize.pop();
|
143
|
+
return state.tokenize[state.tokenize.length-1](stream, state);
|
144
|
+
}
|
145
|
+
alreadyCalled = true;
|
146
|
+
return tokenBase(stream, state);
|
147
|
+
};
|
148
|
+
}
|
112
149
|
function readQuoted(quote, style, embed, unescaped) {
|
113
150
|
return function(stream, state) {
|
114
151
|
var escaped = false, ch;
|
152
|
+
|
153
|
+
if (state.context.type === 'read-quoted-paused') {
|
154
|
+
state.context = state.context.prev;
|
155
|
+
stream.eat("}");
|
156
|
+
}
|
157
|
+
|
115
158
|
while ((ch = stream.next()) != null) {
|
116
159
|
if (ch == quote && (unescaped || !escaped)) {
|
117
160
|
state.tokenize.pop();
|
118
161
|
break;
|
119
162
|
}
|
120
|
-
if (embed && ch == "#" && !escaped
|
121
|
-
|
122
|
-
|
163
|
+
if (embed && ch == "#" && !escaped) {
|
164
|
+
if (stream.eat("{")) {
|
165
|
+
if (quote == "}") {
|
166
|
+
state.context = {prev: state.context, type: 'read-quoted-paused'};
|
167
|
+
}
|
168
|
+
state.tokenize.push(tokenBaseUntilBrace());
|
169
|
+
break;
|
170
|
+
} else if (/[@\$]/.test(stream.peek())) {
|
171
|
+
state.tokenize.push(tokenBaseOnce());
|
172
|
+
break;
|
173
|
+
}
|
123
174
|
}
|
124
175
|
escaped = !escaped && ch == "\\";
|
125
176
|
}
|
@@ -1,140 +1,197 @@
|
|
1
|
+
/**
|
2
|
+
* Smarty 2 and 3 mode.
|
3
|
+
*/
|
1
4
|
CodeMirror.defineMode("smarty", function(config) {
|
2
|
-
|
5
|
+
"use strict";
|
6
|
+
|
7
|
+
// our default settings; check to see if they're overridden
|
8
|
+
var settings = {
|
9
|
+
rightDelimiter: '}',
|
10
|
+
leftDelimiter: '{',
|
11
|
+
smartyVersion: 2 // for backward compatibility
|
12
|
+
};
|
13
|
+
if (config.hasOwnProperty("leftDelimiter")) {
|
14
|
+
settings.leftDelimiter = config.leftDelimiter;
|
15
|
+
}
|
16
|
+
if (config.hasOwnProperty("rightDelimiter")) {
|
17
|
+
settings.rightDelimiter = config.rightDelimiter;
|
18
|
+
}
|
19
|
+
if (config.hasOwnProperty("smartyVersion") && config.smartyVersion === 3) {
|
20
|
+
settings.smartyVersion = 3;
|
21
|
+
}
|
22
|
+
|
23
|
+
var keyFunctions = ["debug", "extends", "function", "include", "literal"];
|
3
24
|
var last;
|
4
25
|
var regs = {
|
5
26
|
operatorChars: /[+\-*&%=<>!?]/,
|
6
|
-
validIdentifier: /[a-zA-Z0-
|
7
|
-
stringChar: /[
|
27
|
+
validIdentifier: /[a-zA-Z0-9_]/,
|
28
|
+
stringChar: /['"]/
|
8
29
|
};
|
9
|
-
var leftDelim = (typeof config.mode.leftDelimiter != 'undefined') ? config.mode.leftDelimiter : "{";
|
10
|
-
var rightDelim = (typeof config.mode.rightDelimiter != 'undefined') ? config.mode.rightDelimiter : "}";
|
11
|
-
function ret(style, lst) { last = lst; return style; }
|
12
30
|
|
13
|
-
|
14
|
-
|
15
|
-
|
31
|
+
var helpers = {
|
32
|
+
cont: function(style, lastType) {
|
33
|
+
last = lastType;
|
34
|
+
return style;
|
35
|
+
},
|
36
|
+
chain: function(stream, state, parser) {
|
16
37
|
state.tokenize = parser;
|
17
38
|
return parser(stream, state);
|
18
39
|
}
|
40
|
+
};
|
19
41
|
|
20
|
-
if (stream.match(leftDelim, true)) {
|
21
|
-
if (stream.eat("*")) {
|
22
|
-
return chain(inBlock("comment", "*" + rightDelim));
|
23
|
-
}
|
24
|
-
else {
|
25
|
-
state.tokenize = inSmarty;
|
26
|
-
return "tag";
|
27
|
-
}
|
28
|
-
}
|
29
|
-
else {
|
30
|
-
// I'd like to do an eatWhile() here, but I can't get it to eat only up to the rightDelim string/char
|
31
|
-
stream.next();
|
32
|
-
return null;
|
33
|
-
}
|
34
|
-
}
|
35
42
|
|
36
|
-
|
37
|
-
|
38
|
-
state.tokenize = tokenizer;
|
39
|
-
return ret("tag", null);
|
40
|
-
}
|
43
|
+
// our various parsers
|
44
|
+
var parsers = {
|
41
45
|
|
42
|
-
|
43
|
-
|
44
|
-
stream.
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
}
|
61
|
-
else if (/\d/.test(ch)) {
|
62
|
-
stream.eatWhile(/\d/);
|
63
|
-
return ret("number", "number");
|
64
|
-
}
|
65
|
-
else {
|
66
|
-
if (state.last == "variable") {
|
67
|
-
if (ch == "@") {
|
68
|
-
stream.eatWhile(regs.validIdentifier);
|
69
|
-
return ret("property", "property");
|
46
|
+
// the main tokenizer
|
47
|
+
tokenizer: function(stream, state) {
|
48
|
+
if (stream.match(settings.leftDelimiter, true)) {
|
49
|
+
if (stream.eat("*")) {
|
50
|
+
return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
|
51
|
+
} else {
|
52
|
+
// Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode
|
53
|
+
state.depth++;
|
54
|
+
var isEol = stream.eol();
|
55
|
+
var isFollowedByWhitespace = /\s/.test(stream.peek());
|
56
|
+
if (settings.smartyVersion === 3 && settings.leftDelimiter === "{" && (isEol || isFollowedByWhitespace)) {
|
57
|
+
state.depth--;
|
58
|
+
return null;
|
59
|
+
} else {
|
60
|
+
state.tokenize = parsers.smarty;
|
61
|
+
last = "startTag";
|
62
|
+
return "tag";
|
63
|
+
}
|
70
64
|
}
|
71
|
-
|
72
|
-
|
73
|
-
return ret("qualifier", "modifier");
|
74
|
-
}
|
75
|
-
}
|
76
|
-
else if (state.last == "whitespace") {
|
77
|
-
stream.eatWhile(regs.validIdentifier);
|
78
|
-
return ret("attribute", "modifier");
|
79
|
-
}
|
80
|
-
else if (state.last == "property") {
|
81
|
-
stream.eatWhile(regs.validIdentifier);
|
82
|
-
return ret("property", null);
|
83
|
-
}
|
84
|
-
else if (/\s/.test(ch)) {
|
85
|
-
last = "whitespace";
|
65
|
+
} else {
|
66
|
+
stream.next();
|
86
67
|
return null;
|
87
68
|
}
|
69
|
+
},
|
88
70
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
if (keyFuncs[i] == str) {
|
100
|
-
return ret("keyword", "keyword");
|
71
|
+
// parsing Smarty content
|
72
|
+
smarty: function(stream, state) {
|
73
|
+
if (stream.match(settings.rightDelimiter, true)) {
|
74
|
+
if (settings.smartyVersion === 3) {
|
75
|
+
state.depth--;
|
76
|
+
if (state.depth <= 0) {
|
77
|
+
state.tokenize = parsers.tokenizer;
|
78
|
+
}
|
79
|
+
} else {
|
80
|
+
state.tokenize = parsers.tokenizer;
|
101
81
|
}
|
82
|
+
return helpers.cont("tag", null);
|
102
83
|
}
|
103
|
-
|
104
|
-
|
84
|
+
|
85
|
+
if (stream.match(settings.leftDelimiter, true)) {
|
86
|
+
state.depth++;
|
87
|
+
return helpers.cont("tag", "startTag");
|
105
88
|
}
|
106
|
-
return ret("tag", "tag");
|
107
|
-
}
|
108
|
-
}
|
109
89
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
90
|
+
var ch = stream.next();
|
91
|
+
if (ch == "$") {
|
92
|
+
stream.eatWhile(regs.validIdentifier);
|
93
|
+
return helpers.cont("variable-2", "variable");
|
94
|
+
} else if (ch == "|") {
|
95
|
+
return helpers.cont("operator", "pipe");
|
96
|
+
} else if (ch == ".") {
|
97
|
+
return helpers.cont("operator", "property");
|
98
|
+
} else if (regs.stringChar.test(ch)) {
|
99
|
+
state.tokenize = parsers.inAttribute(ch);
|
100
|
+
return helpers.cont("string", "string");
|
101
|
+
} else if (regs.operatorChars.test(ch)) {
|
102
|
+
stream.eatWhile(regs.operatorChars);
|
103
|
+
return helpers.cont("operator", "operator");
|
104
|
+
} else if (ch == "[" || ch == "]") {
|
105
|
+
return helpers.cont("bracket", "bracket");
|
106
|
+
} else if (ch == "(" || ch == ")") {
|
107
|
+
return helpers.cont("bracket", "operator");
|
108
|
+
} else if (/\d/.test(ch)) {
|
109
|
+
stream.eatWhile(/\d/);
|
110
|
+
return helpers.cont("number", "number");
|
111
|
+
} else {
|
112
|
+
|
113
|
+
if (state.last == "variable") {
|
114
|
+
if (ch == "@") {
|
115
|
+
stream.eatWhile(regs.validIdentifier);
|
116
|
+
return helpers.cont("property", "property");
|
117
|
+
} else if (ch == "|") {
|
118
|
+
stream.eatWhile(regs.validIdentifier);
|
119
|
+
return helpers.cont("qualifier", "modifier");
|
120
|
+
}
|
121
|
+
} else if (state.last == "pipe") {
|
122
|
+
stream.eatWhile(regs.validIdentifier);
|
123
|
+
return helpers.cont("qualifier", "modifier");
|
124
|
+
} else if (state.last == "whitespace") {
|
125
|
+
stream.eatWhile(regs.validIdentifier);
|
126
|
+
return helpers.cont("attribute", "modifier");
|
127
|
+
} if (state.last == "property") {
|
128
|
+
stream.eatWhile(regs.validIdentifier);
|
129
|
+
return helpers.cont("property", null);
|
130
|
+
} else if (/\s/.test(ch)) {
|
131
|
+
last = "whitespace";
|
132
|
+
return null;
|
116
133
|
}
|
117
|
-
}
|
118
|
-
return "string";
|
119
|
-
};
|
120
|
-
}
|
121
134
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
if (stream.match(terminator)) {
|
126
|
-
state.tokenize = tokenizer;
|
127
|
-
break;
|
135
|
+
var str = "";
|
136
|
+
if (ch != "/") {
|
137
|
+
str += ch;
|
128
138
|
}
|
129
|
-
|
139
|
+
var c = null;
|
140
|
+
while (c = stream.eat(regs.validIdentifier)) {
|
141
|
+
str += c;
|
142
|
+
}
|
143
|
+
for (var i=0, j=keyFunctions.length; i<j; i++) {
|
144
|
+
if (keyFunctions[i] == str) {
|
145
|
+
return helpers.cont("keyword", "keyword");
|
146
|
+
}
|
147
|
+
}
|
148
|
+
if (/\s/.test(ch)) {
|
149
|
+
return null;
|
150
|
+
}
|
151
|
+
return helpers.cont("tag", "tag");
|
130
152
|
}
|
131
|
-
|
132
|
-
|
133
|
-
|
153
|
+
},
|
154
|
+
|
155
|
+
inAttribute: function(quote) {
|
156
|
+
return function(stream, state) {
|
157
|
+
var prevChar = null;
|
158
|
+
var currChar = null;
|
159
|
+
while (!stream.eol()) {
|
160
|
+
currChar = stream.peek();
|
161
|
+
if (stream.next() == quote && prevChar !== '\\') {
|
162
|
+
state.tokenize = parsers.smarty;
|
163
|
+
break;
|
164
|
+
}
|
165
|
+
prevChar = currChar;
|
166
|
+
}
|
167
|
+
return "string";
|
168
|
+
};
|
169
|
+
},
|
170
|
+
|
171
|
+
inBlock: function(style, terminator) {
|
172
|
+
return function(stream, state) {
|
173
|
+
while (!stream.eol()) {
|
174
|
+
if (stream.match(terminator)) {
|
175
|
+
state.tokenize = parsers.tokenizer;
|
176
|
+
break;
|
177
|
+
}
|
178
|
+
stream.next();
|
179
|
+
}
|
180
|
+
return style;
|
181
|
+
};
|
182
|
+
}
|
183
|
+
};
|
184
|
+
|
134
185
|
|
186
|
+
// the public API for CodeMirror
|
135
187
|
return {
|
136
188
|
startState: function() {
|
137
|
-
return {
|
189
|
+
return {
|
190
|
+
tokenize: parsers.tokenizer,
|
191
|
+
mode: "smarty",
|
192
|
+
last: null,
|
193
|
+
depth: 0
|
194
|
+
};
|
138
195
|
},
|
139
196
|
token: function(stream, state) {
|
140
197
|
var style = state.tokenize(stream, state);
|