0
|
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
2 // Distributed under an MIT license: https://codemirror.net/5/LICENSE
|
|
3
|
|
4 (function(mod) {
|
|
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
6 mod(require("../../lib/codemirror"));
|
|
7 else if (typeof define == "function" && define.amd) // AMD
|
|
8 define(["../../lib/codemirror"], mod);
|
|
9 else // Plain browser env
|
|
10 mod(CodeMirror);
|
|
11 })(function(CodeMirror) {
|
|
12 "use strict";
|
|
13
|
|
14 var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/,
|
|
15 emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/,
|
|
16 unorderedListRE = /[*+-]\s/;
|
|
17
|
|
18 CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
|
|
19 if (cm.getOption("disableInput")) return CodeMirror.Pass;
|
|
20 var ranges = cm.listSelections(), replacements = [];
|
|
21 for (var i = 0; i < ranges.length; i++) {
|
|
22 var pos = ranges[i].head;
|
|
23
|
|
24 // If we're not in Markdown mode, fall back to normal newlineAndIndent
|
|
25 var eolState = cm.getStateAfter(pos.line);
|
|
26 var inner = CodeMirror.innerMode(cm.getMode(), eolState);
|
|
27 if (inner.mode.name !== "markdown" && inner.mode.helperType !== "markdown") {
|
|
28 cm.execCommand("newlineAndIndent");
|
|
29 return;
|
|
30 } else {
|
|
31 eolState = inner.state;
|
|
32 }
|
|
33
|
|
34 var inList = eolState.list !== false;
|
|
35 var inQuote = eolState.quote !== 0;
|
|
36
|
|
37 var line = cm.getLine(pos.line), match = listRE.exec(line);
|
|
38 var cursorBeforeBullet = /^\s*$/.test(line.slice(0, pos.ch));
|
|
39 if (!ranges[i].empty() || (!inList && !inQuote) || !match || cursorBeforeBullet) {
|
|
40 cm.execCommand("newlineAndIndent");
|
|
41 return;
|
|
42 }
|
|
43 if (emptyListRE.test(line)) {
|
|
44 var endOfQuote = inQuote && />\s*$/.test(line)
|
|
45 var endOfList = !/>\s*$/.test(line)
|
|
46 if (endOfQuote || endOfList) cm.replaceRange("", {
|
|
47 line: pos.line, ch: 0
|
|
48 }, {
|
|
49 line: pos.line, ch: pos.ch + 1
|
|
50 });
|
|
51 replacements[i] = "\n";
|
|
52 } else {
|
|
53 var indent = match[1], after = match[5];
|
|
54 var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0);
|
|
55 var bullet = numbered ? (parseInt(match[3], 10) + 1) + match[4] : match[2].replace("x", " ");
|
|
56 replacements[i] = "\n" + indent + bullet + after;
|
|
57
|
|
58 if (numbered) incrementRemainingMarkdownListNumbers(cm, pos);
|
|
59 }
|
|
60 }
|
|
61
|
|
62 cm.replaceSelections(replacements);
|
|
63 };
|
|
64
|
|
65 // Auto-updating Markdown list numbers when a new item is added to the
|
|
66 // middle of a list
|
|
67 function incrementRemainingMarkdownListNumbers(cm, pos) {
|
|
68 var startLine = pos.line, lookAhead = 0, skipCount = 0;
|
|
69 var startItem = listRE.exec(cm.getLine(startLine)), startIndent = startItem[1];
|
|
70
|
|
71 do {
|
|
72 lookAhead += 1;
|
|
73 var nextLineNumber = startLine + lookAhead;
|
|
74 var nextLine = cm.getLine(nextLineNumber), nextItem = listRE.exec(nextLine);
|
|
75
|
|
76 if (nextItem) {
|
|
77 var nextIndent = nextItem[1];
|
|
78 var newNumber = (parseInt(startItem[3], 10) + lookAhead - skipCount);
|
|
79 var nextNumber = (parseInt(nextItem[3], 10)), itemNumber = nextNumber;
|
|
80
|
|
81 if (startIndent === nextIndent && !isNaN(nextNumber)) {
|
|
82 if (newNumber === nextNumber) itemNumber = nextNumber + 1;
|
|
83 if (newNumber > nextNumber) itemNumber = newNumber + 1;
|
|
84 cm.replaceRange(
|
|
85 nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]),
|
|
86 {
|
|
87 line: nextLineNumber, ch: 0
|
|
88 }, {
|
|
89 line: nextLineNumber, ch: nextLine.length
|
|
90 });
|
|
91 } else {
|
|
92 if (startIndent.length > nextIndent.length) return;
|
|
93 // This doesn't run if the next line immediately indents, as it is
|
|
94 // not clear of the users intention (new indented item or same level)
|
|
95 if ((startIndent.length < nextIndent.length) && (lookAhead === 1)) return;
|
|
96 skipCount += 1;
|
|
97 }
|
|
98 }
|
|
99 } while (nextItem);
|
|
100 }
|
|
101 });
|