mode-vala.js 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  1. ace.define("ace/mode/vala_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 ValaHighlightRules = function() {
  6. this.$rules = { start:
  7. [ { token:
  8. [ 'meta.using.vala',
  9. 'keyword.other.using.vala',
  10. 'meta.using.vala',
  11. 'storage.modifier.using.vala',
  12. 'meta.using.vala',
  13. 'punctuation.terminator.vala' ],
  14. regex: '^(\\s*)(using)\\b(?:(\\s*)([^ ;$]+)(\\s*)((?:;)?))?' },
  15. { include: '#code' } ],
  16. '#all-types':
  17. [ { include: '#primitive-arrays' },
  18. { include: '#primitive-types' },
  19. { include: '#object-types' } ],
  20. '#annotations':
  21. [ { token:
  22. [ 'storage.type.annotation.vala',
  23. 'punctuation.definition.annotation-arguments.begin.vala' ],
  24. regex: '(@[^ (]+)(\\()',
  25. push:
  26. [ { token: 'punctuation.definition.annotation-arguments.end.vala',
  27. regex: '\\)',
  28. next: 'pop' },
  29. { token:
  30. [ 'constant.other.key.vala',
  31. 'text',
  32. 'keyword.operator.assignment.vala' ],
  33. regex: '(\\w*)(\\s*)(=)' },
  34. { include: '#code' },
  35. { token: 'punctuation.seperator.property.vala', regex: ',' },
  36. { defaultToken: 'meta.declaration.annotation.vala' } ] },
  37. { token: 'storage.type.annotation.vala', regex: '@\\w*' } ],
  38. '#anonymous-classes-and-new':
  39. [ { token: 'keyword.control.new.vala',
  40. regex: '\\bnew\\b',
  41. push_disabled:
  42. [ { token: 'text',
  43. regex: '(?<=\\)|\\])(?!\\s*{)|(?<=})|(?=;)',
  44. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  45. originalRegex: '(?<=\\)|\\])(?!\\s*{)|(?<=})|(?=;)',
  46. next: 'pop' },
  47. { token: [ 'storage.type.vala', 'text' ],
  48. regex: '(\\w+)(\\s*)(?=\\[)',
  49. push:
  50. [ { token: 'text', regex: '}|(?=;|\\))', next: 'pop' },
  51. { token: 'text',
  52. regex: '\\[',
  53. push:
  54. [ { token: 'text', regex: '\\]', next: 'pop' },
  55. { include: '#code' } ] },
  56. { token: 'text',
  57. regex: '{',
  58. push:
  59. [ { token: 'text', regex: '(?=})', next: 'pop' },
  60. { include: '#code' } ] } ] },
  61. { token: 'text',
  62. regex: '(?=\\w.*\\()',
  63. push:
  64. [ { token: 'text',
  65. regex: '(?<=\\))',
  66. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  67. originalRegex: '(?<=\\))',
  68. next: 'pop' },
  69. { include: '#object-types' },
  70. { token: 'text',
  71. regex: '\\(',
  72. push:
  73. [ { token: 'text', regex: '\\)', next: 'pop' },
  74. { include: '#code' } ] } ] },
  75. { token: 'meta.inner-class.vala',
  76. regex: '{',
  77. push:
  78. [ { token: 'meta.inner-class.vala', regex: '}', next: 'pop' },
  79. { include: '#class-body' },
  80. { defaultToken: 'meta.inner-class.vala' } ] } ] } ],
  81. '#assertions':
  82. [ { token:
  83. [ 'keyword.control.assert.vala',
  84. 'meta.declaration.assertion.vala' ],
  85. regex: '\\b(assert|requires|ensures)(\\s)',
  86. push:
  87. [ { token: 'meta.declaration.assertion.vala',
  88. regex: '$',
  89. next: 'pop' },
  90. { token: 'keyword.operator.assert.expression-seperator.vala',
  91. regex: ':' },
  92. { include: '#code' },
  93. { defaultToken: 'meta.declaration.assertion.vala' } ] } ],
  94. '#class':
  95. [ { token: 'meta.class.vala',
  96. regex: '(?=\\w?[\\w\\s]*(?:class|(?:@)?interface|enum|struct|namespace)\\s+\\w+)',
  97. push:
  98. [ { token: 'punctuation.section.class.end.vala',
  99. regex: '}',
  100. next: 'pop' },
  101. { include: '#storage-modifiers' },
  102. { include: '#comments' },
  103. { token:
  104. [ 'storage.modifier.vala',
  105. 'meta.class.identifier.vala',
  106. 'entity.name.type.class.vala' ],
  107. regex: '(class|(?:@)?interface|enum|struct|namespace)(\\s+)([\\w\\.]+)' },
  108. { token: 'storage.modifier.extends.vala',
  109. regex: ':',
  110. push:
  111. [ { token: 'meta.definition.class.inherited.classes.vala',
  112. regex: '(?={|,)',
  113. next: 'pop' },
  114. { include: '#object-types-inherited' },
  115. { include: '#comments' },
  116. { defaultToken: 'meta.definition.class.inherited.classes.vala' } ] },
  117. { token:
  118. [ 'storage.modifier.implements.vala',
  119. 'meta.definition.class.implemented.interfaces.vala' ],
  120. regex: '(,)(\\s)',
  121. push:
  122. [ { token: 'meta.definition.class.implemented.interfaces.vala',
  123. regex: '(?=\\{)',
  124. next: 'pop' },
  125. { include: '#object-types-inherited' },
  126. { include: '#comments' },
  127. { defaultToken: 'meta.definition.class.implemented.interfaces.vala' } ] },
  128. { token: 'meta.class.body.vala',
  129. regex: '{',
  130. push:
  131. [ { token: 'meta.class.body.vala', regex: '(?=})', next: 'pop' },
  132. { include: '#class-body' },
  133. { defaultToken: 'meta.class.body.vala' } ] },
  134. { defaultToken: 'meta.class.vala' } ],
  135. comment: 'attempting to put namespace in here.' } ],
  136. '#class-body':
  137. [ { include: '#comments' },
  138. { include: '#class' },
  139. { include: '#enums' },
  140. { include: '#methods' },
  141. { include: '#annotations' },
  142. { include: '#storage-modifiers' },
  143. { include: '#code' } ],
  144. '#code':
  145. [ { include: '#comments' },
  146. { include: '#class' },
  147. { token: 'text',
  148. regex: '{',
  149. push:
  150. [ { token: 'text', regex: '}', next: 'pop' },
  151. { include: '#code' } ] },
  152. { include: '#assertions' },
  153. { include: '#parens' },
  154. { include: '#constants-and-special-vars' },
  155. { include: '#anonymous-classes-and-new' },
  156. { include: '#keywords' },
  157. { include: '#storage-modifiers' },
  158. { include: '#strings' },
  159. { include: '#all-types' } ],
  160. '#comments':
  161. [ { token: 'punctuation.definition.comment.vala',
  162. regex: '/\\*\\*/' },
  163. { include: 'text.html.javadoc' },
  164. { include: '#comments-inline' } ],
  165. '#comments-inline':
  166. [ { token: 'punctuation.definition.comment.vala',
  167. regex: '/\\*',
  168. push:
  169. [ { token: 'punctuation.definition.comment.vala',
  170. regex: '\\*/',
  171. next: 'pop' },
  172. { defaultToken: 'comment.block.vala' } ] },
  173. { token:
  174. [ 'text',
  175. 'punctuation.definition.comment.vala',
  176. 'comment.line.double-slash.vala' ],
  177. regex: '(\\s*)(//)(.*$)' } ],
  178. '#constants-and-special-vars':
  179. [ { token: 'constant.language.vala',
  180. regex: '\\b(?:true|false|null)\\b' },
  181. { token: 'variable.language.vala',
  182. regex: '\\b(?:this|base)\\b' },
  183. { token: 'constant.numeric.vala',
  184. regex: '\\b(?:0(?:x|X)[0-9a-fA-F]*|(?:[0-9]+\\.?[0-9]*|\\.[0-9]+)(?:(?:e|E)(?:\\+|-)?[0-9]+)?)(?:[LlFfUuDd]|UL|ul)?\\b' },
  185. { token: [ 'keyword.operator.dereference.vala', 'constant.other.vala' ],
  186. regex: '((?:\\.)?)\\b([A-Z][A-Z0-9_]+)(?!<|\\.class|\\s*\\w+\\s*=)\\b' } ],
  187. '#enums':
  188. [ { token: 'text',
  189. regex: '^(?=\\s*[A-Z0-9_]+\\s*(?:{|\\(|,))',
  190. push:
  191. [ { token: 'text', regex: '(?=;|})', next: 'pop' },
  192. { token: 'constant.other.enum.vala',
  193. regex: '\\w+',
  194. push:
  195. [ { token: 'meta.enum.vala', regex: '(?=,|;|})', next: 'pop' },
  196. { include: '#parens' },
  197. { token: 'text',
  198. regex: '{',
  199. push:
  200. [ { token: 'text', regex: '}', next: 'pop' },
  201. { include: '#class-body' } ] },
  202. { defaultToken: 'meta.enum.vala' } ] } ] } ],
  203. '#keywords':
  204. [ { token: 'keyword.control.catch-exception.vala',
  205. regex: '\\b(?:try|catch|finally|throw)\\b' },
  206. { token: 'keyword.control.vala', regex: '\\?|:|\\?\\?' },
  207. { token: 'keyword.control.vala',
  208. regex: '\\b(?:return|break|case|continue|default|do|while|for|foreach|switch|if|else|in|yield|get|set|value)\\b' },
  209. { token: 'keyword.operator.vala',
  210. regex: '\\b(?:typeof|is|as)\\b' },
  211. { token: 'keyword.operator.comparison.vala',
  212. regex: '==|!=|<=|>=|<>|<|>' },
  213. { token: 'keyword.operator.assignment.vala', regex: '=' },
  214. { token: 'keyword.operator.increment-decrement.vala',
  215. regex: '\\-\\-|\\+\\+' },
  216. { token: 'keyword.operator.arithmetic.vala',
  217. regex: '\\-|\\+|\\*|\\/|%' },
  218. { token: 'keyword.operator.logical.vala', regex: '!|&&|\\|\\|' },
  219. { token: 'keyword.operator.dereference.vala',
  220. regex: '\\.(?=\\S)',
  221. originalRegex: '(?<=\\S)\\.(?=\\S)' },
  222. { token: 'punctuation.terminator.vala', regex: ';' },
  223. { token: 'keyword.operator.ownership', regex: 'owned|unowned' } ],
  224. '#methods':
  225. [ { token: 'meta.method.vala',
  226. regex: '(?!new)(?=\\w.*\\s+)(?=[^=]+\\()',
  227. push:
  228. [ { token: 'meta.method.vala', regex: '}|(?=;)', next: 'pop' },
  229. { include: '#storage-modifiers' },
  230. { token: [ 'entity.name.function.vala', 'meta.method.identifier.vala' ],
  231. regex: '([\\~\\w\\.]+)(\\s*\\()',
  232. push:
  233. [ { token: 'meta.method.identifier.vala',
  234. regex: '\\)',
  235. next: 'pop' },
  236. { include: '#parameters' },
  237. { defaultToken: 'meta.method.identifier.vala' } ] },
  238. { token: 'meta.method.return-type.vala',
  239. regex: '(?=\\w.*\\s+\\w+\\s*\\()',
  240. push:
  241. [ { token: 'meta.method.return-type.vala',
  242. regex: '(?=\\w+\\s*\\()',
  243. next: 'pop' },
  244. { include: '#all-types' },
  245. { defaultToken: 'meta.method.return-type.vala' } ] },
  246. { include: '#throws' },
  247. { token: 'meta.method.body.vala',
  248. regex: '{',
  249. push:
  250. [ { token: 'meta.method.body.vala', regex: '(?=})', next: 'pop' },
  251. { include: '#code' },
  252. { defaultToken: 'meta.method.body.vala' } ] },
  253. { defaultToken: 'meta.method.vala' } ] } ],
  254. '#namespace':
  255. [ { token: 'text',
  256. regex: '^(?=\\s*[A-Z0-9_]+\\s*(?:{|\\(|,))',
  257. push:
  258. [ { token: 'text', regex: '(?=;|})', next: 'pop' },
  259. { token: 'constant.other.namespace.vala',
  260. regex: '\\w+',
  261. push:
  262. [ { token: 'meta.namespace.vala', regex: '(?=,|;|})', next: 'pop' },
  263. { include: '#parens' },
  264. { token: 'text',
  265. regex: '{',
  266. push:
  267. [ { token: 'text', regex: '}', next: 'pop' },
  268. { include: '#code' } ] },
  269. { defaultToken: 'meta.namespace.vala' } ] } ],
  270. comment: 'This is not quite right. See the class grammar right now' } ],
  271. '#object-types':
  272. [ { token: 'storage.type.generic.vala',
  273. regex: '\\b(?:[a-z]\\w*\\.)*[A-Z]+\\w*<',
  274. push:
  275. [ { token: 'storage.type.generic.vala',
  276. regex: '>|[^\\w\\s,\\?<\\[()\\]]',
  277. TODO: 'FIXME: regexp doesn\'t have js equivalent',
  278. originalRegex: '>|[^\\w\\s,\\?<\\[(?:[,]+)\\]]',
  279. next: 'pop' },
  280. { include: '#object-types' },
  281. { token: 'storage.type.generic.vala',
  282. regex: '<',
  283. push:
  284. [ { token: 'storage.type.generic.vala',
  285. regex: '>|[^\\w\\s,\\[\\]<]',
  286. next: 'pop' },
  287. { defaultToken: 'storage.type.generic.vala' } ],
  288. comment: 'This is just to support <>\'s with no actual type prefix' },
  289. { defaultToken: 'storage.type.generic.vala' } ] },
  290. { token: 'storage.type.object.array.vala',
  291. regex: '\\b(?:[a-z]\\w*\\.)*[A-Z]+\\w*(?=\\[)',
  292. push:
  293. [ { token: 'storage.type.object.array.vala',
  294. regex: '(?=[^\\]\\s])',
  295. next: 'pop' },
  296. { token: 'text',
  297. regex: '\\[',
  298. push:
  299. [ { token: 'text', regex: '\\]', next: 'pop' },
  300. { include: '#code' } ] },
  301. { defaultToken: 'storage.type.object.array.vala' } ] },
  302. { token:
  303. [ 'storage.type.vala',
  304. 'keyword.operator.dereference.vala',
  305. 'storage.type.vala' ],
  306. regex: '\\b(?:([a-z]\\w*)(\\.))*([A-Z]+\\w*\\b)' } ],
  307. '#object-types-inherited':
  308. [ { token: 'entity.other.inherited-class.vala',
  309. regex: '\\b(?:[a-z]\\w*\\.)*[A-Z]+\\w*<',
  310. push:
  311. [ { token: 'entity.other.inherited-class.vala',
  312. regex: '>|[^\\w\\s,<]',
  313. next: 'pop' },
  314. { include: '#object-types' },
  315. { token: 'storage.type.generic.vala',
  316. regex: '<',
  317. push:
  318. [ { token: 'storage.type.generic.vala',
  319. regex: '>|[^\\w\\s,<]',
  320. next: 'pop' },
  321. { defaultToken: 'storage.type.generic.vala' } ],
  322. comment: 'This is just to support <>\'s with no actual type prefix' },
  323. { defaultToken: 'entity.other.inherited-class.vala' } ] },
  324. { token:
  325. [ 'entity.other.inherited-class.vala',
  326. 'keyword.operator.dereference.vala',
  327. 'entity.other.inherited-class.vala' ],
  328. regex: '\\b(?:([a-z]\\w*)(\\.))*([A-Z]+\\w*)' } ],
  329. '#parameters':
  330. [ { token: 'storage.modifier.vala', regex: 'final' },
  331. { include: '#primitive-arrays' },
  332. { include: '#primitive-types' },
  333. { include: '#object-types' },
  334. { token: 'variable.parameter.vala', regex: '\\w+' } ],
  335. '#parens':
  336. [ { token: 'text',
  337. regex: '\\(',
  338. push:
  339. [ { token: 'text', regex: '\\)', next: 'pop' },
  340. { include: '#code' } ] } ],
  341. '#primitive-arrays':
  342. [ { token: 'storage.type.primitive.array.vala',
  343. regex: '\\b(?:bool|byte|sbyte|char|decimal|double|float|int|uint|long|ulong|object|short|ushort|string|void|int8|int16|int32|int64|uint8|uint16|uint32|uint64)(?:\\[\\])*\\b' } ],
  344. '#primitive-types':
  345. [ { token: 'storage.type.primitive.vala',
  346. regex: '\\b(?:var|bool|byte|sbyte|char|decimal|double|float|int|uint|long|ulong|object|short|ushort|string|void|signal|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b',
  347. comment: 'var is not really a primitive, but acts like one in most cases' } ],
  348. '#storage-modifiers':
  349. [ { token: 'storage.modifier.vala',
  350. regex: '\\b(?:public|private|protected|internal|static|final|sealed|virtual|override|abstract|readonly|volatile|dynamic|async|unsafe|out|ref|weak|owned|unowned|const)\\b',
  351. comment: 'Not sure about unsafe and readonly' } ],
  352. '#strings':
  353. [ { token: 'punctuation.definition.string.begin.vala',
  354. regex: '@"',
  355. push:
  356. [ { token: 'punctuation.definition.string.end.vala',
  357. regex: '"',
  358. next: 'pop' },
  359. { token: 'constant.character.escape.vala',
  360. regex: '\\\\.|%[\\w\\.\\-]+|\\$(?:\\w+|\\([\\w\\s\\+\\-\\*\\/]+\\))' },
  361. { defaultToken: 'string.quoted.interpolated.vala' } ] },
  362. { token: 'punctuation.definition.string.begin.vala',
  363. regex: '"',
  364. push:
  365. [ { token: 'punctuation.definition.string.end.vala',
  366. regex: '"',
  367. next: 'pop' },
  368. { token: 'constant.character.escape.vala', regex: '\\\\.' },
  369. { token: 'constant.character.escape.vala',
  370. regex: '%[\\w\\.\\-]+' },
  371. { defaultToken: 'string.quoted.double.vala' } ] },
  372. { token: 'punctuation.definition.string.begin.vala',
  373. regex: '\'',
  374. push:
  375. [ { token: 'punctuation.definition.string.end.vala',
  376. regex: '\'',
  377. next: 'pop' },
  378. { token: 'constant.character.escape.vala', regex: '\\\\.' },
  379. { defaultToken: 'string.quoted.single.vala' } ] },
  380. { token: 'punctuation.definition.string.begin.vala',
  381. regex: '"""',
  382. push:
  383. [ { token: 'punctuation.definition.string.end.vala',
  384. regex: '"""',
  385. next: 'pop' },
  386. { token: 'constant.character.escape.vala',
  387. regex: '%[\\w\\.\\-]+' },
  388. { defaultToken: 'string.quoted.triple.vala' } ] } ],
  389. '#throws':
  390. [ { token: 'storage.modifier.vala',
  391. regex: 'throws',
  392. push:
  393. [ { token: 'meta.throwables.vala', regex: '(?={|;)', next: 'pop' },
  394. { include: '#object-types' },
  395. { defaultToken: 'meta.throwables.vala' } ] } ],
  396. '#values':
  397. [ { include: '#strings' },
  398. { include: '#object-types' },
  399. { include: '#constants-and-special-vars' } ] }
  400. this.normalizeRules();
  401. };
  402. ValaHighlightRules.metaData = {
  403. comment: 'Based heavily on the Java bundle\'s language syntax. TODO:\n* Closures\n* Delegates\n* Properties: Better support for properties.\n* Annotations\n* Error domains\n* Named arguments\n* Array slicing, negative indexes, multidimensional\n* construct blocks\n* lock blocks?\n* regex literals\n* DocBlock syntax highlighting. (Currently importing javadoc)\n* Folding rule for comments.\n',
  404. fileTypes: [ 'vala' ],
  405. foldingStartMarker: '(\\{\\s*(//.*)?$|^\\s*// \\{\\{\\{)',
  406. foldingStopMarker: '^\\s*(\\}|// \\}\\}\\}$)',
  407. name: 'Vala',
  408. scopeName: 'source.vala' }
  409. oop.inherits(ValaHighlightRules, TextHighlightRules);
  410. exports.ValaHighlightRules = ValaHighlightRules;
  411. });
  412. ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) {
  413. "use strict";
  414. var oop = require("../../lib/oop");
  415. var Range = require("../../range").Range;
  416. var BaseFoldMode = require("./fold_mode").FoldMode;
  417. var FoldMode = exports.FoldMode = function(commentRegex) {
  418. if (commentRegex) {
  419. this.foldingStartMarker = new RegExp(
  420. this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start)
  421. );
  422. this.foldingStopMarker = new RegExp(
  423. this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end)
  424. );
  425. }
  426. };
  427. oop.inherits(FoldMode, BaseFoldMode);
  428. (function() {
  429. this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/;
  430. this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/;
  431. this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) {
  432. var line = session.getLine(row);
  433. var match = line.match(this.foldingStartMarker);
  434. if (match) {
  435. var i = match.index;
  436. if (match[1])
  437. return this.openingBracketBlock(session, match[1], row, i);
  438. var range = session.getCommentFoldRange(row, i + match[0].length, 1);
  439. if (range && !range.isMultiLine()) {
  440. if (forceMultiline) {
  441. range = this.getSectionRange(session, row);
  442. } else if (foldStyle != "all")
  443. range = null;
  444. }
  445. return range;
  446. }
  447. if (foldStyle === "markbegin")
  448. return;
  449. var match = line.match(this.foldingStopMarker);
  450. if (match) {
  451. var i = match.index + match[0].length;
  452. if (match[1])
  453. return this.closingBracketBlock(session, match[1], row, i);
  454. return session.getCommentFoldRange(row, i, -1);
  455. }
  456. };
  457. this.getSectionRange = function(session, row) {
  458. var line = session.getLine(row);
  459. var startIndent = line.search(/\S/);
  460. var startRow = row;
  461. var startColumn = line.length;
  462. row = row + 1;
  463. var endRow = row;
  464. var maxRow = session.getLength();
  465. while (++row < maxRow) {
  466. line = session.getLine(row);
  467. var indent = line.search(/\S/);
  468. if (indent === -1)
  469. continue;
  470. if (startIndent > indent)
  471. break;
  472. var subRange = this.getFoldWidgetRange(session, "all", row);
  473. if (subRange) {
  474. if (subRange.start.row <= startRow) {
  475. break;
  476. } else if (subRange.isMultiLine()) {
  477. row = subRange.end.row;
  478. } else if (startIndent == indent) {
  479. break;
  480. }
  481. }
  482. endRow = row;
  483. }
  484. return new Range(startRow, startColumn, endRow, session.getLine(endRow).length);
  485. };
  486. }).call(FoldMode.prototype);
  487. });
  488. ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(require, exports, module) {
  489. "use strict";
  490. var oop = require("../../lib/oop");
  491. var Behaviour = require("../behaviour").Behaviour;
  492. var TokenIterator = require("../../token_iterator").TokenIterator;
  493. var lang = require("../../lib/lang");
  494. var SAFE_INSERT_IN_TOKENS =
  495. ["text", "paren.rparen", "punctuation.operator"];
  496. var SAFE_INSERT_BEFORE_TOKENS =
  497. ["text", "paren.rparen", "punctuation.operator", "comment"];
  498. var context;
  499. var contextCache = {}
  500. var initContext = function(editor) {
  501. var id = -1;
  502. if (editor.multiSelect) {
  503. id = editor.selection.id;
  504. if (contextCache.rangeCount != editor.multiSelect.rangeCount)
  505. contextCache = {rangeCount: editor.multiSelect.rangeCount};
  506. }
  507. if (contextCache[id])
  508. return context = contextCache[id];
  509. context = contextCache[id] = {
  510. autoInsertedBrackets: 0,
  511. autoInsertedRow: -1,
  512. autoInsertedLineEnd: "",
  513. maybeInsertedBrackets: 0,
  514. maybeInsertedRow: -1,
  515. maybeInsertedLineStart: "",
  516. maybeInsertedLineEnd: ""
  517. };
  518. };
  519. var CstyleBehaviour = function() {
  520. this.add("braces", "insertion", function(state, action, editor, session, text) {
  521. var cursor = editor.getCursorPosition();
  522. var line = session.doc.getLine(cursor.row);
  523. if (text == '{') {
  524. initContext(editor);
  525. var selection = editor.getSelectionRange();
  526. var selected = session.doc.getTextRange(selection);
  527. if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) {
  528. return {
  529. text: '{' + selected + '}',
  530. selection: false
  531. };
  532. } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
  533. if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode) {
  534. CstyleBehaviour.recordAutoInsert(editor, session, "}");
  535. return {
  536. text: '{}',
  537. selection: [1, 1]
  538. };
  539. } else {
  540. CstyleBehaviour.recordMaybeInsert(editor, session, "{");
  541. return {
  542. text: '{',
  543. selection: [1, 1]
  544. };
  545. }
  546. }
  547. } else if (text == '}') {
  548. initContext(editor);
  549. var rightChar = line.substring(cursor.column, cursor.column + 1);
  550. if (rightChar == '}') {
  551. var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
  552. if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
  553. CstyleBehaviour.popAutoInsertedClosing();
  554. return {
  555. text: '',
  556. selection: [1, 1]
  557. };
  558. }
  559. }
  560. } else if (text == "\n" || text == "\r\n") {
  561. initContext(editor);
  562. var closing = "";
  563. if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {
  564. closing = lang.stringRepeat("}", context.maybeInsertedBrackets);
  565. CstyleBehaviour.clearMaybeInsertedClosing();
  566. }
  567. var rightChar = line.substring(cursor.column, cursor.column + 1);
  568. if (rightChar === '}') {
  569. var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}');
  570. if (!openBracePos)
  571. return null;
  572. var next_indent = this.$getIndent(session.getLine(openBracePos.row));
  573. } else if (closing) {
  574. var next_indent = this.$getIndent(line);
  575. } else {
  576. CstyleBehaviour.clearMaybeInsertedClosing();
  577. return;
  578. }
  579. var indent = next_indent + session.getTabString();
  580. return {
  581. text: '\n' + indent + '\n' + next_indent + closing,
  582. selection: [1, indent.length, 1, indent.length]
  583. };
  584. } else {
  585. CstyleBehaviour.clearMaybeInsertedClosing();
  586. }
  587. });
  588. this.add("braces", "deletion", function(state, action, editor, session, range) {
  589. var selected = session.doc.getTextRange(range);
  590. if (!range.isMultiLine() && selected == '{') {
  591. initContext(editor);
  592. var line = session.doc.getLine(range.start.row);
  593. var rightChar = line.substring(range.end.column, range.end.column + 1);
  594. if (rightChar == '}') {
  595. range.end.column++;
  596. return range;
  597. } else {
  598. context.maybeInsertedBrackets--;
  599. }
  600. }
  601. });
  602. this.add("parens", "insertion", function(state, action, editor, session, text) {
  603. if (text == '(') {
  604. initContext(editor);
  605. var selection = editor.getSelectionRange();
  606. var selected = session.doc.getTextRange(selection);
  607. if (selected !== "" && editor.getWrapBehavioursEnabled()) {
  608. return {
  609. text: '(' + selected + ')',
  610. selection: false
  611. };
  612. } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
  613. CstyleBehaviour.recordAutoInsert(editor, session, ")");
  614. return {
  615. text: '()',
  616. selection: [1, 1]
  617. };
  618. }
  619. } else if (text == ')') {
  620. initContext(editor);
  621. var cursor = editor.getCursorPosition();
  622. var line = session.doc.getLine(cursor.row);
  623. var rightChar = line.substring(cursor.column, cursor.column + 1);
  624. if (rightChar == ')') {
  625. var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});
  626. if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
  627. CstyleBehaviour.popAutoInsertedClosing();
  628. return {
  629. text: '',
  630. selection: [1, 1]
  631. };
  632. }
  633. }
  634. }
  635. });
  636. this.add("parens", "deletion", function(state, action, editor, session, range) {
  637. var selected = session.doc.getTextRange(range);
  638. if (!range.isMultiLine() && selected == '(') {
  639. initContext(editor);
  640. var line = session.doc.getLine(range.start.row);
  641. var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
  642. if (rightChar == ')') {
  643. range.end.column++;
  644. return range;
  645. }
  646. }
  647. });
  648. this.add("brackets", "insertion", function(state, action, editor, session, text) {
  649. if (text == '[') {
  650. initContext(editor);
  651. var selection = editor.getSelectionRange();
  652. var selected = session.doc.getTextRange(selection);
  653. if (selected !== "" && editor.getWrapBehavioursEnabled()) {
  654. return {
  655. text: '[' + selected + ']',
  656. selection: false
  657. };
  658. } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
  659. CstyleBehaviour.recordAutoInsert(editor, session, "]");
  660. return {
  661. text: '[]',
  662. selection: [1, 1]
  663. };
  664. }
  665. } else if (text == ']') {
  666. initContext(editor);
  667. var cursor = editor.getCursorPosition();
  668. var line = session.doc.getLine(cursor.row);
  669. var rightChar = line.substring(cursor.column, cursor.column + 1);
  670. if (rightChar == ']') {
  671. var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});
  672. if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
  673. CstyleBehaviour.popAutoInsertedClosing();
  674. return {
  675. text: '',
  676. selection: [1, 1]
  677. };
  678. }
  679. }
  680. }
  681. });
  682. this.add("brackets", "deletion", function(state, action, editor, session, range) {
  683. var selected = session.doc.getTextRange(range);
  684. if (!range.isMultiLine() && selected == '[') {
  685. initContext(editor);
  686. var line = session.doc.getLine(range.start.row);
  687. var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
  688. if (rightChar == ']') {
  689. range.end.column++;
  690. return range;
  691. }
  692. }
  693. });
  694. this.add("string_dquotes", "insertion", function(state, action, editor, session, text) {
  695. if (text == '"' || text == "'") {
  696. initContext(editor);
  697. var quote = text;
  698. var selection = editor.getSelectionRange();
  699. var selected = session.doc.getTextRange(selection);
  700. if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) {
  701. return {
  702. text: quote + selected + quote,
  703. selection: false
  704. };
  705. } else {
  706. var cursor = editor.getCursorPosition();
  707. var line = session.doc.getLine(cursor.row);
  708. var leftChar = line.substring(cursor.column-1, cursor.column);
  709. if (leftChar == '\\') {
  710. return null;
  711. }
  712. var tokens = session.getTokens(selection.start.row);
  713. var col = 0, token;
  714. var quotepos = -1; // Track whether we're inside an open quote.
  715. for (var x = 0; x < tokens.length; x++) {
  716. token = tokens[x];
  717. if (token.type == "string") {
  718. quotepos = -1;
  719. } else if (quotepos < 0) {
  720. quotepos = token.value.indexOf(quote);
  721. }
  722. if ((token.value.length + col) > selection.start.column) {
  723. break;
  724. }
  725. col += tokens[x].value.length;
  726. }
  727. if (!token || (quotepos < 0 && token.type !== "comment" && (token.type !== "string" || ((selection.start.column !== token.value.length+col-1) && token.value.lastIndexOf(quote) === token.value.length-1)))) {
  728. if (!CstyleBehaviour.isSaneInsertion(editor, session))
  729. return;
  730. return {
  731. text: quote + quote,
  732. selection: [1,1]
  733. };
  734. } else if (token && token.type === "string") {
  735. var rightChar = line.substring(cursor.column, cursor.column + 1);
  736. if (rightChar == quote) {
  737. return {
  738. text: '',
  739. selection: [1, 1]
  740. };
  741. }
  742. }
  743. }
  744. }
  745. });
  746. this.add("string_dquotes", "deletion", function(state, action, editor, session, range) {
  747. var selected = session.doc.getTextRange(range);
  748. if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
  749. initContext(editor);
  750. var line = session.doc.getLine(range.start.row);
  751. var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
  752. if (rightChar == selected) {
  753. range.end.column++;
  754. return range;
  755. }
  756. }
  757. });
  758. };
  759. CstyleBehaviour.isSaneInsertion = function(editor, session) {
  760. var cursor = editor.getCursorPosition();
  761. var iterator = new TokenIterator(session, cursor.row, cursor.column);
  762. if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) {
  763. var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);
  764. if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS))
  765. return false;
  766. }
  767. iterator.stepForward();
  768. return iterator.getCurrentTokenRow() !== cursor.row ||
  769. this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS);
  770. };
  771. CstyleBehaviour.$matchTokenType = function(token, types) {
  772. return types.indexOf(token.type || token) > -1;
  773. };
  774. CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) {
  775. var cursor = editor.getCursorPosition();
  776. var line = session.doc.getLine(cursor.row);
  777. if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0]))
  778. context.autoInsertedBrackets = 0;
  779. context.autoInsertedRow = cursor.row;
  780. context.autoInsertedLineEnd = bracket + line.substr(cursor.column);
  781. context.autoInsertedBrackets++;
  782. };
  783. CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) {
  784. var cursor = editor.getCursorPosition();
  785. var line = session.doc.getLine(cursor.row);
  786. if (!this.isMaybeInsertedClosing(cursor, line))
  787. context.maybeInsertedBrackets = 0;
  788. context.maybeInsertedRow = cursor.row;
  789. context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;
  790. context.maybeInsertedLineEnd = line.substr(cursor.column);
  791. context.maybeInsertedBrackets++;
  792. };
  793. CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) {
  794. return context.autoInsertedBrackets > 0 &&
  795. cursor.row === context.autoInsertedRow &&
  796. bracket === context.autoInsertedLineEnd[0] &&
  797. line.substr(cursor.column) === context.autoInsertedLineEnd;
  798. };
  799. CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) {
  800. return context.maybeInsertedBrackets > 0 &&
  801. cursor.row === context.maybeInsertedRow &&
  802. line.substr(cursor.column) === context.maybeInsertedLineEnd &&
  803. line.substr(0, cursor.column) == context.maybeInsertedLineStart;
  804. };
  805. CstyleBehaviour.popAutoInsertedClosing = function() {
  806. context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1);
  807. context.autoInsertedBrackets--;
  808. };
  809. CstyleBehaviour.clearMaybeInsertedClosing = function() {
  810. if (context) {
  811. context.maybeInsertedBrackets = 0;
  812. context.maybeInsertedRow = -1;
  813. }
  814. };
  815. oop.inherits(CstyleBehaviour, Behaviour);
  816. exports.CstyleBehaviour = CstyleBehaviour;
  817. });
  818. ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) {
  819. "use strict";
  820. var Range = require("../range").Range;
  821. var MatchingBraceOutdent = function() {};
  822. (function() {
  823. this.checkOutdent = function(line, input) {
  824. if (! /^\s+$/.test(line))
  825. return false;
  826. return /^\s*\}/.test(input);
  827. };
  828. this.autoOutdent = function(doc, row) {
  829. var line = doc.getLine(row);
  830. var match = line.match(/^(\s*\})/);
  831. if (!match) return 0;
  832. var column = match[1].length;
  833. var openBracePos = doc.findMatchingBracket({row: row, column: column});
  834. if (!openBracePos || openBracePos.row == row) return 0;
  835. var indent = this.$getIndent(doc.getLine(openBracePos.row));
  836. doc.replace(new Range(row, 0, row, column-1), indent);
  837. };
  838. this.$getIndent = function(line) {
  839. return line.match(/^\s*/)[0];
  840. };
  841. }).call(MatchingBraceOutdent.prototype);
  842. exports.MatchingBraceOutdent = MatchingBraceOutdent;
  843. });
  844. ace.define("ace/mode/vala",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/vala_highlight_rules","ace/mode/folding/cstyle","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle","ace/mode/matching_brace_outdent"], function(require, exports, module) {
  845. "use strict";
  846. var oop = require("../lib/oop");
  847. var TextMode = require("./text").Mode;
  848. var Tokenizer = require("../tokenizer").Tokenizer;
  849. var ValaHighlightRules = require("./vala_highlight_rules").ValaHighlightRules;
  850. var FoldMode = require("./folding/cstyle").FoldMode;
  851. var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
  852. var CStyleFoldMode = require("./folding/cstyle").FoldMode;
  853. var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
  854. var Mode = function() {
  855. this.HighlightRules = ValaHighlightRules;
  856. this.$outdent = new MatchingBraceOutdent();
  857. this.$behaviour = new CstyleBehaviour();
  858. this.foldingRules = new CStyleFoldMode();
  859. };
  860. oop.inherits(Mode, TextMode);
  861. (function() {
  862. this.lineCommentStart = "//";
  863. this.blockComment = {start: "/*", end: "*/"};
  864. this.getNextLineIndent = function(state, line, tab) {
  865. var indent = this.$getIndent(line);
  866. var tokenizedLine = this.getTokenizer().getLineTokens(line, state);
  867. var tokens = tokenizedLine.tokens;
  868. var endState = tokenizedLine.state;
  869. if (tokens.length && tokens[tokens.length-1].type == "comment") {
  870. return indent;
  871. }
  872. if (state == "start" || state == "no_regex") {
  873. var match = line.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);
  874. if (match) {
  875. indent += tab;
  876. }
  877. } else if (state == "doc-start") {
  878. if (endState == "start" || endState == "no_regex") {
  879. return "";
  880. }
  881. var match = line.match(/^\s*(\/?)\*/);
  882. if (match) {
  883. if (match[1]) {
  884. indent += " ";
  885. }
  886. indent += "* ";
  887. }
  888. }
  889. return indent;
  890. };
  891. this.checkOutdent = function(state, line, input) {
  892. return this.$outdent.checkOutdent(line, input);
  893. };
  894. this.autoOutdent = function(state, doc, row) {
  895. this.$outdent.autoOutdent(doc, row);
  896. };
  897. this.$id = "ace/mode/vala"
  898. }).call(Mode.prototype);
  899. exports.Mode = Mode;
  900. });