// 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' CodeMirror.defineMode('commonlisp', function (config) { var specialForm = /^(block|let*|return-from|catch|load-time-value|setq|eval-when|locally|symbol-macrolet|flet|macrolet|tagbody|function|multiple-value-call|the|go|multiple-value-prog1|throw|if|progn|unwind-protect|labels|progv|let|quote)$/ var assumeBody = /^with|^def|^do|^prog|case$|^cond$|bind$|when$|unless$/ var numLiteral = /^(?:[+\-]?(?:\d+|\d*\.\d+)(?:[efd][+\-]?\d+)?|[+\-]?\d+(?:\/[+\-]?\d+)?|#b[+\-]?[01]+|#o[+\-]?[0-7]+|#x[+\-]?[\da-f]+)/ var symbol = /[^\s'`,@()\[\]";]/ var type function readSym(stream) { var ch while ((ch = stream.next())) { if (ch == '\\') stream.next() else if (!symbol.test(ch)) { stream.backUp(1) break } } return stream.current() } function base(stream, state) { if (stream.eatSpace()) { type = 'ws' return null } if (stream.match(numLiteral)) return 'number' var ch = stream.next() if (ch == '\\') ch = stream.next() if (ch == '"') return (state.tokenize = inString)(stream, state) else if (ch == '(') { type = 'open' return 'bracket' } else if (ch == ')' || ch == ']') { type = 'close' return 'bracket' } else if (ch == ';') { stream.skipToEnd() type = 'ws' return 'comment' } else if (/['`,@]/.test(ch)) return null else if (ch == '|') { if (stream.skipTo('|')) { stream.next() return 'symbol' } else { stream.skipToEnd() return 'error' } } else if (ch == '#') { var ch = stream.next() if (ch == '(') { type = 'open' return 'bracket' } else if (/[+\-=\.']/.test(ch)) return null else if (/\d/.test(ch) && stream.match(/^\d*#/)) return null else if (ch == '|') return (state.tokenize = inComment)(stream, state) else if (ch == ':') { readSym(stream) return 'meta' } else if (ch == '\\') { stream.next() readSym(stream) return 'string-2' } else return 'error' } else { var name = readSym(stream) if (name == '.') return null type = 'symbol' if (name == 'nil' || name == 't' || name.charAt(0) == ':') return 'atom' if (state.lastType == 'open' && (specialForm.test(name) || assumeBody.test(name))) return 'keyword' if (name.charAt(0) == '&') return 'variable-2' return 'variable' } } function inString(stream, state) { var escaped = false, next while ((next = stream.next())) { if (next == '"' && !escaped) { state.tokenize = base break } escaped = !escaped && next == '\\' } return 'string' } function inComment(stream, state) { var next, last while ((next = stream.next())) { if (next == '#' && last == '|') { state.tokenize = base break } last = next } type = 'ws' return 'comment' } return { startState: function () { return { ctx: { prev: null, start: 0, indentTo: 0 }, lastType: null, tokenize: base } }, token: function (stream, state) { if (stream.sol() && typeof state.ctx.indentTo != 'number') state.ctx.indentTo = state.ctx.start + 1 type = null var style = state.tokenize(stream, state) if (type != 'ws') { if (state.ctx.indentTo == null) { if (type == 'symbol' && assumeBody.test(stream.current())) state.ctx.indentTo = state.ctx.start + config.indentUnit else state.ctx.indentTo = 'next' } else if (state.ctx.indentTo == 'next') { state.ctx.indentTo = stream.column() } state.lastType = type } if (type == 'open') state.ctx = { prev: state.ctx, start: stream.column(), indentTo: null } else if (type == 'close') state.ctx = state.ctx.prev || state.ctx return style }, indent: function (state, _textAfter) { var i = state.ctx.indentTo return typeof i == 'number' ? i : state.ctx.start + 1 }, closeBrackets: { pairs: '()[]{}""' }, lineComment: ';;', fold: 'brace-paren', blockCommentStart: '#|', blockCommentEnd: '|#', } }) CodeMirror.defineMIME('text/x-common-lisp', 'commonlisp') })