md/public/libs/scripts/codemirror/format.js
2020-02-11 17:51:04 +08:00

112 lines
3.2 KiB
JavaScript

CodeMirror.extendMode('css', {
commentStart: '/*',
commentEnd: '*/',
newlineAfterToken: function (type, content) {
return /^[;{}]$/.test(content)
}
})
// 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) +
// From comment start till comment end
selText.substring(
startIndex + curMode.commentStart.length,
endIndex
) +
// From comment end till string end
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
}
if (
!atSol &&
inner.mode.newlineAfterToken &&
inner.mode.newlineAfterToken(
style,
cur,
stream.string.slice(stream.pos) || text[i + 1] || '',
inner.state
)
) {
newline()
}
}
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))
})
})