codemirror-rails 2.33 → 2.34
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/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +359 -453
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +4 -1
- data/vendor/assets/javascripts/codemirror/modes/clojure.js +7 -8
- data/vendor/assets/javascripts/codemirror/modes/commonlisp.js +101 -0
- data/vendor/assets/javascripts/codemirror/modes/css.js +336 -62
- data/vendor/assets/javascripts/codemirror/modes/gfm.js +6 -1
- data/vendor/assets/javascripts/codemirror/modes/haxe.js +0 -3
- data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +11 -12
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +131 -17
- data/vendor/assets/javascripts/codemirror/modes/php.js +4 -6
- data/vendor/assets/javascripts/codemirror/modes/shell.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/tiki.js +0 -7
- data/vendor/assets/javascripts/codemirror/modes/vb.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/xml.js +0 -8
- data/vendor/assets/javascripts/codemirror/utils/closetag.js +35 -35
- data/vendor/assets/javascripts/codemirror/utils/formatting.js +147 -253
- data/vendor/assets/javascripts/codemirror/utils/multiplex.js +4 -8
- data/vendor/assets/javascripts/codemirror/utils/overlay.js +3 -1
- data/vendor/assets/javascripts/codemirror/utils/runmode-standalone.js +90 -0
- data/vendor/assets/javascripts/codemirror/utils/simple-hint.js +1 -1
- data/vendor/assets/stylesheets/codemirror.css +2 -2
- metadata +14 -12
@@ -301,13 +301,6 @@ CodeMirror.defineMode('tiki', function(config, parserConfig) {
|
|
301
301
|
if (context) return context.indent + indentUnit;
|
302
302
|
else return 0;
|
303
303
|
},
|
304
|
-
compareStates: function(a, b) {
|
305
|
-
if (a.indented != b.indented || a.pluginName != b.pluginName) return false;
|
306
|
-
for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
|
307
|
-
if (!ca || !cb) return ca == cb;
|
308
|
-
if (ca.pluginName != cb.pluginName) return false;
|
309
|
-
}
|
310
|
-
},
|
311
304
|
electricChars: "/"
|
312
305
|
};
|
313
306
|
});
|
@@ -12,8 +12,8 @@ CodeMirror.defineMode("vb", function(conf, parserConf) {
|
|
12
12
|
var tripleDelimiters = new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
|
13
13
|
var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
|
14
14
|
|
15
|
-
var openingKeywords = ['class','module', 'sub','enum','select','while','if','function', 'get','set','property'];
|
16
|
-
var middleKeywords = ['else','elseif','case'];
|
15
|
+
var openingKeywords = ['class','module', 'sub','enum','select','while','if','function', 'get','set','property', 'try'];
|
16
|
+
var middleKeywords = ['else','elseif','case', 'catch'];
|
17
17
|
var endKeywords = ['next','loop'];
|
18
18
|
|
19
19
|
var wordOperators = wordRegexp(['and', 'or', 'not', 'xor', 'in']);
|
@@ -308,14 +308,6 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
|
308
308
|
else return 0;
|
309
309
|
},
|
310
310
|
|
311
|
-
compareStates: function(a, b) {
|
312
|
-
if (a.indented != b.indented || a.tokenize != b.tokenize) return false;
|
313
|
-
for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
|
314
|
-
if (!ca || !cb) return ca == cb;
|
315
|
-
if (ca.tagName != cb.tagName || ca.indent != cb.indent) return false;
|
316
|
-
}
|
317
|
-
},
|
318
|
-
|
319
311
|
electricChars: "/"
|
320
312
|
};
|
321
313
|
});
|
@@ -26,6 +26,11 @@
|
|
26
26
|
/** Array of tag names where an end tag is forbidden. */
|
27
27
|
CodeMirror.defaults['closeTagVoid'] = ['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
|
28
28
|
|
29
|
+
function innerState(cm, state) {
|
30
|
+
return CodeMirror.innerMode(cm.getMode(), state).state;
|
31
|
+
}
|
32
|
+
|
33
|
+
|
29
34
|
/**
|
30
35
|
* Call during key processing to close tags. Handles the key event if the tag is closed, otherwise throws CodeMirror.Pass.
|
31
36
|
* - cm: The editor instance.
|
@@ -39,40 +44,34 @@
|
|
39
44
|
throw CodeMirror.Pass;
|
40
45
|
}
|
41
46
|
|
42
|
-
|
43
|
-
|
44
|
-
|
47
|
+
/*
|
48
|
+
* Relevant structure of token:
|
49
|
+
*
|
50
|
+
* htmlmixed
|
51
|
+
* className
|
52
|
+
* state
|
53
|
+
* htmlState
|
54
|
+
* type
|
55
|
+
* tagName
|
56
|
+
* context
|
57
|
+
* tagName
|
58
|
+
* mode
|
59
|
+
*
|
60
|
+
* xml
|
61
|
+
* className
|
62
|
+
* state
|
63
|
+
* tagName
|
64
|
+
* type
|
65
|
+
*/
|
45
66
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
* state
|
52
|
-
* htmlState
|
53
|
-
* type
|
54
|
-
* tagName
|
55
|
-
* context
|
56
|
-
* tagName
|
57
|
-
* mode
|
58
|
-
*
|
59
|
-
* xml
|
60
|
-
* className
|
61
|
-
* state
|
62
|
-
* tagName
|
63
|
-
* type
|
64
|
-
*/
|
65
|
-
|
66
|
-
var pos = cm.getCursor();
|
67
|
-
var tok = cm.getTokenAt(pos);
|
68
|
-
var state = tok.state;
|
69
|
-
|
70
|
-
if (state.mode && state.mode != 'html') {
|
71
|
-
throw CodeMirror.Pass; // With htmlmixed, we only care about the html sub-mode.
|
72
|
-
}
|
67
|
+
var pos = cm.getCursor();
|
68
|
+
var tok = cm.getTokenAt(pos);
|
69
|
+
var state = innerState(cm, tok.state);
|
70
|
+
|
71
|
+
if (state) {
|
73
72
|
|
74
73
|
if (ch == '>') {
|
75
|
-
var type = state.
|
74
|
+
var type = state.type;
|
76
75
|
|
77
76
|
if (tok.className == 'tag' && type == 'closeTag') {
|
78
77
|
throw CodeMirror.Pass; // Don't process the '>' at the end of an end-tag.
|
@@ -83,11 +82,12 @@
|
|
83
82
|
cm.setCursor(pos);
|
84
83
|
|
85
84
|
tok = cm.getTokenAt(cm.getCursor());
|
86
|
-
state = tok.state;
|
87
|
-
|
85
|
+
state = innerState(cm, tok.state);
|
86
|
+
if (!state) throw CodeMirror.Pass;
|
87
|
+
var type = state.type;
|
88
88
|
|
89
89
|
if (tok.className == 'tag' && type != 'selfcloseTag') {
|
90
|
-
var tagName = state.
|
90
|
+
var tagName = state.tagName;
|
91
91
|
if (tagName.length > 0 && shouldClose(cm, vd, tagName)) {
|
92
92
|
insertEndTag(cm, indent, pos, tagName);
|
93
93
|
}
|
@@ -100,7 +100,7 @@
|
|
100
100
|
|
101
101
|
} else if (ch == '/') {
|
102
102
|
if (tok.className == 'tag' && tok.string == '<') {
|
103
|
-
var
|
103
|
+
var ctx = state.context, tagName = ctx ? ctx.tagName : '';
|
104
104
|
if (tagName.length > 0) {
|
105
105
|
completeEndTag(cm, pos, tagName);
|
106
106
|
return;
|
@@ -1,110 +1,22 @@
|
|
1
1
|
// ============== Formatting extensions ============================
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
return ext;
|
11
|
-
});
|
12
|
-
|
13
|
-
// If the current mode is 'htmlmixed', returns the extension of a mode located at
|
14
|
-
// the specified position (can be htmlmixed, css or javascript). Otherwise, simply
|
15
|
-
// returns the extension of the editor's current mode.
|
16
|
-
CodeMirror.defineExtension("getModeExtAtPos", function (pos) {
|
17
|
-
var token = this.getTokenAt(pos);
|
18
|
-
if (token && token.state && token.state.mode)
|
19
|
-
return CodeMirror.modeExtensions[token.state.mode == "html" ? "htmlmixed" : token.state.mode];
|
20
|
-
else
|
21
|
-
return this.getModeExt();
|
22
|
-
});
|
23
|
-
|
24
|
-
// Comment/uncomment the specified range
|
25
|
-
CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
|
26
|
-
var curMode = this.getModeExtAtPos(this.getCursor());
|
27
|
-
if (isComment) { // Comment range
|
28
|
-
var commentedText = this.getRange(from, to);
|
29
|
-
this.replaceRange(curMode.commentStart + this.getRange(from, to) + curMode.commentEnd
|
30
|
-
, from, to);
|
31
|
-
if (from.line == to.line && from.ch == to.ch) { // An empty comment inserted - put cursor inside
|
32
|
-
this.setCursor(from.line, from.ch + curMode.commentStart.length);
|
33
|
-
}
|
34
|
-
}
|
35
|
-
else { // Uncomment range
|
36
|
-
var selText = this.getRange(from, to);
|
37
|
-
var startIndex = selText.indexOf(curMode.commentStart);
|
38
|
-
var endIndex = selText.lastIndexOf(curMode.commentEnd);
|
39
|
-
if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {
|
40
|
-
// Take string till comment start
|
41
|
-
selText = selText.substr(0, startIndex)
|
42
|
-
// From comment start till comment end
|
43
|
-
+ selText.substring(startIndex + curMode.commentStart.length, endIndex)
|
44
|
-
// From comment end till string end
|
45
|
-
+ selText.substr(endIndex + curMode.commentEnd.length);
|
46
|
-
}
|
47
|
-
this.replaceRange(selText, from, to);
|
48
|
-
}
|
49
|
-
});
|
50
|
-
|
51
|
-
// Applies automatic mode-aware indentation to the specified range
|
52
|
-
CodeMirror.defineExtension("autoIndentRange", function (from, to) {
|
53
|
-
var cmInstance = this;
|
54
|
-
this.operation(function () {
|
55
|
-
for (var i = from.line; i <= to.line; i++) {
|
56
|
-
cmInstance.indentLine(i, "smart");
|
2
|
+
(function() {
|
3
|
+
// Define extensions for a few modes
|
4
|
+
CodeMirror.extendMode("css", {
|
5
|
+
commentStart: "/*",
|
6
|
+
commentEnd: "*/",
|
7
|
+
wordWrapChars: [";", "\\{", "\\}"],
|
8
|
+
autoFormatLineBreaks: function (text) {
|
9
|
+
return text.replace(new RegExp("(;|\\{|\\})([^\r\n])", "g"), "$1\n$2");
|
57
10
|
}
|
58
11
|
});
|
59
|
-
});
|
60
|
-
|
61
|
-
// Applies automatic formatting to the specified range
|
62
|
-
CodeMirror.defineExtension("autoFormatRange", function (from, to) {
|
63
|
-
var absStart = this.indexFromPos(from);
|
64
|
-
var absEnd = this.indexFromPos(to);
|
65
|
-
// Insert additional line breaks where necessary according to the
|
66
|
-
// mode's syntax
|
67
|
-
var res = this.getModeExt().autoFormatLineBreaks(this.getValue(), absStart, absEnd);
|
68
|
-
var cmInstance = this;
|
69
|
-
|
70
|
-
// Replace and auto-indent the range
|
71
|
-
this.operation(function () {
|
72
|
-
cmInstance.replaceRange(res, from, to);
|
73
|
-
var startLine = cmInstance.posFromIndex(absStart).line;
|
74
|
-
var endLine = cmInstance.posFromIndex(absStart + res.length).line;
|
75
|
-
for (var i = startLine; i <= endLine; i++) {
|
76
|
-
cmInstance.indentLine(i, "smart");
|
77
|
-
}
|
78
|
-
});
|
79
|
-
});
|
80
|
-
|
81
|
-
// Define extensions for a few modes
|
82
|
-
|
83
|
-
CodeMirror.modeExtensions["css"] = {
|
84
|
-
commentStart: "/*",
|
85
|
-
commentEnd: "*/",
|
86
|
-
wordWrapChars: [";", "\\{", "\\}"],
|
87
|
-
autoFormatLineBreaks: function (text, startPos, endPos) {
|
88
|
-
text = text.substring(startPos, endPos);
|
89
|
-
return text.replace(new RegExp("(;|\\{|\\})([^\r\n])", "g"), "$1\n$2");
|
90
|
-
}
|
91
|
-
};
|
92
12
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
var
|
100
|
-
new RegExp("for\\s*?\\(([\\s\\S]*?)\\)"),
|
101
|
-
new RegExp("\\\\\"([\\s\\S]*?)(\\\\\"|$)"),
|
102
|
-
new RegExp("\\\\\'([\\s\\S]*?)(\\\\\'|$)"),
|
103
|
-
new RegExp("'([\\s\\S]*?)('|$)"),
|
104
|
-
new RegExp("\"([\\s\\S]*?)(\"|$)"),
|
105
|
-
new RegExp("//.*([\r\n]|$)")
|
106
|
-
];
|
107
|
-
var nonBreakableBlocks = new Array();
|
13
|
+
function jsNonBreakableBlocks(text) {
|
14
|
+
var nonBreakableRegexes = [/for\s*?\((.*?)\)/,
|
15
|
+
/\"(.*?)(\"|$)/,
|
16
|
+
/\'(.*?)(\'|$)/,
|
17
|
+
/\/\*(.*?)(\*\/|$)/,
|
18
|
+
/\/\/.*/];
|
19
|
+
var nonBreakableBlocks = [];
|
108
20
|
for (var i = 0; i < nonBreakableRegexes.length; i++) {
|
109
21
|
var curPos = 0;
|
110
22
|
while (curPos < text.length) {
|
@@ -126,174 +38,156 @@ CodeMirror.modeExtensions["javascript"] = {
|
|
126
38
|
});
|
127
39
|
|
128
40
|
return nonBreakableBlocks;
|
129
|
-
}
|
41
|
+
}
|
130
42
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
var
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
43
|
+
CodeMirror.extendMode("javascript", {
|
44
|
+
commentStart: "/*",
|
45
|
+
commentEnd: "*/",
|
46
|
+
wordWrapChars: [";", "\\{", "\\}"],
|
47
|
+
|
48
|
+
autoFormatLineBreaks: function (text) {
|
49
|
+
var curPos = 0;
|
50
|
+
var reLinesSplitter = /(;|\{|\})([^\r\n;])/g;
|
51
|
+
var nonBreakableBlocks = jsNonBreakableBlocks(text);
|
52
|
+
if (nonBreakableBlocks != null) {
|
53
|
+
var res = "";
|
54
|
+
for (var i = 0; i < nonBreakableBlocks.length; i++) {
|
55
|
+
if (nonBreakableBlocks[i].start > curPos) { // Break lines till the block
|
56
|
+
res += text.substring(curPos, nonBreakableBlocks[i].start).replace(reLinesSplitter, "$1\n$2");
|
57
|
+
curPos = nonBreakableBlocks[i].start;
|
58
|
+
}
|
59
|
+
if (nonBreakableBlocks[i].start <= curPos
|
60
|
+
&& nonBreakableBlocks[i].end >= curPos) { // Skip non-breakable block
|
61
|
+
res += text.substring(curPos, nonBreakableBlocks[i].end);
|
62
|
+
curPos = nonBreakableBlocks[i].end;
|
63
|
+
}
|
147
64
|
}
|
65
|
+
if (curPos < text.length)
|
66
|
+
res += text.substr(curPos).replace(reLinesSplitter, "$1\n$2");
|
67
|
+
return res;
|
68
|
+
} else {
|
69
|
+
return text.replace(reLinesSplitter, "$1\n$2");
|
148
70
|
}
|
149
|
-
if (curPos < text.length - 1) {
|
150
|
-
res += text.substr(curPos).replace(reLinesSplitter, "$1\n$2");
|
151
|
-
}
|
152
|
-
return res;
|
153
71
|
}
|
154
|
-
|
155
|
-
return text.replace(reLinesSplitter, "$1\n$2");
|
156
|
-
}
|
157
|
-
}
|
158
|
-
};
|
159
|
-
|
160
|
-
CodeMirror.modeExtensions["xml"] = {
|
161
|
-
commentStart: "<!--",
|
162
|
-
commentEnd: "-->",
|
163
|
-
wordWrapChars: [">"],
|
72
|
+
});
|
164
73
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
var
|
173
|
-
|
174
|
-
|
74
|
+
CodeMirror.extendMode("xml", {
|
75
|
+
commentStart: "<!--",
|
76
|
+
commentEnd: "-->",
|
77
|
+
wordWrapChars: [">"],
|
78
|
+
|
79
|
+
autoFormatLineBreaks: function (text) {
|
80
|
+
var lines = text.split("\n");
|
81
|
+
var reProcessedPortion = new RegExp("(^\\s*?<|^[^<]*?)(.+)(>\\s*?$|[^>]*?$)");
|
82
|
+
var reOpenBrackets = new RegExp("<", "g");
|
83
|
+
var reCloseBrackets = new RegExp("(>)([^\r\n])", "g");
|
84
|
+
for (var i = 0; i < lines.length; i++) {
|
85
|
+
var mToProcess = lines[i].match(reProcessedPortion);
|
86
|
+
if (mToProcess != null && mToProcess.length > 3) { // The line starts with whitespaces and ends with whitespaces
|
87
|
+
lines[i] = mToProcess[1]
|
175
88
|
+ mToProcess[2].replace(reOpenBrackets, "\n$&").replace(reCloseBrackets, "$1\n$2")
|
176
89
|
+ mToProcess[3];
|
177
|
-
|
90
|
+
continue;
|
91
|
+
}
|
178
92
|
}
|
93
|
+
return lines.join("\n");
|
179
94
|
}
|
95
|
+
});
|
180
96
|
|
181
|
-
|
97
|
+
function localModeAt(cm, pos) {
|
98
|
+
return CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(pos).state).mode;
|
182
99
|
}
|
183
|
-
};
|
184
|
-
|
185
|
-
CodeMirror.modeExtensions["htmlmixed"] = {
|
186
|
-
commentStart: "<!--",
|
187
|
-
commentEnd: "-->",
|
188
|
-
wordWrapChars: [">", ";", "\\{", "\\}"],
|
189
100
|
|
190
|
-
|
191
|
-
var
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
{
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
101
|
+
function enumerateModesBetween(cm, line, start, end) {
|
102
|
+
var outer = cm.getMode(), text = cm.getLine(line);
|
103
|
+
if (end == null) end = text.length;
|
104
|
+
if (!outer.innerMode) return [{from: start, to: end, mode: outer}];
|
105
|
+
var state = cm.getTokenAt({line: line, ch: start}).state;
|
106
|
+
var mode = CodeMirror.innerMode(outer, state).mode;
|
107
|
+
var found = [], stream = new CodeMirror.StringStream(text);
|
108
|
+
stream.pos = stream.start = start;
|
109
|
+
for (;;) {
|
110
|
+
outer.token(stream, state);
|
111
|
+
var curMode = CodeMirror.innerMode(outer, state).mode;
|
112
|
+
if (curMode != mode) {
|
113
|
+
var cut = stream.start;
|
114
|
+
// Crappy heuristic to deal with the fact that a change in
|
115
|
+
// mode can occur both at the end and the start of a token,
|
116
|
+
// and we don't know which it was.
|
117
|
+
if (mode.name == "xml" && text.charAt(stream.pos - 1) == ">") cut = stream.pos;
|
118
|
+
found.push({from: start, to: cut, mode: mode});
|
119
|
+
start = cut;
|
120
|
+
mode = curMode;
|
121
|
+
}
|
122
|
+
if (stream.pos >= end) break;
|
123
|
+
stream.start = stream.pos;
|
124
|
+
}
|
125
|
+
if (start < end) found.push({from: start, to: end, mode: mode});
|
126
|
+
return found;
|
127
|
+
}
|
212
128
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
modeExt: modeInfos[0].modeExt,
|
234
|
-
modeName: modeInfos[0].modeName
|
235
|
-
});
|
236
|
-
curPos += m.index + m[0].length;
|
237
|
-
continue;
|
238
|
-
}
|
239
|
-
else {
|
240
|
-
curPos += m.index + Math.max(m[0].length, 1);
|
241
|
-
}
|
242
|
-
}
|
243
|
-
else { // No more matches
|
244
|
-
break;
|
129
|
+
// Comment/uncomment the specified range
|
130
|
+
CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
|
131
|
+
var curMode = localModeAt(this, from), cm = this;
|
132
|
+
this.operation(function() {
|
133
|
+
if (isComment) { // Comment range
|
134
|
+
cm.replaceRange(curMode.commentEnd, to);
|
135
|
+
cm.replaceRange(curMode.commentStart, from);
|
136
|
+
if (from.line == to.line && from.ch == to.ch) // An empty comment inserted - put cursor inside
|
137
|
+
cm.setCursor(from.line, from.ch + curMode.commentStart.length);
|
138
|
+
} else { // Uncomment range
|
139
|
+
var selText = cm.getRange(from, to);
|
140
|
+
var startIndex = selText.indexOf(curMode.commentStart);
|
141
|
+
var endIndex = selText.lastIndexOf(curMode.commentEnd);
|
142
|
+
if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {
|
143
|
+
// Take string till comment start
|
144
|
+
selText = selText.substr(0, startIndex)
|
145
|
+
// From comment start till comment end
|
146
|
+
+ selText.substring(startIndex + curMode.commentStart.length, endIndex)
|
147
|
+
// From comment end till string end
|
148
|
+
+ selText.substr(endIndex + curMode.commentEnd.length);
|
245
149
|
}
|
150
|
+
cm.replaceRange(selText, from, to);
|
246
151
|
}
|
247
|
-
}
|
248
|
-
// Sort mode infos
|
249
|
-
modeInfos.sort(function sortModeInfo(a, b) {
|
250
|
-
return a.pos - b.pos;
|
251
152
|
});
|
153
|
+
});
|
252
154
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
if (modeInfos.length > 1) { // Deal with multi-mode text
|
263
|
-
for (var i = 1; i <= modeInfos.length; i++) {
|
264
|
-
var selStart = modeInfos[i - 1].pos;
|
265
|
-
var selEnd = (i < modeInfos.length ? modeInfos[i].pos : endPos);
|
155
|
+
// Applies automatic mode-aware indentation to the specified range
|
156
|
+
CodeMirror.defineExtension("autoIndentRange", function (from, to) {
|
157
|
+
var cmInstance = this;
|
158
|
+
this.operation(function () {
|
159
|
+
for (var i = from.line; i <= to.line; i++) {
|
160
|
+
cmInstance.indentLine(i, "smart");
|
161
|
+
}
|
162
|
+
});
|
163
|
+
});
|
266
164
|
|
267
|
-
|
268
|
-
|
165
|
+
// Applies automatic formatting to the specified range
|
166
|
+
CodeMirror.defineExtension("autoFormatRange", function (from, to) {
|
167
|
+
var cm = this;
|
168
|
+
cm.operation(function () {
|
169
|
+
for (var cur = from.line, end = to.line; cur <= end; ++cur) {
|
170
|
+
var f = {line: cur, ch: cur == from.line ? from.ch : 0};
|
171
|
+
var t = {line: cur, ch: cur == end ? to.ch : null};
|
172
|
+
var modes = enumerateModesBetween(cm, cur, f.ch, t.ch), mangled = "";
|
173
|
+
var text = cm.getRange(f, t);
|
174
|
+
for (var i = 0; i < modes.length; ++i) {
|
175
|
+
var part = modes.length > 1 ? text.slice(modes[i].from, modes[i].to) : text;
|
176
|
+
if (mangled) mangled += "\n";
|
177
|
+
if (modes[i].mode.autoFormatLineBreaks) {
|
178
|
+
mangled += modes[i].mode.autoFormatLineBreaks(part);
|
179
|
+
} else mangled += text;
|
269
180
|
}
|
270
|
-
if (
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
}
|
276
|
-
if (selEnd > endPos) {
|
277
|
-
selEnd = endPos;
|
278
|
-
}
|
279
|
-
var textPortion = text.substring(selStart, selEnd);
|
280
|
-
if (modeInfos[i - 1].modeName != "xml") { // Starting a CSS or JavaScript block
|
281
|
-
if (!reBlockStartsWithNewline.test(textPortion)
|
282
|
-
&& selStart > 0) { // The block does not start with a line break
|
283
|
-
textPortion = "\n" + textPortion;
|
284
|
-
}
|
285
|
-
if (!reBlockEndsWithNewline.test(textPortion)
|
286
|
-
&& selEnd < text.length - 1) { // The block does not end with a line break
|
287
|
-
textPortion += "\n";
|
288
|
-
}
|
181
|
+
if (mangled != text) {
|
182
|
+
for (var count = 0, pos = mangled.indexOf("\n"); pos != -1; pos = mangled.indexOf("\n", pos + 1), ++count) {}
|
183
|
+
cm.replaceRange(mangled, f, t);
|
184
|
+
cur += count;
|
185
|
+
end += count;
|
289
186
|
}
|
290
|
-
res += modeInfos[i - 1].modeExt.autoFormatLineBreaks(textPortion);
|
291
187
|
}
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
}
|
296
|
-
|
297
|
-
|
298
|
-
}
|
299
|
-
};
|
188
|
+
for (var cur = from.line + 1; cur <= end; ++cur)
|
189
|
+
cm.indentLine(cur, "smart");
|
190
|
+
cm.setSelection(from, cm.getCursor(false));
|
191
|
+
});
|
192
|
+
});
|
193
|
+
})();
|