codemirror-rails 3.12 → 3.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/codemirror-rails.gemspec +1 -1
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +168 -116
- data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +144 -0
- data/vendor/assets/javascripts/codemirror/addons/display/placeholder.js +4 -4
- data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +2 -2
- data/vendor/assets/javascripts/codemirror/addons/fold/brace-fold.js +9 -3
- data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +13 -13
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.js +5 -1
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.node.js +13 -1
- data/vendor/assets/javascripts/codemirror/addons/search/match-highlighter.js +4 -4
- data/vendor/assets/javascripts/codemirror/addons/search/search.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/search/searchcursor.js +15 -5
- data/vendor/assets/javascripts/codemirror/addons/selection/active-line.js +6 -6
- data/vendor/assets/javascripts/codemirror/addons/selection/mark-selection.js +89 -15
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +451 -187
- data/vendor/assets/javascripts/codemirror/modes/clike.js +6 -3
- data/vendor/assets/javascripts/codemirror/modes/clojure.js +3 -1
- data/vendor/assets/javascripts/codemirror/modes/cobol.js +240 -0
- data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +2 -1
- data/vendor/assets/javascripts/codemirror/modes/commonlisp.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/css.js +63 -24
- data/vendor/assets/javascripts/codemirror/modes/erlang.js +3 -2
- data/vendor/assets/javascripts/codemirror/modes/gas.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/go.js +4 -1
- data/vendor/assets/javascripts/codemirror/modes/haml.js +153 -0
- data/vendor/assets/javascripts/codemirror/modes/haskell.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/less.js +0 -8
- data/vendor/assets/javascripts/codemirror/modes/lua.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +2 -2
- data/vendor/assets/javascripts/codemirror/modes/ocaml.js +4 -1
- data/vendor/assets/javascripts/codemirror/modes/php.js +3 -0
- data/vendor/assets/javascripts/codemirror/modes/python.js +2 -1
- data/vendor/assets/javascripts/codemirror/modes/ruby.js +2 -1
- data/vendor/assets/javascripts/codemirror/modes/rust.js +4 -1
- data/vendor/assets/javascripts/codemirror/modes/sass.js +8 -27
- data/vendor/assets/javascripts/codemirror/modes/scheme.js +3 -1
- data/vendor/assets/javascripts/codemirror/modes/smalltalk.js +6 -4
- data/vendor/assets/javascripts/codemirror/modes/sql.js +3 -4
- data/vendor/assets/javascripts/codemirror/modes/stex.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/xml.js +2 -0
- data/vendor/assets/javascripts/codemirror/modes/yaml.js +3 -1
- data/vendor/assets/stylesheets/codemirror.css +7 -4
- data/vendor/assets/stylesheets/codemirror/addons/lint/lint.css +3 -3
- data/vendor/assets/stylesheets/codemirror/themes/rubyblue.css +1 -1
- metadata +14 -6
- data/vendor/assets/javascripts/codemirror/modes/test.js +0 -64
@@ -0,0 +1,144 @@
|
|
1
|
+
(function() {
|
2
|
+
"use strict";
|
3
|
+
|
4
|
+
var noOptions = {};
|
5
|
+
var nonWS = /[^\s\u00a0]/;
|
6
|
+
var Pos = CodeMirror.Pos;
|
7
|
+
|
8
|
+
function firstNonWS(str) {
|
9
|
+
var found = str.search(nonWS);
|
10
|
+
return found == -1 ? 0 : found;
|
11
|
+
}
|
12
|
+
|
13
|
+
CodeMirror.commands.toggleComment = function(cm) {
|
14
|
+
var from = cm.getCursor("start"), to = cm.getCursor("end");
|
15
|
+
cm.uncomment(from, to) || cm.lineComment(from, to);
|
16
|
+
};
|
17
|
+
|
18
|
+
CodeMirror.defineExtension("lineComment", function(from, to, options) {
|
19
|
+
if (!options) options = noOptions;
|
20
|
+
var self = this, mode = CodeMirror.innerMode(self.getMode(), self.getTokenAt(from).state).mode;
|
21
|
+
var commentString = options.lineComment || mode.lineComment;
|
22
|
+
if (!commentString) {
|
23
|
+
if (options.blockCommentStart || mode.blockCommentStart) {
|
24
|
+
options.fullLines = true;
|
25
|
+
self.blockComment(from, to, options);
|
26
|
+
}
|
27
|
+
return;
|
28
|
+
}
|
29
|
+
var firstLine = self.getLine(from.line);
|
30
|
+
if (firstLine == null) return;
|
31
|
+
var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1);
|
32
|
+
var pad = options.padding == null ? " " : options.padding;
|
33
|
+
var blankLines = options.commentBlankLines;
|
34
|
+
|
35
|
+
self.operation(function() {
|
36
|
+
if (options.indent) {
|
37
|
+
var baseString = firstLine.slice(0, firstNonWS(firstLine));
|
38
|
+
for (var i = from.line; i < end; ++i) {
|
39
|
+
var line = self.getLine(i), cut = baseString.length;
|
40
|
+
if (!blankLines && !nonWS.test(line)) continue;
|
41
|
+
if (line.slice(0, cut) != baseString) cut = firstNonWS(line);
|
42
|
+
self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut));
|
43
|
+
}
|
44
|
+
} else {
|
45
|
+
for (var i = from.line; i < end; ++i) {
|
46
|
+
if (blankLines || nonWS.test(self.getLine(i)))
|
47
|
+
self.replaceRange(commentString + pad, Pos(i, 0));
|
48
|
+
}
|
49
|
+
}
|
50
|
+
});
|
51
|
+
});
|
52
|
+
|
53
|
+
CodeMirror.defineExtension("blockComment", function(from, to, options) {
|
54
|
+
if (!options) options = noOptions;
|
55
|
+
var self = this, mode = CodeMirror.innerMode(self.getMode(), self.getTokenAt(from).state).mode;
|
56
|
+
var startString = options.blockCommentStart || mode.blockCommentStart;
|
57
|
+
var endString = options.blockCommentEnd || mode.blockCommentEnd;
|
58
|
+
if (!startString || !endString) {
|
59
|
+
if ((options.lineComment || mode.lineComment) && options.fullLines != false)
|
60
|
+
self.lineComment(from, to, options);
|
61
|
+
return;
|
62
|
+
}
|
63
|
+
|
64
|
+
var end = Math.min(to.line, self.lastLine());
|
65
|
+
if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end;
|
66
|
+
|
67
|
+
var pad = options.padding == null ? " " : options.padding;
|
68
|
+
if (from.line > end) return;
|
69
|
+
|
70
|
+
self.operation(function() {
|
71
|
+
if (options.fullLines != false) {
|
72
|
+
var lastLineHasText = nonWS.test(self.getLine(end));
|
73
|
+
self.replaceRange(pad + endString, Pos(end));
|
74
|
+
self.replaceRange(startString + pad, Pos(from.line, 0));
|
75
|
+
var lead = options.blockCommentLead || mode.blockCommentLead;
|
76
|
+
if (lead != null) for (var i = from.line + 1; i <= end; ++i)
|
77
|
+
if (i != end || lastLineHasText)
|
78
|
+
self.replaceRange(lead + pad, Pos(i, 0));
|
79
|
+
} else {
|
80
|
+
self.replaceRange(endString, to);
|
81
|
+
self.replaceRange(startString, from);
|
82
|
+
}
|
83
|
+
});
|
84
|
+
});
|
85
|
+
|
86
|
+
CodeMirror.defineExtension("uncomment", function(from, to, options) {
|
87
|
+
if (!options) options = noOptions;
|
88
|
+
var self = this, mode = CodeMirror.innerMode(self.getMode(), self.getTokenAt(from).state).mode;
|
89
|
+
var end = Math.min(to.line, self.lastLine()), start = Math.min(from.line, end);
|
90
|
+
|
91
|
+
// Try finding line comments
|
92
|
+
var lineString = options.lineComment || mode.lineComment, lines = [];
|
93
|
+
var pad = options.padding == null ? " " : options.padding;
|
94
|
+
lineComment: for(;;) {
|
95
|
+
if (!lineString) break;
|
96
|
+
for (var i = start; i <= end; ++i) {
|
97
|
+
var line = self.getLine(i);
|
98
|
+
var found = line.indexOf(lineString);
|
99
|
+
if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment;
|
100
|
+
if (i != start && nonWS.test(line.slice(0, found))) break lineComment;
|
101
|
+
lines.push(line);
|
102
|
+
}
|
103
|
+
self.operation(function() {
|
104
|
+
for (var i = start; i <= end; ++i) {
|
105
|
+
var line = lines[i - start];
|
106
|
+
var pos = line.indexOf(lineString), endPos = pos + lineString.length;
|
107
|
+
if (pos < 0) continue;
|
108
|
+
if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length;
|
109
|
+
self.replaceRange("", Pos(i, pos), Pos(i, endPos));
|
110
|
+
}
|
111
|
+
});
|
112
|
+
return true;
|
113
|
+
}
|
114
|
+
|
115
|
+
// Try block comments
|
116
|
+
var startString = options.blockCommentStart || mode.blockCommentStart;
|
117
|
+
var endString = options.blockCommentEnd || mode.blockCommentEnd;
|
118
|
+
if (!startString || !endString) return false;
|
119
|
+
var lead = options.blockCommentLead || mode.blockCommentLead;
|
120
|
+
var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end);
|
121
|
+
var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString);
|
122
|
+
if (close == -1 && start != end) {
|
123
|
+
endLine = self.getLine(--end);
|
124
|
+
close = endLine.lastIndexOf(endString);
|
125
|
+
}
|
126
|
+
if (open == -1 || close == -1) return false;
|
127
|
+
|
128
|
+
self.operation(function() {
|
129
|
+
self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
|
130
|
+
Pos(end, close + endString.length));
|
131
|
+
var openEnd = open + startString.length;
|
132
|
+
if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length;
|
133
|
+
self.replaceRange("", Pos(start, open), Pos(start, openEnd));
|
134
|
+
if (lead) for (var i = start + 1; i <= end; ++i) {
|
135
|
+
var line = self.getLine(i), found = line.indexOf(lead);
|
136
|
+
if (found == -1 || nonWS.test(line.slice(0, found))) continue;
|
137
|
+
var foundEnd = found + lead.length;
|
138
|
+
if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length;
|
139
|
+
self.replaceRange("", Pos(i, found), Pos(i, foundEnd));
|
140
|
+
}
|
141
|
+
});
|
142
|
+
return true;
|
143
|
+
});
|
144
|
+
})();
|
@@ -19,14 +19,14 @@
|
|
19
19
|
});
|
20
20
|
|
21
21
|
function clearPlaceholder(cm) {
|
22
|
-
if (cm.
|
23
|
-
cm.
|
24
|
-
cm.
|
22
|
+
if (cm.state.placeholder) {
|
23
|
+
cm.state.placeholder.parentNode.removeChild(cm.state.placeholder);
|
24
|
+
cm.state.placeholder = null;
|
25
25
|
}
|
26
26
|
}
|
27
27
|
function setPlaceholder(cm) {
|
28
28
|
clearPlaceholder(cm);
|
29
|
-
var elt = cm.
|
29
|
+
var elt = cm.state.placeholder = document.createElement("pre");
|
30
30
|
elt.style.cssText = "height: 0; overflow: visible";
|
31
31
|
elt.className = "CodeMirror-placeholder";
|
32
32
|
elt.appendChild(document.createTextNode(cm.getOption("placeholder")));
|
@@ -23,9 +23,9 @@
|
|
23
23
|
return CodeMirror.Pass;
|
24
24
|
}
|
25
25
|
};
|
26
|
-
var closingBrackets =
|
26
|
+
var closingBrackets = "";
|
27
27
|
for (var i = 0; i < pairs.length; i += 2) (function(left, right) {
|
28
|
-
if (left != right) closingBrackets
|
28
|
+
if (left != right) closingBrackets += right;
|
29
29
|
function surround(cm) {
|
30
30
|
var selection = cm.getSelection();
|
31
31
|
cm.replaceSelection(left + selection + right);
|
@@ -3,17 +3,23 @@ CodeMirror.braceRangeFinder = function(cm, start) {
|
|
3
3
|
var at = lineText.length, startChar, tokenType;
|
4
4
|
for (; at > 0;) {
|
5
5
|
var found = lineText.lastIndexOf("{", at);
|
6
|
-
|
6
|
+
var startToken = '{', endToken = '}';
|
7
|
+
if (found < start.ch) {
|
8
|
+
found = lineText.lastIndexOf("[", at);
|
9
|
+
if (found < start.ch) break;
|
10
|
+
startToken = '['; endToken = ']';
|
11
|
+
}
|
12
|
+
|
7
13
|
tokenType = cm.getTokenAt(CodeMirror.Pos(line, found + 1)).type;
|
8
14
|
if (!/^(comment|string)/.test(tokenType)) { startChar = found; break; }
|
9
15
|
at = found - 1;
|
10
16
|
}
|
11
|
-
if (startChar == null || lineText.lastIndexOf(
|
17
|
+
if (startChar == null || lineText.lastIndexOf(startToken) > startChar) return;
|
12
18
|
var count = 1, lastLine = cm.lineCount(), end, endCh;
|
13
19
|
outer: for (var i = line + 1; i < lastLine; ++i) {
|
14
20
|
var text = cm.getLine(i), pos = 0;
|
15
21
|
for (;;) {
|
16
|
-
var nextOpen = text.indexOf(
|
22
|
+
var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
|
17
23
|
if (nextOpen < 0) nextOpen = text.length;
|
18
24
|
if (nextClose < 0) nextClose = text.length;
|
19
25
|
pos = Math.min(nextOpen, nextClose);
|
@@ -59,7 +59,7 @@ CodeMirror.validate = (function() {
|
|
59
59
|
}
|
60
60
|
|
61
61
|
function clearMarks(cm) {
|
62
|
-
var state = cm.
|
62
|
+
var state = cm.state.lint;
|
63
63
|
if (state.hasGutter) cm.clearGutter(GUTTER_ID);
|
64
64
|
for (var i = 0; i < state.marked.length; ++i)
|
65
65
|
state.marked[i].clear();
|
@@ -105,16 +105,16 @@ CodeMirror.validate = (function() {
|
|
105
105
|
}
|
106
106
|
|
107
107
|
function startLinting(cm) {
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
108
|
+
var state = cm.state.lint, options = state.options;
|
109
|
+
if (options.async)
|
110
|
+
options.getAnnotations(cm, updateLinting, options);
|
111
|
+
else
|
112
|
+
updateLinting(cm, options.getAnnotations(cm.getValue()));
|
113
113
|
}
|
114
114
|
|
115
115
|
function updateLinting(cm, annotationsNotSorted) {
|
116
116
|
clearMarks(cm);
|
117
|
-
var state = cm.
|
117
|
+
var state = cm.state.lint, options = state.options;
|
118
118
|
|
119
119
|
var annotations = groupByLine(annotationsNotSorted);
|
120
120
|
|
@@ -135,7 +135,7 @@ CodeMirror.validate = (function() {
|
|
135
135
|
if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));
|
136
136
|
|
137
137
|
if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {
|
138
|
-
className: "CodeMirror-lint-
|
138
|
+
className: "CodeMirror-lint-mark-" + severity,
|
139
139
|
__annotation: ann
|
140
140
|
}));
|
141
141
|
}
|
@@ -148,7 +148,7 @@ CodeMirror.validate = (function() {
|
|
148
148
|
}
|
149
149
|
|
150
150
|
function onChange(cm) {
|
151
|
-
var state = cm.
|
151
|
+
var state = cm.state.lint;
|
152
152
|
clearTimeout(state.timeout);
|
153
153
|
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
|
154
154
|
}
|
@@ -164,7 +164,7 @@ CodeMirror.validate = (function() {
|
|
164
164
|
var nearby = [0, 0, 0, 5, 0, -5, 5, 0, -5, 0];
|
165
165
|
|
166
166
|
function onMouseOver(cm, e) {
|
167
|
-
if (!/\bCodeMirror-lint-
|
167
|
+
if (!/\bCodeMirror-lint-mark-/.test((e.target || e.srcElement).className)) return;
|
168
168
|
for (var i = 0; i < nearby.length; i += 2) {
|
169
169
|
var spans = cm.findMarksAt(cm.coordsChar({left: e.clientX + nearby[i],
|
170
170
|
top: e.clientY + nearby[i + 1]}));
|
@@ -179,14 +179,14 @@ CodeMirror.validate = (function() {
|
|
179
179
|
if (old && old != CodeMirror.Init) {
|
180
180
|
clearMarks(cm);
|
181
181
|
cm.off("change", onChange);
|
182
|
-
CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.
|
183
|
-
delete cm.
|
182
|
+
CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
|
183
|
+
delete cm.state.lint;
|
184
184
|
}
|
185
185
|
|
186
186
|
if (val) {
|
187
187
|
var gutters = cm.getOption("gutters"), hasLintGutter = false;
|
188
188
|
for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
|
189
|
-
var state = cm.
|
189
|
+
var state = cm.state.lint = new LintState(cm, parseOptions(val), hasLintGutter);
|
190
190
|
cm.on("change", onChange);
|
191
191
|
if (state.options.tooltips != false)
|
192
192
|
CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
|
@@ -1,5 +1,7 @@
|
|
1
1
|
CodeMirror.runMode = function(string, modespec, callback, options) {
|
2
2
|
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
|
3
|
+
var ie = /MSIE \d/.test(navigator.userAgent);
|
4
|
+
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
|
3
5
|
|
4
6
|
if (callback.nodeType == 1) {
|
5
7
|
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
|
@@ -7,7 +9,9 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
|
|
7
9
|
node.innerHTML = "";
|
8
10
|
callback = function(text, style) {
|
9
11
|
if (text == "\n") {
|
10
|
-
|
12
|
+
// Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
|
13
|
+
// Emitting a carriage return makes everything ok.
|
14
|
+
node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text));
|
11
15
|
col = 0;
|
12
16
|
return;
|
13
17
|
}
|
@@ -60,8 +60,20 @@ exports.startState = function(mode, a1, a2) {
|
|
60
60
|
};
|
61
61
|
|
62
62
|
var modes = exports.modes = {}, mimeModes = exports.mimeModes = {};
|
63
|
-
exports.defineMode = function(name, mode) {
|
63
|
+
exports.defineMode = function(name, mode) {
|
64
|
+
if (arguments.length > 2) {
|
65
|
+
mode.dependencies = [];
|
66
|
+
for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
|
67
|
+
}
|
68
|
+
modes[name] = mode;
|
69
|
+
};
|
64
70
|
exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; };
|
71
|
+
|
72
|
+
exports.defineMode("null", function() {
|
73
|
+
return {token: function(stream) {stream.skipToEnd();}};
|
74
|
+
});
|
75
|
+
exports.defineMIME("text/plain", "null");
|
76
|
+
|
65
77
|
exports.getMode = function(options, spec) {
|
66
78
|
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
|
67
79
|
spec = mimeModes[spec];
|
@@ -24,19 +24,19 @@
|
|
24
24
|
CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) {
|
25
25
|
var prev = old && old != CodeMirror.Init;
|
26
26
|
if (val && !prev) {
|
27
|
-
cm.
|
27
|
+
cm.state.matchHighlighter = new State(val);
|
28
28
|
cm.on("cursorActivity", highlightMatches);
|
29
29
|
} else if (!val && prev) {
|
30
|
-
var over = cm.
|
30
|
+
var over = cm.state.matchHighlighter.overlay;
|
31
31
|
if (over) cm.removeOverlay(over);
|
32
|
-
cm.
|
32
|
+
cm.state.matchHighlighter = null;
|
33
33
|
cm.off("cursorActivity", highlightMatches);
|
34
34
|
}
|
35
35
|
});
|
36
36
|
|
37
37
|
function highlightMatches(cm) {
|
38
38
|
cm.operation(function() {
|
39
|
-
var state = cm.
|
39
|
+
var state = cm.state.matchHighlighter;
|
40
40
|
if (state.overlay) {
|
41
41
|
cm.removeOverlay(state.overlay);
|
42
42
|
state.overlay = null;
|
@@ -27,7 +27,7 @@
|
|
27
27
|
this.overlay = null;
|
28
28
|
}
|
29
29
|
function getSearchState(cm) {
|
30
|
-
return cm.
|
30
|
+
return cm.state.search || (cm.state.search = new SearchState());
|
31
31
|
}
|
32
32
|
function getSearchCursor(cm, query, pos) {
|
33
33
|
// Heuristic: if the query string is all lowercase, do a case insensitive search.
|
@@ -24,16 +24,26 @@
|
|
24
24
|
if (!newMatch) break;
|
25
25
|
match = newMatch;
|
26
26
|
start = match.index;
|
27
|
-
cutOff = match.index + 1;
|
27
|
+
cutOff = match.index + (match[0].length || 1);
|
28
|
+
if (cutOff == line.length) break;
|
29
|
+
}
|
30
|
+
var matchLen = (match && match[0].length) || 0;
|
31
|
+
if (!matchLen) {
|
32
|
+
if (start == 0 && line.length == 0) {match = undefined;}
|
33
|
+
else if (start != doc.getLine(pos.line).length) {
|
34
|
+
matchLen++;
|
35
|
+
}
|
28
36
|
}
|
29
37
|
} else {
|
30
38
|
query.lastIndex = pos.ch;
|
31
|
-
var line = doc.getLine(pos.line), match = query.exec(line)
|
32
|
-
|
39
|
+
var line = doc.getLine(pos.line), match = query.exec(line);
|
40
|
+
var matchLen = (match && match[0].length) || 0;
|
41
|
+
var start = match && match.index;
|
42
|
+
if (start + matchLen != line.length && !matchLen) matchLen = 1;
|
33
43
|
}
|
34
|
-
if (match &&
|
44
|
+
if (match && matchLen)
|
35
45
|
return {from: Pos(pos.line, start),
|
36
|
-
to: Pos(pos.line, start +
|
46
|
+
to: Pos(pos.line, start + matchLen),
|
37
47
|
match: match};
|
38
48
|
};
|
39
49
|
} else { // String query
|
@@ -17,23 +17,23 @@
|
|
17
17
|
} else if (!val && prev) {
|
18
18
|
cm.off("cursorActivity", updateActiveLine);
|
19
19
|
clearActiveLine(cm);
|
20
|
-
delete cm.
|
20
|
+
delete cm.state.activeLine;
|
21
21
|
}
|
22
22
|
});
|
23
23
|
|
24
24
|
function clearActiveLine(cm) {
|
25
|
-
if ("
|
26
|
-
cm.removeLineClass(cm.
|
27
|
-
cm.removeLineClass(cm.
|
25
|
+
if ("activeLine" in cm.state) {
|
26
|
+
cm.removeLineClass(cm.state.activeLine, "wrap", WRAP_CLASS);
|
27
|
+
cm.removeLineClass(cm.state.activeLine, "background", BACK_CLASS);
|
28
28
|
}
|
29
29
|
}
|
30
30
|
|
31
31
|
function updateActiveLine(cm) {
|
32
32
|
var line = cm.getLineHandle(cm.getCursor().line);
|
33
|
-
if (cm.
|
33
|
+
if (cm.state.activeLine == line) return;
|
34
34
|
clearActiveLine(cm);
|
35
35
|
cm.addLineClass(line, "wrap", WRAP_CLASS);
|
36
36
|
cm.addLineClass(line, "background", BACK_CLASS);
|
37
|
-
cm.
|
37
|
+
cm.state.activeLine = line;
|
38
38
|
}
|
39
39
|
})();
|
@@ -1,7 +1,8 @@
|
|
1
1
|
// Because sometimes you need to mark the selected *text*.
|
2
2
|
//
|
3
3
|
// Adds an option 'styleSelectedText' which, when enabled, gives
|
4
|
-
// selected text the CSS class
|
4
|
+
// selected text the CSS class given as option value, or
|
5
|
+
// "CodeMirror-selectedtext" when the value is not a string.
|
5
6
|
|
6
7
|
(function() {
|
7
8
|
"use strict";
|
@@ -9,26 +10,99 @@
|
|
9
10
|
CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) {
|
10
11
|
var prev = old && old != CodeMirror.Init;
|
11
12
|
if (val && !prev) {
|
12
|
-
|
13
|
-
cm.
|
13
|
+
cm.state.markedSelection = [];
|
14
|
+
cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext";
|
15
|
+
reset(cm);
|
16
|
+
cm.on("cursorActivity", onCursorActivity);
|
17
|
+
cm.on("change", onChange);
|
14
18
|
} else if (!val && prev) {
|
15
|
-
cm.off("cursorActivity",
|
16
|
-
|
17
|
-
|
19
|
+
cm.off("cursorActivity", onCursorActivity);
|
20
|
+
cm.off("change", onChange);
|
21
|
+
clear(cm);
|
22
|
+
cm.state.markedSelection = cm.state.markedSelectionStyle = null;
|
18
23
|
}
|
19
24
|
});
|
20
25
|
|
21
|
-
function
|
22
|
-
|
26
|
+
function onCursorActivity(cm) {
|
27
|
+
cm.operation(function() { update(cm); });
|
23
28
|
}
|
24
29
|
|
25
|
-
function
|
26
|
-
|
30
|
+
function onChange(cm) {
|
31
|
+
if (cm.state.markedSelection.length)
|
32
|
+
cm.operation(function() { clear(cm); });
|
33
|
+
}
|
34
|
+
|
35
|
+
var CHUNK_SIZE = 8;
|
36
|
+
var Pos = CodeMirror.Pos;
|
37
|
+
|
38
|
+
function cmp(pos1, pos2) {
|
39
|
+
return pos1.line - pos2.line || pos1.ch - pos2.ch;
|
40
|
+
}
|
41
|
+
|
42
|
+
function coverRange(cm, from, to, addAt) {
|
43
|
+
if (cmp(from, to) == 0) return;
|
44
|
+
var array = cm.state.markedSelection;
|
45
|
+
var cls = cm.state.markedSelectionStyle;
|
46
|
+
for (var line = from.line;;) {
|
47
|
+
var start = line == from.line ? from : Pos(line, 0);
|
48
|
+
var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line;
|
49
|
+
var end = atEnd ? to : Pos(endLine, 0);
|
50
|
+
var mark = cm.markText(start, end, {className: cls});
|
51
|
+
if (addAt == null) array.push(mark);
|
52
|
+
else array.splice(addAt++, 0, mark);
|
53
|
+
if (atEnd) break;
|
54
|
+
line = endLine;
|
55
|
+
}
|
56
|
+
}
|
27
57
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
58
|
+
function clear(cm) {
|
59
|
+
var array = cm.state.markedSelection;
|
60
|
+
for (var i = 0; i < array.length; ++i) array[i].clear();
|
61
|
+
array.length = 0;
|
62
|
+
}
|
63
|
+
|
64
|
+
function reset(cm) {
|
65
|
+
clear(cm);
|
66
|
+
var from = cm.getCursor("start"), to = cm.getCursor("end");
|
67
|
+
coverRange(cm, from, to);
|
68
|
+
}
|
69
|
+
|
70
|
+
function update(cm) {
|
71
|
+
var from = cm.getCursor("start"), to = cm.getCursor("end");
|
72
|
+
if (cmp(from, to) == 0) return clear(cm);
|
73
|
+
|
74
|
+
var array = cm.state.markedSelection;
|
75
|
+
if (!array.length) return coverRange(cm, from, to);
|
76
|
+
|
77
|
+
var coverStart = array[0].find(), coverEnd = array[array.length - 1].find();
|
78
|
+
if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE ||
|
79
|
+
cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0)
|
80
|
+
return reset(cm);
|
81
|
+
|
82
|
+
while (cmp(from, coverStart.from) > 0) {
|
83
|
+
array.shift().clear();
|
84
|
+
coverStart = array[0].find();
|
85
|
+
}
|
86
|
+
if (cmp(from, coverStart.from) < 0) {
|
87
|
+
if (coverStart.to.line - from.line < CHUNK_SIZE) {
|
88
|
+
array.shift().clear();
|
89
|
+
coverRange(cm, from, coverStart.to, 0);
|
90
|
+
} else {
|
91
|
+
coverRange(cm, from, coverStart.from, 0);
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
while (cmp(to, coverEnd.to) < 0) {
|
96
|
+
array.pop().clear();
|
97
|
+
coverEnd = array[array.length - 1].find();
|
98
|
+
}
|
99
|
+
if (cmp(to, coverEnd.to) > 0) {
|
100
|
+
if (to.line - coverEnd.from.line < CHUNK_SIZE) {
|
101
|
+
array.pop().clear();
|
102
|
+
coverRange(cm, coverEnd.from, to);
|
103
|
+
} else {
|
104
|
+
coverRange(cm, coverEnd.to, to);
|
105
|
+
}
|
106
|
+
}
|
33
107
|
}
|
34
108
|
})();
|