123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- // 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 noOptions = {}
- var nonWS = /[^\s\u00a0]/
- var Pos = CodeMirror.Pos,
- cmp = CodeMirror.cmpPos
- function firstNonWS(str) {
- var found = str.search(nonWS)
- return found == -1 ? 0 : found
- }
- CodeMirror.commands.toggleComment = function (cm) {
- cm.toggleComment()
- }
- CodeMirror.defineExtension('toggleComment', function (options) {
- if (!options) options = noOptions
- var cm = this
- var minLine = Infinity,
- ranges = this.listSelections(),
- mode = null
- for (var i = ranges.length - 1; i >= 0; i--) {
- var from = ranges[i].from(),
- to = ranges[i].to()
- if (from.line >= minLine) continue
- if (to.line >= minLine) to = Pos(minLine, 0)
- minLine = from.line
- if (mode == null) {
- if (cm.uncomment(from, to, options)) mode = 'un'
- else {
- cm.lineComment(from, to, options)
- mode = 'line'
- }
- } else if (mode == 'un') {
- cm.uncomment(from, to, options)
- } else {
- cm.lineComment(from, to, options)
- }
- }
- })
- // Rough heuristic to try and detect lines that are part of multi-line string
- function probablyInsideString(cm, pos, line) {
- return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"\`]/.test(line)
- }
- function getMode(cm, pos) {
- var mode = cm.getMode()
- return mode.useInnerComments === false || !mode.innerMode ? mode : cm.getModeAt(pos)
- }
- CodeMirror.defineExtension('lineComment', function (from, to, options) {
- if (!options) options = noOptions
- var self = this,
- mode = getMode(self, from)
- var firstLine = self.getLine(from.line)
- if (firstLine == null || probablyInsideString(self, from, firstLine)) return
- var commentString = options.lineComment || mode.lineComment
- if (!commentString) {
- if (options.blockCommentStart || mode.blockCommentStart) {
- options.fullLines = true
- self.blockComment(from, to, options)
- }
- return
- }
- var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1)
- var pad = options.padding == null ? ' ' : options.padding
- var blankLines = options.commentBlankLines || from.line == to.line
- self.operation(function () {
- if (options.indent) {
- var baseString = null
- for (var i = from.line; i < end; ++i) {
- var line = self.getLine(i)
- var whitespace = line.slice(0, firstNonWS(line))
- if (baseString == null || baseString.length > whitespace.length) {
- baseString = whitespace
- }
- }
- for (var i = from.line; i < end; ++i) {
- var line = self.getLine(i),
- cut = baseString.length
- if (!blankLines && !nonWS.test(line)) continue
- if (line.slice(0, cut) != baseString) cut = firstNonWS(line)
- self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut))
- }
- } else {
- for (var i = from.line; i < end; ++i) {
- if (blankLines || nonWS.test(self.getLine(i))) self.replaceRange(commentString + pad, Pos(i, 0))
- }
- }
- })
- })
- CodeMirror.defineExtension('blockComment', function (from, to, options) {
- if (!options) options = noOptions
- var self = this,
- mode = getMode(self, from)
- var startString = options.blockCommentStart || mode.blockCommentStart
- var endString = options.blockCommentEnd || mode.blockCommentEnd
- if (!startString || !endString) {
- if ((options.lineComment || mode.lineComment) && options.fullLines != false) self.lineComment(from, to, options)
- return
- }
- if (/\bcomment\b/.test(self.getTokenTypeAt(Pos(from.line, 0)))) return
- var end = Math.min(to.line, self.lastLine())
- if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end
- var pad = options.padding == null ? ' ' : options.padding
- if (from.line > end) return
- self.operation(function () {
- if (options.fullLines != false) {
- var lastLineHasText = nonWS.test(self.getLine(end))
- self.replaceRange(pad + endString, Pos(end))
- self.replaceRange(startString + pad, Pos(from.line, 0))
- var lead = options.blockCommentLead || mode.blockCommentLead
- if (lead != null) for (var i = from.line + 1; i <= end; ++i) if (i != end || lastLineHasText) self.replaceRange(lead + pad, Pos(i, 0))
- } else {
- var atCursor = cmp(self.getCursor('to'), to) == 0,
- empty = !self.somethingSelected()
- self.replaceRange(endString, to)
- if (atCursor) self.setSelection(empty ? to : self.getCursor('from'), to)
- self.replaceRange(startString, from)
- }
- })
- })
- CodeMirror.defineExtension('uncomment', function (from, to, options) {
- if (!options) options = noOptions
- var self = this,
- mode = getMode(self, from)
- var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()),
- start = Math.min(from.line, end)
- // Try finding line comments
- var lineString = options.lineComment || mode.lineComment,
- lines = []
- var pad = options.padding == null ? ' ' : options.padding,
- didSomething
- lineComment: {
- if (!lineString) break lineComment
- for (var i = start; i <= end; ++i) {
- var line = self.getLine(i)
- var found = line.indexOf(lineString)
- if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1
- if (found == -1 && nonWS.test(line)) break lineComment
- if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment
- lines.push(line)
- }
- self.operation(function () {
- for (var i = start; i <= end; ++i) {
- var line = lines[i - start]
- var pos = line.indexOf(lineString),
- endPos = pos + lineString.length
- if (pos < 0) continue
- if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length
- didSomething = true
- self.replaceRange('', Pos(i, pos), Pos(i, endPos))
- }
- })
- if (didSomething) return true
- }
- // Try block comments
- var startString = options.blockCommentStart || mode.blockCommentStart
- var endString = options.blockCommentEnd || mode.blockCommentEnd
- if (!startString || !endString) return false
- var lead = options.blockCommentLead || mode.blockCommentLead
- var startLine = self.getLine(start),
- open = startLine.indexOf(startString)
- if (open == -1) return false
- var endLine = end == start ? startLine : self.getLine(end)
- var close = endLine.indexOf(endString, end == start ? open + startString.length : 0)
- var insideStart = Pos(start, open + 1),
- insideEnd = Pos(end, close + 1)
- if (close == -1 || !/comment/.test(self.getTokenTypeAt(insideStart)) || !/comment/.test(self.getTokenTypeAt(insideEnd)) || self.getRange(insideStart, insideEnd, '\n').indexOf(endString) > -1)
- return false
- // Avoid killing block comments completely outside the selection.
- // Positions of the last startString before the start of the selection, and the first endString after it.
- var lastStart = startLine.lastIndexOf(startString, from.ch)
- var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length)
- if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false
- // Positions of the first endString after the end of the selection, and the last startString before it.
- firstEnd = endLine.indexOf(endString, to.ch)
- var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch)
- lastStart = firstEnd == -1 || almostLastStart == -1 ? -1 : to.ch + almostLastStart
- if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false
- self.operation(function () {
- self.replaceRange('', Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)), Pos(end, close + endString.length))
- var openEnd = open + startString.length
- if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length
- self.replaceRange('', Pos(start, open), Pos(start, openEnd))
- if (lead)
- for (var i = start + 1; i <= end; ++i) {
- var line = self.getLine(i),
- found = line.indexOf(lead)
- if (found == -1 || nonWS.test(line.slice(0, found))) continue
- var foundEnd = found + lead.length
- if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length
- self.replaceRange('', Pos(i, found), Pos(i, foundEnd))
- }
- })
- return true
- })
- })
|