mode-csharp.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. ace.define("ace/mode/doc_comment_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 DocCommentHighlightRules = function() {
  6. this.$rules = {
  7. "start" : [ {
  8. token : "comment.doc.tag",
  9. regex : "@[\\w\\d_]+" // TODO: fix email addresses
  10. }, {
  11. token : "comment.doc.tag",
  12. regex : "\\bTODO\\b"
  13. }, {
  14. defaultToken : "comment.doc"
  15. }]
  16. };
  17. };
  18. oop.inherits(DocCommentHighlightRules, TextHighlightRules);
  19. DocCommentHighlightRules.getStartRule = function(start) {
  20. return {
  21. token : "comment.doc", // doc comment
  22. regex : "\\/\\*(?=\\*)",
  23. next : start
  24. };
  25. };
  26. DocCommentHighlightRules.getEndRule = function (start) {
  27. return {
  28. token : "comment.doc", // closing comment
  29. regex : "\\*\\/",
  30. next : start
  31. };
  32. };
  33. exports.DocCommentHighlightRules = DocCommentHighlightRules;
  34. });
  35. ace.define("ace/mode/csharp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"], function(require, exports, module) {
  36. "use strict";
  37. var oop = require("../lib/oop");
  38. var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
  39. var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
  40. var CSharpHighlightRules = function() {
  41. var keywordMapper = this.createKeywordMapper({
  42. "variable.language": "this",
  43. "keyword": "abstract|event|new|struct|as|explicit|null|switch|base|extern|object|this|bool|false|operator|throw|break|finally|out|true|byte|fixed|override|try|case|float|params|typeof|catch|for|private|uint|char|foreach|protected|ulong|checked|goto|public|unchecked|class|if|readonly|unsafe|const|implicit|ref|ushort|continue|in|return|using|decimal|int|sbyte|virtual|default|interface|sealed|volatile|delegate|internal|short|void|do|is|sizeof|while|double|lock|stackalloc|else|long|static|enum|namespace|string|var|dynamic",
  44. "constant.language": "null|true|false"
  45. }, "identifier");
  46. this.$rules = {
  47. "start" : [
  48. {
  49. token : "comment",
  50. regex : "\\/\\/.*$"
  51. },
  52. DocCommentHighlightRules.getStartRule("doc-start"),
  53. {
  54. token : "comment", // multi line comment
  55. regex : "\\/\\*",
  56. next : "comment"
  57. }, {
  58. token : "string", // character
  59. regex : /'(?:.|\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n]))'/
  60. }, {
  61. token : "string", start : '"', end : '"|$', next: [
  62. {token: "constant.language.escape", regex: /\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n])/},
  63. {token: "invalid", regex: /\\./}
  64. ]
  65. }, {
  66. token : "string", start : '@"', end : '"', next:[
  67. {token: "constant.language.escape", regex: '""'}
  68. ]
  69. }, {
  70. token : "constant.numeric", // hex
  71. regex : "0[xX][0-9a-fA-F]+\\b"
  72. }, {
  73. token : "constant.numeric", // float
  74. regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
  75. }, {
  76. token : "constant.language.boolean",
  77. regex : "(?:true|false)\\b"
  78. }, {
  79. token : keywordMapper,
  80. regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
  81. }, {
  82. token : "keyword.operator",
  83. regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"
  84. }, {
  85. token : "keyword",
  86. regex : "^\\s*#(if|else|elif|endif|define|undef|warning|error|line|region|endregion|pragma)"
  87. }, {
  88. token : "punctuation.operator",
  89. regex : "\\?|\\:|\\,|\\;|\\."
  90. }, {
  91. token : "paren.lparen",
  92. regex : "[[({]"
  93. }, {
  94. token : "paren.rparen",
  95. regex : "[\\])}]"
  96. }, {
  97. token : "text",
  98. regex : "\\s+"
  99. }
  100. ],
  101. "comment" : [
  102. {
  103. token : "comment", // closing comment
  104. regex : ".*?\\*\\/",
  105. next : "start"
  106. }, {
  107. token : "comment", // comment spanning whole line
  108. regex : ".+"
  109. }
  110. ]
  111. };
  112. this.embedRules(DocCommentHighlightRules, "doc-",
  113. [ DocCommentHighlightRules.getEndRule("start") ]);
  114. this.normalizeRules();
  115. };
  116. oop.inherits(CSharpHighlightRules, TextHighlightRules);
  117. exports.CSharpHighlightRules = CSharpHighlightRules;
  118. });
  119. ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) {
  120. "use strict";
  121. var Range = require("../range").Range;
  122. var MatchingBraceOutdent = function() {};
  123. (function() {
  124. this.checkOutdent = function(line, input) {
  125. if (! /^\s+$/.test(line))
  126. return false;
  127. return /^\s*\}/.test(input);
  128. };
  129. this.autoOutdent = function(doc, row) {
  130. var line = doc.getLine(row);
  131. var match = line.match(/^(\s*\})/);
  132. if (!match) return 0;
  133. var column = match[1].length;
  134. var openBracePos = doc.findMatchingBracket({row: row, column: column});
  135. if (!openBracePos || openBracePos.row == row) return 0;
  136. var indent = this.$getIndent(doc.getLine(openBracePos.row));
  137. doc.replace(new Range(row, 0, row, column-1), indent);
  138. };
  139. this.$getIndent = function(line) {
  140. return line.match(/^\s*/)[0];
  141. };
  142. }).call(MatchingBraceOutdent.prototype);
  143. exports.MatchingBraceOutdent = MatchingBraceOutdent;
  144. });
  145. 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) {
  146. "use strict";
  147. var oop = require("../../lib/oop");
  148. var Behaviour = require("../behaviour").Behaviour;
  149. var TokenIterator = require("../../token_iterator").TokenIterator;
  150. var lang = require("../../lib/lang");
  151. var SAFE_INSERT_IN_TOKENS =
  152. ["text", "paren.rparen", "punctuation.operator"];
  153. var SAFE_INSERT_BEFORE_TOKENS =
  154. ["text", "paren.rparen", "punctuation.operator", "comment"];
  155. var context;
  156. var contextCache = {}
  157. var initContext = function(editor) {
  158. var id = -1;
  159. if (editor.multiSelect) {
  160. id = editor.selection.id;
  161. if (contextCache.rangeCount != editor.multiSelect.rangeCount)
  162. contextCache = {rangeCount: editor.multiSelect.rangeCount};
  163. }
  164. if (contextCache[id])
  165. return context = contextCache[id];
  166. context = contextCache[id] = {
  167. autoInsertedBrackets: 0,
  168. autoInsertedRow: -1,
  169. autoInsertedLineEnd: "",
  170. maybeInsertedBrackets: 0,
  171. maybeInsertedRow: -1,
  172. maybeInsertedLineStart: "",
  173. maybeInsertedLineEnd: ""
  174. };
  175. };
  176. var CstyleBehaviour = function() {
  177. this.add("braces", "insertion", function(state, action, editor, session, text) {
  178. var cursor = editor.getCursorPosition();
  179. var line = session.doc.getLine(cursor.row);
  180. if (text == '{') {
  181. initContext(editor);
  182. var selection = editor.getSelectionRange();
  183. var selected = session.doc.getTextRange(selection);
  184. if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) {
  185. return {
  186. text: '{' + selected + '}',
  187. selection: false
  188. };
  189. } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
  190. if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode) {
  191. CstyleBehaviour.recordAutoInsert(editor, session, "}");
  192. return {
  193. text: '{}',
  194. selection: [1, 1]
  195. };
  196. } else {
  197. CstyleBehaviour.recordMaybeInsert(editor, session, "{");
  198. return {
  199. text: '{',
  200. selection: [1, 1]
  201. };
  202. }
  203. }
  204. } else if (text == '}') {
  205. initContext(editor);
  206. var rightChar = line.substring(cursor.column, cursor.column + 1);
  207. if (rightChar == '}') {
  208. var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
  209. if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
  210. CstyleBehaviour.popAutoInsertedClosing();
  211. return {
  212. text: '',
  213. selection: [1, 1]
  214. };
  215. }
  216. }
  217. } else if (text == "\n" || text == "\r\n") {
  218. initContext(editor);
  219. var closing = "";
  220. if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {
  221. closing = lang.stringRepeat("}", context.maybeInsertedBrackets);
  222. CstyleBehaviour.clearMaybeInsertedClosing();
  223. }
  224. var rightChar = line.substring(cursor.column, cursor.column + 1);
  225. if (rightChar === '}') {
  226. var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}');
  227. if (!openBracePos)
  228. return null;
  229. var next_indent = this.$getIndent(session.getLine(openBracePos.row));
  230. } else if (closing) {
  231. var next_indent = this.$getIndent(line);
  232. } else {
  233. CstyleBehaviour.clearMaybeInsertedClosing();
  234. return;
  235. }
  236. var indent = next_indent + session.getTabString();
  237. return {
  238. text: '\n' + indent + '\n' + next_indent + closing,
  239. selection: [1, indent.length, 1, indent.length]
  240. };
  241. } else {
  242. CstyleBehaviour.clearMaybeInsertedClosing();
  243. }
  244. });
  245. this.add("braces", "deletion", function(state, action, editor, session, range) {
  246. var selected = session.doc.getTextRange(range);
  247. if (!range.isMultiLine() && selected == '{') {
  248. initContext(editor);
  249. var line = session.doc.getLine(range.start.row);
  250. var rightChar = line.substring(range.end.column, range.end.column + 1);
  251. if (rightChar == '}') {
  252. range.end.column++;
  253. return range;
  254. } else {
  255. context.maybeInsertedBrackets--;
  256. }
  257. }
  258. });
  259. this.add("parens", "insertion", function(state, action, editor, session, text) {
  260. if (text == '(') {
  261. initContext(editor);
  262. var selection = editor.getSelectionRange();
  263. var selected = session.doc.getTextRange(selection);
  264. if (selected !== "" && editor.getWrapBehavioursEnabled()) {
  265. return {
  266. text: '(' + selected + ')',
  267. selection: false
  268. };
  269. } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
  270. CstyleBehaviour.recordAutoInsert(editor, session, ")");
  271. return {
  272. text: '()',
  273. selection: [1, 1]
  274. };
  275. }
  276. } else if (text == ')') {
  277. initContext(editor);
  278. var cursor = editor.getCursorPosition();
  279. var line = session.doc.getLine(cursor.row);
  280. var rightChar = line.substring(cursor.column, cursor.column + 1);
  281. if (rightChar == ')') {
  282. var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});
  283. if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
  284. CstyleBehaviour.popAutoInsertedClosing();
  285. return {
  286. text: '',
  287. selection: [1, 1]
  288. };
  289. }
  290. }
  291. }
  292. });
  293. this.add("parens", "deletion", function(state, action, editor, session, range) {
  294. var selected = session.doc.getTextRange(range);
  295. if (!range.isMultiLine() && selected == '(') {
  296. initContext(editor);
  297. var line = session.doc.getLine(range.start.row);
  298. var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
  299. if (rightChar == ')') {
  300. range.end.column++;
  301. return range;
  302. }
  303. }
  304. });
  305. this.add("brackets", "insertion", function(state, action, editor, session, text) {
  306. if (text == '[') {
  307. initContext(editor);
  308. var selection = editor.getSelectionRange();
  309. var selected = session.doc.getTextRange(selection);
  310. if (selected !== "" && editor.getWrapBehavioursEnabled()) {
  311. return {
  312. text: '[' + selected + ']',
  313. selection: false
  314. };
  315. } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
  316. CstyleBehaviour.recordAutoInsert(editor, session, "]");
  317. return {
  318. text: '[]',
  319. selection: [1, 1]
  320. };
  321. }
  322. } else if (text == ']') {
  323. initContext(editor);
  324. var cursor = editor.getCursorPosition();
  325. var line = session.doc.getLine(cursor.row);
  326. var rightChar = line.substring(cursor.column, cursor.column + 1);
  327. if (rightChar == ']') {
  328. var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});
  329. if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
  330. CstyleBehaviour.popAutoInsertedClosing();
  331. return {
  332. text: '',
  333. selection: [1, 1]
  334. };
  335. }
  336. }
  337. }
  338. });
  339. this.add("brackets", "deletion", function(state, action, editor, session, range) {
  340. var selected = session.doc.getTextRange(range);
  341. if (!range.isMultiLine() && selected == '[') {
  342. initContext(editor);
  343. var line = session.doc.getLine(range.start.row);
  344. var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
  345. if (rightChar == ']') {
  346. range.end.column++;
  347. return range;
  348. }
  349. }
  350. });
  351. this.add("string_dquotes", "insertion", function(state, action, editor, session, text) {
  352. if (text == '"' || text == "'") {
  353. initContext(editor);
  354. var quote = text;
  355. var selection = editor.getSelectionRange();
  356. var selected = session.doc.getTextRange(selection);
  357. if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) {
  358. return {
  359. text: quote + selected + quote,
  360. selection: false
  361. };
  362. } else {
  363. var cursor = editor.getCursorPosition();
  364. var line = session.doc.getLine(cursor.row);
  365. var leftChar = line.substring(cursor.column-1, cursor.column);
  366. if (leftChar == '\\') {
  367. return null;
  368. }
  369. var tokens = session.getTokens(selection.start.row);
  370. var col = 0, token;
  371. var quotepos = -1; // Track whether we're inside an open quote.
  372. for (var x = 0; x < tokens.length; x++) {
  373. token = tokens[x];
  374. if (token.type == "string") {
  375. quotepos = -1;
  376. } else if (quotepos < 0) {
  377. quotepos = token.value.indexOf(quote);
  378. }
  379. if ((token.value.length + col) > selection.start.column) {
  380. break;
  381. }
  382. col += tokens[x].value.length;
  383. }
  384. 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)))) {
  385. if (!CstyleBehaviour.isSaneInsertion(editor, session))
  386. return;
  387. return {
  388. text: quote + quote,
  389. selection: [1,1]
  390. };
  391. } else if (token && token.type === "string") {
  392. var rightChar = line.substring(cursor.column, cursor.column + 1);
  393. if (rightChar == quote) {
  394. return {
  395. text: '',
  396. selection: [1, 1]
  397. };
  398. }
  399. }
  400. }
  401. }
  402. });
  403. this.add("string_dquotes", "deletion", function(state, action, editor, session, range) {
  404. var selected = session.doc.getTextRange(range);
  405. if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
  406. initContext(editor);
  407. var line = session.doc.getLine(range.start.row);
  408. var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
  409. if (rightChar == selected) {
  410. range.end.column++;
  411. return range;
  412. }
  413. }
  414. });
  415. };
  416. CstyleBehaviour.isSaneInsertion = function(editor, session) {
  417. var cursor = editor.getCursorPosition();
  418. var iterator = new TokenIterator(session, cursor.row, cursor.column);
  419. if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) {
  420. var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);
  421. if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS))
  422. return false;
  423. }
  424. iterator.stepForward();
  425. return iterator.getCurrentTokenRow() !== cursor.row ||
  426. this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS);
  427. };
  428. CstyleBehaviour.$matchTokenType = function(token, types) {
  429. return types.indexOf(token.type || token) > -1;
  430. };
  431. CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) {
  432. var cursor = editor.getCursorPosition();
  433. var line = session.doc.getLine(cursor.row);
  434. if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0]))
  435. context.autoInsertedBrackets = 0;
  436. context.autoInsertedRow = cursor.row;
  437. context.autoInsertedLineEnd = bracket + line.substr(cursor.column);
  438. context.autoInsertedBrackets++;
  439. };
  440. CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) {
  441. var cursor = editor.getCursorPosition();
  442. var line = session.doc.getLine(cursor.row);
  443. if (!this.isMaybeInsertedClosing(cursor, line))
  444. context.maybeInsertedBrackets = 0;
  445. context.maybeInsertedRow = cursor.row;
  446. context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;
  447. context.maybeInsertedLineEnd = line.substr(cursor.column);
  448. context.maybeInsertedBrackets++;
  449. };
  450. CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) {
  451. return context.autoInsertedBrackets > 0 &&
  452. cursor.row === context.autoInsertedRow &&
  453. bracket === context.autoInsertedLineEnd[0] &&
  454. line.substr(cursor.column) === context.autoInsertedLineEnd;
  455. };
  456. CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) {
  457. return context.maybeInsertedBrackets > 0 &&
  458. cursor.row === context.maybeInsertedRow &&
  459. line.substr(cursor.column) === context.maybeInsertedLineEnd &&
  460. line.substr(0, cursor.column) == context.maybeInsertedLineStart;
  461. };
  462. CstyleBehaviour.popAutoInsertedClosing = function() {
  463. context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1);
  464. context.autoInsertedBrackets--;
  465. };
  466. CstyleBehaviour.clearMaybeInsertedClosing = function() {
  467. if (context) {
  468. context.maybeInsertedBrackets = 0;
  469. context.maybeInsertedRow = -1;
  470. }
  471. };
  472. oop.inherits(CstyleBehaviour, Behaviour);
  473. exports.CstyleBehaviour = CstyleBehaviour;
  474. });
  475. ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) {
  476. "use strict";
  477. var oop = require("../../lib/oop");
  478. var Range = require("../../range").Range;
  479. var BaseFoldMode = require("./fold_mode").FoldMode;
  480. var FoldMode = exports.FoldMode = function(commentRegex) {
  481. if (commentRegex) {
  482. this.foldingStartMarker = new RegExp(
  483. this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start)
  484. );
  485. this.foldingStopMarker = new RegExp(
  486. this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end)
  487. );
  488. }
  489. };
  490. oop.inherits(FoldMode, BaseFoldMode);
  491. (function() {
  492. this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/;
  493. this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/;
  494. this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) {
  495. var line = session.getLine(row);
  496. var match = line.match(this.foldingStartMarker);
  497. if (match) {
  498. var i = match.index;
  499. if (match[1])
  500. return this.openingBracketBlock(session, match[1], row, i);
  501. var range = session.getCommentFoldRange(row, i + match[0].length, 1);
  502. if (range && !range.isMultiLine()) {
  503. if (forceMultiline) {
  504. range = this.getSectionRange(session, row);
  505. } else if (foldStyle != "all")
  506. range = null;
  507. }
  508. return range;
  509. }
  510. if (foldStyle === "markbegin")
  511. return;
  512. var match = line.match(this.foldingStopMarker);
  513. if (match) {
  514. var i = match.index + match[0].length;
  515. if (match[1])
  516. return this.closingBracketBlock(session, match[1], row, i);
  517. return session.getCommentFoldRange(row, i, -1);
  518. }
  519. };
  520. this.getSectionRange = function(session, row) {
  521. var line = session.getLine(row);
  522. var startIndent = line.search(/\S/);
  523. var startRow = row;
  524. var startColumn = line.length;
  525. row = row + 1;
  526. var endRow = row;
  527. var maxRow = session.getLength();
  528. while (++row < maxRow) {
  529. line = session.getLine(row);
  530. var indent = line.search(/\S/);
  531. if (indent === -1)
  532. continue;
  533. if (startIndent > indent)
  534. break;
  535. var subRange = this.getFoldWidgetRange(session, "all", row);
  536. if (subRange) {
  537. if (subRange.start.row <= startRow) {
  538. break;
  539. } else if (subRange.isMultiLine()) {
  540. row = subRange.end.row;
  541. } else if (startIndent == indent) {
  542. break;
  543. }
  544. }
  545. endRow = row;
  546. }
  547. return new Range(startRow, startColumn, endRow, session.getLine(endRow).length);
  548. };
  549. }).call(FoldMode.prototype);
  550. });
  551. ace.define("ace/mode/folding/csharp",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/cstyle"], function(require, exports, module) {
  552. "use strict";
  553. var oop = require("../../lib/oop");
  554. var Range = require("../../range").Range;
  555. var CFoldMode = require("./cstyle").FoldMode;
  556. var FoldMode = exports.FoldMode = function(commentRegex) {
  557. if (commentRegex) {
  558. this.foldingStartMarker = new RegExp(
  559. this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start)
  560. );
  561. this.foldingStopMarker = new RegExp(
  562. this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end)
  563. );
  564. }
  565. };
  566. oop.inherits(FoldMode, CFoldMode);
  567. (function() {
  568. this.usingRe = /^\s*using \S/;
  569. this.getFoldWidgetRangeBase = this.getFoldWidgetRange;
  570. this.getFoldWidgetBase = this.getFoldWidget;
  571. this.getFoldWidget = function(session, foldStyle, row) {
  572. var fw = this.getFoldWidgetBase(session, foldStyle, row);
  573. if (!fw) {
  574. var line = session.getLine(row);
  575. if (/^\s*#region\b/.test(line))
  576. return "start";
  577. var usingRe = this.usingRe;
  578. if (usingRe.test(line)) {
  579. var prev = session.getLine(row - 1);
  580. var next = session.getLine(row + 1);
  581. if (!usingRe.test(prev) && usingRe.test(next))
  582. return "start"
  583. }
  584. }
  585. return fw;
  586. };
  587. this.getFoldWidgetRange = function(session, foldStyle, row) {
  588. var range = this.getFoldWidgetRangeBase(session, foldStyle, row);
  589. if (range)
  590. return range;
  591. var line = session.getLine(row);
  592. if (this.usingRe.test(line))
  593. return this.getUsingStatementBlock(session, line, row);
  594. if (/^\s*#region\b/.test(line))
  595. return this.getRegionBlock(session, line, row);
  596. };
  597. this.getUsingStatementBlock = function(session, line, row) {
  598. var startColumn = line.match(this.usingRe)[0].length - 1;
  599. var maxRow = session.getLength();
  600. var startRow = row;
  601. var endRow = row;
  602. while (++row < maxRow) {
  603. line = session.getLine(row);
  604. if (/^\s*$/.test(line))
  605. continue;
  606. if (!this.usingRe.test(line))
  607. break;
  608. endRow = row;
  609. }
  610. if (endRow > startRow) {
  611. var endColumn = session.getLine(endRow).length;
  612. return new Range(startRow, startColumn, endRow, endColumn);
  613. }
  614. };
  615. this.getRegionBlock = function(session, line, row) {
  616. var startColumn = line.search(/\s*$/);
  617. var maxRow = session.getLength();
  618. var startRow = row;
  619. var re = /^\s*#(end)?region\b/
  620. var depth = 1
  621. while (++row < maxRow) {
  622. line = session.getLine(row);
  623. var m = re.exec(line);
  624. if (!m)
  625. continue;
  626. if (m[1])
  627. depth--;
  628. else
  629. depth++;
  630. if (!depth)
  631. break;
  632. }
  633. var endRow = row;
  634. if (endRow > startRow) {
  635. var endColumn = line.search(/\S/);
  636. return new Range(startRow, startColumn, endRow, endColumn);
  637. }
  638. };
  639. }).call(FoldMode.prototype);
  640. });
  641. ace.define("ace/mode/csharp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/csharp_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/csharp"], function(require, exports, module) {
  642. "use strict";
  643. var oop = require("../lib/oop");
  644. var TextMode = require("./text").Mode;
  645. var CSharpHighlightRules = require("./csharp_highlight_rules").CSharpHighlightRules;
  646. var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
  647. var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
  648. var CStyleFoldMode = require("./folding/csharp").FoldMode;
  649. var Mode = function() {
  650. this.HighlightRules = CSharpHighlightRules;
  651. this.$outdent = new MatchingBraceOutdent();
  652. this.$behaviour = new CstyleBehaviour();
  653. this.foldingRules = new CStyleFoldMode();
  654. };
  655. oop.inherits(Mode, TextMode);
  656. (function() {
  657. this.lineCommentStart = "//";
  658. this.blockComment = {start: "/*", end: "*/"};
  659. this.getNextLineIndent = function(state, line, tab) {
  660. var indent = this.$getIndent(line);
  661. var tokenizedLine = this.getTokenizer().getLineTokens(line, state);
  662. var tokens = tokenizedLine.tokens;
  663. if (tokens.length && tokens[tokens.length-1].type == "comment") {
  664. return indent;
  665. }
  666. if (state == "start") {
  667. var match = line.match(/^.*[\{\(\[]\s*$/);
  668. if (match) {
  669. indent += tab;
  670. }
  671. }
  672. return indent;
  673. };
  674. this.checkOutdent = function(state, line, input) {
  675. return this.$outdent.checkOutdent(line, input);
  676. };
  677. this.autoOutdent = function(state, doc, row) {
  678. this.$outdent.autoOutdent(doc, row);
  679. };
  680. this.createWorker = function(session) {
  681. return null;
  682. };
  683. this.$id = "ace/mode/csharp";
  684. }).call(Mode.prototype);
  685. exports.Mode = Mode;
  686. });