mode-elixir.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. ace.define("ace/mode/elixir_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) {
  2. "use strict";
  3. var oop = require("../lib/oop");
  4. var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
  5. var ElixirHighlightRules = function() {
  6. this.$rules = { start:
  7. [ { token:
  8. [ 'meta.module.elixir',
  9. 'keyword.control.module.elixir',
  10. 'meta.module.elixir',
  11. 'entity.name.type.module.elixir' ],
  12. regex: '^(\\s*)(defmodule)(\\s+)((?:[A-Z]\\w*\\s*\\.\\s*)*[A-Z]\\w*)' },
  13. { token: 'comment.documentation.heredoc',
  14. regex: '@(?:module|type)?doc (?:~[a-z])?"""',
  15. push:
  16. [ { token: 'comment.documentation.heredoc',
  17. regex: '\\s*"""',
  18. next: 'pop' },
  19. { include: '#interpolated_elixir' },
  20. { include: '#escaped_char' },
  21. { defaultToken: 'comment.documentation.heredoc' } ],
  22. comment: '@doc with heredocs is treated as documentation' },
  23. { token: 'comment.documentation.heredoc',
  24. regex: '@(?:module|type)?doc ~[A-Z]"""',
  25. push:
  26. [ { token: 'comment.documentation.heredoc',
  27. regex: '\\s*"""',
  28. next: 'pop' },
  29. { defaultToken: 'comment.documentation.heredoc' } ],
  30. comment: '@doc with heredocs is treated as documentation' },
  31. { token: 'comment.documentation.heredoc',
  32. regex: '@(?:module|type)?doc (?:~[a-z])?\'\'\'',
  33. push:
  34. [ { token: 'comment.documentation.heredoc',
  35. regex: '\\s*\'\'\'',
  36. next: 'pop' },
  37. { include: '#interpolated_elixir' },
  38. { include: '#escaped_char' },
  39. { defaultToken: 'comment.documentation.heredoc' } ],
  40. comment: '@doc with heredocs is treated as documentation' },
  41. { token: 'comment.documentation.heredoc',
  42. regex: '@(?:module|type)?doc ~[A-Z]\'\'\'',
  43. push:
  44. [ { token: 'comment.documentation.heredoc',
  45. regex: '\\s*\'\'\'',
  46. next: 'pop' },
  47. { defaultToken: 'comment.documentation.heredoc' } ],
  48. comment: '@doc with heredocs is treated as documentation' },
  49. { token: 'comment.documentation.false',
  50. regex: '@(?:module|type)?doc false',
  51. comment: '@doc false is treated as documentation' },
  52. { token: 'comment.documentation.string',
  53. regex: '@(?:module|type)?doc "',
  54. push:
  55. [ { token: 'comment.documentation.string',
  56. regex: '"',
  57. next: 'pop' },
  58. { include: '#interpolated_elixir' },
  59. { include: '#escaped_char' },
  60. { defaultToken: 'comment.documentation.string' } ],
  61. comment: '@doc with string is treated as documentation' },
  62. { token: 'keyword.control.elixir',
  63. regex: '\\b(?:do|end|case|bc|lc|for|if|cond|unless|try|receive|fn|defmodule|defp?|defprotocol|defimpl|defrecord|defstruct|defmacrop?|defdelegate|defcallback|defmacrocallback|defexception|defoverridable|exit|after|rescue|catch|else|raise|throw|import|require|alias|use|quote|unquote|super)\\b(?![?!])',
  64. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  65. originalRegex: '(?<!\\.)\\b(do|end|case|bc|lc|for|if|cond|unless|try|receive|fn|defmodule|defp?|defprotocol|defimpl|defrecord|defstruct|defmacrop?|defdelegate|defcallback|defmacrocallback|defexception|defoverridable|exit|after|rescue|catch|else|raise|throw|import|require|alias|use|quote|unquote|super)\\b(?![?!])' },
  66. { token: 'keyword.operator.elixir',
  67. regex: '\\b(?:and|not|or|when|xor|in|inlist|inbits)\\b',
  68. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  69. originalRegex: '(?<!\\.)\\b(and|not|or|when|xor|in|inlist|inbits)\\b',
  70. comment: ' as above, just doesn\'t need a \'end\' and does a logic operation' },
  71. { token: 'constant.language.elixir',
  72. regex: '\\b(?:nil|true|false)\\b(?![?!])' },
  73. { token: 'variable.language.elixir',
  74. regex: '\\b__(?:CALLER|ENV|MODULE|DIR)__\\b(?![?!])' },
  75. { token:
  76. [ 'punctuation.definition.variable.elixir',
  77. 'variable.other.readwrite.module.elixir' ],
  78. regex: '(@)([a-zA-Z_]\\w*)' },
  79. { token:
  80. [ 'punctuation.definition.variable.elixir',
  81. 'variable.other.anonymous.elixir' ],
  82. regex: '(&)(\\d*)' },
  83. { token: 'variable.other.constant.elixir',
  84. regex: '\\b[A-Z]\\w*\\b' },
  85. { token: 'constant.numeric.elixir',
  86. regex: '\\b(?:0x[\\da-fA-F](?:_?[\\da-fA-F])*|\\d(?:_?\\d)*(?:\\.(?![^[:space:][:digit:]])(?:_?\\d)*)?(?:[eE][-+]?\\d(?:_?\\d)*)?|0b[01]+|0o[0-7]+)\\b',
  87. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  88. originalRegex: '\\b(0x\\h(?>_?\\h)*|\\d(?>_?\\d)*(\\.(?![^[:space:][:digit:]])(?>_?\\d)*)?([eE][-+]?\\d(?>_?\\d)*)?|0b[01]+|0o[0-7]+)\\b' },
  89. { token: 'punctuation.definition.constant.elixir',
  90. regex: ':\'',
  91. push:
  92. [ { token: 'punctuation.definition.constant.elixir',
  93. regex: '\'',
  94. next: 'pop' },
  95. { include: '#interpolated_elixir' },
  96. { include: '#escaped_char' },
  97. { defaultToken: 'constant.other.symbol.single-quoted.elixir' } ] },
  98. { token: 'punctuation.definition.constant.elixir',
  99. regex: ':"',
  100. push:
  101. [ { token: 'punctuation.definition.constant.elixir',
  102. regex: '"',
  103. next: 'pop' },
  104. { include: '#interpolated_elixir' },
  105. { include: '#escaped_char' },
  106. { defaultToken: 'constant.other.symbol.double-quoted.elixir' } ] },
  107. { token: 'punctuation.definition.string.begin.elixir',
  108. regex: '(?:\'\'\')',
  109. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  110. originalRegex: '(?>\'\'\')',
  111. push:
  112. [ { token: 'punctuation.definition.string.end.elixir',
  113. regex: '^\\s*\'\'\'',
  114. next: 'pop' },
  115. { include: '#interpolated_elixir' },
  116. { include: '#escaped_char' },
  117. { defaultToken: 'support.function.variable.quoted.single.heredoc.elixir' } ],
  118. comment: 'Single-quoted heredocs' },
  119. { token: 'punctuation.definition.string.begin.elixir',
  120. regex: '\'',
  121. push:
  122. [ { token: 'punctuation.definition.string.end.elixir',
  123. regex: '\'',
  124. next: 'pop' },
  125. { include: '#interpolated_elixir' },
  126. { include: '#escaped_char' },
  127. { defaultToken: 'support.function.variable.quoted.single.elixir' } ],
  128. comment: 'single quoted string (allows for interpolation)' },
  129. { token: 'punctuation.definition.string.begin.elixir',
  130. regex: '(?:""")',
  131. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  132. originalRegex: '(?>""")',
  133. push:
  134. [ { token: 'punctuation.definition.string.end.elixir',
  135. regex: '^\\s*"""',
  136. next: 'pop' },
  137. { include: '#interpolated_elixir' },
  138. { include: '#escaped_char' },
  139. { defaultToken: 'string.quoted.double.heredoc.elixir' } ],
  140. comment: 'Double-quoted heredocs' },
  141. { token: 'punctuation.definition.string.begin.elixir',
  142. regex: '"',
  143. push:
  144. [ { token: 'punctuation.definition.string.end.elixir',
  145. regex: '"',
  146. next: 'pop' },
  147. { include: '#interpolated_elixir' },
  148. { include: '#escaped_char' },
  149. { defaultToken: 'string.quoted.double.elixir' } ],
  150. comment: 'double quoted string (allows for interpolation)' },
  151. { token: 'punctuation.definition.string.begin.elixir',
  152. regex: '~[a-z](?:""")',
  153. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  154. originalRegex: '~[a-z](?>""")',
  155. push:
  156. [ { token: 'punctuation.definition.string.end.elixir',
  157. regex: '^\\s*"""',
  158. next: 'pop' },
  159. { include: '#interpolated_elixir' },
  160. { include: '#escaped_char' },
  161. { defaultToken: 'string.quoted.double.heredoc.elixir' } ],
  162. comment: 'Double-quoted heredocs sigils' },
  163. { token: 'punctuation.definition.string.begin.elixir',
  164. regex: '~[a-z]\\{',
  165. push:
  166. [ { token: 'punctuation.definition.string.end.elixir',
  167. regex: '\\}[a-z]*',
  168. next: 'pop' },
  169. { include: '#interpolated_elixir' },
  170. { include: '#escaped_char' },
  171. { defaultToken: 'string.interpolated.elixir' } ],
  172. comment: 'sigil (allow for interpolation)' },
  173. { token: 'punctuation.definition.string.begin.elixir',
  174. regex: '~[a-z]\\[',
  175. push:
  176. [ { token: 'punctuation.definition.string.end.elixir',
  177. regex: '\\][a-z]*',
  178. next: 'pop' },
  179. { include: '#interpolated_elixir' },
  180. { include: '#escaped_char' },
  181. { defaultToken: 'string.interpolated.elixir' } ],
  182. comment: 'sigil (allow for interpolation)' },
  183. { token: 'punctuation.definition.string.begin.elixir',
  184. regex: '~[a-z]\\<',
  185. push:
  186. [ { token: 'punctuation.definition.string.end.elixir',
  187. regex: '\\>[a-z]*',
  188. next: 'pop' },
  189. { include: '#interpolated_elixir' },
  190. { include: '#escaped_char' },
  191. { defaultToken: 'string.interpolated.elixir' } ],
  192. comment: 'sigil (allow for interpolation)' },
  193. { token: 'punctuation.definition.string.begin.elixir',
  194. regex: '~[a-z]\\(',
  195. push:
  196. [ { token: 'punctuation.definition.string.end.elixir',
  197. regex: '\\)[a-z]*',
  198. next: 'pop' },
  199. { include: '#interpolated_elixir' },
  200. { include: '#escaped_char' },
  201. { defaultToken: 'string.interpolated.elixir' } ],
  202. comment: 'sigil (allow for interpolation)' },
  203. { token: 'punctuation.definition.string.begin.elixir',
  204. regex: '~[a-z][^\\w]',
  205. push:
  206. [ { token: 'punctuation.definition.string.end.elixir',
  207. regex: '[^\\w][a-z]*',
  208. next: 'pop' },
  209. { include: '#interpolated_elixir' },
  210. { include: '#escaped_char' },
  211. { include: '#escaped_char' },
  212. { defaultToken: 'string.interpolated.elixir' } ],
  213. comment: 'sigil (allow for interpolation)' },
  214. { token: 'punctuation.definition.string.begin.elixir',
  215. regex: '~[A-Z](?:""")',
  216. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  217. originalRegex: '~[A-Z](?>""")',
  218. push:
  219. [ { token: 'punctuation.definition.string.end.elixir',
  220. regex: '^\\s*"""',
  221. next: 'pop' },
  222. { defaultToken: 'string.quoted.other.literal.upper.elixir' } ],
  223. comment: 'Double-quoted heredocs sigils' },
  224. { token: 'punctuation.definition.string.begin.elixir',
  225. regex: '~[A-Z]\\{',
  226. push:
  227. [ { token: 'punctuation.definition.string.end.elixir',
  228. regex: '\\}[a-z]*',
  229. next: 'pop' },
  230. { defaultToken: 'string.quoted.other.literal.upper.elixir' } ],
  231. comment: 'sigil (without interpolation)' },
  232. { token: 'punctuation.definition.string.begin.elixir',
  233. regex: '~[A-Z]\\[',
  234. push:
  235. [ { token: 'punctuation.definition.string.end.elixir',
  236. regex: '\\][a-z]*',
  237. next: 'pop' },
  238. { defaultToken: 'string.quoted.other.literal.upper.elixir' } ],
  239. comment: 'sigil (without interpolation)' },
  240. { token: 'punctuation.definition.string.begin.elixir',
  241. regex: '~[A-Z]\\<',
  242. push:
  243. [ { token: 'punctuation.definition.string.end.elixir',
  244. regex: '\\>[a-z]*',
  245. next: 'pop' },
  246. { defaultToken: 'string.quoted.other.literal.upper.elixir' } ],
  247. comment: 'sigil (without interpolation)' },
  248. { token: 'punctuation.definition.string.begin.elixir',
  249. regex: '~[A-Z]\\(',
  250. push:
  251. [ { token: 'punctuation.definition.string.end.elixir',
  252. regex: '\\)[a-z]*',
  253. next: 'pop' },
  254. { defaultToken: 'string.quoted.other.literal.upper.elixir' } ],
  255. comment: 'sigil (without interpolation)' },
  256. { token: 'punctuation.definition.string.begin.elixir',
  257. regex: '~[A-Z][^\\w]',
  258. push:
  259. [ { token: 'punctuation.definition.string.end.elixir',
  260. regex: '[^\\w][a-z]*',
  261. next: 'pop' },
  262. { defaultToken: 'string.quoted.other.literal.upper.elixir' } ],
  263. comment: 'sigil (without interpolation)' },
  264. { token: ['punctuation.definition.constant.elixir', 'constant.other.symbol.elixir'],
  265. regex: '(:)([a-zA-Z_][\\w@]*(?:[?!]|=(?![>=]))?|\\<\\>|===?|!==?|<<>>|<<<|>>>|~~~|::|<\\-|\\|>|=>|~|~=|=|/|\\\\\\\\|\\*\\*?|\\.\\.?\\.?|>=?|<=?|&&?&?|\\+\\+?|\\-\\-?|\\|\\|?\\|?|\\!|@|\\%?\\{\\}|%|\\[\\]|\\^(?:\\^\\^)?)',
  266. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  267. originalRegex: '(?<!:)(:)(?>[a-zA-Z_][\\w@]*(?>[?!]|=(?![>=]))?|\\<\\>|===?|!==?|<<>>|<<<|>>>|~~~|::|<\\-|\\|>|=>|~|~=|=|/|\\\\\\\\|\\*\\*?|\\.\\.?\\.?|>=?|<=?|&&?&?|\\+\\+?|\\-\\-?|\\|\\|?\\|?|\\!|@|\\%?\\{\\}|%|\\[\\]|\\^(\\^\\^)?)',
  268. comment: 'symbols' },
  269. { token: 'punctuation.definition.constant.elixir',
  270. regex: '(?:[a-zA-Z_][\\w@]*(?:[?!])?):(?!:)',
  271. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  272. originalRegex: '(?>[a-zA-Z_][\\w@]*(?>[?!])?)(:)(?!:)',
  273. comment: 'symbols' },
  274. { token:
  275. [ 'punctuation.definition.comment.elixir',
  276. 'comment.line.number-sign.elixir' ],
  277. regex: '(#)(.*)' },
  278. { token: 'constant.numeric.elixir',
  279. regex: '\\?(?:\\\\(?:x[\\da-fA-F]{1,2}(?![\\da-fA-F])\\b|[^xMC])|[^\\s\\\\])',
  280. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  281. originalRegex: '(?<!\\w)\\?(\\\\(x\\h{1,2}(?!\\h)\\b|[^xMC])|[^\\s\\\\])',
  282. comment: '\n\t\t\tmatches questionmark-letters.\n\n\t\t\texamples (1st alternation = hex):\n\t\t\t?\\x1 ?\\x61\n\n\t\t\texamples (2rd alternation = escaped):\n\t\t\t?\\n ?\\b\n\n\t\t\texamples (3rd alternation = normal):\n\t\t\t?a ?A ?0 \n\t\t\t?* ?" ?( \n\t\t\t?. ?#\n\t\t\t\n\t\t\tthe negative lookbehind prevents against matching\n\t\t\tp(42.tainted?)\n\t\t\t' },
  283. { token: 'keyword.operator.assignment.augmented.elixir',
  284. regex: '\\+=|\\-=|\\|\\|=|~=|&&=' },
  285. { token: 'keyword.operator.comparison.elixir',
  286. regex: '===?|!==?|<=?|>=?' },
  287. { token: 'keyword.operator.bitwise.elixir',
  288. regex: '\\|{3}|&{3}|\\^{3}|<{3}|>{3}|~{3}' },
  289. { token: 'keyword.operator.logical.elixir',
  290. regex: '!+|\\bnot\\b|&&|\\band\\b|\\|\\||\\bor\\b|\\bxor\\b',
  291. originalRegex: '(?<=[ \\t])!+|\\bnot\\b|&&|\\band\\b|\\|\\||\\bor\\b|\\bxor\\b' },
  292. { token: 'keyword.operator.arithmetic.elixir',
  293. regex: '\\*|\\+|\\-|/' },
  294. { token: 'keyword.operator.other.elixir',
  295. regex: '\\||\\+\\+|\\-\\-|\\*\\*|\\\\\\\\|\\<\\-|\\<\\>|\\<\\<|\\>\\>|\\:\\:|\\.\\.|\\|>|~|=>' },
  296. { token: 'keyword.operator.assignment.elixir', regex: '=' },
  297. { token: 'punctuation.separator.other.elixir', regex: ':' },
  298. { token: 'punctuation.separator.statement.elixir',
  299. regex: '\\;' },
  300. { token: 'punctuation.separator.object.elixir', regex: ',' },
  301. { token: 'punctuation.separator.method.elixir', regex: '\\.' },
  302. { token: 'punctuation.section.scope.elixir', regex: '\\{|\\}' },
  303. { token: 'punctuation.section.array.elixir', regex: '\\[|\\]' },
  304. { token: 'punctuation.section.function.elixir',
  305. regex: '\\(|\\)' } ],
  306. '#escaped_char':
  307. [ { token: 'constant.character.escape.elixir',
  308. regex: '\\\\(?:x[\\da-fA-F]{1,2}|.)' } ],
  309. '#interpolated_elixir':
  310. [ { token:
  311. [ 'source.elixir.embedded.source',
  312. 'source.elixir.embedded.source.empty' ],
  313. regex: '(#\\{)(\\})' },
  314. { todo:
  315. { token: 'punctuation.section.embedded.elixir',
  316. regex: '#\\{',
  317. push:
  318. [ { token: 'punctuation.section.embedded.elixir',
  319. regex: '\\}',
  320. next: 'pop' },
  321. { include: '#nest_curly_and_self' },
  322. { include: '$self' },
  323. { defaultToken: 'source.elixir.embedded.source' } ] } } ],
  324. '#nest_curly_and_self':
  325. [ { token: 'punctuation.section.scope.elixir',
  326. regex: '\\{',
  327. push:
  328. [ { token: 'punctuation.section.scope.elixir',
  329. regex: '\\}',
  330. next: 'pop' },
  331. { include: '#nest_curly_and_self' } ] },
  332. { include: '$self' } ],
  333. '#regex_sub':
  334. [ { include: '#interpolated_elixir' },
  335. { include: '#escaped_char' },
  336. { token:
  337. [ 'punctuation.definition.arbitrary-repitition.elixir',
  338. 'string.regexp.arbitrary-repitition.elixir',
  339. 'string.regexp.arbitrary-repitition.elixir',
  340. 'punctuation.definition.arbitrary-repitition.elixir' ],
  341. regex: '(\\{)(\\d+)((?:,\\d+)?)(\\})' },
  342. { token: 'punctuation.definition.character-class.elixir',
  343. regex: '\\[(?:\\^?\\])?',
  344. push:
  345. [ { token: 'punctuation.definition.character-class.elixir',
  346. regex: '\\]',
  347. next: 'pop' },
  348. { include: '#escaped_char' },
  349. { defaultToken: 'string.regexp.character-class.elixir' } ] },
  350. { token: 'punctuation.definition.group.elixir',
  351. regex: '\\(',
  352. push:
  353. [ { token: 'punctuation.definition.group.elixir',
  354. regex: '\\)',
  355. next: 'pop' },
  356. { include: '#regex_sub' },
  357. { defaultToken: 'string.regexp.group.elixir' } ] },
  358. { token:
  359. [ 'punctuation.definition.comment.elixir',
  360. 'comment.line.number-sign.elixir' ],
  361. regex: '(?:^|\\s)(#)(\\s[[a-zA-Z0-9,. \\t?!-][^\\x00-\\x7F]]*$)',
  362. originalRegex: '(?<=^|\\s)(#)\\s[[a-zA-Z0-9,. \\t?!-][^\\x{00}-\\x{7F}]]*$',
  363. comment: 'We are restrictive in what we allow to go after the comment character to avoid false positives, since the availability of comments depend on regexp flags.' } ] }
  364. this.normalizeRules();
  365. };
  366. ElixirHighlightRules.metaData = { comment: 'Textmate bundle for Elixir Programming Language.',
  367. fileTypes: [ 'ex', 'exs' ],
  368. firstLineMatch: '^#!/.*\\belixir',
  369. foldingStartMarker: '(after|else|catch|rescue|\\-\\>|\\{|\\[|do)\\s*$',
  370. foldingStopMarker: '^\\s*((\\}|\\]|after|else|catch|rescue)\\s*$|end\\b)',
  371. keyEquivalent: '^~E',
  372. name: 'Elixir',
  373. scopeName: 'source.elixir' }
  374. oop.inherits(ElixirHighlightRules, TextHighlightRules);
  375. exports.ElixirHighlightRules = ElixirHighlightRules;
  376. });
  377. ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"], function(require, exports, module) {
  378. "use strict";
  379. var oop = require("../../lib/oop");
  380. var BaseFoldMode = require("./fold_mode").FoldMode;
  381. var Range = require("../../range").Range;
  382. var FoldMode = exports.FoldMode = function() {};
  383. oop.inherits(FoldMode, BaseFoldMode);
  384. (function() {
  385. this.getFoldWidgetRange = function(session, foldStyle, row) {
  386. var range = this.indentationBlock(session, row);
  387. if (range)
  388. return range;
  389. var re = /\S/;
  390. var line = session.getLine(row);
  391. var startLevel = line.search(re);
  392. if (startLevel == -1 || line[startLevel] != "#")
  393. return;
  394. var startColumn = line.length;
  395. var maxRow = session.getLength();
  396. var startRow = row;
  397. var endRow = row;
  398. while (++row < maxRow) {
  399. line = session.getLine(row);
  400. var level = line.search(re);
  401. if (level == -1)
  402. continue;
  403. if (line[level] != "#")
  404. break;
  405. endRow = row;
  406. }
  407. if (endRow > startRow) {
  408. var endColumn = session.getLine(endRow).length;
  409. return new Range(startRow, startColumn, endRow, endColumn);
  410. }
  411. };
  412. this.getFoldWidget = function(session, foldStyle, row) {
  413. var line = session.getLine(row);
  414. var indent = line.search(/\S/);
  415. var next = session.getLine(row + 1);
  416. var prev = session.getLine(row - 1);
  417. var prevIndent = prev.search(/\S/);
  418. var nextIndent = next.search(/\S/);
  419. if (indent == -1) {
  420. session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? "start" : "";
  421. return "";
  422. }
  423. if (prevIndent == -1) {
  424. if (indent == nextIndent && line[indent] == "#" && next[indent] == "#") {
  425. session.foldWidgets[row - 1] = "";
  426. session.foldWidgets[row + 1] = "";
  427. return "start";
  428. }
  429. } else if (prevIndent == indent && line[indent] == "#" && prev[indent] == "#") {
  430. if (session.getLine(row - 2).search(/\S/) == -1) {
  431. session.foldWidgets[row - 1] = "start";
  432. session.foldWidgets[row + 1] = "";
  433. return "";
  434. }
  435. }
  436. if (prevIndent!= -1 && prevIndent < indent)
  437. session.foldWidgets[row - 1] = "start";
  438. else
  439. session.foldWidgets[row - 1] = "";
  440. if (indent < nextIndent)
  441. return "start";
  442. else
  443. return "";
  444. };
  445. }).call(FoldMode.prototype);
  446. });
  447. ace.define("ace/mode/elixir",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/elixir_highlight_rules","ace/mode/folding/coffee"], function(require, exports, module) {
  448. "use strict";
  449. var oop = require("../lib/oop");
  450. var TextMode = require("./text").Mode;
  451. var ElixirHighlightRules = require("./elixir_highlight_rules").ElixirHighlightRules;
  452. var FoldMode = require("./folding/coffee").FoldMode;
  453. var Mode = function() {
  454. this.HighlightRules = ElixirHighlightRules;
  455. this.foldingRules = new FoldMode();
  456. this.$behaviour = this.$defaultBehaviour;
  457. };
  458. oop.inherits(Mode, TextMode);
  459. (function() {
  460. this.lineCommentStart = "#";
  461. this.$id = "ace/mode/elixir"
  462. }).call(Mode.prototype);
  463. exports.Mode = Mode;
  464. });