123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- // CodeMirror, copyright (c) by Marijn Haverbeke and others
- // Distributed under an MIT license: https://codemirror.net/LICENSE
- ;(function (mod) {
- if (typeof exports == 'object' && typeof module == 'object')
- // CommonJS
- mod(require('../../lib/codemirror'))
- else if (typeof define == 'function' && define.amd)
- // AMD
- define(['../../lib/codemirror'], mod)
- // Plain browser env
- else mod(CodeMirror)
- })(function (CodeMirror) {
- 'use strict'
- var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/,
- emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/,
- unorderedListRE = /[*+-]\s/
- CodeMirror.commands.newlineAndIndentContinueMarkdownList = function (cm) {
- if (cm.getOption('disableInput')) return CodeMirror.Pass
- var ranges = cm.listSelections(),
- replacements = []
- for (var i = 0; i < ranges.length; i++) {
- var pos = ranges[i].head
- // If we're not in Markdown mode, fall back to normal newlineAndIndent
- var eolState = cm.getStateAfter(pos.line)
- var inner = CodeMirror.innerMode(cm.getMode(), eolState)
- if (inner.mode.name !== 'markdown' && inner.mode.helperType !== 'markdown') {
- cm.execCommand('newlineAndIndent')
- return
- } else {
- eolState = inner.state
- }
- var inList = eolState.list !== false
- var inQuote = eolState.quote !== 0
- var line = cm.getLine(pos.line),
- match = listRE.exec(line)
- var cursorBeforeBullet = /^\s*$/.test(line.slice(0, pos.ch))
- if (!ranges[i].empty() || (!inList && !inQuote) || !match || cursorBeforeBullet) {
- cm.execCommand('newlineAndIndent')
- return
- }
- if (emptyListRE.test(line)) {
- var endOfQuote = inQuote && />\s*$/.test(line)
- var endOfList = !/>\s*$/.test(line)
- if (endOfQuote || endOfList)
- cm.replaceRange(
- '',
- {
- line: pos.line,
- ch: 0,
- },
- {
- line: pos.line,
- ch: pos.ch + 1,
- }
- )
- replacements[i] = '\n'
- } else {
- var indent = match[1],
- after = match[5]
- var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf('>') >= 0)
- var bullet = numbered ? parseInt(match[3], 10) + 1 + match[4] : match[2].replace('x', ' ')
- replacements[i] = '\n' + indent + bullet + after
- if (numbered) incrementRemainingMarkdownListNumbers(cm, pos)
- }
- }
- cm.replaceSelections(replacements)
- }
- // Auto-updating Markdown list numbers when a new item is added to the
- // middle of a list
- function incrementRemainingMarkdownListNumbers(cm, pos) {
- var startLine = pos.line,
- lookAhead = 0,
- skipCount = 0
- var startItem = listRE.exec(cm.getLine(startLine)),
- startIndent = startItem[1]
- do {
- lookAhead += 1
- var nextLineNumber = startLine + lookAhead
- var nextLine = cm.getLine(nextLineNumber),
- nextItem = listRE.exec(nextLine)
- if (nextItem) {
- var nextIndent = nextItem[1]
- var newNumber = parseInt(startItem[3], 10) + lookAhead - skipCount
- var nextNumber = parseInt(nextItem[3], 10),
- itemNumber = nextNumber
- if (startIndent === nextIndent && !isNaN(nextNumber)) {
- if (newNumber === nextNumber) itemNumber = nextNumber + 1
- if (newNumber > nextNumber) itemNumber = newNumber + 1
- cm.replaceRange(
- nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]),
- {
- line: nextLineNumber,
- ch: 0,
- },
- {
- line: nextLineNumber,
- ch: nextLine.length,
- }
- )
- } else {
- if (startIndent.length > nextIndent.length) return
- // This doesn't run if the next line immediately indents, as it is
- // not clear of the users intention (new indented item or same level)
- if (startIndent.length < nextIndent.length && lookAhead === 1) return
- skipCount += 1
- }
- }
- } while (nextItem)
- }
- })
|