123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- // 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) {
- var defaults = {
- pairs: '()[]{}\'\'""',
- closeBefore: ')]}\'":;>',
- triples: '',
- explode: '[]{}',
- }
- var Pos = CodeMirror.Pos
- CodeMirror.defineOption('autoCloseBrackets', false, function (cm, val, old) {
- if (old && old != CodeMirror.Init) {
- cm.removeKeyMap(keyMap)
- cm.state.closeBrackets = null
- }
- if (val) {
- ensureBound(getOption(val, 'pairs'))
- cm.state.closeBrackets = val
- cm.addKeyMap(keyMap)
- }
- })
- function getOption(conf, name) {
- if (name == 'pairs' && typeof conf == 'string') return conf
- if (typeof conf == 'object' && conf[name] != null) return conf[name]
- return defaults[name]
- }
- var keyMap = { Backspace: handleBackspace, Enter: handleEnter }
- function ensureBound(chars) {
- for (var i = 0; i < chars.length; i++) {
- var ch = chars.charAt(i),
- key = "'" + ch + "'"
- if (!keyMap[key]) keyMap[key] = handler(ch)
- }
- }
- ensureBound(defaults.pairs + '`')
- function handler(ch) {
- return function (cm) {
- return handleChar(cm, ch)
- }
- }
- function getConfig(cm) {
- var deflt = cm.state.closeBrackets
- if (!deflt || deflt.override) return deflt
- var mode = cm.getModeAt(cm.getCursor())
- return mode.closeBrackets || deflt
- }
- function handleBackspace(cm) {
- var conf = getConfig(cm)
- if (!conf || cm.getOption('disableInput')) return CodeMirror.Pass
- var pairs = getOption(conf, 'pairs')
- var ranges = cm.listSelections()
- for (var i = 0; i < ranges.length; i++) {
- if (!ranges[i].empty()) return CodeMirror.Pass
- var around = charsAround(cm, ranges[i].head)
- if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass
- }
- for (var i = ranges.length - 1; i >= 0; i--) {
- var cur = ranges[i].head
- cm.replaceRange('', Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), '+delete')
- }
- }
- function handleEnter(cm) {
- var conf = getConfig(cm)
- var explode = conf && getOption(conf, 'explode')
- if (!explode || cm.getOption('disableInput')) return CodeMirror.Pass
- var ranges = cm.listSelections()
- for (var i = 0; i < ranges.length; i++) {
- if (!ranges[i].empty()) return CodeMirror.Pass
- var around = charsAround(cm, ranges[i].head)
- if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass
- }
- cm.operation(function () {
- var linesep = cm.lineSeparator() || '\n'
- cm.replaceSelection(linesep + linesep, null)
- moveSel(cm, -1)
- ranges = cm.listSelections()
- for (var i = 0; i < ranges.length; i++) {
- var line = ranges[i].head.line
- cm.indentLine(line, null, true)
- cm.indentLine(line + 1, null, true)
- }
- })
- }
- function moveSel(cm, dir) {
- var newRanges = [],
- ranges = cm.listSelections(),
- primary = 0
- for (var i = 0; i < ranges.length; i++) {
- var range = ranges[i]
- if (range.head == cm.getCursor()) primary = i
- var pos = range.head.ch || dir > 0 ? { line: range.head.line, ch: range.head.ch + dir } : { line: range.head.line - 1 }
- newRanges.push({ anchor: pos, head: pos })
- }
- cm.setSelections(newRanges, primary)
- }
- function contractSelection(sel) {
- var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0
- return { anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)), head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1)) }
- }
- function handleChar(cm, ch) {
- var conf = getConfig(cm)
- if (!conf || cm.getOption('disableInput')) return CodeMirror.Pass
- var pairs = getOption(conf, 'pairs')
- var pos = pairs.indexOf(ch)
- if (pos == -1) return CodeMirror.Pass
- var closeBefore = getOption(conf, 'closeBefore')
- var triples = getOption(conf, 'triples')
- var identical = pairs.charAt(pos + 1) == ch
- var ranges = cm.listSelections()
- var opening = pos % 2 == 0
- var type
- for (var i = 0; i < ranges.length; i++) {
- var range = ranges[i],
- cur = range.head,
- curType
- var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1))
- if (opening && !range.empty()) {
- curType = 'surround'
- } else if ((identical || !opening) && next == ch) {
- if (identical && stringStartsAfter(cm, cur)) curType = 'both'
- else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch) curType = 'skipThree'
- else curType = 'skip'
- } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) {
- if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass
- curType = 'addFour'
- } else if (identical) {
- var prev = cur.ch == 0 ? ' ' : cm.getRange(Pos(cur.line, cur.ch - 1), cur)
- if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = 'both'
- else return CodeMirror.Pass
- } else if (opening && (next.length === 0 || /\s/.test(next) || closeBefore.indexOf(next) > -1)) {
- curType = 'both'
- } else {
- return CodeMirror.Pass
- }
- if (!type) type = curType
- else if (type != curType) return CodeMirror.Pass
- }
- var left = pos % 2 ? pairs.charAt(pos - 1) : ch
- var right = pos % 2 ? ch : pairs.charAt(pos + 1)
- cm.operation(function () {
- if (type == 'skip') {
- moveSel(cm, 1)
- } else if (type == 'skipThree') {
- moveSel(cm, 3)
- } else if (type == 'surround') {
- var sels = cm.getSelections()
- for (var i = 0; i < sels.length; i++) sels[i] = left + sels[i] + right
- cm.replaceSelections(sels, 'around')
- sels = cm.listSelections().slice()
- for (var i = 0; i < sels.length; i++) sels[i] = contractSelection(sels[i])
- cm.setSelections(sels)
- } else if (type == 'both') {
- cm.replaceSelection(left + right, null)
- cm.triggerElectric(left + right)
- moveSel(cm, -1)
- } else if (type == 'addFour') {
- cm.replaceSelection(left + left + left + left, 'before')
- moveSel(cm, 1)
- }
- })
- }
- function charsAround(cm, pos) {
- var str = cm.getRange(Pos(pos.line, pos.ch - 1), Pos(pos.line, pos.ch + 1))
- return str.length == 2 ? str : null
- }
- function stringStartsAfter(cm, pos) {
- var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
- return /\bstring/.test(token.type) && token.start == pos.ch && (pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos)))
- }
- })
|