coffeescript.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. (function(mod){if(typeof exports=="object"&&typeof module=="object")
  2. mod(require("../../lib/codemirror"));else if(typeof define=="function"&&define.amd)
  3. define(["../../lib/codemirror"],mod);else
  4. mod(CodeMirror);})(function(CodeMirror){"use strict";CodeMirror.defineMode("coffeescript",function(conf,parserConf){var ERRORCLASS="error";function wordRegexp(words){return new RegExp("^(("+words.join(")|(")+"))\\b");}
  5. var operators=/^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;var delimiters=/^(?:[()\[\]{},:`=;]|\.\.?\.?)/;var identifiers=/^[_A-Za-z$][_A-Za-z$0-9]*/;var atProp=/^@[_A-Za-z$][_A-Za-z$0-9]*/;var wordOperators=wordRegexp(["and","or","not","is","isnt","in","instanceof","typeof"]);var indentKeywords=["for","while","loop","if","unless","else","switch","try","catch","finally","class"];var commonKeywords=["break","by","continue","debugger","delete","do","in","of","new","return","then","this","@","throw","when","until","extends"];var keywords=wordRegexp(indentKeywords.concat(commonKeywords));indentKeywords=wordRegexp(indentKeywords);var stringPrefixes=/^('{3}|\"{3}|['\"])/;var regexPrefixes=/^(\/{3}|\/)/;var commonConstants=["Infinity","NaN","undefined","null","true","false","on","off","yes","no"];var constants=wordRegexp(commonConstants);function tokenBase(stream,state){if(stream.sol()){if(state.scope.align===null)state.scope.align=false;var scopeOffset=state.scope.offset;if(stream.eatSpace()){var lineOffset=stream.indentation();if(lineOffset>scopeOffset&&state.scope.type=="coffee"){return"indent";}else if(lineOffset<scopeOffset){return"dedent";}
  6. return null;}else{if(scopeOffset>0){dedent(stream,state);}}}
  7. if(stream.eatSpace()){return null;}
  8. var ch=stream.peek();if(stream.match("####")){stream.skipToEnd();return"comment";}
  9. if(stream.match("###")){state.tokenize=longComment;return state.tokenize(stream,state);}
  10. if(ch==="#"){stream.skipToEnd();return"comment";}
  11. if(stream.match(/^-?[0-9\.]/,false)){var floatLiteral=false;if(stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)){floatLiteral=true;}
  12. if(stream.match(/^-?\d+\.\d*/)){floatLiteral=true;}
  13. if(stream.match(/^-?\.\d+/)){floatLiteral=true;}
  14. if(floatLiteral){if(stream.peek()=="."){stream.backUp(1);}
  15. return"number";}
  16. var intLiteral=false;if(stream.match(/^-?0x[0-9a-f]+/i)){intLiteral=true;}
  17. if(stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)){intLiteral=true;}
  18. if(stream.match(/^-?0(?![\dx])/i)){intLiteral=true;}
  19. if(intLiteral){return"number";}}
  20. if(stream.match(stringPrefixes)){state.tokenize=tokenFactory(stream.current(),false,"string");return state.tokenize(stream,state);}
  21. if(stream.match(regexPrefixes)){if(stream.current()!="/"||stream.match(/^.*\//,false)){state.tokenize=tokenFactory(stream.current(),true,"string-2");return state.tokenize(stream,state);}else{stream.backUp(1);}}
  22. if(stream.match(operators)||stream.match(wordOperators)){return"operator";}
  23. if(stream.match(delimiters)){return"punctuation";}
  24. if(stream.match(constants)){return"atom";}
  25. if(stream.match(atProp)||state.prop&&stream.match(identifiers)){return"property";}
  26. if(stream.match(keywords)){return"keyword";}
  27. if(stream.match(identifiers)){return"variable";}
  28. stream.next();return ERRORCLASS;}
  29. function tokenFactory(delimiter,singleline,outclass){return function(stream,state){while(!stream.eol()){stream.eatWhile(/[^'"\/\\]/);if(stream.eat("\\")){stream.next();if(singleline&&stream.eol()){return outclass;}}else if(stream.match(delimiter)){state.tokenize=tokenBase;return outclass;}else{stream.eat(/['"\/]/);}}
  30. if(singleline){if(parserConf.singleLineStringErrors){outclass=ERRORCLASS;}else{state.tokenize=tokenBase;}}
  31. return outclass;};}
  32. function longComment(stream,state){while(!stream.eol()){stream.eatWhile(/[^#]/);if(stream.match("###")){state.tokenize=tokenBase;break;}
  33. stream.eatWhile("#");}
  34. return"comment";}
  35. function indent(stream,state,type){type=type||"coffee";var offset=0,align=false,alignOffset=null;for(var scope=state.scope;scope;scope=scope.prev){if(scope.type==="coffee"||scope.type=="}"){offset=scope.offset+conf.indentUnit;break;}}
  36. if(type!=="coffee"){align=null;alignOffset=stream.column()+stream.current().length;}else if(state.scope.align){state.scope.align=false;}
  37. state.scope={offset:offset,type:type,prev:state.scope,align:align,alignOffset:alignOffset};}
  38. function dedent(stream,state){if(!state.scope.prev)return;if(state.scope.type==="coffee"){var _indent=stream.indentation();var matched=false;for(var scope=state.scope;scope;scope=scope.prev){if(_indent===scope.offset){matched=true;break;}}
  39. if(!matched){return true;}
  40. while(state.scope.prev&&state.scope.offset!==_indent){state.scope=state.scope.prev;}
  41. return false;}else{state.scope=state.scope.prev;return false;}}
  42. function tokenLexer(stream,state){var style=state.tokenize(stream,state);var current=stream.current();if(current==="return"){state.dedent=true;}
  43. if(((current==="->"||current==="=>")&&stream.eol())||style==="indent"){indent(stream,state);}
  44. var delimiter_index="[({".indexOf(current);if(delimiter_index!==-1){indent(stream,state,"])}".slice(delimiter_index,delimiter_index+1));}
  45. if(indentKeywords.exec(current)){indent(stream,state);}
  46. if(current=="then"){dedent(stream,state);}
  47. if(style==="dedent"){if(dedent(stream,state)){return ERRORCLASS;}}
  48. delimiter_index="])}".indexOf(current);if(delimiter_index!==-1){while(state.scope.type=="coffee"&&state.scope.prev)
  49. state.scope=state.scope.prev;if(state.scope.type==current)
  50. state.scope=state.scope.prev;}
  51. if(state.dedent&&stream.eol()){if(state.scope.type=="coffee"&&state.scope.prev)
  52. state.scope=state.scope.prev;state.dedent=false;}
  53. return style;}
  54. var external={startState:function(basecolumn){return{tokenize:tokenBase,scope:{offset:basecolumn||0,type:"coffee",prev:null,align:false},prop:false,dedent:0};},token:function(stream,state){var fillAlign=state.scope.align===null&&state.scope;if(fillAlign&&stream.sol())fillAlign.align=false;var style=tokenLexer(stream,state);if(style&&style!="comment"){if(fillAlign)fillAlign.align=true;state.prop=style=="punctuation"&&stream.current()=="."}
  55. return style;},indent:function(state,text){if(state.tokenize!=tokenBase)return 0;var scope=state.scope;var closer=text&&"])}".indexOf(text.charAt(0))>-1;if(closer)while(scope.type=="coffee"&&scope.prev)scope=scope.prev;var closes=closer&&scope.type===text.charAt(0);if(scope.align)
  56. return scope.alignOffset-(closes?1:0);else
  57. return(closes?scope.prev:scope).offset;},lineComment:"#",fold:"indent"};return external;});CodeMirror.defineMIME("application/vnd.coffeescript","coffeescript");CodeMirror.defineMIME("text/x-coffeescript","coffeescript");CodeMirror.defineMIME("text/coffeescript","coffeescript");});