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

     1  // CodeMirror, copyright (c) by Marijn Haverbeke and others
     2  // Distributed under an MIT license: http://codemirror.net/LICENSE
     3  
     4  // By the Neo4j Team and contributors.
     5  // https://github.com/neo4j-contrib/CodeMirror
     6  
     7  (function(mod) {
     8    if (typeof exports == "object" && typeof module == "object") // CommonJS
     9      mod(require("../../lib/codemirror"));
    10    else if (typeof define == "function" && define.amd) // AMD
    11      define(["../../lib/codemirror"], mod);
    12    else // Plain browser env
    13      mod(CodeMirror);
    14  })(function(CodeMirror) {
    15    "use strict";
    16    var wordRegexp = function(words) {
    17      return new RegExp("^(?:" + words.join("|") + ")$", "i");
    18    };
    19  
    20    CodeMirror.defineMode("cypher", function(config) {
    21      var tokenBase = function(stream/*, state*/) {
    22        var ch = stream.next();
    23        if (ch === "\"" || ch === "'") {
    24          stream.match(/.+?["']/);
    25          return "string";
    26        }
    27        if (/[{}\(\),\.;\[\]]/.test(ch)) {
    28          curPunc = ch;
    29          return "node";
    30        } else if (ch === "/" && stream.eat("/")) {
    31          stream.skipToEnd();
    32          return "comment";
    33        } else if (operatorChars.test(ch)) {
    34          stream.eatWhile(operatorChars);
    35          return null;
    36        } else {
    37          stream.eatWhile(/[_\w\d]/);
    38          if (stream.eat(":")) {
    39            stream.eatWhile(/[\w\d_\-]/);
    40            return "atom";
    41          }
    42          var word = stream.current();
    43          if (funcs.test(word)) return "builtin";
    44          if (preds.test(word)) return "def";
    45          if (keywords.test(word)) return "keyword";
    46          return "variable";
    47        }
    48      };
    49      var pushContext = function(state, type, col) {
    50        return state.context = {
    51          prev: state.context,
    52          indent: state.indent,
    53          col: col,
    54          type: type
    55        };
    56      };
    57      var popContext = function(state) {
    58        state.indent = state.context.indent;
    59        return state.context = state.context.prev;
    60      };
    61      var indentUnit = config.indentUnit;
    62      var curPunc;
    63      var funcs = wordRegexp(["abs", "acos", "allShortestPaths", "asin", "atan", "atan2", "avg", "ceil", "coalesce", "collect", "cos", "cot", "count", "degrees", "e", "endnode", "exp", "extract", "filter", "floor", "haversin", "head", "id", "keys", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "reverse", "right", "round", "rtrim", "shortestPath", "sign", "sin", "size", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "toString", "trim", "type", "upper"]);
    64      var preds = wordRegexp(["all", "and", "any", "contains", "exists", "has", "in", "none", "not", "or", "single", "xor"]);
    65      var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "detach", "distinct", "drop", "else", "end", "ends", "explain", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "join", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "profile", "remove", "return", "scan", "set", "skip", "start", "starts", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with"]);
    66      var operatorChars = /[*+\-<>=&|~%^]/;
    67  
    68      return {
    69        startState: function(/*base*/) {
    70          return {
    71            tokenize: tokenBase,
    72            context: null,
    73            indent: 0,
    74            col: 0
    75          };
    76        },
    77        token: function(stream, state) {
    78          if (stream.sol()) {
    79            if (state.context && (state.context.align == null)) {
    80              state.context.align = false;
    81            }
    82            state.indent = stream.indentation();
    83          }
    84          if (stream.eatSpace()) {
    85            return null;
    86          }
    87          var style = state.tokenize(stream, state);
    88          if (style !== "comment" && state.context && (state.context.align == null) && state.context.type !== "pattern") {
    89            state.context.align = true;
    90          }
    91          if (curPunc === "(") {
    92            pushContext(state, ")", stream.column());
    93          } else if (curPunc === "[") {
    94            pushContext(state, "]", stream.column());
    95          } else if (curPunc === "{") {
    96            pushContext(state, "}", stream.column());
    97          } else if (/[\]\}\)]/.test(curPunc)) {
    98            while (state.context && state.context.type === "pattern") {
    99              popContext(state);
   100            }
   101            if (state.context && curPunc === state.context.type) {
   102              popContext(state);
   103            }
   104          } else if (curPunc === "." && state.context && state.context.type === "pattern") {
   105            popContext(state);
   106          } else if (/atom|string|variable/.test(style) && state.context) {
   107            if (/[\}\]]/.test(state.context.type)) {
   108              pushContext(state, "pattern", stream.column());
   109            } else if (state.context.type === "pattern" && !state.context.align) {
   110              state.context.align = true;
   111              state.context.col = stream.column();
   112            }
   113          }
   114          return style;
   115        },
   116        indent: function(state, textAfter) {
   117          var firstChar = textAfter && textAfter.charAt(0);
   118          var context = state.context;
   119          if (/[\]\}]/.test(firstChar)) {
   120            while (context && context.type === "pattern") {
   121              context = context.prev;
   122            }
   123          }
   124          var closing = context && firstChar === context.type;
   125          if (!context) return 0;
   126          if (context.type === "keywords") return CodeMirror.commands.newlineAndIndent;
   127          if (context.align) return context.col + (closing ? 0 : 1);
   128          return context.indent + (closing ? 0 : indentUnit);
   129        }
   130      };
   131    });
   132  
   133    CodeMirror.modeExtensions["cypher"] = {
   134      autoFormatLineBreaks: function(text) {
   135        var i, lines, reProcessedPortion;
   136        var lines = text.split("\n");
   137        var reProcessedPortion = /\s+\b(return|where|order by|match|with|skip|limit|create|delete|set)\b\s/g;
   138        for (var i = 0; i < lines.length; i++)
   139          lines[i] = lines[i].replace(reProcessedPortion, " \n$1 ").trim();
   140        return lines.join("\n");
   141      }
   142    };
   143  
   144    CodeMirror.defineMIME("application/x-cypher-query", "cypher");
   145  
   146  });