github.com/elliott5/community@v0.14.1-0.20160709191136-823126fb026a/app/public/codemirror/mode/smalltalk/smalltalk.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('smalltalk', function(config) {
    15  
    16    var specialChars = /[+\-\/\\*~<>=@%|&?!.,:;^]/;
    17    var keywords = /true|false|nil|self|super|thisContext/;
    18  
    19    var Context = function(tokenizer, parent) {
    20      this.next = tokenizer;
    21      this.parent = parent;
    22    };
    23  
    24    var Token = function(name, context, eos) {
    25      this.name = name;
    26      this.context = context;
    27      this.eos = eos;
    28    };
    29  
    30    var State = function() {
    31      this.context = new Context(next, null);
    32      this.expectVariable = true;
    33      this.indentation = 0;
    34      this.userIndentationDelta = 0;
    35    };
    36  
    37    State.prototype.userIndent = function(indentation) {
    38      this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0;
    39    };
    40  
    41    var next = function(stream, context, state) {
    42      var token = new Token(null, context, false);
    43      var aChar = stream.next();
    44  
    45      if (aChar === '"') {
    46        token = nextComment(stream, new Context(nextComment, context));
    47  
    48      } else if (aChar === '\'') {
    49        token = nextString(stream, new Context(nextString, context));
    50  
    51      } else if (aChar === '#') {
    52        if (stream.peek() === '\'') {
    53          stream.next();
    54          token = nextSymbol(stream, new Context(nextSymbol, context));
    55        } else {
    56          if (stream.eatWhile(/[^\s.{}\[\]()]/))
    57            token.name = 'string-2';
    58          else
    59            token.name = 'meta';
    60        }
    61  
    62      } else if (aChar === '$') {
    63        if (stream.next() === '<') {
    64          stream.eatWhile(/[^\s>]/);
    65          stream.next();
    66        }
    67        token.name = 'string-2';
    68  
    69      } else if (aChar === '|' && state.expectVariable) {
    70        token.context = new Context(nextTemporaries, context);
    71  
    72      } else if (/[\[\]{}()]/.test(aChar)) {
    73        token.name = 'bracket';
    74        token.eos = /[\[{(]/.test(aChar);
    75  
    76        if (aChar === '[') {
    77          state.indentation++;
    78        } else if (aChar === ']') {
    79          state.indentation = Math.max(0, state.indentation - 1);
    80        }
    81  
    82      } else if (specialChars.test(aChar)) {
    83        stream.eatWhile(specialChars);
    84        token.name = 'operator';
    85        token.eos = aChar !== ';'; // ; cascaded message expression
    86  
    87      } else if (/\d/.test(aChar)) {
    88        stream.eatWhile(/[\w\d]/);
    89        token.name = 'number';
    90  
    91      } else if (/[\w_]/.test(aChar)) {
    92        stream.eatWhile(/[\w\d_]/);
    93        token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null;
    94  
    95      } else {
    96        token.eos = state.expectVariable;
    97      }
    98  
    99      return token;
   100    };
   101  
   102    var nextComment = function(stream, context) {
   103      stream.eatWhile(/[^"]/);
   104      return new Token('comment', stream.eat('"') ? context.parent : context, true);
   105    };
   106  
   107    var nextString = function(stream, context) {
   108      stream.eatWhile(/[^']/);
   109      return new Token('string', stream.eat('\'') ? context.parent : context, false);
   110    };
   111  
   112    var nextSymbol = function(stream, context) {
   113      stream.eatWhile(/[^']/);
   114      return new Token('string-2', stream.eat('\'') ? context.parent : context, false);
   115    };
   116  
   117    var nextTemporaries = function(stream, context) {
   118      var token = new Token(null, context, false);
   119      var aChar = stream.next();
   120  
   121      if (aChar === '|') {
   122        token.context = context.parent;
   123        token.eos = true;
   124  
   125      } else {
   126        stream.eatWhile(/[^|]/);
   127        token.name = 'variable';
   128      }
   129  
   130      return token;
   131    };
   132  
   133    return {
   134      startState: function() {
   135        return new State;
   136      },
   137  
   138      token: function(stream, state) {
   139        state.userIndent(stream.indentation());
   140  
   141        if (stream.eatSpace()) {
   142          return null;
   143        }
   144  
   145        var token = state.context.next(stream, state.context, state);
   146        state.context = token.context;
   147        state.expectVariable = token.eos;
   148  
   149        return token.name;
   150      },
   151  
   152      blankLine: function(state) {
   153        state.userIndent(0);
   154      },
   155  
   156      indent: function(state, textAfter) {
   157        var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta;
   158        return (state.indentation + i) * config.indentUnit;
   159      },
   160  
   161      electricChars: ']'
   162    };
   163  
   164  });
   165  
   166  CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'});
   167  
   168  });