codemirror-rails 2.36 → 3.00
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +3727 -2345
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +2226 -825
- data/vendor/assets/javascripts/codemirror/modes/clike.js +23 -8
- data/vendor/assets/javascripts/codemirror/modes/clojure.js +4 -4
- data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/commonlisp.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/css.js +20 -3
- data/vendor/assets/javascripts/codemirror/modes/diff.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/ecl.js +192 -203
- data/vendor/assets/javascripts/codemirror/modes/erlang.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/gfm.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/go.js +1 -6
- data/vendor/assets/javascripts/codemirror/modes/groovy.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/haskell.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/haxe.js +13 -13
- data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +3 -3
- data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/http.js +98 -0
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/jinja2.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +7 -14
- data/vendor/assets/javascripts/codemirror/modes/mysql.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/ntriples.js +0 -2
- data/vendor/assets/javascripts/codemirror/modes/ocaml.js +1 -2
- data/vendor/assets/javascripts/codemirror/modes/pascal.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/perl.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/php.js +5 -4
- data/vendor/assets/javascripts/codemirror/modes/pig.js +3 -4
- data/vendor/assets/javascripts/codemirror/modes/plsql.js +3 -4
- data/vendor/assets/javascripts/codemirror/modes/python.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/r.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/rpm-changes.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/rpm-spec.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/rst.js +1 -13
- data/vendor/assets/javascripts/codemirror/modes/ruby.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/rust.js +3 -3
- data/vendor/assets/javascripts/codemirror/modes/scheme.js +4 -4
- data/vendor/assets/javascripts/codemirror/modes/shell.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/sieve.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/smarty.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/sparql.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/stex.js +6 -13
- data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +6 -37
- data/vendor/assets/javascripts/codemirror/modes/tiki.js +3 -3
- data/vendor/assets/javascripts/codemirror/modes/vb.js +3 -3
- data/vendor/assets/javascripts/codemirror/modes/velocity.js +2 -4
- data/vendor/assets/javascripts/codemirror/modes/verilog.js +182 -194
- data/vendor/assets/javascripts/codemirror/modes/xml.js +9 -5
- data/vendor/assets/javascripts/codemirror/modes/xquery.js +3 -4
- data/vendor/assets/javascripts/codemirror/utils/closetag.js +85 -164
- data/vendor/assets/javascripts/codemirror/utils/colorize.js +29 -0
- data/vendor/assets/javascripts/codemirror/utils/continuecomment.js +1 -1
- data/vendor/assets/javascripts/codemirror/utils/continuelist.js +28 -0
- data/vendor/assets/javascripts/codemirror/utils/dialog.js +21 -16
- data/vendor/assets/javascripts/codemirror/utils/foldcode.js +59 -73
- data/vendor/assets/javascripts/codemirror/utils/formatting.js +43 -131
- data/vendor/assets/javascripts/codemirror/utils/javascript-hint.js +22 -19
- data/vendor/assets/javascripts/codemirror/utils/match-highlighter.js +5 -3
- data/vendor/assets/javascripts/codemirror/utils/matchbrackets.js +63 -0
- data/vendor/assets/javascripts/codemirror/utils/multiplex.js +18 -0
- data/vendor/assets/javascripts/codemirror/utils/pig-hint.js +3 -9
- data/vendor/assets/javascripts/codemirror/utils/runmode.js +19 -20
- data/vendor/assets/javascripts/codemirror/utils/search.js +6 -5
- data/vendor/assets/javascripts/codemirror/utils/searchcursor.js +1 -1
- data/vendor/assets/javascripts/codemirror/utils/simple-hint.js +10 -10
- data/vendor/assets/javascripts/codemirror/utils/xml-hint.js +2 -2
- data/vendor/assets/stylesheets/codemirror.css +169 -104
- data/vendor/assets/stylesheets/codemirror/themes/ambiance-mobile.css +1 -1
- data/vendor/assets/stylesheets/codemirror/themes/ambiance.css +7 -12
- data/vendor/assets/stylesheets/codemirror/themes/blackboard.css +3 -3
- data/vendor/assets/stylesheets/codemirror/themes/cobalt.css +3 -3
- data/vendor/assets/stylesheets/codemirror/themes/erlang-dark.css +3 -3
- data/vendor/assets/stylesheets/codemirror/themes/lesser-dark.css +4 -4
- data/vendor/assets/stylesheets/codemirror/themes/monokai.css +3 -3
- data/vendor/assets/stylesheets/codemirror/themes/night.css +3 -3
- data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +3 -3
- data/vendor/assets/stylesheets/codemirror/themes/solarized.css +207 -0
- data/vendor/assets/stylesheets/codemirror/themes/twilight.css +4 -4
- data/vendor/assets/stylesheets/codemirror/themes/vibrant-ink.css +3 -3
- data/vendor/assets/stylesheets/codemirror/themes/xq-dark.css +3 -3
- data/vendor/assets/stylesheets/codemirror/utils/dialog.css +12 -7
- metadata +16 -11
@@ -1,15 +1,15 @@
|
|
1
1
|
// the tagRangeFinder function is
|
2
2
|
// Copyright (C) 2011 by Daniel Glazman <daniel@glazman.org>
|
3
3
|
// released under the MIT license (../../LICENSE) like the rest of CodeMirror
|
4
|
-
CodeMirror.tagRangeFinder = function(cm,
|
4
|
+
CodeMirror.tagRangeFinder = function(cm, start) {
|
5
5
|
var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
|
6
6
|
var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
|
7
7
|
var xmlNAMERegExp = new RegExp("^[" + nameStartChar + "][" + nameChar + "]*");
|
8
8
|
|
9
|
-
var lineText = cm.getLine(line);
|
9
|
+
var lineText = cm.getLine(start.line);
|
10
10
|
var found = false;
|
11
11
|
var tag = null;
|
12
|
-
var pos =
|
12
|
+
var pos = start.ch;
|
13
13
|
while (!found) {
|
14
14
|
pos = lineText.indexOf("<", pos);
|
15
15
|
if (-1 == pos) // no tag on line
|
@@ -18,28 +18,26 @@ CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
|
|
18
18
|
pos++;
|
19
19
|
continue;
|
20
20
|
}
|
21
|
-
// ok we
|
21
|
+
// ok we seem to have a start tag
|
22
22
|
if (!lineText.substr(pos + 1).match(xmlNAMERegExp)) { // not a tag name...
|
23
23
|
pos++;
|
24
24
|
continue;
|
25
25
|
}
|
26
26
|
var gtPos = lineText.indexOf(">", pos + 1);
|
27
27
|
if (-1 == gtPos) { // end of start tag not in line
|
28
|
-
var l = line + 1;
|
28
|
+
var l = start.line + 1;
|
29
29
|
var foundGt = false;
|
30
30
|
var lastLine = cm.lineCount();
|
31
31
|
while (l < lastLine && !foundGt) {
|
32
32
|
var lt = cm.getLine(l);
|
33
|
-
|
34
|
-
if (-1 !=
|
33
|
+
gtPos = lt.indexOf(">");
|
34
|
+
if (-1 != gtPos) { // found a >
|
35
35
|
foundGt = true;
|
36
|
-
var slash = lt.lastIndexOf("/",
|
37
|
-
if (-1 != slash && slash <
|
38
|
-
var str = lineText.substr(slash,
|
39
|
-
if (!str.match( /\/\s*\>/ ))
|
40
|
-
|
41
|
-
return l;
|
42
|
-
}
|
36
|
+
var slash = lt.lastIndexOf("/", gtPos);
|
37
|
+
if (-1 != slash && slash < gtPos) {
|
38
|
+
var str = lineText.substr(slash, gtPos - slash + 1);
|
39
|
+
if (!str.match( /\/\s*\>/ )) // yep, that's the end of empty tag
|
40
|
+
return;
|
43
41
|
}
|
44
42
|
}
|
45
43
|
l++;
|
@@ -83,10 +81,10 @@ CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
|
|
83
81
|
|
84
82
|
if (found) {
|
85
83
|
var startTag = "(\\<\\/" + tag + "\\>)|(\\<" + tag + "\\>)|(\\<" + tag + "\\s)|(\\<" + tag + "$)";
|
86
|
-
var startTagRegExp = new RegExp(startTag
|
84
|
+
var startTagRegExp = new RegExp(startTag);
|
87
85
|
var endTag = "</" + tag + ">";
|
88
86
|
var depth = 1;
|
89
|
-
var l = line + 1;
|
87
|
+
var l = start.line + 1;
|
90
88
|
var lastLine = cm.lineCount();
|
91
89
|
while (l < lastLine) {
|
92
90
|
lineText = cm.getLine(l);
|
@@ -97,10 +95,8 @@ CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
|
|
97
95
|
depth--;
|
98
96
|
else
|
99
97
|
depth++;
|
100
|
-
if (!depth) {
|
101
|
-
|
102
|
-
return l;
|
103
|
-
}
|
98
|
+
if (!depth) return {from: {line: start.line, ch: gtPos + 1},
|
99
|
+
to: {line: l, ch: match.index}};
|
104
100
|
}
|
105
101
|
}
|
106
102
|
l++;
|
@@ -109,17 +105,18 @@ CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
|
|
109
105
|
}
|
110
106
|
};
|
111
107
|
|
112
|
-
CodeMirror.braceRangeFinder = function(cm,
|
113
|
-
var
|
108
|
+
CodeMirror.braceRangeFinder = function(cm, start) {
|
109
|
+
var line = start.line, lineText = cm.getLine(line);
|
110
|
+
var at = lineText.length, startChar, tokenType;
|
114
111
|
for (;;) {
|
115
112
|
var found = lineText.lastIndexOf("{", at);
|
116
|
-
if (found <
|
117
|
-
tokenType = cm.getTokenAt({line: line, ch: found}).
|
113
|
+
if (found < start.ch) break;
|
114
|
+
tokenType = cm.getTokenAt({line: line, ch: found}).type;
|
118
115
|
if (!/^(comment|string)/.test(tokenType)) { startChar = found; break; }
|
119
116
|
at = found - 1;
|
120
117
|
}
|
121
118
|
if (startChar == null || lineText.lastIndexOf("}") > startChar) return;
|
122
|
-
var count = 1, lastLine = cm.lineCount(), end;
|
119
|
+
var count = 1, lastLine = cm.lineCount(), end, endCh;
|
123
120
|
outer: for (var i = line + 1; i < lastLine; ++i) {
|
124
121
|
var text = cm.getLine(i), pos = 0;
|
125
122
|
for (;;) {
|
@@ -128,69 +125,58 @@ CodeMirror.braceRangeFinder = function(cm, line, hideEnd) {
|
|
128
125
|
if (nextClose < 0) nextClose = text.length;
|
129
126
|
pos = Math.min(nextOpen, nextClose);
|
130
127
|
if (pos == text.length) break;
|
131
|
-
if (cm.getTokenAt({line: i, ch: pos + 1}).
|
128
|
+
if (cm.getTokenAt({line: i, ch: pos + 1}).type == tokenType) {
|
132
129
|
if (pos == nextOpen) ++count;
|
133
|
-
else if (!--count) { end = i; break outer; }
|
130
|
+
else if (!--count) { end = i; endCh = pos; break outer; }
|
134
131
|
}
|
135
132
|
++pos;
|
136
133
|
}
|
137
134
|
}
|
138
135
|
if (end == null || end == line + 1) return;
|
139
|
-
|
140
|
-
|
136
|
+
return {from: {line: line, ch: startChar + 1},
|
137
|
+
to: {line: end, ch: endCh}};
|
141
138
|
};
|
142
139
|
|
143
|
-
CodeMirror.indentRangeFinder = function(cm,
|
144
|
-
var tabSize = cm.getOption("tabSize");
|
145
|
-
var myIndent =
|
146
|
-
for (var i = line + 1, end = cm.lineCount(); i < end; ++i) {
|
147
|
-
var
|
148
|
-
if (
|
149
|
-
|
150
|
-
|
151
|
-
}
|
140
|
+
CodeMirror.indentRangeFinder = function(cm, start) {
|
141
|
+
var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line);
|
142
|
+
var myIndent = CodeMirror.countColumn(firstLine, null, tabSize);
|
143
|
+
for (var i = start.line + 1, end = cm.lineCount(); i < end; ++i) {
|
144
|
+
var curLine = cm.getLine(i);
|
145
|
+
if (CodeMirror.countColumn(curLine, null, tabSize) < myIndent)
|
146
|
+
return {from: {line: start.line, ch: firstLine.length},
|
147
|
+
to: {line: i, ch: curLine.length}};
|
152
148
|
}
|
153
|
-
if (!last) return null;
|
154
|
-
return last + 1;
|
155
149
|
};
|
156
150
|
|
157
|
-
CodeMirror.newFoldFunction = function(rangeFinder,
|
158
|
-
|
159
|
-
if (
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
if (!start) folded.splice(i--, 1);
|
165
|
-
else if (start.line == n) return {pos: i, region: folded[i]};
|
166
|
-
}
|
151
|
+
CodeMirror.newFoldFunction = function(rangeFinder, widget) {
|
152
|
+
if (widget == null) widget = "\u2194";
|
153
|
+
if (typeof widget == "string") {
|
154
|
+
var text = document.createTextNode(widget);
|
155
|
+
widget = document.createElement("span");
|
156
|
+
widget.appendChild(text);
|
157
|
+
widget.className = "CodeMirror-foldmarker";
|
167
158
|
}
|
168
159
|
|
169
|
-
function
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
}
|
160
|
+
return function(cm, pos) {
|
161
|
+
if (typeof pos == "number") pos = {line: pos, ch: 0};
|
162
|
+
var range = rangeFinder(cm, pos);
|
163
|
+
if (!range) return;
|
174
164
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
expand(cm, known.region);
|
181
|
-
} else {
|
182
|
-
var end = rangeFinder(cm, line, hideEnd);
|
183
|
-
if (end == null) return;
|
184
|
-
var hidden = [];
|
185
|
-
for (var i = line + 1; i < end; ++i) {
|
186
|
-
var handle = cm.hideLine(i);
|
187
|
-
if (handle) hidden.push(handle);
|
188
|
-
}
|
189
|
-
var first = cm.setMarker(line, markText);
|
190
|
-
var region = {start: first, hidden: hidden};
|
191
|
-
cm.onDeleteLine(first, function() { expand(cm, region); });
|
192
|
-
folded.push(region);
|
165
|
+
var present = cm.findMarksAt(range.from), cleared = 0;
|
166
|
+
for (var i = 0; i < present.length; ++i) {
|
167
|
+
if (present[i].__isFold) {
|
168
|
+
++cleared;
|
169
|
+
present[i].clear();
|
193
170
|
}
|
171
|
+
}
|
172
|
+
if (cleared) return;
|
173
|
+
|
174
|
+
var myWidget = widget.cloneNode(true);
|
175
|
+
CodeMirror.on(myWidget, "mousedown", function() {myRange.clear();});
|
176
|
+
var myRange = cm.markText(range.from, range.to, {
|
177
|
+
replacedWith: myWidget,
|
178
|
+
clearOnEnter: true,
|
179
|
+
__isFold: true
|
194
180
|
});
|
195
181
|
};
|
196
182
|
};
|
@@ -1,138 +1,39 @@
|
|
1
|
-
// ============== Formatting extensions ============================
|
2
1
|
(function() {
|
3
|
-
|
2
|
+
|
4
3
|
CodeMirror.extendMode("css", {
|
5
4
|
commentStart: "/*",
|
6
5
|
commentEnd: "*/",
|
7
|
-
|
8
|
-
|
9
|
-
return text.replace(new RegExp("(;|\\{|\\})([^\r\n])", "g"), "$1\n$2");
|
6
|
+
newlineAfterToken: function(_type, content) {
|
7
|
+
return /^[;{}]$/.test(content);
|
10
8
|
}
|
11
9
|
});
|
12
10
|
|
13
|
-
function jsNonBreakableBlocks(text) {
|
14
|
-
var nonBreakableRegexes = [/for\s*?\((.*?)\)/,
|
15
|
-
/\"(.*?)(\"|$)/,
|
16
|
-
/\'(.*?)(\'|$)/,
|
17
|
-
/\/\*(.*?)(\*\/|$)/,
|
18
|
-
/\/\/.*/];
|
19
|
-
var nonBreakableBlocks = [];
|
20
|
-
for (var i = 0; i < nonBreakableRegexes.length; i++) {
|
21
|
-
var curPos = 0;
|
22
|
-
while (curPos < text.length) {
|
23
|
-
var m = text.substr(curPos).match(nonBreakableRegexes[i]);
|
24
|
-
if (m != null) {
|
25
|
-
nonBreakableBlocks.push({
|
26
|
-
start: curPos + m.index,
|
27
|
-
end: curPos + m.index + m[0].length
|
28
|
-
});
|
29
|
-
curPos += m.index + Math.max(1, m[0].length);
|
30
|
-
}
|
31
|
-
else { // No more matches
|
32
|
-
break;
|
33
|
-
}
|
34
|
-
}
|
35
|
-
}
|
36
|
-
nonBreakableBlocks.sort(function (a, b) {
|
37
|
-
return a.start - b.start;
|
38
|
-
});
|
39
|
-
|
40
|
-
return nonBreakableBlocks;
|
41
|
-
}
|
42
|
-
|
43
11
|
CodeMirror.extendMode("javascript", {
|
44
12
|
commentStart: "/*",
|
45
13
|
commentEnd: "*/",
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
var split = this.jsonMode ? function(str) {
|
51
|
-
return str.replace(/([,{])/g, "$1\n").replace(/}/g, "\n}");
|
52
|
-
} : function(str) {
|
53
|
-
return str.replace(/(;|\{|\})([^\r\n;])/g, "$1\n$2");
|
54
|
-
};
|
55
|
-
var nonBreakableBlocks = jsNonBreakableBlocks(text), res = "";
|
56
|
-
if (nonBreakableBlocks != null) {
|
57
|
-
for (var i = 0; i < nonBreakableBlocks.length; i++) {
|
58
|
-
if (nonBreakableBlocks[i].start > curPos) { // Break lines till the block
|
59
|
-
res += split(text.substring(curPos, nonBreakableBlocks[i].start));
|
60
|
-
curPos = nonBreakableBlocks[i].start;
|
61
|
-
}
|
62
|
-
if (nonBreakableBlocks[i].start <= curPos
|
63
|
-
&& nonBreakableBlocks[i].end >= curPos) { // Skip non-breakable block
|
64
|
-
res += text.substring(curPos, nonBreakableBlocks[i].end);
|
65
|
-
curPos = nonBreakableBlocks[i].end;
|
66
|
-
}
|
67
|
-
}
|
68
|
-
if (curPos < text.length)
|
69
|
-
res += split(text.substr(curPos));
|
14
|
+
// FIXME semicolons inside of for
|
15
|
+
newlineAfterToken: function(_type, content, textAfter, state) {
|
16
|
+
if (this.jsonMode) {
|
17
|
+
return /^[\[,{]$/.test(content) || /^}/.test(textAfter);
|
70
18
|
} else {
|
71
|
-
|
19
|
+
if (content == ";" && state.lexical && state.lexical.type == ")") return false;
|
20
|
+
return /^[;{}]$/.test(content) && !/^;/.test(textAfter);
|
72
21
|
}
|
73
|
-
return res.replace(/^\n*|\n*$/, "");
|
74
22
|
}
|
75
23
|
});
|
76
24
|
|
77
25
|
CodeMirror.extendMode("xml", {
|
78
26
|
commentStart: "<!--",
|
79
27
|
commentEnd: "-->",
|
80
|
-
|
81
|
-
|
82
|
-
autoFormatLineBreaks: function (text) {
|
83
|
-
var lines = text.split("\n");
|
84
|
-
var reProcessedPortion = new RegExp("(^\\s*?<|^[^<]*?)(.+)(>\\s*?$|[^>]*?$)");
|
85
|
-
var reOpenBrackets = new RegExp("<", "g");
|
86
|
-
var reCloseBrackets = new RegExp("(>)([^\r\n])", "g");
|
87
|
-
for (var i = 0; i < lines.length; i++) {
|
88
|
-
var mToProcess = lines[i].match(reProcessedPortion);
|
89
|
-
if (mToProcess != null && mToProcess.length > 3) { // The line starts with whitespaces and ends with whitespaces
|
90
|
-
lines[i] = mToProcess[1]
|
91
|
-
+ mToProcess[2].replace(reOpenBrackets, "\n$&").replace(reCloseBrackets, "$1\n$2")
|
92
|
-
+ mToProcess[3];
|
93
|
-
continue;
|
94
|
-
}
|
95
|
-
}
|
96
|
-
return lines.join("\n");
|
28
|
+
newlineAfterToken: function(type, content, textAfter) {
|
29
|
+
return type == "tag" && />$/.test(content) || /^</.test(textAfter);
|
97
30
|
}
|
98
31
|
});
|
99
32
|
|
100
|
-
function localModeAt(cm, pos) {
|
101
|
-
return CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(pos).state).mode;
|
102
|
-
}
|
103
|
-
|
104
|
-
function enumerateModesBetween(cm, line, start, end) {
|
105
|
-
var outer = cm.getMode(), text = cm.getLine(line);
|
106
|
-
if (end == null) end = text.length;
|
107
|
-
if (!outer.innerMode) return [{from: start, to: end, mode: outer}];
|
108
|
-
var state = cm.getTokenAt({line: line, ch: start}).state;
|
109
|
-
var mode = CodeMirror.innerMode(outer, state).mode;
|
110
|
-
var found = [], stream = new CodeMirror.StringStream(text);
|
111
|
-
stream.pos = stream.start = start;
|
112
|
-
for (;;) {
|
113
|
-
outer.token(stream, state);
|
114
|
-
var curMode = CodeMirror.innerMode(outer, state).mode;
|
115
|
-
if (curMode != mode) {
|
116
|
-
var cut = stream.start;
|
117
|
-
// Crappy heuristic to deal with the fact that a change in
|
118
|
-
// mode can occur both at the end and the start of a token,
|
119
|
-
// and we don't know which it was.
|
120
|
-
if (mode.name == "xml" && text.charAt(stream.pos - 1) == ">") cut = stream.pos;
|
121
|
-
found.push({from: start, to: cut, mode: mode});
|
122
|
-
start = cut;
|
123
|
-
mode = curMode;
|
124
|
-
}
|
125
|
-
if (stream.pos >= end) break;
|
126
|
-
stream.start = stream.pos;
|
127
|
-
}
|
128
|
-
if (start < end) found.push({from: start, to: end, mode: mode});
|
129
|
-
return found;
|
130
|
-
}
|
131
|
-
|
132
33
|
// Comment/uncomment the specified range
|
133
34
|
CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
|
134
|
-
var
|
135
|
-
|
35
|
+
var cm = this, curMode = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(from).state).mode;
|
36
|
+
cm.operation(function() {
|
136
37
|
if (isComment) { // Comment range
|
137
38
|
cm.replaceRange(curMode.commentEnd, to);
|
138
39
|
cm.replaceRange(curMode.commentStart, from);
|
@@ -168,27 +69,38 @@
|
|
168
69
|
// Applies automatic formatting to the specified range
|
169
70
|
CodeMirror.defineExtension("autoFormatRange", function (from, to) {
|
170
71
|
var cm = this;
|
171
|
-
cm.
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
72
|
+
var outer = cm.getMode(), text = cm.getRange(from, to).split("\n");
|
73
|
+
var state = CodeMirror.copyState(outer, cm.getTokenAt(from).state);
|
74
|
+
var tabSize = cm.getOption("tabSize");
|
75
|
+
|
76
|
+
var out = "", lines = 0, atSol = from.ch == 0;
|
77
|
+
function newline() {
|
78
|
+
out += "\n";
|
79
|
+
atSol = true;
|
80
|
+
++lines;
|
81
|
+
}
|
82
|
+
|
83
|
+
for (var i = 0; i < text.length; ++i) {
|
84
|
+
var stream = new CodeMirror.StringStream(text[i], tabSize);
|
85
|
+
while (!stream.eol()) {
|
86
|
+
var inner = CodeMirror.innerMode(outer, state);
|
87
|
+
var style = outer.token(stream, state), cur = stream.current();
|
88
|
+
stream.start = stream.pos;
|
89
|
+
if (!atSol || /\S/.test(cur)) {
|
90
|
+
out += cur;
|
91
|
+
atSol = false;
|
189
92
|
}
|
93
|
+
if (!atSol && inner.mode.newlineAfterToken &&
|
94
|
+
inner.mode.newlineAfterToken(style, cur, stream.string.slice(stream.pos) || text[i+1] || "", inner.state))
|
95
|
+
newline();
|
190
96
|
}
|
191
|
-
|
97
|
+
if (!stream.pos && outer.blankLine) outer.blankLine(state);
|
98
|
+
if (!atSol) newline();
|
99
|
+
}
|
100
|
+
|
101
|
+
cm.operation(function () {
|
102
|
+
cm.replaceRange(out, from, to);
|
103
|
+
for (var cur = from.line + 1, end = from.line + lines; cur <= end; ++cur)
|
192
104
|
cm.indentLine(cur, "smart");
|
193
105
|
cm.setSelection(from, cm.getCursor(false));
|
194
106
|
});
|
@@ -16,16 +16,16 @@
|
|
16
16
|
return arr.indexOf(item) != -1;
|
17
17
|
}
|
18
18
|
|
19
|
-
function scriptHint(editor, keywords, getToken) {
|
19
|
+
function scriptHint(editor, keywords, getToken, options) {
|
20
20
|
// Find the token at the cursor
|
21
21
|
var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
|
22
22
|
// If it's not a 'word-style' token, ignore the token.
|
23
23
|
if (!/^[\w$_]*$/.test(token.string)) {
|
24
24
|
token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
|
25
|
-
|
25
|
+
type: token.string == "." ? "property" : null};
|
26
26
|
}
|
27
27
|
// If it is a property, find out what it is a property of.
|
28
|
-
while (tprop.
|
28
|
+
while (tprop.type == "property") {
|
29
29
|
tprop = getToken(editor, {line: cur.line, ch: tprop.start});
|
30
30
|
if (tprop.string != ".") return;
|
31
31
|
tprop = getToken(editor, {line: cur.line, ch: tprop.start});
|
@@ -40,21 +40,22 @@
|
|
40
40
|
}
|
41
41
|
} while (level > 0);
|
42
42
|
tprop = getToken(editor, {line: cur.line, ch: tprop.start});
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
if (tprop.type == 'variable')
|
44
|
+
tprop.type = 'function';
|
45
|
+
else return; // no clue
|
46
46
|
}
|
47
47
|
if (!context) var context = [];
|
48
48
|
context.push(tprop);
|
49
49
|
}
|
50
|
-
return {list: getCompletions(token, context, keywords),
|
50
|
+
return {list: getCompletions(token, context, keywords, options),
|
51
51
|
from: {line: cur.line, ch: token.start},
|
52
52
|
to: {line: cur.line, ch: token.end}};
|
53
53
|
}
|
54
54
|
|
55
|
-
CodeMirror.javascriptHint = function(editor) {
|
55
|
+
CodeMirror.javascriptHint = function(editor, options) {
|
56
56
|
return scriptHint(editor, javascriptKeywords,
|
57
|
-
function (e, cur) {return e.getTokenAt(cur);}
|
57
|
+
function (e, cur) {return e.getTokenAt(cur);},
|
58
|
+
options);
|
58
59
|
};
|
59
60
|
|
60
61
|
function getCoffeeScriptToken(editor, cur) {
|
@@ -65,18 +66,18 @@
|
|
65
66
|
if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
|
66
67
|
token.end = token.start;
|
67
68
|
token.string = '.';
|
68
|
-
token.
|
69
|
+
token.type = "property";
|
69
70
|
}
|
70
71
|
else if (/^\.[\w$_]*$/.test(token.string)) {
|
71
|
-
token.
|
72
|
+
token.type = "property";
|
72
73
|
token.start++;
|
73
74
|
token.string = token.string.replace(/\./, '');
|
74
75
|
}
|
75
76
|
return token;
|
76
77
|
}
|
77
78
|
|
78
|
-
CodeMirror.coffeescriptHint = function(editor) {
|
79
|
-
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken);
|
79
|
+
CodeMirror.coffeescriptHint = function(editor, options) {
|
80
|
+
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
|
80
81
|
};
|
81
82
|
|
82
83
|
var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
|
@@ -89,7 +90,7 @@
|
|
89
90
|
var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
|
90
91
|
"if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
|
91
92
|
|
92
|
-
function getCompletions(token, context, keywords) {
|
93
|
+
function getCompletions(token, context, keywords, options) {
|
93
94
|
var found = [], start = token.string;
|
94
95
|
function maybeAdd(str) {
|
95
96
|
if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
|
@@ -105,13 +106,15 @@
|
|
105
106
|
// If this is a property, see if it belongs to some object we can
|
106
107
|
// find in the current environment.
|
107
108
|
var obj = context.pop(), base;
|
108
|
-
if (obj.
|
109
|
-
|
110
|
-
|
109
|
+
if (obj.type == "variable") {
|
110
|
+
if (options && options.additionalContext)
|
111
|
+
base = options.additionalContext[obj.string];
|
112
|
+
base = base || window[obj.string];
|
113
|
+
} else if (obj.type == "string") {
|
111
114
|
base = "";
|
112
|
-
else if (obj.
|
115
|
+
} else if (obj.type == "atom") {
|
113
116
|
base = 1;
|
114
|
-
else if (obj.
|
117
|
+
} else if (obj.type == "function") {
|
115
118
|
if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
|
116
119
|
(typeof window.jQuery == 'function'))
|
117
120
|
base = window.jQuery();
|