github.com/elliott5/community@v0.14.1-0.20160709191136-823126fb026a/app/public/codemirror/mode/d/d.js (about)

     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("d", function(config, parserConfig) {
    15    var indentUnit = config.indentUnit,
    16        statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
    17        keywords = parserConfig.keywords || {},
    18        builtin = parserConfig.builtin || {},
    19        blockKeywords = parserConfig.blockKeywords || {},
    20        atoms = parserConfig.atoms || {},
    21        hooks = parserConfig.hooks || {},
    22        multiLineStrings = parserConfig.multiLineStrings;
    23    var isOperatorChar = /[+\-*&%=<>!?|\/]/;
    24  
    25    var curPunc;
    26  
    27    function tokenBase(stream, state) {
    28      var ch = stream.next();
    29      if (hooks[ch]) {
    30        var result = hooks[ch](stream, state);
    31        if (result !== false) return result;
    32      }
    33      if (ch == '"' || ch == "'" || ch == "`") {
    34        state.tokenize = tokenString(ch);
    35        return state.tokenize(stream, state);
    36      }
    37      if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
    38        curPunc = ch;
    39        return null;
    40      }
    41      if (/\d/.test(ch)) {
    42        stream.eatWhile(/[\w\.]/);
    43        return "number";
    44      }
    45      if (ch == "/") {
    46        if (stream.eat("+")) {
    47          state.tokenize = tokenComment;
    48          return tokenNestedComment(stream, state);
    49        }
    50        if (stream.eat("*")) {
    51          state.tokenize = tokenComment;
    52          return tokenComment(stream, state);
    53        }
    54        if (stream.eat("/")) {
    55          stream.skipToEnd();
    56          return "comment";
    57        }
    58      }
    59      if (isOperatorChar.test(ch)) {
    60        stream.eatWhile(isOperatorChar);
    61        return "operator";
    62      }
    63      stream.eatWhile(/[\w\$_\xa1-\uffff]/);
    64      var cur = stream.current();
    65      if (keywords.propertyIsEnumerable(cur)) {
    66        if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
    67        return "keyword";
    68      }
    69      if (builtin.propertyIsEnumerable(cur)) {
    70        if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
    71        return "builtin";
    72      }
    73      if (atoms.propertyIsEnumerable(cur)) return "atom";
    74      return "variable";
    75    }
    76  
    77    function tokenString(quote) {
    78      return function(stream, state) {
    79        var escaped = false, next, end = false;
    80        while ((next = stream.next()) != null) {
    81          if (next == quote && !escaped) {end = true; break;}
    82          escaped = !escaped && next == "\\";
    83        }
    84        if (end || !(escaped || multiLineStrings))
    85          state.tokenize = null;
    86        return "string";
    87      };
    88    }
    89  
    90    function tokenComment(stream, state) {
    91      var maybeEnd = false, ch;
    92      while (ch = stream.next()) {
    93        if (ch == "/" && maybeEnd) {
    94          state.tokenize = null;
    95          break;
    96        }
    97        maybeEnd = (ch == "*");
    98      }
    99      return "comment";
   100    }
   101  
   102    function tokenNestedComment(stream, state) {
   103      var maybeEnd = false, ch;
   104      while (ch = stream.next()) {
   105        if (ch == "/" && maybeEnd) {
   106          state.tokenize = null;
   107          break;
   108        }
   109        maybeEnd = (ch == "+");
   110      }
   111      return "comment";
   112    }
   113  
   114    function Context(indented, column, type, align, prev) {
   115      this.indented = indented;
   116      this.column = column;
   117      this.type = type;
   118      this.align = align;
   119      this.prev = prev;
   120    }
   121    function pushContext(state, col, type) {
   122      var indent = state.indented;
   123      if (state.context && state.context.type == "statement")
   124        indent = state.context.indented;
   125      return state.context = new Context(indent, col, type, null, state.context);
   126    }
   127    function popContext(state) {
   128      var t = state.context.type;
   129      if (t == ")" || t == "]" || t == "}")
   130        state.indented = state.context.indented;
   131      return state.context = state.context.prev;
   132    }
   133  
   134    // Interface
   135  
   136    return {
   137      startState: function(basecolumn) {
   138        return {
   139          tokenize: null,
   140          context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
   141          indented: 0,
   142          startOfLine: true
   143        };
   144      },
   145  
   146      token: function(stream, state) {
   147        var ctx = state.context;
   148        if (stream.sol()) {
   149          if (ctx.align == null) ctx.align = false;
   150          state.indented = stream.indentation();
   151          state.startOfLine = true;
   152        }
   153        if (stream.eatSpace()) return null;
   154        curPunc = null;
   155        var style = (state.tokenize || tokenBase)(stream, state);
   156        if (style == "comment" || style == "meta") return style;
   157        if (ctx.align == null) ctx.align = true;
   158  
   159        if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
   160        else if (curPunc == "{") pushContext(state, stream.column(), "}");
   161        else if (curPunc == "[") pushContext(state, stream.column(), "]");
   162        else if (curPunc == "(") pushContext(state, stream.column(), ")");
   163        else if (curPunc == "}") {
   164          while (ctx.type == "statement") ctx = popContext(state);
   165          if (ctx.type == "}") ctx = popContext(state);
   166          while (ctx.type == "statement") ctx = popContext(state);
   167        }
   168        else if (curPunc == ctx.type) popContext(state);
   169        else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement"))
   170          pushContext(state, stream.column(), "statement");
   171        state.startOfLine = false;
   172        return style;
   173      },
   174  
   175      indent: function(state, textAfter) {
   176        if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
   177        var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
   178        if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
   179        var closing = firstChar == ctx.type;
   180        if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
   181        else if (ctx.align) return ctx.column + (closing ? 0 : 1);
   182        else return ctx.indented + (closing ? 0 : indentUnit);
   183      },
   184  
   185      electricChars: "{}"
   186    };
   187  });
   188  
   189    function words(str) {
   190      var obj = {}, words = str.split(" ");
   191      for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
   192      return obj;
   193    }
   194  
   195    var blockKeywords = "body catch class do else enum for foreach foreach_reverse if in interface mixin " +
   196                        "out scope struct switch try union unittest version while with";
   197  
   198    CodeMirror.defineMIME("text/x-d", {
   199      name: "d",
   200      keywords: words("abstract alias align asm assert auto break case cast cdouble cent cfloat const continue " +
   201                      "debug default delegate delete deprecated export extern final finally function goto immutable " +
   202                      "import inout invariant is lazy macro module new nothrow override package pragma private " +
   203                      "protected public pure ref return shared short static super synchronized template this " +
   204                      "throw typedef typeid typeof volatile __FILE__ __LINE__ __gshared __traits __vector __parameters " +
   205                      blockKeywords),
   206      blockKeywords: words(blockKeywords),
   207      builtin: words("bool byte char creal dchar double float idouble ifloat int ireal long real short ubyte " +
   208                     "ucent uint ulong ushort wchar wstring void size_t sizediff_t"),
   209      atoms: words("exit failure success true false null"),
   210      hooks: {
   211        "@": function(stream, _state) {
   212          stream.eatWhile(/[\w\$_]/);
   213          return "meta";
   214        }
   215      }
   216    });
   217  
   218  });