livescript.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. /**
  4. * Link to the project's GitHub page:
  5. * https://github.com/duralog/CodeMirror
  6. */
  7. ;(function (mod) {
  8. if (typeof exports == 'object' && typeof module == 'object')
  9. // CommonJS
  10. mod(require('../../lib/codemirror'))
  11. else if (typeof define == 'function' && define.amd)
  12. // AMD
  13. define(['../../lib/codemirror'], mod)
  14. // Plain browser env
  15. else mod(CodeMirror)
  16. })(function (CodeMirror) {
  17. 'use strict'
  18. CodeMirror.defineMode('livescript', function () {
  19. var tokenBase = function (stream, state) {
  20. var next_rule = state.next || 'start'
  21. if (next_rule) {
  22. state.next = state.next
  23. var nr = Rules[next_rule]
  24. if (nr.splice) {
  25. for (var i$ = 0; i$ < nr.length; ++i$) {
  26. var r = nr[i$]
  27. if (r.regex && stream.match(r.regex)) {
  28. state.next = r.next || state.next
  29. return r.token
  30. }
  31. }
  32. stream.next()
  33. return 'error'
  34. }
  35. if (stream.match((r = Rules[next_rule]))) {
  36. if (r.regex && stream.match(r.regex)) {
  37. state.next = r.next
  38. return r.token
  39. } else {
  40. stream.next()
  41. return 'error'
  42. }
  43. }
  44. }
  45. stream.next()
  46. return 'error'
  47. }
  48. var external = {
  49. startState: function () {
  50. return {
  51. next: 'start',
  52. lastToken: { style: null, indent: 0, content: '' },
  53. }
  54. },
  55. token: function (stream, state) {
  56. while (stream.pos == stream.start) var style = tokenBase(stream, state)
  57. state.lastToken = {
  58. style: style,
  59. indent: stream.indentation(),
  60. content: stream.current(),
  61. }
  62. return style.replace(/\./g, ' ')
  63. },
  64. indent: function (state) {
  65. var indentation = state.lastToken.indent
  66. if (state.lastToken.content.match(indenter)) {
  67. indentation += 2
  68. }
  69. return indentation
  70. },
  71. }
  72. return external
  73. })
  74. var identifier = '(?![\\d\\s])[$\\w\\xAA-\\uFFDC](?:(?!\\s)[$\\w\\xAA-\\uFFDC]|-[A-Za-z])*'
  75. 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*$')
  76. var keywordend = '(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))'
  77. var stringfill = {
  78. token: 'string',
  79. regex: '.+',
  80. }
  81. var Rules = {
  82. start: [
  83. {
  84. token: 'comment.doc',
  85. regex: '/\\*',
  86. next: 'comment',
  87. },
  88. {
  89. token: 'comment',
  90. regex: '#.*',
  91. },
  92. {
  93. token: 'keyword',
  94. regex:
  95. '(?: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)' +
  96. keywordend,
  97. },
  98. {
  99. token: 'constant.language',
  100. regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend,
  101. },
  102. {
  103. token: 'invalid.illegal',
  104. regex: '(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)' + keywordend,
  105. },
  106. {
  107. token: 'language.support.class',
  108. regex: '(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)' + keywordend,
  109. },
  110. {
  111. token: 'language.support.function',
  112. regex: '(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)' + keywordend,
  113. },
  114. {
  115. token: 'variable.language',
  116. regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend,
  117. },
  118. {
  119. token: 'identifier',
  120. regex: identifier + '\\s*:(?![:=])',
  121. },
  122. {
  123. token: 'variable',
  124. regex: identifier,
  125. },
  126. {
  127. token: 'keyword.operator',
  128. regex: '(?:\\.{3}|\\s+\\?)',
  129. },
  130. {
  131. token: 'keyword.variable',
  132. regex: '(?:@+|::|\\.\\.)',
  133. next: 'key',
  134. },
  135. {
  136. token: 'keyword.operator',
  137. regex: '\\.\\s*',
  138. next: 'key',
  139. },
  140. {
  141. token: 'string',
  142. regex: '\\\\\\S[^\\s,;)}\\]]*',
  143. },
  144. {
  145. token: 'string.doc',
  146. regex: "'''",
  147. next: 'qdoc',
  148. },
  149. {
  150. token: 'string.doc',
  151. regex: '"""',
  152. next: 'qqdoc',
  153. },
  154. {
  155. token: 'string',
  156. regex: "'",
  157. next: 'qstring',
  158. },
  159. {
  160. token: 'string',
  161. regex: '"',
  162. next: 'qqstring',
  163. },
  164. {
  165. token: 'string',
  166. regex: '`',
  167. next: 'js',
  168. },
  169. {
  170. token: 'string',
  171. regex: '<\\[',
  172. next: 'words',
  173. },
  174. {
  175. token: 'string.regex',
  176. regex: '//',
  177. next: 'heregex',
  178. },
  179. {
  180. token: 'string.regex',
  181. regex: '\\/(?:[^[\\/\\n\\\\]*(?:(?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[\\/\\n\\\\]*)*)\\/[gimy$]{0,4}',
  182. next: 'key',
  183. },
  184. {
  185. token: 'constant.numeric',
  186. 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$]*)',
  187. },
  188. {
  189. token: 'lparen',
  190. regex: '[({[]',
  191. },
  192. {
  193. token: 'rparen',
  194. regex: '[)}\\]]',
  195. next: 'key',
  196. },
  197. {
  198. token: 'keyword.operator',
  199. regex: '\\S+',
  200. },
  201. {
  202. token: 'text',
  203. regex: '\\s+',
  204. },
  205. ],
  206. heregex: [
  207. {
  208. token: 'string.regex',
  209. regex: '.*?//[gimy$?]{0,4}',
  210. next: 'start',
  211. },
  212. {
  213. token: 'string.regex',
  214. regex: '\\s*#{',
  215. },
  216. {
  217. token: 'comment.regex',
  218. regex: '\\s+(?:#.*)?',
  219. },
  220. {
  221. token: 'string.regex',
  222. regex: '\\S+',
  223. },
  224. ],
  225. key: [
  226. {
  227. token: 'keyword.operator',
  228. regex: '[.?@!]+',
  229. },
  230. {
  231. token: 'identifier',
  232. regex: identifier,
  233. next: 'start',
  234. },
  235. {
  236. token: 'text',
  237. regex: '',
  238. next: 'start',
  239. },
  240. ],
  241. comment: [
  242. {
  243. token: 'comment.doc',
  244. regex: '.*?\\*/',
  245. next: 'start',
  246. },
  247. {
  248. token: 'comment.doc',
  249. regex: '.+',
  250. },
  251. ],
  252. qdoc: [
  253. {
  254. token: 'string',
  255. regex: ".*?'''",
  256. next: 'key',
  257. },
  258. stringfill,
  259. ],
  260. qqdoc: [
  261. {
  262. token: 'string',
  263. regex: '.*?"""',
  264. next: 'key',
  265. },
  266. stringfill,
  267. ],
  268. qstring: [
  269. {
  270. token: 'string',
  271. regex: "[^\\\\']*(?:\\\\.[^\\\\']*)*'",
  272. next: 'key',
  273. },
  274. stringfill,
  275. ],
  276. qqstring: [
  277. {
  278. token: 'string',
  279. regex: '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',
  280. next: 'key',
  281. },
  282. stringfill,
  283. ],
  284. js: [
  285. {
  286. token: 'string',
  287. regex: '[^\\\\`]*(?:\\\\.[^\\\\`]*)*`',
  288. next: 'key',
  289. },
  290. stringfill,
  291. ],
  292. words: [
  293. {
  294. token: 'string',
  295. regex: '.*?\\]>',
  296. next: 'key',
  297. },
  298. stringfill,
  299. ],
  300. }
  301. for (var idx in Rules) {
  302. var r = Rules[idx]
  303. if (r.splice) {
  304. for (var i = 0, len = r.length; i < len; ++i) {
  305. var rr = r[i]
  306. if (typeof rr.regex === 'string') {
  307. Rules[idx][i].regex = new RegExp('^' + rr.regex)
  308. }
  309. }
  310. } else if (typeof rr.regex === 'string') {
  311. Rules[idx].regex = new RegExp('^' + r.regex)
  312. }
  313. }
  314. CodeMirror.defineMIME('text/x-livescript', 'livescript')
  315. })