2020-02-11 17:51:04 +08:00
|
|
|
CodeMirror.extendMode('css', {
|
|
|
|
commentStart: '/*',
|
|
|
|
commentEnd: '*/',
|
|
|
|
newlineAfterToken: function (type, content) {
|
|
|
|
return /^[;{}]$/.test(content)
|
|
|
|
}
|
|
|
|
})
|
2019-12-10 19:16:05 +08:00
|
|
|
|
2020-02-11 17:51:04 +08:00
|
|
|
// Comment/uncomment the specified range
|
|
|
|
CodeMirror.defineExtension('commentRange', function (isComment, from, to) {
|
|
|
|
var cm = this
|
|
|
|
var curMode = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(from).state)
|
|
|
|
.mode
|
|
|
|
cm.operation(function () {
|
|
|
|
if (isComment) {
|
|
|
|
// Comment range
|
|
|
|
cm.replaceRange(curMode.commentEnd, to)
|
|
|
|
cm.replaceRange(curMode.commentStart, from)
|
|
|
|
if (from.line == to.line && from.ch == to.ch) {
|
|
|
|
// An empty comment inserted - put cursor inside
|
|
|
|
cm.setCursor(from.line, from.ch + curMode.commentStart.length)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Uncomment range
|
|
|
|
var selText = cm.getRange(from, to)
|
|
|
|
var startIndex = selText.indexOf(curMode.commentStart)
|
|
|
|
var endIndex = selText.lastIndexOf(curMode.commentEnd)
|
|
|
|
if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {
|
|
|
|
// Take string till comment start
|
|
|
|
selText =
|
|
|
|
selText.substr(0, startIndex) +
|
2019-12-10 19:16:05 +08:00
|
|
|
// From comment start till comment end
|
2020-02-11 17:51:04 +08:00
|
|
|
selText.substring(
|
|
|
|
startIndex + curMode.commentStart.length,
|
|
|
|
endIndex
|
|
|
|
) +
|
2019-12-10 19:16:05 +08:00
|
|
|
// From comment end till string end
|
2020-02-11 17:51:04 +08:00
|
|
|
selText.substr(endIndex + curMode.commentEnd.length)
|
|
|
|
}
|
|
|
|
cm.replaceRange(selText, from, to)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
// Applies automatic mode-aware indentation to the specified range
|
|
|
|
CodeMirror.defineExtension('autoIndentRange', function (from, to) {
|
|
|
|
var cmInstance = this
|
|
|
|
this.operation(function () {
|
|
|
|
for (var i = from.line; i <= to.line; i++) {
|
|
|
|
cmInstance.indentLine(i, 'smart')
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
// Applies automatic formatting to the specified range
|
|
|
|
CodeMirror.defineExtension('autoFormatRange', function (from, to) {
|
|
|
|
var cm = this
|
|
|
|
var outer = cm.getMode()
|
|
|
|
var text = cm.getRange(from, to).split('\n')
|
|
|
|
var state = CodeMirror.copyState(outer, cm.getTokenAt(from).state)
|
|
|
|
var tabSize = cm.getOption('tabSize')
|
|
|
|
|
|
|
|
var out = ''
|
|
|
|
var lines = 0
|
|
|
|
var atSol = from.ch == 0
|
|
|
|
function newline () {
|
|
|
|
out += '\n'
|
|
|
|
atSol = true
|
|
|
|
++lines
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < text.length; ++i) {
|
|
|
|
var stream = new CodeMirror.StringStream(text[i], tabSize)
|
|
|
|
while (!stream.eol()) {
|
|
|
|
var inner = CodeMirror.innerMode(outer, state)
|
|
|
|
var style = outer.token(stream, state)
|
|
|
|
var cur = stream.current()
|
|
|
|
stream.start = stream.pos
|
|
|
|
if (!atSol || /\S/.test(cur)) {
|
|
|
|
out += cur
|
|
|
|
atSol = false
|
2019-12-10 19:16:05 +08:00
|
|
|
}
|
2020-02-11 17:51:04 +08:00
|
|
|
if (
|
|
|
|
!atSol &&
|
|
|
|
inner.mode.newlineAfterToken &&
|
|
|
|
inner.mode.newlineAfterToken(
|
|
|
|
style,
|
|
|
|
cur,
|
|
|
|
stream.string.slice(stream.pos) || text[i + 1] || '',
|
|
|
|
inner.state
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
newline()
|
2019-12-10 19:16:05 +08:00
|
|
|
}
|
2020-02-11 17:51:04 +08:00
|
|
|
}
|
|
|
|
if (!stream.pos && outer.blankLine) outer.blankLine(state)
|
|
|
|
if (!atSol) newline()
|
|
|
|
}
|
|
|
|
|
|
|
|
cm.operation(function () {
|
|
|
|
cm.replaceRange(out, from, to)
|
|
|
|
for (
|
|
|
|
var cur = from.line + 1, end = from.line + lines;
|
|
|
|
cur <= end;
|
|
|
|
++cur
|
|
|
|
) {
|
|
|
|
cm.indentLine(cur, 'smart')
|
|
|
|
}
|
|
|
|
cm.setSelection(from, cm.getCursor(false))
|
|
|
|
})
|
|
|
|
})
|