livescript.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /**
  2. * Link to the project's GitHub page:
  3. * https://github.com/duralog/CodeMirror
  4. */
  5. (function() {
  6. CodeMirror.defineMode('livescript', function(){
  7. var tokenBase, external;
  8. tokenBase = function(stream, state){
  9. var next_rule, nr, i$, len$, r, m;
  10. if (next_rule = state.next || 'start') {
  11. state.next = state.next;
  12. if (Array.isArray(nr = Rules[next_rule])) {
  13. for (i$ = 0, len$ = nr.length; i$ < len$; ++i$) {
  14. r = nr[i$];
  15. if (r.regex && (m = stream.match(r.regex))) {
  16. state.next = r.next;
  17. return r.token;
  18. }
  19. }
  20. stream.next();
  21. return 'error';
  22. }
  23. if (stream.match(r = Rules[next_rule])) {
  24. if (r.regex && stream.match(r.regex)) {
  25. state.next = r.next;
  26. return r.token;
  27. } else {
  28. stream.next();
  29. return 'error';
  30. }
  31. }
  32. }
  33. stream.next();
  34. return 'error';
  35. };
  36. external = {
  37. startState: function(){
  38. return {
  39. next: 'start',
  40. lastToken: null
  41. };
  42. },
  43. token: function(stream, state){
  44. var style;
  45. style = tokenBase(stream, state);
  46. state.lastToken = {
  47. style: style,
  48. indent: stream.indentation(),
  49. content: stream.current()
  50. };
  51. return style.replace(/\./g, ' ');
  52. },
  53. indent: function(state){
  54. var indentation;
  55. indentation = state.lastToken.indent;
  56. if (state.lastToken.content.match(indenter)) {
  57. indentation += 2;
  58. }
  59. return indentation;
  60. }
  61. };
  62. return external;
  63. });
  64. var identifier = '(?![\\d\\s])[$\\w\\xAA-\\uFFDC](?:(?!\\s)[$\\w\\xAA-\\uFFDC]|-[A-Za-z])*';
  65. var indenter = RegExp('(?:[({[=:]|[-~]>|\\b(?:e(?:lse|xport)|d(?:o|efault)|t(?:ry|hen)|finally|import(?:\\s*all)?|const|var|let|new|catch(?:\\s*' + identifier + ')?))\\s*$');
  66. var keywordend = '(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))';
  67. var stringfill = {
  68. token: 'string',
  69. regex: '.+'
  70. };
  71. var Rules = {
  72. start: [
  73. {
  74. token: 'comment.doc',
  75. regex: '/\\*',
  76. next: 'comment'
  77. }, {
  78. token: 'comment',
  79. regex: '#.*'
  80. }, {
  81. token: 'keyword',
  82. regex: '(?:t(?:h(?:is|row|en)|ry|ypeof!?)|c(?:on(?:tinue|st)|a(?:se|tch)|lass)|i(?:n(?:stanceof)?|mp(?:ort(?:\\s+all)?|lements)|[fs])|d(?:e(?:fault|lete|bugger)|o)|f(?:or(?:\\s+own)?|inally|unction)|s(?:uper|witch)|e(?:lse|x(?:tends|port)|val)|a(?:nd|rguments)|n(?:ew|ot)|un(?:less|til)|w(?:hile|ith)|o[fr]|return|break|let|var|loop)' + keywordend
  83. }, {
  84. token: 'constant.language',
  85. regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend
  86. }, {
  87. token: 'invalid.illegal',
  88. regex: '(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)' + keywordend
  89. }, {
  90. token: 'language.support.class',
  91. regex: '(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)' + keywordend
  92. }, {
  93. token: 'language.support.function',
  94. regex: '(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)' + keywordend
  95. }, {
  96. token: 'variable.language',
  97. regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend
  98. }, {
  99. token: 'identifier',
  100. regex: identifier + '\\s*:(?![:=])'
  101. }, {
  102. token: 'variable',
  103. regex: identifier
  104. }, {
  105. token: 'keyword.operator',
  106. regex: '(?:\\.{3}|\\s+\\?)'
  107. }, {
  108. token: 'keyword.variable',
  109. regex: '(?:@+|::|\\.\\.)',
  110. next: 'key'
  111. }, {
  112. token: 'keyword.operator',
  113. regex: '\\.\\s*',
  114. next: 'key'
  115. }, {
  116. token: 'string',
  117. regex: '\\\\\\S[^\\s,;)}\\]]*'
  118. }, {
  119. token: 'string.doc',
  120. regex: '\'\'\'',
  121. next: 'qdoc'
  122. }, {
  123. token: 'string.doc',
  124. regex: '"""',
  125. next: 'qqdoc'
  126. }, {
  127. token: 'string',
  128. regex: '\'',
  129. next: 'qstring'
  130. }, {
  131. token: 'string',
  132. regex: '"',
  133. next: 'qqstring'
  134. }, {
  135. token: 'string',
  136. regex: '`',
  137. next: 'js'
  138. }, {
  139. token: 'string',
  140. regex: '<\\[',
  141. next: 'words'
  142. }, {
  143. token: 'string.regex',
  144. regex: '//',
  145. next: 'heregex'
  146. }, {
  147. token: 'string.regex',
  148. regex: '\\/(?:[^[\\/\\n\\\\]*(?:(?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[\\/\\n\\\\]*)*)\\/[gimy$]{0,4}',
  149. next: 'key'
  150. }, {
  151. token: 'constant.numeric',
  152. regex: '(?:0x[\\da-fA-F][\\da-fA-F_]*|(?:[2-9]|[12]\\d|3[0-6])r[\\da-zA-Z][\\da-zA-Z_]*|(?:\\d[\\d_]*(?:\\.\\d[\\d_]*)?|\\.\\d[\\d_]*)(?:e[+-]?\\d[\\d_]*)?[\\w$]*)'
  153. }, {
  154. token: 'lparen',
  155. regex: '[({[]'
  156. }, {
  157. token: 'rparen',
  158. regex: '[)}\\]]',
  159. next: 'key'
  160. }, {
  161. token: 'keyword.operator',
  162. regex: '\\S+'
  163. }, {
  164. token: 'text',
  165. regex: '\\s+'
  166. }
  167. ],
  168. heregex: [
  169. {
  170. token: 'string.regex',
  171. regex: '.*?//[gimy$?]{0,4}',
  172. next: 'start'
  173. }, {
  174. token: 'string.regex',
  175. regex: '\\s*#{'
  176. }, {
  177. token: 'comment.regex',
  178. regex: '\\s+(?:#.*)?'
  179. }, {
  180. token: 'string.regex',
  181. regex: '\\S+'
  182. }
  183. ],
  184. key: [
  185. {
  186. token: 'keyword.operator',
  187. regex: '[.?@!]+'
  188. }, {
  189. token: 'identifier',
  190. regex: identifier,
  191. next: 'start'
  192. }, {
  193. token: 'text',
  194. regex: '.',
  195. next: 'start'
  196. }
  197. ],
  198. comment: [
  199. {
  200. token: 'comment.doc',
  201. regex: '.*?\\*/',
  202. next: 'start'
  203. }, {
  204. token: 'comment.doc',
  205. regex: '.+'
  206. }
  207. ],
  208. qdoc: [
  209. {
  210. token: 'string',
  211. regex: ".*?'''",
  212. next: 'key'
  213. }, stringfill
  214. ],
  215. qqdoc: [
  216. {
  217. token: 'string',
  218. regex: '.*?"""',
  219. next: 'key'
  220. }, stringfill
  221. ],
  222. qstring: [
  223. {
  224. token: 'string',
  225. regex: '[^\\\\\']*(?:\\\\.[^\\\\\']*)*\'',
  226. next: 'key'
  227. }, stringfill
  228. ],
  229. qqstring: [
  230. {
  231. token: 'string',
  232. regex: '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',
  233. next: 'key'
  234. }, stringfill
  235. ],
  236. js: [
  237. {
  238. token: 'string',
  239. regex: '[^\\\\`]*(?:\\\\.[^\\\\`]*)*`',
  240. next: 'key'
  241. }, stringfill
  242. ],
  243. words: [
  244. {
  245. token: 'string',
  246. regex: '.*?\\]>',
  247. next: 'key'
  248. }, stringfill
  249. ]
  250. };
  251. for (var idx in Rules) {
  252. var r = Rules[idx];
  253. if (Array.isArray(r)) {
  254. for (var i = 0, len = r.length; i < len; ++i) {
  255. var rr = r[i];
  256. if (rr.regex) {
  257. Rules[idx][i].regex = new RegExp('^' + rr.regex);
  258. }
  259. }
  260. } else if (r.regex) {
  261. Rules[idx].regex = new RegExp('^' + r.regex);
  262. }
  263. }
  264. })();
  265. CodeMirror.defineMIME('text/x-livescript', 'livescript');