6ec65010d232a04e28167b08c4854a7b4f394d5b
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: https://codemirror.net/LICENSE
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
11 })(function(CodeMirror
) {
14 var listRE
= /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/,
15 emptyListRE
= /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/,
16 unorderedListRE
= /[*+-]\s/;
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
;
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") {
28 cm
.execCommand("newlineAndIndent");
31 eolState
= inner
.state
;
34 var inList
= eolState
.list
!== false;
35 var inQuote
= eolState
.quote
!== 0;
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");
43 if (emptyListRE
.test(line
)) {
44 var endOfQuote
= inQuote
&& />\s*$/.test(line
)
45 var endOfList
= !/>\s*$/.test(line
)
46 if (endOfQuote
|| endOfList
) cm
.replaceRange("", {
49 line
: pos
.line
, ch
: pos
.ch
+ 1
51 replacements
[i
] = "\n";
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
;
58 if (numbered
) incrementRemainingMarkdownListNumbers(cm
, pos
);
62 cm
.replaceSelections(replacements
);
65 // Auto-updating Markdown list numbers when a new item is added to the
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];
73 var nextLineNumber
= startLine
+ lookAhead
;
74 var nextLine
= cm
.getLine(nextLineNumber
), nextItem
= listRE
.exec(nextLine
);
77 var nextIndent
= nextItem
[1];
78 var newNumber
= (parseInt(startItem
[3], 10) + lookAhead
- skipCount
);
79 var nextNumber
= (parseInt(nextItem
[3], 10)), itemNumber
= nextNumber
;
81 if (startIndent
=== nextIndent
&& !isNaN(nextNumber
)) {
82 if (newNumber
=== nextNumber
) itemNumber
= nextNumber
+ 1;
83 if (newNumber
> nextNumber
) itemNumber
= newNumber
+ 1;
85 nextLine
.replace(listRE
, nextIndent
+ itemNumber
+ nextItem
[4] + nextItem
[5]),
87 line
: nextLineNumber
, ch
: 0
89 line
: nextLineNumber
, ch
: nextLine
.length
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;