codemirror-rails 2.34 → 2.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/codemirror/rails/version.rb +2 -2
- data/vendor/assets/javascripts/codemirror.js +53 -31
- data/vendor/assets/javascripts/codemirror/keymaps/vim.js +9 -10
- data/vendor/assets/javascripts/codemirror/modes/clike.js +1 -0
- data/vendor/assets/javascripts/codemirror/modes/css.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/gfm.js +83 -139
- data/vendor/assets/javascripts/codemirror/modes/htmlembedded.js +1 -0
- data/vendor/assets/javascripts/codemirror/modes/javascript.js +63 -15
- data/vendor/assets/javascripts/codemirror/modes/lua.js +1 -1
- data/vendor/assets/javascripts/codemirror/modes/markdown.js +122 -23
- data/vendor/assets/javascripts/codemirror/utils/overlay.js +6 -1
- data/vendor/assets/javascripts/codemirror/utils/runmode.js +1 -1
- data/vendor/assets/javascripts/codemirror/utils/searchcursor.js +3 -3
- data/vendor/assets/javascripts/codemirror/utils/simple-hint.js +9 -4
- data/vendor/assets/stylesheets/codemirror.css +1 -0
- metadata +12 -12
@@ -1,5 +1,5 @@
|
|
1
|
-
// CodeMirror version 2.
|
2
|
-
|
1
|
+
// CodeMirror version 2.35
|
2
|
+
//
|
3
3
|
// All functions that need access to the editor's state live inside
|
4
4
|
// the CodeMirror function. Below that, at the bottom of the file,
|
5
5
|
// some utilities are defined.
|
@@ -77,7 +77,7 @@ window.CodeMirror = (function() {
|
|
77
77
|
// Selection-related flags. shiftSelecting obviously tracks
|
78
78
|
// whether the user is holding shift.
|
79
79
|
var shiftSelecting, lastClick, lastDoubleClick, lastScrollTop = 0, draggingText,
|
80
|
-
overwrite = false, suppressEdits = false;
|
80
|
+
overwrite = false, suppressEdits = false, pasteIncoming = false;
|
81
81
|
// Variables used by startOperation/endOperation to track what
|
82
82
|
// happened during the operation.
|
83
83
|
var updateInput, userSelChange, changes, textChanged, selectionChanged,
|
@@ -130,7 +130,7 @@ window.CodeMirror = (function() {
|
|
130
130
|
connect(scroller, "drop", operation(onDrop));
|
131
131
|
}
|
132
132
|
connect(scroller, "paste", function(){focusInput(); fastPoll();});
|
133
|
-
connect(input, "paste", fastPoll);
|
133
|
+
connect(input, "paste", function(){pasteIncoming = true; fastPoll();});
|
134
134
|
connect(input, "cut", operation(function(){
|
135
135
|
if (!options.readOnly) replaceSelection("");
|
136
136
|
}));
|
@@ -169,6 +169,7 @@ window.CodeMirror = (function() {
|
|
169
169
|
else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)();
|
170
170
|
else if (option == "tabSize") updateDisplay(true);
|
171
171
|
else if (option == "keyMap") keyMapChanged();
|
172
|
+
else if (option == "tabindex") input.tabIndex = value;
|
172
173
|
if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" ||
|
173
174
|
option == "theme" || option == "lineNumberFormatter") {
|
174
175
|
gutterChanged();
|
@@ -956,12 +957,13 @@ window.CodeMirror = (function() {
|
|
956
957
|
while (same < l && prevInput[same] == text[same]) ++same;
|
957
958
|
if (same < prevInput.length)
|
958
959
|
sel.from = {line: sel.from.line, ch: sel.from.ch - (prevInput.length - same)};
|
959
|
-
else if (overwrite && posEq(sel.from, sel.to))
|
960
|
+
else if (overwrite && posEq(sel.from, sel.to) && !pasteIncoming)
|
960
961
|
sel.to = {line: sel.to.line, ch: Math.min(getLine(sel.to.line).text.length, sel.to.ch + (text.length - same))};
|
961
962
|
replaceSelection(text.slice(same), "end");
|
962
963
|
if (text.length > 1000) { input.value = prevInput = ""; }
|
963
964
|
else prevInput = text;
|
964
965
|
if (!nestedOperation) endOperation();
|
966
|
+
pasteIncoming = false;
|
965
967
|
return true;
|
966
968
|
}
|
967
969
|
function resetInput(user) {
|
@@ -1418,7 +1420,7 @@ window.CodeMirror = (function() {
|
|
1418
1420
|
var startChar = line.charAt(start);
|
1419
1421
|
var check = isWordChar(startChar) ? isWordChar :
|
1420
1422
|
/\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} :
|
1421
|
-
function(ch) {return !/\s/.test(ch) &&
|
1423
|
+
function(ch) {return !/\s/.test(ch) && isWordChar(ch);};
|
1422
1424
|
while (start > 0 && check(line.charAt(start - 1))) --start;
|
1423
1425
|
while (end < line.length && check(line.charAt(end))) ++end;
|
1424
1426
|
}
|
@@ -1462,6 +1464,7 @@ window.CodeMirror = (function() {
|
|
1462
1464
|
|
1463
1465
|
if (indentString != curSpaceString)
|
1464
1466
|
replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length});
|
1467
|
+
line.stateAfter = null;
|
1465
1468
|
}
|
1466
1469
|
|
1467
1470
|
function loadMode() {
|
@@ -1507,18 +1510,17 @@ window.CodeMirror = (function() {
|
|
1507
1510
|
|
1508
1511
|
function TextMarker(type, style) { this.lines = []; this.type = type; if (style) this.style = style; }
|
1509
1512
|
TextMarker.prototype.clear = operation(function() {
|
1510
|
-
var min
|
1513
|
+
var min, max;
|
1511
1514
|
for (var i = 0; i < this.lines.length; ++i) {
|
1512
1515
|
var line = this.lines[i];
|
1513
|
-
var span = getMarkedSpanFor(line.markedSpans, this
|
1514
|
-
if (span.from != null
|
1515
|
-
|
1516
|
-
|
1517
|
-
}
|
1516
|
+
var span = getMarkedSpanFor(line.markedSpans, this);
|
1517
|
+
if (span.from != null) min = lineNo(line);
|
1518
|
+
if (span.to != null) max = lineNo(line);
|
1519
|
+
line.markedSpans = removeMarkedSpan(line.markedSpans, span);
|
1518
1520
|
}
|
1519
|
-
if (min !=
|
1520
|
-
changes.push({from: min, to: max + 1});
|
1521
|
+
if (min != null) changes.push({from: min, to: max + 1});
|
1521
1522
|
this.lines.length = 0;
|
1523
|
+
this.explicitlyCleared = true;
|
1522
1524
|
});
|
1523
1525
|
TextMarker.prototype.find = function() {
|
1524
1526
|
var from, to;
|
@@ -1545,7 +1547,7 @@ window.CodeMirror = (function() {
|
|
1545
1547
|
var span = {from: curLine == from.line ? from.ch : null,
|
1546
1548
|
to: curLine == to.line ? to.ch : null,
|
1547
1549
|
marker: marker};
|
1548
|
-
|
1550
|
+
line.markedSpans = (line.markedSpans || []).concat([span]);
|
1549
1551
|
marker.lines.push(line);
|
1550
1552
|
++curLine;
|
1551
1553
|
});
|
@@ -1556,8 +1558,9 @@ window.CodeMirror = (function() {
|
|
1556
1558
|
function setBookmark(pos) {
|
1557
1559
|
pos = clipPos(pos);
|
1558
1560
|
var marker = new TextMarker("bookmark"), line = getLine(pos.line);
|
1561
|
+
history.addChange(pos.line, 1, [newHL(line.text, line.markedSpans)], true);
|
1559
1562
|
var span = {from: pos.ch, to: pos.ch, marker: marker};
|
1560
|
-
|
1563
|
+
line.markedSpans = (line.markedSpans || []).concat([span]);
|
1561
1564
|
marker.lines.push(line);
|
1562
1565
|
return marker;
|
1563
1566
|
}
|
@@ -1646,8 +1649,6 @@ window.CodeMirror = (function() {
|
|
1646
1649
|
|
1647
1650
|
function measureLine(line, ch) {
|
1648
1651
|
if (ch == 0) return {top: 0, left: 0};
|
1649
|
-
var wbr = options.lineWrapping && ch < line.text.length &&
|
1650
|
-
spanAffectsWrapping.test(line.text.slice(ch - 1, ch + 1));
|
1651
1652
|
var pre = lineContent(line, ch);
|
1652
1653
|
removeChildrenAndAdd(measure, pre);
|
1653
1654
|
var anchor = pre.anchor;
|
@@ -1980,6 +1981,7 @@ window.CodeMirror = (function() {
|
|
1980
1981
|
if (extensions.propertyIsEnumerable(ext) &&
|
1981
1982
|
!instance.propertyIsEnumerable(ext))
|
1982
1983
|
instance[ext] = extensions[ext];
|
1984
|
+
for (var i = 0; i < initHooks.length; ++i) initHooks[i](instance);
|
1983
1985
|
return instance;
|
1984
1986
|
} // (end of function CodeMirror)
|
1985
1987
|
|
@@ -2077,6 +2079,9 @@ window.CodeMirror = (function() {
|
|
2077
2079
|
extensions[name] = func;
|
2078
2080
|
};
|
2079
2081
|
|
2082
|
+
var initHooks = [];
|
2083
|
+
CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
|
2084
|
+
|
2080
2085
|
var modeExtensions = CodeMirror.modeExtensions = {};
|
2081
2086
|
CodeMirror.extendMode = function(mode, properties) {
|
2082
2087
|
var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
|
@@ -2206,6 +2211,7 @@ window.CodeMirror = (function() {
|
|
2206
2211
|
var name = keyNames[e_prop(event, "keyCode")];
|
2207
2212
|
return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
|
2208
2213
|
}
|
2214
|
+
CodeMirror.isModifierKey = isModifierKey;
|
2209
2215
|
|
2210
2216
|
CodeMirror.fromTextArea = function(textarea, options) {
|
2211
2217
|
if (!options) options = {};
|
@@ -2355,16 +2361,20 @@ window.CodeMirror = (function() {
|
|
2355
2361
|
this.from = from; this.to = to; this.marker = marker;
|
2356
2362
|
}
|
2357
2363
|
|
2358
|
-
function getMarkedSpanFor(spans, marker
|
2364
|
+
function getMarkedSpanFor(spans, marker) {
|
2359
2365
|
if (spans) for (var i = 0; i < spans.length; ++i) {
|
2360
2366
|
var span = spans[i];
|
2361
|
-
if (span.marker == marker)
|
2362
|
-
if (del) spans.splice(i, 1);
|
2363
|
-
return span;
|
2364
|
-
}
|
2367
|
+
if (span.marker == marker) return span;
|
2365
2368
|
}
|
2366
2369
|
}
|
2367
2370
|
|
2371
|
+
function removeMarkedSpan(spans, span) {
|
2372
|
+
var r;
|
2373
|
+
for (var i = 0; i < spans.length; ++i)
|
2374
|
+
if (spans[i] != span) (r || (r = [])).push(spans[i]);
|
2375
|
+
return r;
|
2376
|
+
}
|
2377
|
+
|
2368
2378
|
function markedSpansBefore(old, startCh, endCh) {
|
2369
2379
|
if (old) for (var i = 0, nw; i < old.length; ++i) {
|
2370
2380
|
var span = old[i], marker = span.marker;
|
@@ -2448,7 +2458,15 @@ window.CodeMirror = (function() {
|
|
2448
2458
|
// hl stands for history-line, a data structure that can be either a
|
2449
2459
|
// string (line without markers) or a {text, markedSpans} object.
|
2450
2460
|
function hlText(val) { return typeof val == "string" ? val : val.text; }
|
2451
|
-
function hlSpans(val) {
|
2461
|
+
function hlSpans(val) {
|
2462
|
+
if (typeof val == "string") return null;
|
2463
|
+
var spans = val.markedSpans, out = null;
|
2464
|
+
for (var i = 0; i < spans.length; ++i) {
|
2465
|
+
if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
|
2466
|
+
else if (out) out.push(spans[i]);
|
2467
|
+
}
|
2468
|
+
return !out ? spans : out.length ? out : null;
|
2469
|
+
}
|
2452
2470
|
function newHL(text, spans) { return spans ? {text: text, markedSpans: spans} : text; }
|
2453
2471
|
|
2454
2472
|
function detachMarkedSpans(line) {
|
@@ -2584,13 +2602,17 @@ window.CodeMirror = (function() {
|
|
2584
2602
|
span = function(html, text, style) {
|
2585
2603
|
var l = text.length;
|
2586
2604
|
if (wrapAt >= outPos && wrapAt < outPos + l) {
|
2587
|
-
|
2588
|
-
|
2605
|
+
var cut = wrapAt - outPos;
|
2606
|
+
if (cut) {
|
2607
|
+
span_(html, text.slice(0, cut), style);
|
2589
2608
|
// See comment at the definition of spanAffectsWrapping
|
2590
|
-
if (compensateForWrapping)
|
2609
|
+
if (compensateForWrapping) {
|
2610
|
+
var view = text.slice(cut - 1, cut + 1);
|
2611
|
+
if (spanAffectsWrapping.test(view)) html.appendChild(elt("wbr"));
|
2612
|
+
else if (!ie_lt8 && /\w\w/.test(view)) html.appendChild(document.createTextNode("\u200d"));
|
2613
|
+
}
|
2591
2614
|
}
|
2592
2615
|
html.appendChild(anchor);
|
2593
|
-
var cut = wrapAt - outPos;
|
2594
2616
|
span_(anchor, opera ? text.slice(cut, cut + 1) : text.slice(cut), style);
|
2595
2617
|
if (opera) span_(html, text.slice(cut + 1), style);
|
2596
2618
|
wrapAt--;
|
@@ -2874,7 +2896,7 @@ window.CodeMirror = (function() {
|
|
2874
2896
|
var time = +new Date, cur = lst(this.done), last = cur && lst(cur);
|
2875
2897
|
var dtime = time - this.time;
|
2876
2898
|
|
2877
|
-
if (
|
2899
|
+
if (cur && !this.closed && this.compound) {
|
2878
2900
|
cur.push({start: start, added: added, old: old});
|
2879
2901
|
} else if (dtime > 400 || !last || this.closed ||
|
2880
2902
|
last.start > start + old.length || last.start + last.added < start) {
|
@@ -3081,7 +3103,7 @@ window.CodeMirror = (function() {
|
|
3081
3103
|
return -1;
|
3082
3104
|
}
|
3083
3105
|
function isWordChar(ch) {
|
3084
|
-
return /\w/.test(ch) || ch.toUpperCase() != ch.toLowerCase();
|
3106
|
+
return /\w/.test(ch) || ch.toUpperCase() != ch.toLowerCase() || /[\u4E00-\u9FA5]/.test(ch);
|
3085
3107
|
}
|
3086
3108
|
|
3087
3109
|
// See if "".split is the broken IE version, if so, provide an
|
@@ -3137,7 +3159,7 @@ window.CodeMirror = (function() {
|
|
3137
3159
|
for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
|
3138
3160
|
})();
|
3139
3161
|
|
3140
|
-
CodeMirror.version = "2.
|
3162
|
+
CodeMirror.version = "2.35";
|
3141
3163
|
|
3142
3164
|
return CodeMirror;
|
3143
3165
|
})();
|
@@ -318,13 +318,12 @@
|
|
318
318
|
};
|
319
319
|
|
320
320
|
// standard mode switching
|
321
|
-
iterList(["d", "t", "T", "f", "F", "c", "r"],
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
});
|
321
|
+
iterList(["d", "t", "T", "f", "F", "c", "r"], function (ch) {
|
322
|
+
CodeMirror.keyMap.vim[toCombo(ch)] = function (cm) {
|
323
|
+
cm.setOption("keyMap", "vim-prefix-" + ch);
|
324
|
+
emptyBuffer();
|
325
|
+
};
|
326
|
+
});
|
328
327
|
|
329
328
|
function addCountBindings(keyMap) {
|
330
329
|
// Add bindings for number keys
|
@@ -645,7 +644,7 @@
|
|
645
644
|
};
|
646
645
|
|
647
646
|
// Map our movement actions each operator and non-operational movement
|
648
|
-
motionList
|
647
|
+
iterList(motionList, function(key, index, array) {
|
649
648
|
CodeMirror.keyMap['vim-prefix-d'][key] = function(cm) {
|
650
649
|
// Get our selected range
|
651
650
|
var start = cm.getCursor();
|
@@ -695,7 +694,7 @@
|
|
695
694
|
});
|
696
695
|
|
697
696
|
var nums = [1,2,3,4,5,6,7,8,9];
|
698
|
-
nums
|
697
|
+
iterList(nums, function(key, index, array) {
|
699
698
|
CodeMirror.keyMap['vim'][key] = function (cm) {
|
700
699
|
reptTimes = (reptTimes * 10) + key;
|
701
700
|
};
|
@@ -713,7 +712,7 @@
|
|
713
712
|
// Create our keymaps for each operator and make xa and xi where x is an operator
|
714
713
|
// change to the corrosponding keymap
|
715
714
|
var operators = ['d', 'y', 'c'];
|
716
|
-
operators
|
715
|
+
iterList(operators, function(key, index, array) {
|
717
716
|
CodeMirror.keyMap['vim-prefix-'+key+'a'] = {
|
718
717
|
auto: 'vim', nofallthrough: true, style: "fat-cursor"
|
719
718
|
};
|
@@ -140,6 +140,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|
140
140
|
},
|
141
141
|
|
142
142
|
indent: function(state, textAfter) {
|
143
|
+
if (state.tokenize == tokenComment) return CodeMirror.Pass;
|
143
144
|
if (state.tokenize != tokenBase && state.tokenize != null) return 0;
|
144
145
|
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
|
145
146
|
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
|
@@ -228,7 +228,7 @@ CodeMirror.defineMode("css", function(config) {
|
|
228
228
|
else if (/[,+>*\/]/.test(ch)) {
|
229
229
|
return ret(null, "select-op");
|
230
230
|
}
|
231
|
-
else if (ch == "." && stream.match(
|
231
|
+
else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
|
232
232
|
return ret("qualifier", type);
|
233
233
|
}
|
234
234
|
else if (ch == ":") {
|
@@ -1,150 +1,94 @@
|
|
1
1
|
CodeMirror.defineMode("gfm", function(config, parserConfig) {
|
2
|
-
var
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
json: "application/json",
|
7
|
-
c: "text/x-csrc",
|
8
|
-
"c++": "text/x-c++src",
|
9
|
-
java: "text/x-java",
|
10
|
-
csharp: "text/x-csharp",
|
11
|
-
"c#": "text/x-csharp"
|
12
|
-
};
|
13
|
-
|
14
|
-
// make this lazy so that we don't need to load GFM last
|
15
|
-
var getMode = (function () {
|
16
|
-
var i, modes = {}, mimes = {}, mime;
|
17
|
-
|
18
|
-
var list = CodeMirror.listModes();
|
19
|
-
for (i = 0; i < list.length; i++) {
|
20
|
-
modes[list[i]] = list[i];
|
21
|
-
}
|
22
|
-
var mimesList = CodeMirror.listMIMEs();
|
23
|
-
for (i = 0; i < mimesList.length; i++) {
|
24
|
-
mime = mimesList[i].mime;
|
25
|
-
mimes[mime] = mimesList[i].mime;
|
26
|
-
}
|
27
|
-
|
28
|
-
for (var a in aliases) {
|
29
|
-
if (aliases[a] in modes || aliases[a] in mimes)
|
30
|
-
modes[a] = aliases[a];
|
31
|
-
}
|
32
|
-
|
33
|
-
return function (lang) {
|
34
|
-
return modes[lang] ? CodeMirror.getMode(config, modes[lang]) : null;
|
35
|
-
};
|
36
|
-
}());
|
37
|
-
|
38
|
-
function markdown(stream, state) {
|
39
|
-
// intercept fenced code blocks
|
40
|
-
if (stream.sol() && stream.match(/^```([\w+#]*)/)) {
|
41
|
-
// try switching mode
|
42
|
-
state.localMode = getMode(RegExp.$1);
|
43
|
-
if (state.localMode)
|
44
|
-
state.localState = state.localMode.startState();
|
45
|
-
|
46
|
-
state.token = local;
|
47
|
-
return 'code';
|
48
|
-
}
|
49
|
-
|
50
|
-
return mdMode.token(stream, state.mdState);
|
51
|
-
}
|
52
|
-
|
53
|
-
function local(stream, state) {
|
54
|
-
if (stream.sol() && stream.match(/^```/)) {
|
55
|
-
state.localMode = state.localState = null;
|
56
|
-
state.token = markdown;
|
57
|
-
return 'code';
|
58
|
-
}
|
59
|
-
else if (state.localMode) {
|
60
|
-
return state.localMode.token(stream, state.localState);
|
61
|
-
} else {
|
62
|
-
stream.skipToEnd();
|
63
|
-
return 'code';
|
64
|
-
}
|
65
|
-
}
|
66
|
-
|
67
|
-
// custom handleText to prevent emphasis in the middle of a word
|
68
|
-
// and add autolinking
|
69
|
-
function handleText(stream, mdState) {
|
70
|
-
var match;
|
71
|
-
if (stream.match(/^\w+:\/\/\S+/)) {
|
72
|
-
return 'link';
|
73
|
-
}
|
74
|
-
if (stream.match(/^[^\[*\\<>` _][^\[*\\<>` ]*[^\[*\\<>` _]/)) {
|
75
|
-
return mdMode.getType(mdState);
|
76
|
-
}
|
77
|
-
if (match = stream.match(/^[^\[*\\<>` ]+/)) {
|
78
|
-
var word = match[0];
|
79
|
-
if (word[0] === '_' && word[word.length-1] === '_') {
|
80
|
-
stream.backUp(word.length);
|
81
|
-
return undefined;
|
82
|
-
}
|
83
|
-
return mdMode.getType(mdState);
|
84
|
-
}
|
85
|
-
if (stream.eatSpace()) {
|
86
|
-
return null;
|
87
|
-
}
|
2
|
+
var codeDepth = 0;
|
3
|
+
function blankLine(state) {
|
4
|
+
state.code = false;
|
5
|
+
return null;
|
88
6
|
}
|
89
|
-
|
90
|
-
return {
|
7
|
+
var gfmOverlay = {
|
91
8
|
startState: function() {
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
9
|
+
return {
|
10
|
+
code: false,
|
11
|
+
codeBlock: false,
|
12
|
+
ateSpace: false
|
13
|
+
};
|
96
14
|
},
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
15
|
+
copyState: function(s) {
|
16
|
+
return {
|
17
|
+
code: s.code,
|
18
|
+
codeBlock: s.codeBlock,
|
19
|
+
ateSpace: s.ateSpace
|
20
|
+
};
|
102
21
|
},
|
103
|
-
|
104
22
|
token: function(stream, state) {
|
105
|
-
|
106
|
-
|
107
|
-
if (
|
108
|
-
|
109
|
-
|
110
|
-
/* Only handle double bracket links */
|
111
|
-
if ((ch = stream.peek()) == undefined || ch != '[') {
|
112
|
-
stream.backUp(1);
|
113
|
-
return state.token(stream, state);
|
114
|
-
}
|
115
|
-
|
116
|
-
while ((ch = stream.next()) != undefined && ch != ']') {}
|
117
|
-
|
118
|
-
if (ch == ']' && (ch = stream.next()) != undefined && ch == ']')
|
119
|
-
return 'link';
|
120
|
-
|
121
|
-
/* If we did not find the second ']' */
|
122
|
-
stream.backUp(1);
|
123
|
-
}
|
124
|
-
|
125
|
-
/* Match GFM latex formulas, as well as latex formulas within '$' */
|
126
|
-
if (stream.match(/^\$[^\$]+\$/)) {
|
127
|
-
return "string";
|
23
|
+
// Hack to prevent formatting override inside code blocks (block and inline)
|
24
|
+
if (state.codeBlock) {
|
25
|
+
if (stream.match(/^```/)) {
|
26
|
+
state.codeBlock = false;
|
27
|
+
return null;
|
128
28
|
}
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
29
|
+
stream.skipToEnd();
|
30
|
+
return null;
|
31
|
+
}
|
32
|
+
if (stream.sol()) {
|
33
|
+
state.code = false;
|
34
|
+
}
|
35
|
+
if (stream.sol() && stream.match(/^```/)) {
|
36
|
+
stream.skipToEnd();
|
37
|
+
state.codeBlock = true;
|
38
|
+
return null;
|
39
|
+
}
|
40
|
+
// If this block is changed, it may need to be updated in Markdown mode
|
41
|
+
if (stream.peek() === '`') {
|
42
|
+
stream.next();
|
43
|
+
var before = stream.pos;
|
44
|
+
stream.eatWhile('`');
|
45
|
+
var difference = 1 + stream.pos - before;
|
46
|
+
if (!state.code) {
|
47
|
+
codeDepth = difference;
|
48
|
+
state.code = true;
|
49
|
+
} else {
|
50
|
+
if (difference === codeDepth) { // Must be exact
|
51
|
+
state.code = false;
|
52
|
+
}
|
136
53
|
}
|
137
|
-
|
138
|
-
|
139
|
-
|
54
|
+
return null;
|
55
|
+
} else if (state.code) {
|
56
|
+
stream.next();
|
57
|
+
return null;
|
58
|
+
}
|
59
|
+
// Check if space. If so, links can be formatted later on
|
60
|
+
if (stream.eatSpace()) {
|
61
|
+
state.ateSpace = true;
|
62
|
+
return null;
|
63
|
+
}
|
64
|
+
if (stream.sol() || state.ateSpace) {
|
65
|
+
state.ateSpace = false;
|
66
|
+
if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) {
|
67
|
+
// User/Project@SHA
|
68
|
+
// User@SHA
|
69
|
+
// SHA
|
70
|
+
return "link";
|
71
|
+
} else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) {
|
72
|
+
// User/Project#Num
|
73
|
+
// User#Num
|
74
|
+
// #Num
|
75
|
+
return "link";
|
140
76
|
}
|
141
|
-
|
142
|
-
|
77
|
+
}
|
78
|
+
if (stream.match(/^((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i)) {
|
79
|
+
// URLs
|
80
|
+
// Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
81
|
+
return "link";
|
82
|
+
}
|
83
|
+
stream.next();
|
84
|
+
return null;
|
143
85
|
},
|
144
|
-
|
145
|
-
innerMode: function(state) {
|
146
|
-
if (state.token == markdown) return {state: state.mdState, mode: mdMode};
|
147
|
-
else return {state: state.localState, mode: state.localMode};
|
148
|
-
}
|
86
|
+
blankLine: blankLine
|
149
87
|
};
|
150
|
-
|
88
|
+
CodeMirror.defineMIME("gfmBase", {
|
89
|
+
name: "markdown",
|
90
|
+
underscoresBreakWords: false,
|
91
|
+
fencedCodeBlocks: true
|
92
|
+
});
|
93
|
+
return CodeMirror.overlayMode(CodeMirror.getMode(config, "gfmBase"), gfmOverlay);
|
94
|
+
});
|
@@ -70,3 +70,4 @@ CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
|
|
70
70
|
CodeMirror.defineMIME("application/x-ejs", { name: "htmlembedded", scriptingModeSpec:"javascript"});
|
71
71
|
CodeMirror.defineMIME("application/x-aspx", { name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
|
72
72
|
CodeMirror.defineMIME("application/x-jsp", { name: "htmlembedded", scriptingModeSpec:"text/x-java"});
|
73
|
+
CodeMirror.defineMIME("application/x-erb", { name: "htmlembedded", scriptingModeSpec:"ruby"});
|
@@ -1,6 +1,9 @@
|
|
1
|
+
// TODO actually recognize syntax of TypeScript constructs
|
2
|
+
|
1
3
|
CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
2
4
|
var indentUnit = config.indentUnit;
|
3
5
|
var jsonMode = parserConfig.json;
|
6
|
+
var isTS = parserConfig.typescript;
|
4
7
|
|
5
8
|
// Tokenizer
|
6
9
|
|
@@ -8,7 +11,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
8
11
|
function kw(type) {return {type: type, style: "keyword"};}
|
9
12
|
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
|
10
13
|
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
|
11
|
-
|
14
|
+
|
15
|
+
var jsKeywords = {
|
12
16
|
"if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
|
13
17
|
"return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
|
14
18
|
"var": kw("var"), "const": kw("var"), "let": kw("var"),
|
@@ -17,6 +21,35 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
17
21
|
"in": operator, "typeof": operator, "instanceof": operator,
|
18
22
|
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
|
19
23
|
};
|
24
|
+
|
25
|
+
// Extend the 'normal' keywords with the TypeScript language extensions
|
26
|
+
if (isTS) {
|
27
|
+
var type = {type: "variable", style: "variable-3"};
|
28
|
+
var tsKeywords = {
|
29
|
+
// object-like things
|
30
|
+
"interface": kw("interface"),
|
31
|
+
"class": kw("class"),
|
32
|
+
"extends": kw("extends"),
|
33
|
+
"constructor": kw("constructor"),
|
34
|
+
|
35
|
+
// scope modifiers
|
36
|
+
"public": kw("public"),
|
37
|
+
"private": kw("private"),
|
38
|
+
"protected": kw("protected"),
|
39
|
+
"static": kw("static"),
|
40
|
+
|
41
|
+
"super": kw("super"),
|
42
|
+
|
43
|
+
// types
|
44
|
+
"string": type, "number": type, "bool": type, "any": type
|
45
|
+
};
|
46
|
+
|
47
|
+
for (var attr in tsKeywords) {
|
48
|
+
jsKeywords[attr] = tsKeywords[attr];
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
return jsKeywords;
|
20
53
|
}();
|
21
54
|
|
22
55
|
var isOperatorChar = /[+\-*&%=<>!?|]/;
|
@@ -66,7 +99,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
66
99
|
stream.skipToEnd();
|
67
100
|
return ret("comment", "comment");
|
68
101
|
}
|
69
|
-
else if (state.
|
102
|
+
else if (state.lastType == "operator" || state.lastType == "keyword c" ||
|
103
|
+
/^[\[{}\(,;:]$/.test(state.lastType)) {
|
70
104
|
nextUntilUnescaped(stream, "/");
|
71
105
|
stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
|
72
106
|
return ret("regexp", "string-2");
|
@@ -87,7 +121,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
87
121
|
else {
|
88
122
|
stream.eatWhile(/[\w\$_]/);
|
89
123
|
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
|
90
|
-
return (known && state.
|
124
|
+
return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
|
91
125
|
ret("variable", "variable", word);
|
92
126
|
}
|
93
127
|
}
|
@@ -275,19 +309,30 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
275
309
|
if (type == "}") return cont();
|
276
310
|
return pass(statement, block);
|
277
311
|
}
|
312
|
+
function maybetype(type) {
|
313
|
+
if (type == ":") return cont(typedef);
|
314
|
+
return pass();
|
315
|
+
}
|
316
|
+
function typedef(type) {
|
317
|
+
if (type == "variable"){cx.marked = "variable-3"; return cont();}
|
318
|
+
return pass();
|
319
|
+
}
|
278
320
|
function vardef1(type, value) {
|
279
|
-
if (type == "variable"){
|
280
|
-
|
321
|
+
if (type == "variable") {
|
322
|
+
register(value);
|
323
|
+
return isTS ? cont(maybetype, vardef2) : cont(vardef2);
|
324
|
+
}
|
325
|
+
return pass();
|
281
326
|
}
|
282
327
|
function vardef2(type, value) {
|
283
328
|
if (value == "=") return cont(expression, vardef2);
|
284
329
|
if (type == ",") return cont(vardef1);
|
285
330
|
}
|
286
331
|
function forspec1(type) {
|
287
|
-
if (type == "var") return cont(vardef1, forspec2);
|
288
|
-
if (type == ";") return
|
332
|
+
if (type == "var") return cont(vardef1, expect(";"), forspec2);
|
333
|
+
if (type == ";") return cont(forspec2);
|
289
334
|
if (type == "variable") return cont(formaybein);
|
290
|
-
return
|
335
|
+
return cont(forspec2);
|
291
336
|
}
|
292
337
|
function formaybein(type, value) {
|
293
338
|
if (value == "in") return cont(expression);
|
@@ -306,7 +351,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
306
351
|
if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
|
307
352
|
}
|
308
353
|
function funarg(type, value) {
|
309
|
-
if (type == "variable") {register(value); return cont();}
|
354
|
+
if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();}
|
310
355
|
}
|
311
356
|
|
312
357
|
// Interface
|
@@ -315,8 +360,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
315
360
|
startState: function(basecolumn) {
|
316
361
|
return {
|
317
362
|
tokenize: jsTokenBase,
|
318
|
-
|
319
|
-
kwAllowed: true,
|
363
|
+
lastType: null,
|
320
364
|
cc: [],
|
321
365
|
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
|
322
366
|
localVars: parserConfig.localVars,
|
@@ -334,19 +378,21 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
334
378
|
if (stream.eatSpace()) return null;
|
335
379
|
var style = state.tokenize(stream, state);
|
336
380
|
if (type == "comment") return style;
|
337
|
-
state.
|
338
|
-
state.kwAllowed = type != '.';
|
381
|
+
state.lastType = type;
|
339
382
|
return parseJS(state, style, type, content, stream);
|
340
383
|
},
|
341
384
|
|
342
385
|
indent: function(state, textAfter) {
|
386
|
+
if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
|
343
387
|
if (state.tokenize != jsTokenBase) return 0;
|
344
388
|
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
|
345
389
|
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
|
346
390
|
var type = lexical.type, closing = firstChar == type;
|
347
|
-
if (type == "vardef") return lexical.indented + 4;
|
391
|
+
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0);
|
348
392
|
else if (type == "form" && firstChar == "{") return lexical.indented;
|
349
|
-
else if (type == "
|
393
|
+
else if (type == "form") return lexical.indented + indentUnit;
|
394
|
+
else if (type == "stat")
|
395
|
+
return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? indentUnit : 0);
|
350
396
|
else if (lexical.info == "switch" && !closing)
|
351
397
|
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
|
352
398
|
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
|
@@ -359,3 +405,5 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
359
405
|
|
360
406
|
CodeMirror.defineMIME("text/javascript", "javascript");
|
361
407
|
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
|
408
|
+
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
|
409
|
+
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
|
@@ -64,7 +64,7 @@ CodeMirror.defineMode("lua", function(config, parserConfig) {
|
|
64
64
|
function normal(stream, state) {
|
65
65
|
var ch = stream.next();
|
66
66
|
if (ch == "-" && stream.eat("-")) {
|
67
|
-
if (stream.eat("["))
|
67
|
+
if (stream.eat("[") && stream.eat("["))
|
68
68
|
return (state.cur = bracketed(readBracket(stream), "comment"))(stream, state);
|
69
69
|
stream.skipToEnd();
|
70
70
|
return "comment";
|
@@ -2,6 +2,46 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
2
2
|
|
3
3
|
var htmlFound = CodeMirror.mimeModes.hasOwnProperty("text/html");
|
4
4
|
var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? "text/html" : "text/plain");
|
5
|
+
var aliases = {
|
6
|
+
html: "htmlmixed",
|
7
|
+
js: "javascript",
|
8
|
+
json: "application/json",
|
9
|
+
c: "text/x-csrc",
|
10
|
+
"c++": "text/x-c++src",
|
11
|
+
java: "text/x-java",
|
12
|
+
csharp: "text/x-csharp",
|
13
|
+
"c#": "text/x-csharp"
|
14
|
+
};
|
15
|
+
|
16
|
+
var getMode = (function () {
|
17
|
+
var i, modes = {}, mimes = {}, mime;
|
18
|
+
|
19
|
+
var list = CodeMirror.listModes();
|
20
|
+
for (i = 0; i < list.length; i++) {
|
21
|
+
modes[list[i]] = list[i];
|
22
|
+
}
|
23
|
+
var mimesList = CodeMirror.listMIMEs();
|
24
|
+
for (i = 0; i < mimesList.length; i++) {
|
25
|
+
mime = mimesList[i].mime;
|
26
|
+
mimes[mime] = mimesList[i].mime;
|
27
|
+
}
|
28
|
+
|
29
|
+
for (var a in aliases) {
|
30
|
+
if (aliases[a] in modes || aliases[a] in mimes)
|
31
|
+
modes[a] = aliases[a];
|
32
|
+
}
|
33
|
+
|
34
|
+
return function (lang) {
|
35
|
+
return modes[lang] ? CodeMirror.getMode(cmCfg, modes[lang]) : null;
|
36
|
+
};
|
37
|
+
}());
|
38
|
+
|
39
|
+
// Should underscores in words open/close em/strong?
|
40
|
+
if (modeCfg.underscoresBreakWords === undefined)
|
41
|
+
modeCfg.underscoresBreakWords = true;
|
42
|
+
|
43
|
+
// Turn on fenced code blocks? ("```" to start/end)
|
44
|
+
if (modeCfg.fencedCodeBlocks === undefined) modeCfg.fencedCodeBlocks = false;
|
5
45
|
|
6
46
|
var codeDepth = 0;
|
7
47
|
var prevLineHasContent = false
|
@@ -12,6 +52,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
12
52
|
, quote = 'quote'
|
13
53
|
, list = 'string'
|
14
54
|
, hr = 'hr'
|
55
|
+
, image = 'tag'
|
15
56
|
, linkinline = 'link'
|
16
57
|
, linkemail = 'link'
|
17
58
|
, linktext = 'link'
|
@@ -24,7 +65,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
24
65
|
, ulRE = /^[*\-+]\s+/
|
25
66
|
, olRE = /^[0-9]+\.\s+/
|
26
67
|
, headerRE = /^(?:\={1,}|-{1,})$/
|
27
|
-
, textRE = /^[
|
68
|
+
, textRE = /^[^!\[\]*_\\<>` "'(]+/;
|
28
69
|
|
29
70
|
function switchInline(stream, state, f) {
|
30
71
|
state.f = state.inline = f;
|
@@ -42,8 +83,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
42
83
|
function blankLine(state) {
|
43
84
|
// Reset linkTitle state
|
44
85
|
state.linkTitle = false;
|
45
|
-
// Reset CODE state
|
46
|
-
state.code = false;
|
47
86
|
// Reset EM state
|
48
87
|
state.em = false;
|
49
88
|
// Reset STRONG state
|
@@ -58,7 +97,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
58
97
|
}
|
59
98
|
|
60
99
|
function blockNormal(stream, state) {
|
61
|
-
var match;
|
62
100
|
|
63
101
|
if (state.list !== false && state.indentationDiff >= 0) { // Continued list
|
64
102
|
if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
|
@@ -84,9 +122,15 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
84
122
|
return switchInline(stream, state, footnoteLink);
|
85
123
|
} else if (stream.match(hrRE, true)) {
|
86
124
|
return hr;
|
87
|
-
} else if (
|
125
|
+
} else if (stream.match(ulRE, true) || stream.match(olRE, true)) {
|
88
126
|
state.indentation += 4;
|
89
127
|
state.list = true;
|
128
|
+
} else if (modeCfg.fencedCodeBlocks && stream.match(/^```([\w+#]*)/, true)) {
|
129
|
+
// try switching mode
|
130
|
+
state.localMode = getMode(RegExp.$1);
|
131
|
+
if (state.localMode) state.localState = state.localMode.startState();
|
132
|
+
switchBlock(stream, state, local);
|
133
|
+
return code;
|
90
134
|
}
|
91
135
|
|
92
136
|
return switchInline(stream, state, state.inline);
|
@@ -106,6 +150,30 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
106
150
|
return style;
|
107
151
|
}
|
108
152
|
|
153
|
+
function local(stream, state) {
|
154
|
+
if (stream.sol() && stream.match(/^```/, true)) {
|
155
|
+
state.localMode = state.localState = null;
|
156
|
+
state.f = inlineNormal;
|
157
|
+
state.block = blockNormal;
|
158
|
+
return code;
|
159
|
+
} else if (state.localMode) {
|
160
|
+
return state.localMode.token(stream, state.localState);
|
161
|
+
} else {
|
162
|
+
stream.skipToEnd();
|
163
|
+
return code;
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
function codeBlock(stream, state) {
|
168
|
+
if(stream.match(codeBlockRE, true)){
|
169
|
+
state.f = inlineNormal;
|
170
|
+
state.block = blockNormal;
|
171
|
+
switchInline(stream, state, state.inline);
|
172
|
+
return code;
|
173
|
+
}
|
174
|
+
stream.skipToEnd();
|
175
|
+
return code;
|
176
|
+
}
|
109
177
|
|
110
178
|
// Inline
|
111
179
|
function getType(state) {
|
@@ -114,6 +182,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
114
182
|
if (state.strong) { styles.push(state.em ? emstrong : strong); }
|
115
183
|
else if (state.em) { styles.push(em); }
|
116
184
|
|
185
|
+
if (state.linkText) { styles.push(linktext); }
|
186
|
+
|
117
187
|
if (state.code) { styles.push(code); }
|
118
188
|
|
119
189
|
if (state.header) { styles.push(header); }
|
@@ -161,6 +231,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
161
231
|
}
|
162
232
|
}
|
163
233
|
|
234
|
+
// If this block is changed, it may need to be updated in GFM mode
|
164
235
|
if (ch === '`') {
|
165
236
|
var t = getType(state);
|
166
237
|
var before = stream.pos;
|
@@ -181,8 +252,22 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
181
252
|
return getType(state);
|
182
253
|
}
|
183
254
|
|
184
|
-
if (ch === '
|
185
|
-
|
255
|
+
if (ch === '!' && stream.match(/\[.*\] ?(?:\(|\[)/, false)) {
|
256
|
+
stream.match(/\[.*\]/);
|
257
|
+
state.inline = state.f = linkHref;
|
258
|
+
return image;
|
259
|
+
}
|
260
|
+
|
261
|
+
if (ch === '[' && stream.match(/.*\](\(| ?\[)/, false)) {
|
262
|
+
state.linkText = true;
|
263
|
+
return getType(state);
|
264
|
+
}
|
265
|
+
|
266
|
+
if (ch === ']' && state.linkText) {
|
267
|
+
var type = getType(state);
|
268
|
+
state.linkText = false;
|
269
|
+
state.inline = state.f = linkHref;
|
270
|
+
return type;
|
186
271
|
}
|
187
272
|
|
188
273
|
if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, true)) {
|
@@ -210,8 +295,20 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
210
295
|
return "tag";
|
211
296
|
}
|
212
297
|
|
298
|
+
var ignoreUnderscore = false;
|
299
|
+
if (!modeCfg.underscoresBreakWords) {
|
300
|
+
if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
|
301
|
+
var prevPos = stream.pos - 2;
|
302
|
+
if (prevPos >= 0) {
|
303
|
+
var prevCh = stream.string.charAt(prevPos);
|
304
|
+
if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
|
305
|
+
ignoreUnderscore = true;
|
306
|
+
}
|
307
|
+
}
|
308
|
+
}
|
309
|
+
}
|
213
310
|
var t = getType(state);
|
214
|
-
if (ch === '*' || ch === '_') {
|
311
|
+
if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
|
215
312
|
if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
|
216
313
|
state.strong = false;
|
217
314
|
return t;
|
@@ -238,18 +335,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
238
335
|
return getType(state);
|
239
336
|
}
|
240
337
|
|
241
|
-
function linkText(stream, state) {
|
242
|
-
while (!stream.eol()) {
|
243
|
-
var ch = stream.next();
|
244
|
-
if (ch === '\\') stream.next();
|
245
|
-
if (ch === ']') {
|
246
|
-
state.inline = state.f = linkHref;
|
247
|
-
return linktext;
|
248
|
-
}
|
249
|
-
}
|
250
|
-
return linktext;
|
251
|
-
}
|
252
|
-
|
253
338
|
function linkHref(stream, state) {
|
254
339
|
// Check if space, and return NULL if so (to avoid marking the space)
|
255
340
|
if(stream.eatSpace()){
|
@@ -287,15 +372,16 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
287
372
|
return linkhref;
|
288
373
|
}
|
289
374
|
|
375
|
+
var savedInlineRE = [];
|
290
376
|
function inlineRE(endChar) {
|
291
|
-
if (!
|
377
|
+
if (!savedInlineRE[endChar]) {
|
292
378
|
// Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741)
|
293
379
|
endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
|
294
380
|
// Match any non-endChar, escaped character, as well as the closing
|
295
381
|
// endChar.
|
296
|
-
|
382
|
+
savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')');
|
297
383
|
}
|
298
|
-
return
|
384
|
+
return savedInlineRE[endChar];
|
299
385
|
}
|
300
386
|
|
301
387
|
function inlineElement(type, endChar, next) {
|
@@ -309,6 +395,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
309
395
|
|
310
396
|
return {
|
311
397
|
startState: function() {
|
398
|
+
prevLineHasContent = false;
|
399
|
+
thisLineHasContent = false;
|
312
400
|
return {
|
313
401
|
f: blockNormal,
|
314
402
|
|
@@ -318,6 +406,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
318
406
|
|
319
407
|
inline: inlineNormal,
|
320
408
|
text: handleText,
|
409
|
+
|
410
|
+
linkText: false,
|
321
411
|
linkTitle: false,
|
322
412
|
em: false,
|
323
413
|
strong: false,
|
@@ -334,6 +424,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
334
424
|
block: s.block,
|
335
425
|
htmlState: CodeMirror.copyState(htmlMode, s.htmlState),
|
336
426
|
indentation: s.indentation,
|
427
|
+
|
428
|
+
localMode: s.localMode,
|
429
|
+
localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
|
337
430
|
|
338
431
|
inline: s.inline,
|
339
432
|
text: s.text,
|
@@ -362,9 +455,15 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
|
362
455
|
|
363
456
|
// Reset state.header
|
364
457
|
state.header = false;
|
458
|
+
|
459
|
+
// Reset state.code
|
460
|
+
state.code = false;
|
365
461
|
|
366
462
|
state.f = state.block;
|
367
463
|
var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
|
464
|
+
var difference = Math.floor((indentation - state.indentation) / 4) * 4;
|
465
|
+
if (difference > 4) difference = 4;
|
466
|
+
indentation = state.indentation + difference;
|
368
467
|
state.indentationDiff = indentation - state.indentation;
|
369
468
|
state.indentation = indentation;
|
370
469
|
if (indentation > 0) { return null; }
|
@@ -49,6 +49,11 @@ CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, comb
|
|
49
49
|
},
|
50
50
|
electricChars: base.electricChars,
|
51
51
|
|
52
|
-
innerMode: function(state) { return {state: state.base, mode: base}; }
|
52
|
+
innerMode: function(state) { return {state: state.base, mode: base}; },
|
53
|
+
|
54
|
+
blankLine: function(state) {
|
55
|
+
if (base.blankLine) base.blankLine(state.base);
|
56
|
+
if (overlay.blankLine) overlay.blankLine(state.overlay);
|
57
|
+
}
|
53
58
|
};
|
54
59
|
};
|
@@ -1,6 +1,6 @@
|
|
1
1
|
CodeMirror.runMode = function(string, modespec, callback, options) {
|
2
2
|
function esc(str) {
|
3
|
-
return str.replace(/[<&]
|
3
|
+
return str.replace(/[<&]/g, function(ch) { return ch == "<" ? "<" : "&"; });
|
4
4
|
}
|
5
5
|
|
6
6
|
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
|
@@ -17,14 +17,14 @@
|
|
17
17
|
query.lastIndex = 0;
|
18
18
|
var line = cm.getLine(pos.line).slice(0, pos.ch), match = query.exec(line), start = 0;
|
19
19
|
while (match) {
|
20
|
-
start += match.index;
|
21
|
-
|
20
|
+
start += match.index + 1;
|
21
|
+
line = line.slice(start);
|
22
22
|
query.lastIndex = 0;
|
23
23
|
var newmatch = query.exec(line);
|
24
24
|
if (newmatch) match = newmatch;
|
25
25
|
else break;
|
26
|
-
start++;
|
27
26
|
}
|
27
|
+
start--;
|
28
28
|
} else {
|
29
29
|
query.lastIndex = pos.ch;
|
30
30
|
var line = cm.getLine(pos.line), match = query.exec(line),
|
@@ -25,7 +25,10 @@
|
|
25
25
|
editor.replaceRange(str, result.from, result.to);
|
26
26
|
}
|
27
27
|
// When there is only one completion, use it directly.
|
28
|
-
if (completions.length == 1) {
|
28
|
+
if (options.completeSingle && completions.length == 1) {
|
29
|
+
insert(completions[0]);
|
30
|
+
return true;
|
31
|
+
}
|
29
32
|
|
30
33
|
// Build the select widget
|
31
34
|
var complete = document.createElement("div");
|
@@ -41,7 +44,7 @@
|
|
41
44
|
}
|
42
45
|
sel.firstChild.selected = true;
|
43
46
|
sel.size = Math.min(10, completions.length);
|
44
|
-
var pos = editor.cursorCoords();
|
47
|
+
var pos = options.alignWithWord ? editor.charCoords(result.from) : editor.cursorCoords();
|
45
48
|
complete.style.left = pos.x + "px";
|
46
49
|
complete.style.top = pos.yBot + "px";
|
47
50
|
document.body.appendChild(complete);
|
@@ -71,7 +74,7 @@
|
|
71
74
|
if (code == 13) {CodeMirror.e_stop(event); pick();}
|
72
75
|
// Escape
|
73
76
|
else if (code == 27) {CodeMirror.e_stop(event); close(); editor.focus();}
|
74
|
-
else if (code != 38 && code != 40 && code != 33 && code != 34) {
|
77
|
+
else if (code != 38 && code != 40 && code != 33 && code != 34 && !CodeMirror.isModifierKey(event)) {
|
75
78
|
close(); editor.focus();
|
76
79
|
// Pass the event to the CodeMirror instance so that it can handle things like backspace properly.
|
77
80
|
editor.triggerOnKeyDown(event);
|
@@ -92,6 +95,8 @@
|
|
92
95
|
};
|
93
96
|
CodeMirror.simpleHint.defaults = {
|
94
97
|
closeOnBackspace: true,
|
95
|
-
closeOnTokenChange: false
|
98
|
+
closeOnTokenChange: false,
|
99
|
+
completeSingle: true,
|
100
|
+
alignWithWord: true
|
96
101
|
};
|
97
102
|
})();
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: codemirror-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '2.
|
4
|
+
version: '2.35'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-27 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: railties
|
16
|
-
requirement: &
|
16
|
+
requirement: &2165649660 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '3.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2165649660
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rails
|
27
|
-
requirement: &
|
27
|
+
requirement: &2165648920 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '3.0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2165648920
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: sqlite3
|
38
|
-
requirement: &
|
38
|
+
requirement: &2165647960 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2165647960
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: minitest
|
49
|
-
requirement: &
|
49
|
+
requirement: &2165647440 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2165647440
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: capybara
|
60
|
-
requirement: &
|
60
|
+
requirement: &2165647020 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *2165647020
|
69
69
|
description: This gem provides CodeMirror assets for your Rails 3 application.
|
70
70
|
email: nathan@fixler.org
|
71
71
|
executables: []
|