codemirror-rails 3.16 → 3.17
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/README.md +9 -0
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +104 -48
- data/vendor/assets/javascripts/codemirror/addons/comment/continuecomment.js +25 -15
- data/vendor/assets/javascripts/codemirror/addons/edit/closetag.js +28 -27
- data/vendor/assets/javascripts/codemirror/addons/edit/matchtags.js +10 -5
- data/vendor/assets/javascripts/codemirror/addons/hint/css-hint.js +50 -0
- data/vendor/assets/javascripts/codemirror/addons/hint/html-hint.js +0 -0
- data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +10 -7
- data/vendor/assets/javascripts/codemirror/addons/lint/css-lint.js +17 -0
- data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/merge/merge.js +32 -6
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode-standalone.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/runmode/runmode.node.js +1 -1
- data/vendor/assets/javascripts/codemirror/addons/search/searchcursor.js +2 -2
- data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +29 -6
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +13 -0
- data/vendor/assets/javascripts/codemirror/modes/coffeescript.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/css.js +15 -13
- data/vendor/assets/javascripts/codemirror/modes/d.js +0 -0
- data/vendor/assets/javascripts/codemirror/modes/dtd.js +127 -0
- data/vendor/assets/javascripts/codemirror/modes/fortran.js +173 -0
- data/vendor/assets/javascripts/codemirror/modes/haskell.js +5 -1
- data/vendor/assets/javascripts/codemirror/modes/less.js +47 -49
- data/vendor/assets/javascripts/codemirror/modes/octave.js +118 -0
- data/vendor/assets/javascripts/codemirror/modes/sql.js +8 -5
- data/vendor/assets/javascripts/codemirror/modes/toml.js +71 -0
- data/vendor/assets/stylesheets/codemirror.css +7 -3
- data/vendor/assets/stylesheets/codemirror/addons/display/fullscreen.css +1 -1
- data/vendor/assets/stylesheets/codemirror/addons/lint/lint.css +3 -27
- data/vendor/assets/stylesheets/codemirror/themes/solarized.css +2 -24
- metadata +24 -21
- data/vendor/assets/javascripts/codemirror/addons/edit/continuecomment.js +0 -44
- data/vendor/assets/javascripts/codemirror/addons/merge/dep/diff_match_patch.js +0 -50
- data/vendor/assets/javascripts/codemirror/modes/scss_test.js +0 -80
@@ -27,9 +27,9 @@
|
|
27
27
|
if (val && (old == CodeMirror.Init || !old)) {
|
28
28
|
var map = {name: "autoCloseTags"};
|
29
29
|
if (typeof val != "object" || val.whenClosing)
|
30
|
-
map["'/'"] = function(cm) { return
|
30
|
+
map["'/'"] = function(cm) { return autoCloseSlash(cm); };
|
31
31
|
if (typeof val != "object" || val.whenOpening)
|
32
|
-
map["'>'"] = function(cm) { return
|
32
|
+
map["'>'"] = function(cm) { return autoCloseGT(cm); };
|
33
33
|
cm.addKeyMap(map);
|
34
34
|
} else if (!val && (old != CodeMirror.Init && old)) {
|
35
35
|
cm.removeKeyMap("autoCloseTags");
|
@@ -41,40 +41,41 @@
|
|
41
41
|
var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4",
|
42
42
|
"h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"];
|
43
43
|
|
44
|
-
function
|
44
|
+
function autoCloseGT(cm) {
|
45
45
|
var pos = cm.getCursor(), tok = cm.getTokenAt(pos);
|
46
46
|
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
|
47
|
-
if (inner.mode.name != "xml") return CodeMirror.Pass;
|
47
|
+
if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass;
|
48
48
|
|
49
49
|
var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html";
|
50
50
|
var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
|
51
51
|
var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
return CodeMirror.Pass;
|
53
|
+
var tagName = state.tagName;
|
54
|
+
if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
|
55
|
+
var lowerTagName = tagName.toLowerCase();
|
56
|
+
// Don't process the '>' at the end of an end-tag or self-closing tag
|
57
|
+
if (tok.type == "tag" && state.type == "closeTag" ||
|
58
|
+
tok.string.indexOf("/") == (tok.string.length - 1) || // match something like <someTagName />
|
59
|
+
dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1)
|
60
|
+
return CodeMirror.Pass;
|
62
61
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
}
|
71
|
-
return;
|
72
|
-
} else if (ch == "/" && tok.string == "<") {
|
73
|
-
var tagName = state.context && state.context.tagName;
|
74
|
-
if (tagName) cm.replaceSelection("/" + tagName + ">", "end");
|
75
|
-
return;
|
62
|
+
var doIndent = indentTags && indexOf(indentTags, lowerTagName) > -1;
|
63
|
+
var curPos = doIndent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1);
|
64
|
+
cm.replaceSelection(">" + (doIndent ? "\n\n" : "") + "</" + tagName + ">",
|
65
|
+
{head: curPos, anchor: curPos});
|
66
|
+
if (doIndent) {
|
67
|
+
cm.indentLine(pos.line + 1);
|
68
|
+
cm.indentLine(pos.line + 2);
|
76
69
|
}
|
77
|
-
|
70
|
+
}
|
71
|
+
|
72
|
+
function autoCloseSlash(cm) {
|
73
|
+
var pos = cm.getCursor(), tok = cm.getTokenAt(pos);
|
74
|
+
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
|
75
|
+
if (tok.string.charAt(0) != "<" || inner.mode.name != "xml") return CodeMirror.Pass;
|
76
|
+
|
77
|
+
var tagName = state.context && state.context.tagName;
|
78
|
+
if (tagName) cm.replaceSelection("/" + tagName + ">", "end");
|
78
79
|
}
|
79
80
|
|
80
81
|
function indexOf(collection, elt) {
|
@@ -8,6 +8,7 @@
|
|
8
8
|
clear(cm);
|
9
9
|
}
|
10
10
|
if (val) {
|
11
|
+
cm.state.matchBothTags = typeof val == "object" && val.bothTags;
|
11
12
|
cm.on("cursorActivity", doMatchTags);
|
12
13
|
cm.on("viewportChange", maybeUpdateMatch);
|
13
14
|
doMatchTags(cm);
|
@@ -15,23 +16,27 @@
|
|
15
16
|
});
|
16
17
|
|
17
18
|
function clear(cm) {
|
18
|
-
if (cm.state.
|
19
|
-
|
20
|
-
|
21
|
-
}
|
19
|
+
if (cm.state.tagHit) cm.state.tagHit.clear();
|
20
|
+
if (cm.state.tagOther) cm.state.tagOther.clear();
|
21
|
+
cm.state.tagHit = cm.state.tagOther = null;
|
22
22
|
}
|
23
23
|
|
24
24
|
function doMatchTags(cm) {
|
25
25
|
cm.state.failedTagMatch = false;
|
26
26
|
cm.operation(function() {
|
27
27
|
clear(cm);
|
28
|
+
if (cm.somethingSelected()) return;
|
28
29
|
var cur = cm.getCursor(), range = cm.getViewport();
|
29
30
|
range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to);
|
30
31
|
var match = CodeMirror.findMatchingTag(cm, cur, range);
|
31
32
|
if (!match) return;
|
33
|
+
if (cm.state.matchBothTags) {
|
34
|
+
var hit = match.at == "open" ? match.open : match.close;
|
35
|
+
if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"});
|
36
|
+
}
|
32
37
|
var other = match.at == "close" ? match.open : match.close;
|
33
38
|
if (other)
|
34
|
-
cm.state.
|
39
|
+
cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"});
|
35
40
|
else
|
36
41
|
cm.state.failedTagMatch = true;
|
37
42
|
});
|
@@ -0,0 +1,50 @@
|
|
1
|
+
(function () {
|
2
|
+
"use strict";
|
3
|
+
|
4
|
+
function getHints(cm) {
|
5
|
+
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
|
6
|
+
var inner = CodeMirror.innerMode(cm.getMode(), token.state);
|
7
|
+
if (inner.mode.name != "css") return;
|
8
|
+
|
9
|
+
// If it's not a 'word-style' token, ignore the token.
|
10
|
+
if (!/^[\w$_-]*$/.test(token.string)) {
|
11
|
+
token = {
|
12
|
+
start: cur.ch, end: cur.ch, string: "", state: token.state,
|
13
|
+
type: null
|
14
|
+
};
|
15
|
+
var stack = token.state.stack;
|
16
|
+
var lastToken = stack && stack.length > 0 ? stack[stack.length - 1] : "";
|
17
|
+
if (token.string == ":" || lastToken.indexOf("property") == 0)
|
18
|
+
token.type = "variable";
|
19
|
+
else if (token.string == "{" || lastToken.indexOf("rule") == 0)
|
20
|
+
token.type = "property";
|
21
|
+
}
|
22
|
+
|
23
|
+
if (!token.type)
|
24
|
+
return;
|
25
|
+
|
26
|
+
var spec = CodeMirror.resolveMode("text/css");
|
27
|
+
var keywords = null;
|
28
|
+
if (token.type.indexOf("property") == 0)
|
29
|
+
keywords = spec.propertyKeywords;
|
30
|
+
else if (token.type.indexOf("variable") == 0)
|
31
|
+
keywords = spec.valueKeywords;
|
32
|
+
|
33
|
+
if (!keywords)
|
34
|
+
return;
|
35
|
+
|
36
|
+
var result = [];
|
37
|
+
for (var name in keywords) {
|
38
|
+
if (name.indexOf(token.string) == 0 /* > -1 */)
|
39
|
+
result.push(name);
|
40
|
+
}
|
41
|
+
|
42
|
+
return {
|
43
|
+
list: result,
|
44
|
+
from: CodeMirror.Pos(cur.line, token.start),
|
45
|
+
to: CodeMirror.Pos(cur.line, token.end)
|
46
|
+
};
|
47
|
+
}
|
48
|
+
|
49
|
+
CodeMirror.registerHelper("hint", "css", getHints);
|
50
|
+
})();
|
File without changes
|
@@ -111,10 +111,10 @@
|
|
111
111
|
var baseMap = {
|
112
112
|
Up: function() {handle.moveFocus(-1);},
|
113
113
|
Down: function() {handle.moveFocus(1);},
|
114
|
-
PageUp: function() {handle.moveFocus(-handle.menuSize());},
|
115
|
-
PageDown: function() {handle.moveFocus(handle.menuSize());},
|
114
|
+
PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
|
115
|
+
PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
|
116
116
|
Home: function() {handle.setFocus(0);},
|
117
|
-
End: function() {handle.setFocus(handle.length);},
|
117
|
+
End: function() {handle.setFocus(handle.length - 1);},
|
118
118
|
Enter: handle.pick,
|
119
119
|
Tab: handle.pick,
|
120
120
|
Esc: handle.close
|
@@ -167,6 +167,7 @@
|
|
167
167
|
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
|
168
168
|
var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
|
169
169
|
var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
|
170
|
+
(options.container || document.body).appendChild(hints);
|
170
171
|
var box = hints.getBoundingClientRect();
|
171
172
|
var overlapX = box.right - winW, overlapY = box.bottom - winH;
|
172
173
|
if (overlapX > 0) {
|
@@ -187,10 +188,9 @@
|
|
187
188
|
}
|
188
189
|
hints.style.top = (top = pos.bottom - overlapY) + "px";
|
189
190
|
}
|
190
|
-
(options.container || document.body).appendChild(hints);
|
191
191
|
|
192
192
|
cm.addKeyMap(this.keyMap = buildKeyMap(options, {
|
193
|
-
moveFocus: function(n) { widget.changeActive(widget.selectedHint + n); },
|
193
|
+
moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
|
194
194
|
setFocus: function(n) { widget.changeActive(n); },
|
195
195
|
menuSize: function() { return widget.screenAmount(); },
|
196
196
|
length: completions.length,
|
@@ -250,8 +250,11 @@
|
|
250
250
|
this.completion.pick(this.data, this.selectedHint);
|
251
251
|
},
|
252
252
|
|
253
|
-
changeActive: function(i) {
|
254
|
-
|
253
|
+
changeActive: function(i, avoidWrap) {
|
254
|
+
if (i >= this.data.list.length)
|
255
|
+
i = avoidWrap ? this.data.list.length - 1 : 0;
|
256
|
+
else if (i < 0)
|
257
|
+
i = avoidWrap ? 0 : this.data.list.length - 1;
|
255
258
|
if (this.selectedHint == i) return;
|
256
259
|
var node = this.hints.childNodes[this.selectedHint];
|
257
260
|
node.className = node.className.replace(" CodeMirror-hint-active", "");
|
@@ -0,0 +1,17 @@
|
|
1
|
+
// Depends on csslint.js from https://github.com/stubbornella/csslint
|
2
|
+
|
3
|
+
CodeMirror.registerHelper("lint", "css", function(text) {
|
4
|
+
var found = [];
|
5
|
+
var results = CSSLint.verify(text), messages = results.messages, message = null;
|
6
|
+
for ( var i = 0; i < messages.length; i++) {
|
7
|
+
message = messages[i];
|
8
|
+
var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col;
|
9
|
+
found.push({
|
10
|
+
from: CodeMirror.Pos(startLine, startCol),
|
11
|
+
to: CodeMirror.Pos(endLine, endCol),
|
12
|
+
message: message.message,
|
13
|
+
severity : message.type
|
14
|
+
});
|
15
|
+
}
|
16
|
+
return found;
|
17
|
+
});
|
@@ -112,7 +112,7 @@
|
|
112
112
|
if (options.async)
|
113
113
|
options.getAnnotations(cm, updateLinting, options);
|
114
114
|
else
|
115
|
-
updateLinting(cm, options.getAnnotations(cm.getValue()));
|
115
|
+
updateLinting(cm, options.getAnnotations(cm.getValue(), options));
|
116
116
|
}
|
117
117
|
|
118
118
|
function updateLinting(cm, annotationsNotSorted) {
|
@@ -31,9 +31,17 @@
|
|
31
31
|
this.diff = getDiff(orig, options.value);
|
32
32
|
this.diffOutOfDate = false;
|
33
33
|
|
34
|
+
this.showDifferences = options.showDifferences !== false;
|
34
35
|
this.forceUpdate = registerUpdate(this);
|
35
36
|
setScrollLock(this, true, false);
|
36
37
|
registerScroll(this);
|
38
|
+
},
|
39
|
+
setShowDifferences: function(val) {
|
40
|
+
val = val !== false;
|
41
|
+
if (val != this.showDifferences) {
|
42
|
+
this.showDifferences = val;
|
43
|
+
this.forceUpdate("full");
|
44
|
+
}
|
37
45
|
}
|
38
46
|
};
|
39
47
|
|
@@ -41,26 +49,38 @@
|
|
41
49
|
var edit = {from: 0, to: 0, marked: []};
|
42
50
|
var orig = {from: 0, to: 0, marked: []};
|
43
51
|
var debounceChange;
|
44
|
-
function update() {
|
52
|
+
function update(mode) {
|
53
|
+
if (mode == "full") {
|
54
|
+
if (dv.svg) clear(dv.svg);
|
55
|
+
clear(dv.copyButtons);
|
56
|
+
clearMarks(dv.edit, edit.marked, dv.classes);
|
57
|
+
clearMarks(dv.orig, orig.marked, dv.classes);
|
58
|
+
edit.from = edit.to = orig.from = orig.to = 0;
|
59
|
+
}
|
45
60
|
if (dv.diffOutOfDate) {
|
46
61
|
dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue());
|
47
62
|
dv.diffOutOfDate = false;
|
63
|
+
CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
|
64
|
+
}
|
65
|
+
if (dv.showDifferences) {
|
66
|
+
updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes);
|
67
|
+
updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
|
48
68
|
}
|
49
|
-
updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes);
|
50
|
-
updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
|
51
69
|
drawConnectors(dv);
|
52
70
|
}
|
53
71
|
function set(slow) {
|
54
72
|
clearTimeout(debounceChange);
|
55
73
|
debounceChange = setTimeout(update, slow == true ? 250 : 100);
|
56
74
|
}
|
57
|
-
|
75
|
+
function change() {
|
58
76
|
if (!dv.diffOutOfDate) {
|
59
77
|
dv.diffOutOfDate = true;
|
60
78
|
edit.from = edit.to = orig.from = orig.to = 0;
|
61
79
|
}
|
62
80
|
set(true);
|
63
|
-
}
|
81
|
+
}
|
82
|
+
dv.edit.on("change", change);
|
83
|
+
dv.orig.on("change", change);
|
64
84
|
dv.edit.on("viewportChange", set);
|
65
85
|
dv.orig.on("viewportChange", set);
|
66
86
|
update();
|
@@ -211,6 +231,8 @@
|
|
211
231
|
// Updating the gap between editor and original
|
212
232
|
|
213
233
|
function drawConnectors(dv) {
|
234
|
+
if (!dv.showDifferences) return;
|
235
|
+
|
214
236
|
if (dv.svg) {
|
215
237
|
clear(dv.svg);
|
216
238
|
var w = dv.gap.offsetWidth;
|
@@ -322,7 +344,11 @@
|
|
322
344
|
constuctor: MergeView,
|
323
345
|
editor: function() { return this.edit; },
|
324
346
|
rightOriginal: function() { return this.right && this.right.orig; },
|
325
|
-
leftOriginal: function() { return this.left && this.left.orig; }
|
347
|
+
leftOriginal: function() { return this.left && this.left.orig; },
|
348
|
+
setShowDifferences: function(val) {
|
349
|
+
if (this.right) this.right.setShowDifferences(val);
|
350
|
+
if (this.left) this.left.setShowDifferences(val);
|
351
|
+
}
|
326
352
|
};
|
327
353
|
|
328
354
|
// Operations on diffs
|
@@ -125,7 +125,7 @@ CodeMirror.runMode = function (string, modespec, callback, options) {
|
|
125
125
|
var stream = new CodeMirror.StringStream(lines[i]);
|
126
126
|
while (!stream.eol()) {
|
127
127
|
var style = mode.token(stream, state);
|
128
|
-
callback(stream.current(), style, i, stream.start);
|
128
|
+
callback(stream.current(), style, i, stream.start, state);
|
129
129
|
stream.start = stream.pos;
|
130
130
|
}
|
131
131
|
}
|
@@ -49,7 +49,7 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
|
|
49
49
|
var stream = new CodeMirror.StringStream(lines[i]);
|
50
50
|
while (!stream.eol()) {
|
51
51
|
var style = mode.token(stream, state);
|
52
|
-
callback(stream.current(), style, i, stream.start);
|
52
|
+
callback(stream.current(), style, i, stream.start, state);
|
53
53
|
stream.start = stream.pos;
|
54
54
|
}
|
55
55
|
}
|
@@ -96,7 +96,7 @@ exports.runMode = function(string, modespec, callback) {
|
|
96
96
|
var stream = new exports.StringStream(lines[i]);
|
97
97
|
while (!stream.eol()) {
|
98
98
|
var style = mode.token(stream, state);
|
99
|
-
callback(stream.current(), style, i, stream.start);
|
99
|
+
callback(stream.current(), style, i, stream.start, state);
|
100
100
|
stream.start = stream.pos;
|
101
101
|
}
|
102
102
|
}
|
@@ -69,8 +69,8 @@
|
|
69
69
|
this.matches = function(reverse, pos) {
|
70
70
|
var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(doc.getLine(ln));
|
71
71
|
var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match));
|
72
|
-
if (reverse ? offsetA
|
73
|
-
: offsetA
|
72
|
+
if (reverse ? offsetA > pos.ch || offsetA != match.length
|
73
|
+
: offsetA < pos.ch || offsetA != line.length - match.length)
|
74
74
|
return;
|
75
75
|
for (;;) {
|
76
76
|
if (reverse ? !ln : ln == doc.lineCount() - 1) return;
|
@@ -24,6 +24,9 @@
|
|
24
24
|
// no tip should be shown. By default the docstring is shown.
|
25
25
|
// * typeTip: Like completionTip, but for the tooltips shown for type
|
26
26
|
// queries.
|
27
|
+
// * responseFilter: A function(doc, query, request, error, data) that
|
28
|
+
// will be applied to the Tern responses before treating them
|
29
|
+
//
|
27
30
|
//
|
28
31
|
// It is possible to run the Tern server in a web worker by specifying
|
29
32
|
// these additional options:
|
@@ -102,8 +105,16 @@
|
|
102
105
|
|
103
106
|
rename: function(cm) { rename(this, cm); },
|
104
107
|
|
105
|
-
request: function(cm, query, c) {
|
106
|
-
|
108
|
+
request: function (cm, query, c) {
|
109
|
+
var self = this;
|
110
|
+
var doc = findDoc(this, cm.getDoc());
|
111
|
+
var request = buildRequest(this, doc, query);
|
112
|
+
|
113
|
+
this.server.request(request, function (error, data) {
|
114
|
+
if (!error && self.options.responseFilter)
|
115
|
+
data = self.options.responseFilter(doc, query, request, error, data);
|
116
|
+
c(error, data);
|
117
|
+
});
|
107
118
|
}
|
108
119
|
};
|
109
120
|
|
@@ -233,12 +244,24 @@
|
|
233
244
|
closeArgHints(ts);
|
234
245
|
|
235
246
|
if (cm.somethingSelected()) return;
|
236
|
-
var
|
247
|
+
var state = cm.getTokenAt(cm.getCursor()).state;
|
248
|
+
var inner = CodeMirror.innerMode(cm.getMode(), state);
|
249
|
+
if (inner.mode.name != "javascript") return;
|
250
|
+
var lex = inner.state.lexical;
|
237
251
|
if (lex.info != "call") return;
|
238
252
|
|
239
|
-
var ch
|
240
|
-
for (var line = cm.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line)
|
241
|
-
|
253
|
+
var ch, pos = lex.pos || 0, tabSize = cm.getOption("tabSize");
|
254
|
+
for (var line = cm.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) {
|
255
|
+
var str = cm.getLine(line), extra = 0;
|
256
|
+
for (var pos = 0;;) {
|
257
|
+
var tab = str.indexOf("\t", pos);
|
258
|
+
if (tab == -1) break;
|
259
|
+
extra += tabSize - (tab + extra) % tabSize - 1;
|
260
|
+
pos = tab + 1;
|
261
|
+
}
|
262
|
+
ch = lex.column - extra;
|
263
|
+
if (str.charAt(ch) == "(") {found = true; break;}
|
264
|
+
}
|
242
265
|
if (!found) return;
|
243
266
|
|
244
267
|
var start = Pos(line, ch);
|
@@ -40,6 +40,10 @@
|
|
40
40
|
* TODO: Implement the remaining special marks. They have more complex
|
41
41
|
* behavior.
|
42
42
|
*
|
43
|
+
* Events:
|
44
|
+
* 'vim-mode-change' - raised on the editor anytime the current mode changes,
|
45
|
+
* Event object: {mode: "visual", subMode: "linewise"}
|
46
|
+
*
|
43
47
|
* Code structure:
|
44
48
|
* 1. Default keymap
|
45
49
|
* 2. Variable declarations and short basic helpers
|
@@ -318,6 +322,7 @@
|
|
318
322
|
CodeMirror.defineOption('vimMode', false, function(cm, val) {
|
319
323
|
if (val) {
|
320
324
|
cm.setOption('keyMap', 'vim');
|
325
|
+
CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
|
321
326
|
cm.on('beforeSelectionChange', beforeSelectionChange);
|
322
327
|
maybeInitVimState(cm);
|
323
328
|
} else if (cm.state.vim) {
|
@@ -579,6 +584,7 @@
|
|
579
584
|
!cursorEqual(cm.getCursor('head'), cm.getCursor('anchor'))) {
|
580
585
|
vim.visualMode = true;
|
581
586
|
vim.visualLine = false;
|
587
|
+
CodeMirror.signal(cm, "vim-mode-change", {mode: "visual"});
|
582
588
|
cm.on('mousedown', exitVisualMode);
|
583
589
|
}
|
584
590
|
if (key != '0' || (key == '0' && vim.inputState.getRepeat() === 0)) {
|
@@ -1651,8 +1657,10 @@
|
|
1651
1657
|
// Handle Replace-mode as a special case of insert mode.
|
1652
1658
|
cm.toggleOverwrite(true);
|
1653
1659
|
cm.setOption('keyMap', 'vim-replace');
|
1660
|
+
CodeMirror.signal(cm, "vim-mode-change", {mode: "replace"});
|
1654
1661
|
} else {
|
1655
1662
|
cm.setOption('keyMap', 'vim-insert');
|
1663
|
+
CodeMirror.signal(cm, "vim-mode-change", {mode: "insert"});
|
1656
1664
|
}
|
1657
1665
|
if (!vimGlobalState.macroModeState.inReplay) {
|
1658
1666
|
// Only record if not replaying.
|
@@ -1694,6 +1702,7 @@
|
|
1694
1702
|
} else {
|
1695
1703
|
cm.setSelection(curStart, curEnd);
|
1696
1704
|
}
|
1705
|
+
CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: vim.visualLine ? "linewise" : ""});
|
1697
1706
|
} else {
|
1698
1707
|
curStart = cm.getCursor('anchor');
|
1699
1708
|
curEnd = cm.getCursor('head');
|
@@ -1706,10 +1715,12 @@
|
|
1706
1715
|
curEnd.ch = cursorIsBefore(curStart, curEnd) ?
|
1707
1716
|
lineLength(cm, curEnd.line) : 0;
|
1708
1717
|
cm.setSelection(curStart, curEnd);
|
1718
|
+
CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: "linewise"});
|
1709
1719
|
} else if (vim.visualLine && !actionArgs.linewise) {
|
1710
1720
|
// v pressed in linewise visual mode. Switch to characterwise visual
|
1711
1721
|
// mode instead of exiting visual mode.
|
1712
1722
|
vim.visualLine = false;
|
1723
|
+
CodeMirror.signal(cm, "vim-mode-change", {mode: "visual"});
|
1713
1724
|
} else {
|
1714
1725
|
exitVisualMode(cm);
|
1715
1726
|
}
|
@@ -2022,6 +2033,7 @@
|
|
2022
2033
|
// it's not supposed to be.
|
2023
2034
|
cm.setCursor(clipCursorToContent(cm, selectionEnd));
|
2024
2035
|
}
|
2036
|
+
CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
|
2025
2037
|
}
|
2026
2038
|
|
2027
2039
|
// Remove any trailing newlines from the selection. For
|
@@ -3444,6 +3456,7 @@
|
|
3444
3456
|
vim.insertMode = false;
|
3445
3457
|
cm.setOption('keyMap', 'vim');
|
3446
3458
|
cm.toggleOverwrite(false); // exit replace mode if we were in it.
|
3459
|
+
CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
|
3447
3460
|
}
|
3448
3461
|
|
3449
3462
|
CodeMirror.keyMap['vim-insert'] = {
|