123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- // 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.registerHelper('wordChars', 'r', /[\w.]/)
- CodeMirror.defineMode('r', function (config) {
- function wordObj(words) {
- var res = {}
- for (var i = 0; i < words.length; ++i) res[words[i]] = true
- return res
- }
- var commonAtoms = ['NULL', 'NA', 'Inf', 'NaN', 'NA_integer_', 'NA_real_', 'NA_complex_', 'NA_character_', 'TRUE', 'FALSE']
- var commonBuiltins = ['list', 'quote', 'bquote', 'eval', 'return', 'call', 'parse', 'deparse']
- var commonKeywords = ['if', 'else', 'repeat', 'while', 'function', 'for', 'in', 'next', 'break']
- var commonBlockKeywords = ['if', 'else', 'repeat', 'while', 'function', 'for']
- CodeMirror.registerHelper('hintWords', 'r', commonAtoms.concat(commonBuiltins, commonKeywords))
- var atoms = wordObj(commonAtoms)
- var builtins = wordObj(commonBuiltins)
- var keywords = wordObj(commonKeywords)
- var blockkeywords = wordObj(commonBlockKeywords)
- var opChars = /[+\-*\/^<>=!&|~$:]/
- var curPunc
- function tokenBase(stream, state) {
- curPunc = null
- var ch = stream.next()
- if (ch == '#') {
- stream.skipToEnd()
- return 'comment'
- } else if (ch == '0' && stream.eat('x')) {
- stream.eatWhile(/[\da-f]/i)
- return 'number'
- } else if (ch == '.' && stream.eat(/\d/)) {
- stream.match(/\d*(?:e[+\-]?\d+)?/)
- return 'number'
- } else if (/\d/.test(ch)) {
- stream.match(/\d*(?:\.\d+)?(?:e[+\-]\d+)?L?/)
- return 'number'
- } else if (ch == "'" || ch == '"') {
- state.tokenize = tokenString(ch)
- return 'string'
- } else if (ch == '`') {
- stream.match(/[^`]+`/)
- return 'variable-3'
- } else if (ch == '.' && stream.match(/.(?:[.]|\d+)/)) {
- return 'keyword'
- } else if (/[a-zA-Z\.]/.test(ch)) {
- stream.eatWhile(/[\w\.]/)
- var word = stream.current()
- if (atoms.propertyIsEnumerable(word)) return 'atom'
- if (keywords.propertyIsEnumerable(word)) {
- // Block keywords start new blocks, except 'else if', which only starts
- // one new block for the 'if', no block for the 'else'.
- if (blockkeywords.propertyIsEnumerable(word) && !stream.match(/\s*if(\s+|$)/, false)) curPunc = 'block'
- return 'keyword'
- }
- if (builtins.propertyIsEnumerable(word)) return 'builtin'
- return 'variable'
- } else if (ch == '%') {
- if (stream.skipTo('%')) stream.next()
- return 'operator variable-2'
- } else if ((ch == '<' && stream.eat('-')) || (ch == '<' && stream.match('<-')) || (ch == '-' && stream.match(/>>?/))) {
- return 'operator arrow'
- } else if (ch == '=' && state.ctx.argList) {
- return 'arg-is'
- } else if (opChars.test(ch)) {
- if (ch == '$') return 'operator dollar'
- stream.eatWhile(opChars)
- return 'operator'
- } else if (/[\(\){}\[\];]/.test(ch)) {
- curPunc = ch
- if (ch == ';') return 'semi'
- return null
- } else {
- return null
- }
- }
- function tokenString(quote) {
- return function (stream, state) {
- if (stream.eat('\\')) {
- var ch = stream.next()
- if (ch == 'x') stream.match(/^[a-f0-9]{2}/i)
- else if ((ch == 'u' || ch == 'U') && stream.eat('{') && stream.skipTo('}')) stream.next()
- else if (ch == 'u') stream.match(/^[a-f0-9]{4}/i)
- else if (ch == 'U') stream.match(/^[a-f0-9]{8}/i)
- else if (/[0-7]/.test(ch)) stream.match(/^[0-7]{1,2}/)
- return 'string-2'
- } else {
- var next
- while ((next = stream.next()) != null) {
- if (next == quote) {
- state.tokenize = tokenBase
- break
- }
- if (next == '\\') {
- stream.backUp(1)
- break
- }
- }
- return 'string'
- }
- }
- }
- var ALIGN_YES = 1,
- ALIGN_NO = 2,
- BRACELESS = 4
- function push(state, type, stream) {
- state.ctx = { type: type, indent: state.indent, flags: 0, column: stream.column(), prev: state.ctx }
- }
- function setFlag(state, flag) {
- var ctx = state.ctx
- state.ctx = { type: ctx.type, indent: ctx.indent, flags: ctx.flags | flag, column: ctx.column, prev: ctx.prev }
- }
- function pop(state) {
- state.indent = state.ctx.indent
- state.ctx = state.ctx.prev
- }
- return {
- startState: function () {
- return { tokenize: tokenBase, ctx: { type: 'top', indent: -config.indentUnit, flags: ALIGN_NO }, indent: 0, afterIdent: false }
- },
- token: function (stream, state) {
- if (stream.sol()) {
- if ((state.ctx.flags & 3) == 0) state.ctx.flags |= ALIGN_NO
- if (state.ctx.flags & BRACELESS) pop(state)
- state.indent = stream.indentation()
- }
- if (stream.eatSpace()) return null
- var style = state.tokenize(stream, state)
- if (style != 'comment' && (state.ctx.flags & ALIGN_NO) == 0) setFlag(state, ALIGN_YES)
- if ((curPunc == ';' || curPunc == '{' || curPunc == '}') && state.ctx.type == 'block') pop(state)
- if (curPunc == '{') push(state, '}', stream)
- else if (curPunc == '(') {
- push(state, ')', stream)
- if (state.afterIdent) state.ctx.argList = true
- } else if (curPunc == '[') push(state, ']', stream)
- else if (curPunc == 'block') push(state, 'block', stream)
- else if (curPunc == state.ctx.type) pop(state)
- else if (state.ctx.type == 'block' && style != 'comment') setFlag(state, BRACELESS)
- state.afterIdent = style == 'variable' || style == 'keyword'
- return style
- },
- indent: function (state, textAfter) {
- if (state.tokenize != tokenBase) return 0
- var firstChar = textAfter && textAfter.charAt(0),
- ctx = state.ctx,
- closing = firstChar == ctx.type
- if (ctx.flags & BRACELESS) ctx = ctx.prev
- if (ctx.type == 'block') return ctx.indent + (firstChar == '{' ? 0 : config.indentUnit)
- else if (ctx.flags & ALIGN_YES) return ctx.column + (closing ? 0 : 1)
- else return ctx.indent + (closing ? 0 : config.indentUnit)
- },
- lineComment: '#',
- }
- })
- CodeMirror.defineMIME('text/x-rsrc', 'r')
- })
|