Subversion-Projekte lars-tiefland.ci

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
776 lars 1
// CodeMirror, copyright (c) by Marijn Haverbeke and others
2
// Distributed under an MIT license: http://codemirror.net/LICENSE
3
 
4
(function(mod) {
5
  if (typeof exports == "object" && typeof module == "object") // CommonJS
6
    mod(require("../../lib/codemirror"));
7
  else if (typeof define == "function" && define.amd) // AMD
8
    define(["../../lib/codemirror"], mod);
9
  else // Plain browser env
10
    mod(CodeMirror);
11
})(function(CodeMirror) {
12
"use strict";
13
 
14
CodeMirror.defineMode("r", function(config) {
15
  function wordObj(str) {
16
    var words = str.split(" "), res = {};
17
    for (var i = 0; i < words.length; ++i) res[words[i]] = true;
18
    return res;
19
  }
20
  var atoms = wordObj("NULL NA Inf NaN NA_integer_ NA_real_ NA_complex_ NA_character_");
21
  var builtins = wordObj("list quote bquote eval return call parse deparse");
22
  var keywords = wordObj("if else repeat while function for in next break");
23
  var blockkeywords = wordObj("if else repeat while function for");
24
  var opChars = /[+\-*\/^<>=!&|~$:]/;
25
  var curPunc;
26
 
27
  function tokenBase(stream, state) {
28
    curPunc = null;
29
    var ch = stream.next();
30
    if (ch == "#") {
31
      stream.skipToEnd();
32
      return "comment";
33
    } else if (ch == "0" && stream.eat("x")) {
34
      stream.eatWhile(/[\da-f]/i);
35
      return "number";
36
    } else if (ch == "." && stream.eat(/\d/)) {
37
      stream.match(/\d*(?:e[+\-]?\d+)?/);
38
      return "number";
39
    } else if (/\d/.test(ch)) {
40
      stream.match(/\d*(?:\.\d+)?(?:e[+\-]\d+)?L?/);
41
      return "number";
42
    } else if (ch == "'" || ch == '"') {
43
      state.tokenize = tokenString(ch);
44
      return "string";
45
    } else if (ch == "." && stream.match(/.[.\d]+/)) {
46
      return "keyword";
47
    } else if (/[\w\.]/.test(ch) && ch != "_") {
48
      stream.eatWhile(/[\w\.]/);
49
      var word = stream.current();
50
      if (atoms.propertyIsEnumerable(word)) return "atom";
51
      if (keywords.propertyIsEnumerable(word)) {
52
        // Block keywords start new blocks, except 'else if', which only starts
53
        // one new block for the 'if', no block for the 'else'.
54
        if (blockkeywords.propertyIsEnumerable(word) &&
55
            !stream.match(/\s*if(\s+|$)/, false))
56
          curPunc = "block";
57
        return "keyword";
58
      }
59
      if (builtins.propertyIsEnumerable(word)) return "builtin";
60
      return "variable";
61
    } else if (ch == "%") {
62
      if (stream.skipTo("%")) stream.next();
63
      return "variable-2";
64
    } else if (ch == "<" && stream.eat("-")) {
65
      return "arrow";
66
    } else if (ch == "=" && state.ctx.argList) {
67
      return "arg-is";
68
    } else if (opChars.test(ch)) {
69
      if (ch == "$") return "dollar";
70
      stream.eatWhile(opChars);
71
      return "operator";
72
    } else if (/[\(\){}\[\];]/.test(ch)) {
73
      curPunc = ch;
74
      if (ch == ";") return "semi";
75
      return null;
76
    } else {
77
      return null;
78
    }
79
  }
80
 
81
  function tokenString(quote) {
82
    return function(stream, state) {
83
      if (stream.eat("\\")) {
84
        var ch = stream.next();
85
        if (ch == "x") stream.match(/^[a-f0-9]{2}/i);
86
        else if ((ch == "u" || ch == "U") && stream.eat("{") && stream.skipTo("}")) stream.next();
87
        else if (ch == "u") stream.match(/^[a-f0-9]{4}/i);
88
        else if (ch == "U") stream.match(/^[a-f0-9]{8}/i);
89
        else if (/[0-7]/.test(ch)) stream.match(/^[0-7]{1,2}/);
90
        return "string-2";
91
      } else {
92
        var next;
93
        while ((next = stream.next()) != null) {
94
          if (next == quote) { state.tokenize = tokenBase; break; }
95
          if (next == "\\") { stream.backUp(1); break; }
96
        }
97
        return "string";
98
      }
99
    };
100
  }
101
 
102
  function push(state, type, stream) {
103
    state.ctx = {type: type,
104
                 indent: state.indent,
105
                 align: null,
106
                 column: stream.column(),
107
                 prev: state.ctx};
108
  }
109
  function pop(state) {
110
    state.indent = state.ctx.indent;
111
    state.ctx = state.ctx.prev;
112
  }
113
 
114
  return {
115
    startState: function() {
116
      return {tokenize: tokenBase,
117
              ctx: {type: "top",
118
                    indent: -config.indentUnit,
119
                    align: false},
120
              indent: 0,
121
              afterIdent: false};
122
    },
123
 
124
    token: function(stream, state) {
125
      if (stream.sol()) {
126
        if (state.ctx.align == null) state.ctx.align = false;
127
        state.indent = stream.indentation();
128
      }
129
      if (stream.eatSpace()) return null;
130
      var style = state.tokenize(stream, state);
131
      if (style != "comment" && state.ctx.align == null) state.ctx.align = true;
132
 
133
      var ctype = state.ctx.type;
134
      if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && ctype == "block") pop(state);
135
      if (curPunc == "{") push(state, "}", stream);
136
      else if (curPunc == "(") {
137
        push(state, ")", stream);
138
        if (state.afterIdent) state.ctx.argList = true;
139
      }
140
      else if (curPunc == "[") push(state, "]", stream);
141
      else if (curPunc == "block") push(state, "block", stream);
142
      else if (curPunc == ctype) pop(state);
143
      state.afterIdent = style == "variable" || style == "keyword";
144
      return style;
145
    },
146
 
147
    indent: function(state, textAfter) {
148
      if (state.tokenize != tokenBase) return 0;
149
      var firstChar = textAfter && textAfter.charAt(0), ctx = state.ctx,
150
          closing = firstChar == ctx.type;
151
      if (ctx.type == "block") return ctx.indent + (firstChar == "{" ? 0 : config.indentUnit);
152
      else if (ctx.align) return ctx.column + (closing ? 0 : 1);
153
      else return ctx.indent + (closing ? 0 : config.indentUnit);
154
    },
155
 
156
    lineComment: "#"
157
  };
158
});
159
 
160
CodeMirror.defineMIME("text/x-rsrc", "r");
161
 
162
});