ruby.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /*!-----------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Version: 0.31.1(337587859b1c171314b40503171188b6cea6a32a)
  4. * Released under the MIT license
  5. * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
  6. *-----------------------------------------------------------------------------*/
  7. // src/basic-languages/ruby/ruby.ts
  8. var conf = {
  9. comments: {
  10. lineComment: "#",
  11. blockComment: ["=begin", "=end"]
  12. },
  13. brackets: [
  14. ["(", ")"],
  15. ["{", "}"],
  16. ["[", "]"]
  17. ],
  18. autoClosingPairs: [
  19. { open: "{", close: "}" },
  20. { open: "[", close: "]" },
  21. { open: "(", close: ")" },
  22. { open: '"', close: '"' },
  23. { open: "'", close: "'" }
  24. ],
  25. surroundingPairs: [
  26. { open: "{", close: "}" },
  27. { open: "[", close: "]" },
  28. { open: "(", close: ")" },
  29. { open: '"', close: '"' },
  30. { open: "'", close: "'" }
  31. ],
  32. indentationRules: {
  33. increaseIndentPattern: new RegExp(`^\\s*((begin|class|(private|protected)\\s+def|def|else|elsif|ensure|for|if|module|rescue|unless|until|when|while|case)|([^#]*\\sdo\\b)|([^#]*=\\s*(case|if|unless)))\\b([^#\\{;]|("|'|/).*\\4)*(#.*)?$`),
  34. decreaseIndentPattern: new RegExp("^\\s*([}\\]]([,)]?\\s*(#|$)|\\.[a-zA-Z_]\\w*\\b)|(end|rescue|ensure|else|elsif|when)\\b)")
  35. }
  36. };
  37. var language = {
  38. tokenPostfix: ".ruby",
  39. keywords: [
  40. "__LINE__",
  41. "__ENCODING__",
  42. "__FILE__",
  43. "BEGIN",
  44. "END",
  45. "alias",
  46. "and",
  47. "begin",
  48. "break",
  49. "case",
  50. "class",
  51. "def",
  52. "defined?",
  53. "do",
  54. "else",
  55. "elsif",
  56. "end",
  57. "ensure",
  58. "for",
  59. "false",
  60. "if",
  61. "in",
  62. "module",
  63. "next",
  64. "nil",
  65. "not",
  66. "or",
  67. "redo",
  68. "rescue",
  69. "retry",
  70. "return",
  71. "self",
  72. "super",
  73. "then",
  74. "true",
  75. "undef",
  76. "unless",
  77. "until",
  78. "when",
  79. "while",
  80. "yield"
  81. ],
  82. keywordops: ["::", "..", "...", "?", ":", "=>"],
  83. builtins: [
  84. "require",
  85. "public",
  86. "private",
  87. "include",
  88. "extend",
  89. "attr_reader",
  90. "protected",
  91. "private_class_method",
  92. "protected_class_method",
  93. "new"
  94. ],
  95. declarations: [
  96. "module",
  97. "class",
  98. "def",
  99. "case",
  100. "do",
  101. "begin",
  102. "for",
  103. "if",
  104. "while",
  105. "until",
  106. "unless"
  107. ],
  108. linedecls: ["def", "case", "do", "begin", "for", "if", "while", "until", "unless"],
  109. operators: [
  110. "^",
  111. "&",
  112. "|",
  113. "<=>",
  114. "==",
  115. "===",
  116. "!~",
  117. "=~",
  118. ">",
  119. ">=",
  120. "<",
  121. "<=",
  122. "<<",
  123. ">>",
  124. "+",
  125. "-",
  126. "*",
  127. "/",
  128. "%",
  129. "**",
  130. "~",
  131. "+@",
  132. "-@",
  133. "[]",
  134. "[]=",
  135. "`",
  136. "+=",
  137. "-=",
  138. "*=",
  139. "**=",
  140. "/=",
  141. "^=",
  142. "%=",
  143. "<<=",
  144. ">>=",
  145. "&=",
  146. "&&=",
  147. "||=",
  148. "|="
  149. ],
  150. brackets: [
  151. { open: "(", close: ")", token: "delimiter.parenthesis" },
  152. { open: "{", close: "}", token: "delimiter.curly" },
  153. { open: "[", close: "]", token: "delimiter.square" }
  154. ],
  155. symbols: /[=><!~?:&|+\-*\/\^%\.]+/,
  156. escape: /(?:[abefnrstv\\"'\n\r]|[0-7]{1,3}|x[0-9A-Fa-f]{1,2}|u[0-9A-Fa-f]{4})/,
  157. escapes: /\\(?:C\-(@escape|.)|c(@escape|.)|@escape)/,
  158. decpart: /\d(_?\d)*/,
  159. decimal: /0|@decpart/,
  160. delim: /[^a-zA-Z0-9\s\n\r]/,
  161. heredelim: /(?:\w+|'[^']*'|"[^"]*"|`[^`]*`)/,
  162. regexpctl: /[(){}\[\]\$\^|\-*+?\.]/,
  163. regexpesc: /\\(?:[AzZbBdDfnrstvwWn0\\\/]|@regexpctl|c[A-Z]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})?/,
  164. tokenizer: {
  165. root: [
  166. [
  167. /^(\s*)([a-z_]\w*[!?=]?)/,
  168. [
  169. "white",
  170. {
  171. cases: {
  172. "for|until|while": {
  173. token: "keyword.$2",
  174. next: "@dodecl.$2"
  175. },
  176. "@declarations": {
  177. token: "keyword.$2",
  178. next: "@root.$2"
  179. },
  180. end: { token: "keyword.$S2", next: "@pop" },
  181. "@keywords": "keyword",
  182. "@builtins": "predefined",
  183. "@default": "identifier"
  184. }
  185. }
  186. ]
  187. ],
  188. [
  189. /[a-z_]\w*[!?=]?/,
  190. {
  191. cases: {
  192. "if|unless|while|until": {
  193. token: "keyword.$0x",
  194. next: "@modifier.$0x"
  195. },
  196. for: { token: "keyword.$2", next: "@dodecl.$2" },
  197. "@linedecls": { token: "keyword.$0", next: "@root.$0" },
  198. end: { token: "keyword.$S2", next: "@pop" },
  199. "@keywords": "keyword",
  200. "@builtins": "predefined",
  201. "@default": "identifier"
  202. }
  203. }
  204. ],
  205. [/[A-Z][\w]*[!?=]?/, "constructor.identifier"],
  206. [/\$[\w]*/, "global.constant"],
  207. [/@[\w]*/, "namespace.instance.identifier"],
  208. [/@@@[\w]*/, "namespace.class.identifier"],
  209. [/<<[-~](@heredelim).*/, { token: "string.heredoc.delimiter", next: "@heredoc.$1" }],
  210. [/[ \t\r\n]+<<(@heredelim).*/, { token: "string.heredoc.delimiter", next: "@heredoc.$1" }],
  211. [/^<<(@heredelim).*/, { token: "string.heredoc.delimiter", next: "@heredoc.$1" }],
  212. { include: "@whitespace" },
  213. [/"/, { token: "string.d.delim", next: '@dstring.d."' }],
  214. [/'/, { token: "string.sq.delim", next: "@sstring.sq" }],
  215. [/%([rsqxwW]|Q?)/, { token: "@rematch", next: "pstring" }],
  216. [/`/, { token: "string.x.delim", next: "@dstring.x.`" }],
  217. [/:(\w|[$@])\w*[!?=]?/, "string.s"],
  218. [/:"/, { token: "string.s.delim", next: '@dstring.s."' }],
  219. [/:'/, { token: "string.s.delim", next: "@sstring.s" }],
  220. [/\/(?=(\\\/|[^\/\n])+\/)/, { token: "regexp.delim", next: "@regexp" }],
  221. [/[{}()\[\]]/, "@brackets"],
  222. [
  223. /@symbols/,
  224. {
  225. cases: {
  226. "@keywordops": "keyword",
  227. "@operators": "operator",
  228. "@default": ""
  229. }
  230. }
  231. ],
  232. [/[;,]/, "delimiter"],
  233. [/0[xX][0-9a-fA-F](_?[0-9a-fA-F])*/, "number.hex"],
  234. [/0[_oO][0-7](_?[0-7])*/, "number.octal"],
  235. [/0[bB][01](_?[01])*/, "number.binary"],
  236. [/0[dD]@decpart/, "number"],
  237. [
  238. /@decimal((\.@decpart)?([eE][\-+]?@decpart)?)/,
  239. {
  240. cases: {
  241. $1: "number.float",
  242. "@default": "number"
  243. }
  244. }
  245. ]
  246. ],
  247. dodecl: [
  248. [/^/, { token: "", switchTo: "@root.$S2" }],
  249. [
  250. /[a-z_]\w*[!?=]?/,
  251. {
  252. cases: {
  253. end: { token: "keyword.$S2", next: "@pop" },
  254. do: { token: "keyword", switchTo: "@root.$S2" },
  255. "@linedecls": {
  256. token: "@rematch",
  257. switchTo: "@root.$S2"
  258. },
  259. "@keywords": "keyword",
  260. "@builtins": "predefined",
  261. "@default": "identifier"
  262. }
  263. }
  264. ],
  265. { include: "@root" }
  266. ],
  267. modifier: [
  268. [/^/, "", "@pop"],
  269. [
  270. /[a-z_]\w*[!?=]?/,
  271. {
  272. cases: {
  273. end: { token: "keyword.$S2", next: "@pop" },
  274. "then|else|elsif|do": {
  275. token: "keyword",
  276. switchTo: "@root.$S2"
  277. },
  278. "@linedecls": {
  279. token: "@rematch",
  280. switchTo: "@root.$S2"
  281. },
  282. "@keywords": "keyword",
  283. "@builtins": "predefined",
  284. "@default": "identifier"
  285. }
  286. }
  287. ],
  288. { include: "@root" }
  289. ],
  290. sstring: [
  291. [/[^\\']+/, "string.$S2"],
  292. [/\\\\|\\'|\\$/, "string.$S2.escape"],
  293. [/\\./, "string.$S2.invalid"],
  294. [/'/, { token: "string.$S2.delim", next: "@pop" }]
  295. ],
  296. dstring: [
  297. [/[^\\`"#]+/, "string.$S2"],
  298. [/#/, "string.$S2.escape", "@interpolated"],
  299. [/\\$/, "string.$S2.escape"],
  300. [/@escapes/, "string.$S2.escape"],
  301. [/\\./, "string.$S2.escape.invalid"],
  302. [
  303. /[`"]/,
  304. {
  305. cases: {
  306. "$#==$S3": { token: "string.$S2.delim", next: "@pop" },
  307. "@default": "string.$S2"
  308. }
  309. }
  310. ]
  311. ],
  312. heredoc: [
  313. [
  314. /^(\s*)(@heredelim)$/,
  315. {
  316. cases: {
  317. "$2==$S2": ["string.heredoc", { token: "string.heredoc.delimiter", next: "@pop" }],
  318. "@default": ["string.heredoc", "string.heredoc"]
  319. }
  320. }
  321. ],
  322. [/.*/, "string.heredoc"]
  323. ],
  324. interpolated: [
  325. [/\$\w*/, "global.constant", "@pop"],
  326. [/@\w*/, "namespace.class.identifier", "@pop"],
  327. [/@@@\w*/, "namespace.instance.identifier", "@pop"],
  328. [
  329. /[{]/,
  330. {
  331. token: "string.escape.curly",
  332. switchTo: "@interpolated_compound"
  333. }
  334. ],
  335. ["", "", "@pop"]
  336. ],
  337. interpolated_compound: [
  338. [/[}]/, { token: "string.escape.curly", next: "@pop" }],
  339. { include: "@root" }
  340. ],
  341. pregexp: [
  342. { include: "@whitespace" },
  343. [
  344. /[^\(\{\[\\]/,
  345. {
  346. cases: {
  347. "$#==$S3": { token: "regexp.delim", next: "@pop" },
  348. "$#==$S2": { token: "regexp.delim", next: "@push" },
  349. "~[)}\\]]": "@brackets.regexp.escape.control",
  350. "~@regexpctl": "regexp.escape.control",
  351. "@default": "regexp"
  352. }
  353. }
  354. ],
  355. { include: "@regexcontrol" }
  356. ],
  357. regexp: [
  358. { include: "@regexcontrol" },
  359. [/[^\\\/]/, "regexp"],
  360. ["/[ixmp]*", { token: "regexp.delim" }, "@pop"]
  361. ],
  362. regexcontrol: [
  363. [
  364. /(\{)(\d+(?:,\d*)?)(\})/,
  365. [
  366. "@brackets.regexp.escape.control",
  367. "regexp.escape.control",
  368. "@brackets.regexp.escape.control"
  369. ]
  370. ],
  371. [
  372. /(\[)(\^?)/,
  373. ["@brackets.regexp.escape.control", { token: "regexp.escape.control", next: "@regexrange" }]
  374. ],
  375. [/(\()(\?[:=!])/, ["@brackets.regexp.escape.control", "regexp.escape.control"]],
  376. [/\(\?#/, { token: "regexp.escape.control", next: "@regexpcomment" }],
  377. [/[()]/, "@brackets.regexp.escape.control"],
  378. [/@regexpctl/, "regexp.escape.control"],
  379. [/\\$/, "regexp.escape"],
  380. [/@regexpesc/, "regexp.escape"],
  381. [/\\\./, "regexp.invalid"],
  382. [/#/, "regexp.escape", "@interpolated"]
  383. ],
  384. regexrange: [
  385. [/-/, "regexp.escape.control"],
  386. [/\^/, "regexp.invalid"],
  387. [/\\$/, "regexp.escape"],
  388. [/@regexpesc/, "regexp.escape"],
  389. [/[^\]]/, "regexp"],
  390. [/\]/, "@brackets.regexp.escape.control", "@pop"]
  391. ],
  392. regexpcomment: [
  393. [/[^)]+/, "comment"],
  394. [/\)/, { token: "regexp.escape.control", next: "@pop" }]
  395. ],
  396. pstring: [
  397. [/%([qws])\(/, { token: "string.$1.delim", switchTo: "@qstring.$1.(.)" }],
  398. [/%([qws])\[/, { token: "string.$1.delim", switchTo: "@qstring.$1.[.]" }],
  399. [/%([qws])\{/, { token: "string.$1.delim", switchTo: "@qstring.$1.{.}" }],
  400. [/%([qws])</, { token: "string.$1.delim", switchTo: "@qstring.$1.<.>" }],
  401. [/%([qws])(@delim)/, { token: "string.$1.delim", switchTo: "@qstring.$1.$2.$2" }],
  402. [/%r\(/, { token: "regexp.delim", switchTo: "@pregexp.(.)" }],
  403. [/%r\[/, { token: "regexp.delim", switchTo: "@pregexp.[.]" }],
  404. [/%r\{/, { token: "regexp.delim", switchTo: "@pregexp.{.}" }],
  405. [/%r</, { token: "regexp.delim", switchTo: "@pregexp.<.>" }],
  406. [/%r(@delim)/, { token: "regexp.delim", switchTo: "@pregexp.$1.$1" }],
  407. [/%(x|W|Q?)\(/, { token: "string.$1.delim", switchTo: "@qqstring.$1.(.)" }],
  408. [/%(x|W|Q?)\[/, { token: "string.$1.delim", switchTo: "@qqstring.$1.[.]" }],
  409. [/%(x|W|Q?)\{/, { token: "string.$1.delim", switchTo: "@qqstring.$1.{.}" }],
  410. [/%(x|W|Q?)</, { token: "string.$1.delim", switchTo: "@qqstring.$1.<.>" }],
  411. [/%(x|W|Q?)(@delim)/, { token: "string.$1.delim", switchTo: "@qqstring.$1.$2.$2" }],
  412. [/%([rqwsxW]|Q?)./, { token: "invalid", next: "@pop" }],
  413. [/./, { token: "invalid", next: "@pop" }]
  414. ],
  415. qstring: [
  416. [/\\$/, "string.$S2.escape"],
  417. [/\\./, "string.$S2.escape"],
  418. [
  419. /./,
  420. {
  421. cases: {
  422. "$#==$S4": { token: "string.$S2.delim", next: "@pop" },
  423. "$#==$S3": { token: "string.$S2.delim", next: "@push" },
  424. "@default": "string.$S2"
  425. }
  426. }
  427. ]
  428. ],
  429. qqstring: [[/#/, "string.$S2.escape", "@interpolated"], { include: "@qstring" }],
  430. whitespace: [
  431. [/[ \t\r\n]+/, ""],
  432. [/^\s*=begin\b/, "comment", "@comment"],
  433. [/#.*$/, "comment"]
  434. ],
  435. comment: [
  436. [/[^=]+/, "comment"],
  437. [/^\s*=begin\b/, "comment.invalid"],
  438. [/^\s*=end\b.*/, "comment", "@pop"],
  439. [/[=]/, "comment"]
  440. ]
  441. }
  442. };
  443. export {
  444. conf,
  445. language
  446. };