codemirror-rails 5.9 → 5.10
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 +91 -76
- data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +0 -7
- data/vendor/assets/javascripts/codemirror/addons/mode/simple.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/scroll/annotatescrollbar.js +3 -0
- data/vendor/assets/javascripts/codemirror/addons/search/jump-to-line.js +49 -0
- data/vendor/assets/javascripts/codemirror/keymaps/sublime.js +7 -3
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +16 -15
- data/vendor/assets/javascripts/codemirror/modes/clike.js +12 -13
- data/vendor/assets/javascripts/codemirror/modes/crystal.js +391 -0
- data/vendor/assets/javascripts/codemirror/modes/css.js +3 -4
- data/vendor/assets/javascripts/codemirror/modes/django.js +8 -1
- data/vendor/assets/javascripts/codemirror/modes/handlebars.js +12 -3
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +18 -8
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/mscgen.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/sparql.js +3 -1
- data/vendor/assets/javascripts/codemirror/modes/swift.js +128 -168
- data/vendor/assets/javascripts/codemirror/modes/yaml-frontmatter.js +68 -0
- data/vendor/assets/stylesheets/codemirror.css +1 -1
- metadata +4 -1
@@ -108,6 +108,7 @@
|
|
108
108
|
map["Shift-" + ctrl + "K"] = "deleteLine";
|
109
109
|
|
110
110
|
function insertLine(cm, above) {
|
111
|
+
if (cm.isReadOnly()) return CodeMirror.Pass
|
111
112
|
cm.operation(function() {
|
112
113
|
var len = cm.listSelections().length, newSelection = [], last = -1;
|
113
114
|
for (var i = 0; i < len; i++) {
|
@@ -123,9 +124,9 @@
|
|
123
124
|
});
|
124
125
|
}
|
125
126
|
|
126
|
-
cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { insertLine(cm, false); };
|
127
|
+
cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { return insertLine(cm, false); };
|
127
128
|
|
128
|
-
cmds[map["Shift-" + ctrl + "Enter"] = "insertLineBefore"] = function(cm) { insertLine(cm, true); };
|
129
|
+
cmds[map["Shift-" + ctrl + "Enter"] = "insertLineBefore"] = function(cm) { return insertLine(cm, true); };
|
129
130
|
|
130
131
|
function wordAt(cm, pos) {
|
131
132
|
var start = pos.ch, end = start, line = cm.getLine(pos.line);
|
@@ -192,6 +193,7 @@
|
|
192
193
|
var swapLineCombo = mac ? "Cmd-Ctrl-" : "Shift-Ctrl-";
|
193
194
|
|
194
195
|
cmds[map[swapLineCombo + "Up"] = "swapLineUp"] = function(cm) {
|
196
|
+
if (cm.isReadOnly()) return CodeMirror.Pass
|
195
197
|
var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1, newSels = [];
|
196
198
|
for (var i = 0; i < ranges.length; i++) {
|
197
199
|
var range = ranges[i], from = range.from().line - 1, to = range.to().line;
|
@@ -218,6 +220,7 @@
|
|
218
220
|
};
|
219
221
|
|
220
222
|
cmds[map[swapLineCombo + "Down"] = "swapLineDown"] = function(cm) {
|
223
|
+
if (cm.isReadOnly()) return CodeMirror.Pass
|
221
224
|
var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1;
|
222
225
|
for (var i = ranges.length - 1; i >= 0; i--) {
|
223
226
|
var range = ranges[i], from = range.to().line + 1, to = range.from().line;
|
@@ -240,7 +243,7 @@
|
|
240
243
|
});
|
241
244
|
};
|
242
245
|
|
243
|
-
map[ctrl + "/"] = function(cm) {
|
246
|
+
cmds[map[ctrl + "/"] = "toggleCommentIndented"] = function(cm) {
|
244
247
|
cm.toggleComment({ indent: true });
|
245
248
|
}
|
246
249
|
|
@@ -289,6 +292,7 @@
|
|
289
292
|
map[ctrl + "T"] = "transposeChars";
|
290
293
|
|
291
294
|
function sortLines(cm, caseSensitive) {
|
295
|
+
if (cm.isReadOnly()) return CodeMirror.Pass
|
292
296
|
var ranges = cm.listSelections(), toSort = [], selected;
|
293
297
|
for (var i = 0; i < ranges.length; i++) {
|
294
298
|
var range = ranges[i];
|
@@ -292,12 +292,7 @@
|
|
292
292
|
// Keypress character binding of format "'a'"
|
293
293
|
return key.charAt(1);
|
294
294
|
}
|
295
|
-
var pieces = key.split(
|
296
|
-
if (/-$/.test(key)) {
|
297
|
-
// If the - key was typed, split will result in 2 extra empty strings
|
298
|
-
// in the array. Replace them with 1 '-'.
|
299
|
-
pieces.splice(-2, 2, '-');
|
300
|
-
}
|
295
|
+
var pieces = key.split(/-(?!$)/);
|
301
296
|
var lastPiece = pieces[pieces.length - 1];
|
302
297
|
if (pieces.length == 1 && pieces[0].length == 1) {
|
303
298
|
// No-modifier bindings use literal character bindings above. Skip.
|
@@ -1959,13 +1954,21 @@
|
|
1959
1954
|
text = text.slice(0, - match[0].length);
|
1960
1955
|
}
|
1961
1956
|
}
|
1962
|
-
var
|
1963
|
-
cm.
|
1964
|
-
if (args.linewise && !wasLastLine) {
|
1957
|
+
var prevLineEnd = new Pos(anchor.line - 1, Number.MAX_VALUE);
|
1958
|
+
var wasLastLine = cm.firstLine() == cm.lastLine();
|
1959
|
+
if (head.line > cm.lastLine() && args.linewise && !wasLastLine) {
|
1960
|
+
cm.replaceRange('', prevLineEnd, head);
|
1961
|
+
} else {
|
1962
|
+
cm.replaceRange('', anchor, head);
|
1963
|
+
}
|
1964
|
+
if (args.linewise) {
|
1965
1965
|
// Push the next line back down, if there is a next line.
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1966
|
+
if (!wasLastLine) {
|
1967
|
+
cm.setCursor(prevLineEnd);
|
1968
|
+
CodeMirror.commands.newlineAndIndent(cm);
|
1969
|
+
}
|
1970
|
+
// make sure cursor ends up at the end of the line.
|
1971
|
+
anchor.ch = Number.MAX_VALUE;
|
1969
1972
|
}
|
1970
1973
|
finalHead = anchor;
|
1971
1974
|
} else {
|
@@ -2144,9 +2147,7 @@
|
|
2144
2147
|
switch (actionArgs.position) {
|
2145
2148
|
case 'center': y = y - (height / 2) + lineHeight;
|
2146
2149
|
break;
|
2147
|
-
case 'bottom': y = y - height + lineHeight
|
2148
|
-
break;
|
2149
|
-
case 'top': y = y + lineHeight*0.4;
|
2150
|
+
case 'bottom': y = y - height + lineHeight;
|
2150
2151
|
break;
|
2151
2152
|
}
|
2152
2153
|
cm.scrollTo(null, y);
|
@@ -262,21 +262,20 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|
262
262
|
var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
|
263
263
|
|
264
264
|
function cppHook(stream, state) {
|
265
|
-
if (!state.startOfLine) return false
|
266
|
-
for (
|
267
|
-
if (
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
stream.skipToEnd();
|
275
|
-
state.tokenize = null;
|
276
|
-
break;
|
265
|
+
if (!state.startOfLine) return false
|
266
|
+
for (var ch, next = null; ch = stream.peek();) {
|
267
|
+
if (!ch) {
|
268
|
+
break
|
269
|
+
} else if (ch == "\\" && stream.match(/^.$/)) {
|
270
|
+
next = cppHook
|
271
|
+
break
|
272
|
+
} else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) {
|
273
|
+
break
|
277
274
|
}
|
275
|
+
stream.next()
|
278
276
|
}
|
279
|
-
|
277
|
+
state.tokenize = next
|
278
|
+
return "meta"
|
280
279
|
}
|
281
280
|
|
282
281
|
function pointerHook(_stream, state) {
|
@@ -0,0 +1,391 @@
|
|
1
|
+
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
2
|
+
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
3
|
+
|
4
|
+
(function(mod) {
|
5
|
+
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
6
|
+
mod(require("../../lib/codemirror"));
|
7
|
+
else if (typeof define == "function" && define.amd) // AMD
|
8
|
+
define(["../../lib/codemirror"], mod);
|
9
|
+
else // Plain browser env
|
10
|
+
mod(CodeMirror);
|
11
|
+
})(function(CodeMirror) {
|
12
|
+
"use strict";
|
13
|
+
|
14
|
+
CodeMirror.defineMode("crystal", function(config) {
|
15
|
+
function wordRegExp(words, end) {
|
16
|
+
return new RegExp((end ? "" : "^") + "(?:" + words.join("|") + ")" + (end ? "$" : "\\b"));
|
17
|
+
}
|
18
|
+
|
19
|
+
function chain(tokenize, stream, state) {
|
20
|
+
state.tokenize.push(tokenize);
|
21
|
+
return tokenize(stream, state);
|
22
|
+
}
|
23
|
+
|
24
|
+
var operators = /^(?:[-+/%|&^]|\*\*?|[<>]{2})/;
|
25
|
+
var conditionalOperators = /^(?:[=!]~|===|<=>|[<>=!]=?|[|&]{2}|~)/;
|
26
|
+
var indexingOperators = /^(?:\[\][?=]?)/;
|
27
|
+
var anotherOperators = /^(?:\.(?:\.{2})?|->|[?:])/;
|
28
|
+
var idents = /^[a-z_\u009F-\uFFFF][a-zA-Z0-9_\u009F-\uFFFF]*/;
|
29
|
+
var types = /^[A-Z_\u009F-\uFFFF][a-zA-Z0-9_\u009F-\uFFFF]*/;
|
30
|
+
var keywords = wordRegExp([
|
31
|
+
"abstract", "alias", "as", "asm", "begin", "break", "case", "class", "def", "do",
|
32
|
+
"else", "elsif", "end", "ensure", "enum", "extend", "for", "fun", "if", "ifdef",
|
33
|
+
"include", "instance_sizeof", "lib", "macro", "module", "next", "of", "out", "pointerof",
|
34
|
+
"private", "protected", "rescue", "return", "require", "sizeof", "struct",
|
35
|
+
"super", "then", "type", "typeof", "union", "unless", "until", "when", "while", "with",
|
36
|
+
"yield", "__DIR__", "__FILE__", "__LINE__"
|
37
|
+
]);
|
38
|
+
var atomWords = wordRegExp(["true", "false", "nil", "self"]);
|
39
|
+
var indentKeywordsArray = [
|
40
|
+
"def", "fun", "macro",
|
41
|
+
"class", "module", "struct", "lib", "enum", "union",
|
42
|
+
"if", "unless", "case", "while", "until", "begin", "then",
|
43
|
+
"do",
|
44
|
+
"for", "ifdef"
|
45
|
+
];
|
46
|
+
var indentKeywords = wordRegExp(indentKeywordsArray);
|
47
|
+
var dedentKeywordsArray = [
|
48
|
+
"end",
|
49
|
+
"else", "elsif",
|
50
|
+
"rescue", "ensure"
|
51
|
+
];
|
52
|
+
var dedentKeywords = wordRegExp(dedentKeywordsArray);
|
53
|
+
var dedentPunctualsArray = ["\\)", "\\}", "\\]"];
|
54
|
+
var dedentPunctuals = new RegExp("^(?:" + dedentPunctualsArray.join("|") + ")$");
|
55
|
+
var nextTokenizer = {
|
56
|
+
"def": tokenFollowIdent, "fun": tokenFollowIdent, "macro": tokenMacroDef,
|
57
|
+
"class": tokenFollowType, "module": tokenFollowType, "struct": tokenFollowType,
|
58
|
+
"lib": tokenFollowType, "enum": tokenFollowType, "union": tokenFollowType
|
59
|
+
};
|
60
|
+
var matching = {"[": "]", "{": "}", "(": ")", "<": ">"};
|
61
|
+
|
62
|
+
function tokenBase(stream, state) {
|
63
|
+
if (stream.eatSpace()) {
|
64
|
+
return null;
|
65
|
+
}
|
66
|
+
|
67
|
+
// Macros
|
68
|
+
if (state.lastToken != "\\" && stream.match("{%", false)) {
|
69
|
+
return chain(tokenMacro("%", "%"), stream, state);
|
70
|
+
}
|
71
|
+
|
72
|
+
if (state.lastToken != "\\" && stream.match("{{", false)) {
|
73
|
+
return chain(tokenMacro("{", "}"), stream, state);
|
74
|
+
}
|
75
|
+
|
76
|
+
// Comments
|
77
|
+
if (stream.peek() == "#") {
|
78
|
+
stream.skipToEnd();
|
79
|
+
return "comment";
|
80
|
+
}
|
81
|
+
|
82
|
+
// Variables and keywords
|
83
|
+
var matched;
|
84
|
+
if (stream.match(idents)) {
|
85
|
+
stream.eat(/[?!]/);
|
86
|
+
|
87
|
+
matched = stream.current();
|
88
|
+
if (stream.eat(":")) {
|
89
|
+
return "atom";
|
90
|
+
} else if (state.lastToken == ".") {
|
91
|
+
return "property";
|
92
|
+
} else if (keywords.test(matched)) {
|
93
|
+
if (state.lastToken != "abstract" && indentKeywords.test(matched)) {
|
94
|
+
if (!(matched == "fun" && state.blocks.indexOf("lib") >= 0)) {
|
95
|
+
state.blocks.push(matched);
|
96
|
+
state.currentIndent += 1;
|
97
|
+
}
|
98
|
+
} else if (dedentKeywords.test(matched)) {
|
99
|
+
state.blocks.pop();
|
100
|
+
state.currentIndent -= 1;
|
101
|
+
}
|
102
|
+
|
103
|
+
if (nextTokenizer.hasOwnProperty(matched)) {
|
104
|
+
state.tokenize.push(nextTokenizer[matched]);
|
105
|
+
}
|
106
|
+
|
107
|
+
return "keyword";
|
108
|
+
} else if (atomWords.test(matched)) {
|
109
|
+
return "atom";
|
110
|
+
}
|
111
|
+
|
112
|
+
return "variable";
|
113
|
+
}
|
114
|
+
|
115
|
+
// Class variables and instance variables
|
116
|
+
// or attributes
|
117
|
+
if (stream.eat("@")) {
|
118
|
+
if (stream.peek() == "[") {
|
119
|
+
return chain(tokenNest("[", "]", "meta"), stream, state);
|
120
|
+
}
|
121
|
+
|
122
|
+
stream.eat("@");
|
123
|
+
stream.match(idents) || stream.match(types);
|
124
|
+
return "variable-2";
|
125
|
+
}
|
126
|
+
|
127
|
+
// Global variables
|
128
|
+
if (stream.eat("$")) {
|
129
|
+
stream.eat(/[0-9]+|\?/) || stream.match(idents) || stream.match(types);
|
130
|
+
return "variable-3";
|
131
|
+
}
|
132
|
+
|
133
|
+
// Constants and types
|
134
|
+
if (stream.match(types)) {
|
135
|
+
return "tag";
|
136
|
+
}
|
137
|
+
|
138
|
+
// Symbols or ':' operator
|
139
|
+
if (stream.eat(":")) {
|
140
|
+
if (stream.eat("\"")) {
|
141
|
+
return chain(tokenQuote("\"", "atom", false), stream, state);
|
142
|
+
} else if (stream.match(idents) || stream.match(types) ||
|
143
|
+
stream.match(operators) || stream.match(conditionalOperators) || stream.match(indexingOperators)) {
|
144
|
+
return "atom";
|
145
|
+
}
|
146
|
+
stream.eat(":");
|
147
|
+
return "operator";
|
148
|
+
}
|
149
|
+
|
150
|
+
// Strings
|
151
|
+
if (stream.eat("\"")) {
|
152
|
+
return chain(tokenQuote("\"", "string", true), stream, state);
|
153
|
+
}
|
154
|
+
|
155
|
+
// Strings or regexps or macro variables or '%' operator
|
156
|
+
if (stream.peek() == "%") {
|
157
|
+
var style = "string";
|
158
|
+
var embed = true;
|
159
|
+
var delim;
|
160
|
+
|
161
|
+
if (stream.match("%r")) {
|
162
|
+
// Regexps
|
163
|
+
style = "string-2";
|
164
|
+
delim = stream.next();
|
165
|
+
} else if (stream.match("%w")) {
|
166
|
+
embed = false;
|
167
|
+
delim = stream.next();
|
168
|
+
} else {
|
169
|
+
if(delim = stream.match(/^%([^\w\s=])/)) {
|
170
|
+
delim = delim[1];
|
171
|
+
} else if (stream.match(/^%[a-zA-Z0-9_\u009F-\uFFFF]*/)) {
|
172
|
+
// Macro variables
|
173
|
+
return "meta";
|
174
|
+
} else {
|
175
|
+
// '%' operator
|
176
|
+
return "operator";
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
if (matching.hasOwnProperty(delim)) {
|
181
|
+
delim = matching[delim];
|
182
|
+
}
|
183
|
+
return chain(tokenQuote(delim, style, embed), stream, state);
|
184
|
+
}
|
185
|
+
|
186
|
+
// Characters
|
187
|
+
if (stream.eat("'")) {
|
188
|
+
stream.match(/^(?:[^']|\\(?:[befnrtv0'"]|[0-7]{3}|u(?:[0-9a-fA-F]{4}|\{[0-9a-fA-F]{1,6}\})))/);
|
189
|
+
stream.eat("'");
|
190
|
+
return "atom";
|
191
|
+
}
|
192
|
+
|
193
|
+
// Numbers
|
194
|
+
if (stream.eat("0")) {
|
195
|
+
if (stream.eat("x")) {
|
196
|
+
stream.match(/^[0-9a-fA-F]+/);
|
197
|
+
} else if (stream.eat("o")) {
|
198
|
+
stream.match(/^[0-7]+/);
|
199
|
+
} else if (stream.eat("b")) {
|
200
|
+
stream.match(/^[01]+/);
|
201
|
+
}
|
202
|
+
return "number";
|
203
|
+
}
|
204
|
+
|
205
|
+
if (stream.eat(/\d/)) {
|
206
|
+
stream.match(/^\d*(?:\.\d+)?(?:[eE][+-]?\d+)?/);
|
207
|
+
return "number";
|
208
|
+
}
|
209
|
+
|
210
|
+
// Operators
|
211
|
+
if (stream.match(operators)) {
|
212
|
+
stream.eat("="); // Operators can follow assigin symbol.
|
213
|
+
return "operator";
|
214
|
+
}
|
215
|
+
|
216
|
+
if (stream.match(conditionalOperators) || stream.match(anotherOperators)) {
|
217
|
+
return "operator";
|
218
|
+
}
|
219
|
+
|
220
|
+
// Parens and braces
|
221
|
+
if (matched = stream.match(/[({[]/, false)) {
|
222
|
+
matched = matched[0];
|
223
|
+
return chain(tokenNest(matched, matching[matched], null), stream, state);
|
224
|
+
}
|
225
|
+
|
226
|
+
// Escapes
|
227
|
+
if (stream.eat("\\")) {
|
228
|
+
stream.next();
|
229
|
+
return "meta";
|
230
|
+
}
|
231
|
+
|
232
|
+
stream.next();
|
233
|
+
return null;
|
234
|
+
}
|
235
|
+
|
236
|
+
function tokenNest(begin, end, style, started) {
|
237
|
+
return function (stream, state) {
|
238
|
+
if (!started && stream.match(begin)) {
|
239
|
+
state.tokenize[state.tokenize.length - 1] = tokenNest(begin, end, style, true);
|
240
|
+
state.currentIndent += 1;
|
241
|
+
return style;
|
242
|
+
}
|
243
|
+
|
244
|
+
var nextStyle = tokenBase(stream, state);
|
245
|
+
if (stream.current() === end) {
|
246
|
+
state.tokenize.pop();
|
247
|
+
state.currentIndent -= 1;
|
248
|
+
nextStyle = style;
|
249
|
+
}
|
250
|
+
|
251
|
+
return nextStyle;
|
252
|
+
};
|
253
|
+
}
|
254
|
+
|
255
|
+
function tokenMacro(begin, end, started) {
|
256
|
+
return function (stream, state) {
|
257
|
+
if (!started && stream.match("{" + begin)) {
|
258
|
+
state.currentIndent += 1;
|
259
|
+
state.tokenize[state.tokenize.length - 1] = tokenMacro(begin, end, true);
|
260
|
+
return "meta";
|
261
|
+
}
|
262
|
+
|
263
|
+
if (stream.match(end + "}")) {
|
264
|
+
state.currentIndent -= 1;
|
265
|
+
state.tokenize.pop();
|
266
|
+
return "meta";
|
267
|
+
}
|
268
|
+
|
269
|
+
return tokenBase(stream, state);
|
270
|
+
};
|
271
|
+
}
|
272
|
+
|
273
|
+
function tokenMacroDef(stream, state) {
|
274
|
+
if (stream.eatSpace()) {
|
275
|
+
return null;
|
276
|
+
}
|
277
|
+
|
278
|
+
var matched;
|
279
|
+
if (matched = stream.match(idents)) {
|
280
|
+
if (matched == "def") {
|
281
|
+
return "keyword";
|
282
|
+
}
|
283
|
+
stream.eat(/[?!]/);
|
284
|
+
}
|
285
|
+
|
286
|
+
state.tokenize.pop();
|
287
|
+
return "def";
|
288
|
+
}
|
289
|
+
|
290
|
+
function tokenFollowIdent(stream, state) {
|
291
|
+
if (stream.eatSpace()) {
|
292
|
+
return null;
|
293
|
+
}
|
294
|
+
|
295
|
+
if (stream.match(idents)) {
|
296
|
+
stream.eat(/[!?]/);
|
297
|
+
} else {
|
298
|
+
stream.match(operators) || stream.match(conditionalOperators) || stream.match(indexingOperators);
|
299
|
+
}
|
300
|
+
state.tokenize.pop();
|
301
|
+
return "def";
|
302
|
+
}
|
303
|
+
|
304
|
+
function tokenFollowType(stream, state) {
|
305
|
+
if (stream.eatSpace()) {
|
306
|
+
return null;
|
307
|
+
}
|
308
|
+
|
309
|
+
stream.match(types);
|
310
|
+
state.tokenize.pop();
|
311
|
+
return "def";
|
312
|
+
}
|
313
|
+
|
314
|
+
function tokenQuote(end, style, embed) {
|
315
|
+
return function (stream, state) {
|
316
|
+
var escaped = false;
|
317
|
+
|
318
|
+
while (stream.peek()) {
|
319
|
+
if (!escaped) {
|
320
|
+
if (stream.match("{%", false)) {
|
321
|
+
state.tokenize.push(tokenMacro("%", "%"));
|
322
|
+
return style;
|
323
|
+
}
|
324
|
+
|
325
|
+
if (stream.match("{{", false)) {
|
326
|
+
state.tokenize.push(tokenMacro("{", "}"));
|
327
|
+
return style;
|
328
|
+
}
|
329
|
+
|
330
|
+
if (embed && stream.match("#{", false)) {
|
331
|
+
state.tokenize.push(tokenNest("#{", "}", "meta"));
|
332
|
+
return style;
|
333
|
+
}
|
334
|
+
|
335
|
+
var ch = stream.next();
|
336
|
+
|
337
|
+
if (ch == end) {
|
338
|
+
state.tokenize.pop();
|
339
|
+
return style;
|
340
|
+
}
|
341
|
+
|
342
|
+
escaped = ch == "\\";
|
343
|
+
} else {
|
344
|
+
stream.next();
|
345
|
+
escaped = false;
|
346
|
+
}
|
347
|
+
}
|
348
|
+
|
349
|
+
return style;
|
350
|
+
};
|
351
|
+
}
|
352
|
+
|
353
|
+
return {
|
354
|
+
startState: function () {
|
355
|
+
return {
|
356
|
+
tokenize: [tokenBase],
|
357
|
+
currentIndent: 0,
|
358
|
+
lastToken: null,
|
359
|
+
blocks: []
|
360
|
+
};
|
361
|
+
},
|
362
|
+
|
363
|
+
token: function (stream, state) {
|
364
|
+
var style = state.tokenize[state.tokenize.length - 1](stream, state);
|
365
|
+
var token = stream.current();
|
366
|
+
|
367
|
+
if (style && style != "comment") {
|
368
|
+
state.lastToken = token;
|
369
|
+
}
|
370
|
+
|
371
|
+
return style;
|
372
|
+
},
|
373
|
+
|
374
|
+
indent: function (state, textAfter) {
|
375
|
+
textAfter = textAfter.replace(/^\s*(?:\{%)?\s*|\s*(?:%\})?\s*$/g, "");
|
376
|
+
|
377
|
+
if (dedentKeywords.test(textAfter) || dedentPunctuals.test(textAfter)) {
|
378
|
+
return config.indentUnit * (state.currentIndent - 1);
|
379
|
+
}
|
380
|
+
|
381
|
+
return config.indentUnit * state.currentIndent;
|
382
|
+
},
|
383
|
+
|
384
|
+
fold: "indent",
|
385
|
+
electricInput: wordRegExp(dedentPunctualsArray.concat(dedentKeywordsArray), true),
|
386
|
+
lineComment: '#'
|
387
|
+
};
|
388
|
+
});
|
389
|
+
|
390
|
+
CodeMirror.defineMIME("text/x-crystal", "crystal");
|
391
|
+
});
|