Advertisement
Ford

Code Mirror: tcl mode

Feb 23rd, 2013
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //tcl mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara
  2. CodeMirror.defineMode("tcl", function() {
  3.   function parseWords(str) {
  4.     var obj = {}, words = str.split(" ");
  5.     for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
  6.     return obj;
  7.   }
  8.   var keywords = parseWords("Tcl safe after append array auto_execok auto_import auto_load " +
  9.     "auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror " +
  10.     "binary break catch cd close concat continue dde eof encoding error " +
  11.     "eval exec exit expr fblocked fconfigure fcopy file fileevent filename " +
  12.     "filename flush for foreach format gets glob global history http if " +
  13.     "incr info interp join lappend lindex linsert list llength load lrange " +
  14.     "lreplace lsearch lset lsort memory msgcat namespace open package parray " +
  15.     "pid pkg::create pkg_mkIndex proc puts pwd re_syntax read regex regexp " +
  16.     "registry regsub rename resource return scan seek set socket source split " +
  17.     "string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord " +
  18.     "tcl_wordBreakAfter tcl_startOfPreviousWord tcl_wordBreakBefore tcltest " +
  19.     "tclvars tell time trace unknown unset update uplevel upvar variable " +
  20.     "vwait");
  21.     var functions = parseWords("if elseif else and not or eq ne in ni for foreach while switch");
  22.     var isOperatorChar = /[+\-*&%=<>!?:^\/\|]/;
  23.     function chain(stream, state, f) {
  24.       state.tokenize = f;
  25.       return f(stream, state);
  26.     }
  27.     function tokenBase(stream, state) {
  28.       var beforeParams = state.beforeParams;
  29.       state.beforeParams = false;
  30.       var ch = stream.next();
  31.       if ((ch == '"' || ch == "'") && state.inParams)
  32.         return chain(stream, state, tokenString(ch));
  33.       else if (/[\[\]{}\(\),;\.]/.test(ch)) {
  34.         if (ch == "(" && beforeParams) state.inParams = true;
  35.         else if (ch == ")") state.inParams = false;
  36.           return null;
  37.       }
  38.       else if (/\d/.test(ch)) {
  39.         stream.eatWhile(/[\w\.]/);
  40.         return "number";
  41.       }
  42.       else if (ch == "#" && stream.eat("*")) {
  43.         return chain(stream, state, tokenComment);
  44.       }
  45.       else if (ch == "#" && stream.match(/ *\[ *\[/)) {
  46.         return chain(stream, state, tokenUnparsed);
  47.       }
  48.       else if (ch == "#" && stream.eat("#")) {
  49.         stream.skipToEnd();
  50.         return "comment";
  51.       }
  52.       else if (ch == '"') {
  53.         stream.skipTo(/"/)
  54.         return "comment";
  55.       }
  56.       else if (ch == "$") {
  57.         stream.eatWhile(/[$_a-z0-9A-Z\.{:]/);
  58.         stream.eatWhile(/}/)
  59.         state.beforeParams = true;     
  60.         return "builtin";
  61.       }
  62.       else if (isOperatorChar.test(ch)) {
  63.         stream.eatWhile(isOperatorChar);
  64.         return "comment";
  65.       }
  66.       else {
  67.         stream.eatWhile(/[\w\$_{}]/);
  68.         var word = stream.current().toLowerCase();
  69.         if (keywords && keywords.propertyIsEnumerable(word))
  70.           return "keyword";
  71.         if (functions && functions.propertyIsEnumerable(word) || stream.current().match(/^#[a-z0-9_]+ *$/i) && stream.peek()=="(") {
  72.           state.beforeParams = true;
  73.           return "keyword";
  74.         }
  75.         return null;
  76.       }
  77.     }
  78.     function tokenString(quote) {
  79.       return function(stream, state) {
  80.       var escaped = false, next, end = false;
  81.       while ((next = stream.next()) != null) {
  82.         if (next == quote && !escaped) {
  83.           end = true;
  84.           break;
  85.         }
  86.         escaped = !escaped && next == "\\";
  87.       }
  88.       if (end) state.tokenize = tokenBase;
  89.         return "string";
  90.       };
  91.     }
  92.     function tokenComment(stream, state) {
  93.       var maybeEnd = false, ch;
  94.       while (ch = stream.next()) {
  95.         if (ch == "#" && maybeEnd) {
  96.           state.tokenize = tokenBase;
  97.           break;
  98.         }
  99.         maybeEnd = (ch == "*");
  100.       }
  101.       return "comment";
  102.     }
  103.     function tokenUnparsed(stream, state) {
  104.       var maybeEnd = 0, ch;
  105.       while (ch = stream.next()) {
  106.         if (ch == "#" && maybeEnd == 2) {
  107.           state.tokenize = tokenBase;
  108.           break;
  109.         }
  110.         if (ch == "]")
  111.           maybeEnd++;
  112.         else if (ch != " ")
  113.           maybeEnd = 0;
  114.       }
  115.       return "meta";
  116.     }
  117.     return {
  118.       startState: function() {
  119.         return {
  120.           tokenize: tokenBase,
  121.           beforeParams: false,
  122.           inParams: false
  123.         };
  124.       },
  125.       token: function(stream, state) {
  126.         if (stream.eatSpace()) return null;
  127.         return state.tokenize(stream, state);
  128.       }
  129.     };
  130. });
  131. CodeMirror.defineMIME("text/tcl", "tcl");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement