codemirror-rails 3.16 → 3.17
Sign up to get free protection for your applications and to get access to all the features.
- 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'] = {
|