require.config({ paths: { vs: window.pathLib + "monaco-editor/0.16.2/min/vs", tokenizer: window.pathSelfLib + 'vendor/tokenizer' } }); window.onEditorLoaded = function (fn) { if (window.editorLoaded) { fn(); } else { if (!window.editorLoadedHandles) window.editorLoadedHandles = []; window.editorLoadedHandles.push(fn); } }; require(['vs/editor/editor.main'], function () { require(['tokenizer/monaco-tokenizer', 'tokenizer/definitions/c_cpp', 'tokenizer/definitions/csharp', 'tokenizer/definitions/haskell', 'tokenizer/definitions/java', 'tokenizer/definitions/javascript', 'tokenizer/definitions/pascal', 'tokenizer/definitions/python', 'tokenizer/definitions/ruby'], function(MonacoAceTokenizer, c_cppDefinition, CSharpDefinition, HaskellDefinition, JavaDefinition, JavaScriptDefinition, PascalDefinition, PythonDefinition, RubyDefinition) { var overrideLangauges = [ 'cpp', 'c', 'csharp', 'haskell', 'java', 'javascript', 'pascal', 'python', 'ruby', 'markdown' ]; monaco.languages.getLanguages().forEach(function (lang) { if (overrideLangauges.includes(lang.id)) { lang.loader = function () { return { then: function () {} }; }; } }); var cppAliases = ['c', 'cpp', 'c++', 'cxx', 'cc']; for (var i in cppAliases) { var alias = cppAliases[i]; monaco.languages.register({ id: alias }); MonacoAceTokenizer.registerRulesForLanguage(alias, new c_cppDefinition.default); monaco.languages.setLanguageConfiguration(alias, { comments: { lineComment: '//', blockComment: ['/*', '*/'], }, brackets: [ ['{', '}'], ['[', ']'], ['(', ')'] ], autoClosingPairs: [ { open: '[', close: ']' }, { open: '{', close: '}' }, { open: '(', close: ')' }, { open: '\'', close: '\'', notIn: ['string', 'comment'] }, { open: '"', close: '"', notIn: ['string'] }, ], surroundingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '"', close: '"' }, { open: '\'', close: '\'' }, ], folding: { markers: { start: new RegExp("^\\s*#pragma\\s+region\\b"), end: new RegExp("^\\s*#pragma\\s+endregion\\b") } } }); } var csharpAliases = ['csharp', 'cs', 'c#']; for (var i in csharpAliases) { var alias = csharpAliases[i]; monaco.languages.register({ id: alias }); MonacoAceTokenizer.registerRulesForLanguage(alias, new CSharpDefinition.default); monaco.languages.setLanguageConfiguration(alias, { wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, comments: { lineComment: '//', blockComment: ['/*', '*/'], }, brackets: [ ['{', '}'], ['[', ']'], ['(', ')'], ], autoClosingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '\'', close: '\'', notIn: ['string', 'comment'] }, { open: '"', close: '"', notIn: ['string', 'comment'] }, ], surroundingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '<', close: '>' }, { open: '\'', close: '\'' }, { open: '"', close: '"' }, ], folding: { markers: { start: new RegExp("^\\s*#region\\b"), end: new RegExp("^\\s*#endregion\\b") } } }); } monaco.languages.register({ id: 'haskell' }); MonacoAceTokenizer.registerRulesForLanguage('haskell', new HaskellDefinition.default); monaco.languages.setLanguageConfiguration('haskell', { comments: { lineComment: '--', blockComment: ['{-', '-}'] }, brackets: [ ['{', '}'], ['[', ']'], ['(', ')'] ], autoClosingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '\'', close: '\'', notIn: ['string'] }, { open: '`', close: '`', notIn: ['string', 'comment'] } ], surroundingPairs: [ ['{', '}'], ['[', ']'], ['(', ')'], ['\'', '\''], ['"', '"'], ['`', '`'] ], indentationRules: { decreaseIndentPattern: new RegExp("[\\]})][ \\t]*$/m"), increaseIndentPattern: new RegExp("((\\b(if\\b.*|then|else|do|of|let|in|where))|=|->|>>=|>=>|=<<|(^(data)( |\t)+(\\w|')+( |\\t)*))( |\\t)*$/") } }); monaco.languages.register({ id: 'java' }); MonacoAceTokenizer.registerRulesForLanguage('java', new JavaDefinition.default); monaco.languages.setLanguageConfiguration('java', { // the default separators except `@$` wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, comments: { lineComment: '//', blockComment: ['/*', '*/'], }, brackets: [ ['{', '}'], ['[', ']'], ['(', ')'], ], autoClosingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '"', close: '"' }, { open: '\'', close: '\'' }, ], surroundingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '"', close: '"' }, { open: '\'', close: '\'' }, { open: '<', close: '>' }, ], folding: { markers: { start: new RegExp("^\\s*//\\s*(?:(?:#?region\\b)|(?:))") } } }); var javascriptAliases = ['javascript', 'js']; for (var i in javascriptAliases) { var alias = javascriptAliases[i]; monaco.languages.register({ id: alias }); MonacoAceTokenizer.registerRulesForLanguage(alias, new JavaScriptDefinition.default); monaco.languages.setLanguageConfiguration(alias, { wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, comments: { lineComment: '//', blockComment: ['/*', '*/'] }, brackets: [ ['{', '}'], ['[', ']'], ['(', ')'] ], onEnterRules: [ { // e.g. /** | */ beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/, afterText: /^\s*\*\/$/, action: { indentAction: monaco.languages.IndentAction.IndentOutdent, appendText: ' * ' } }, { // e.g. /** ...| beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/, action: { indentAction: monaco.languages.IndentAction.None, appendText: ' * ' } }, { // e.g. * ...| beforeText: /^(\t|(\ \ ))*\ \*(\ ([^\*]|\*(?!\/))*)?$/, action: { indentAction: monaco.languages.IndentAction.None, appendText: '* ' } }, { // e.g. */| beforeText: /^(\t|(\ \ ))*\ \*\/\s*$/, action: { indentAction: monaco.languages.IndentAction.None, removeText: 1 } } ], autoClosingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '"', close: '"', notIn: ['string'] }, { open: '\'', close: '\'', notIn: ['string', 'comment'] }, { open: '`', close: '`', notIn: ['string', 'comment'] }, { open: "/**", close: " */", notIn: ["string"] } ], folding: { markers: { start: new RegExp("^\\s*//\\s*#?region\\b"), end: new RegExp("^\\s*//\\s*#?endregion\\b") } } }); } var pascalAliases = ['pascal', 'pas']; for (var i in pascalAliases) { var alias = pascalAliases[i]; monaco.languages.register({ id: alias }); MonacoAceTokenizer.registerRulesForLanguage(alias, new PascalDefinition.default); monaco.languages.setLanguageConfiguration(alias, { // the default separators except `@$` wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, comments: { lineComment: '//', blockComment: ['{', '}'], }, brackets: [ ['{', '}'], ['[', ']'], ['(', ')'], ['<', '>'], ], autoClosingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '<', close: '>' }, { open: '\'', close: '\'' }, ], surroundingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '<', close: '>' }, { open: '\'', close: '\'' }, ], folding: { markers: { start: new RegExp("^\\s*\\{\\$REGION(\\s\\'.*\\')?\\}"), end: new RegExp("^\\s*\\{\\$ENDREGION\\}") } } }); } var pythonAliases = ['python', 'python2', 'python3', 'py', 'py2', 'py3']; for (var i in pythonAliases) { var alias = pythonAliases[i]; monaco.languages.register({ id: alias }); MonacoAceTokenizer.registerRulesForLanguage(alias, new PythonDefinition.default); monaco.languages.setLanguageConfiguration(alias, { comments: { lineComment: '#', blockComment: ['\'\'\'', '\'\'\''], }, brackets: [ ['{', '}'], ['[', ']'], ['(', ')'] ], autoClosingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '"', close: '"', notIn: ['string'] }, { open: '\'', close: '\'', notIn: ['string', 'comment'] }, ], surroundingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '"', close: '"' }, { open: '\'', close: '\'' }, ], onEnterRules: [ { beforeText: new RegExp("^\\s*(?:def|class|for|if|elif|else|while|try|with|finally|except|async).*?:\\s*$"), action: { indentAction: monaco.languages.IndentAction.Indent } } ], folding: { offSide: true, markers: { start: new RegExp("^\\s*#region\\b"), end: new RegExp("^\\s*#endregion\\b") } } }); } monaco.languages.register({ id: 'ruby' }); MonacoAceTokenizer.registerRulesForLanguage('ruby', new RubyDefinition.default); monaco.languages.setLanguageConfiguration('ruby', { comments: { lineComment: '#', blockComment: ['=begin', '=end'], }, brackets: [ ['(', ')'], ['{', '}'], ['[', ']'] ], autoClosingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '"', close: '"' }, { open: '\'', close: '\'' }, ], surroundingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '"', close: '"' }, { open: '\'', close: '\'' }, ], indentationRules: { 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)*(#.*)?$'), decreaseIndentPattern: new RegExp('^\\s*([}\\]]([,)]?\\s*(#|$)|\\.[a-zA-Z_]\\w*\\b)|(end|rescue|ensure|else|elsif|when)\\b)'), } }); var markdownAliases = ['markdown', 'md']; for (var i in markdownAliases) { var alias = markdownAliases[i]; monaco.languages.register({ id: alias }); monaco.languages.setLanguageConfiguration(alias, { comments: { blockComment: ['',] }, brackets: [ ['{', '}'], ['[', ']'], ['(', ')'] ], autoClosingPairs: [ { open: '{', close: '}' }, { open: '[', close: ']' }, { open: '(', close: ')' }, { open: '<', close: '>', notIn: ['string'] } ], surroundingPairs: [ { open: '(', close: ')' }, { open: '[', close: ']' }, { open: '`', close: '`' }, ], folding: { markers: { start: new RegExp("^\\s*"), end: new RegExp("^\\s*") } } }); monaco.languages.setMonarchTokensProvider(alias, { defaultToken: '', tokenPostfix: '.md', // escape codes control: /[\\`*_\[\]{}()#+\-\.!\$]/, noncontrol: /[^\\`*_\[\]{}()#+\-\.!\$]/, escapes: /\\(?:@control)/, // escape codes for javascript/CSS strings jsescapes: /\\(?:[btnfr\\"']|[0-7][0-7]?|[0-3][0-7]{2})/, // non matched elements empty: [ 'area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param' ], tokenizer: { root: [ // headers (with #) [/^(\s{0,3})(#+)((?:[^\\#]|@escapes)+)((?:#+)?)/, ['white', 'keyword', 'keyword', 'keyword']], // headers (with =) [/^\s*(=+|\-+)\s*$/, 'keyword'], // headers (with ***) [/^\s*((\*[ ]?)+)\s*$/, 'meta.separator'], // quote [/^\s*>+/, 'comment'], // list (starting with * or number) [/^\s*([\*\-+:]|\d+\.)\s/, 'keyword'], // code block (4 spaces indent) [/^(\t|[ ]{4})[^ ].*$/, 'string'], // code block (3 tilde) [/^\s*~~~\s*((?:\w|[\/\-#])+)?\s*$/, { token: 'string', next: '@codeblock' }], // display math [/\$\$/, { token: 'string', next: '@displaymath' }], // github style code blocks (with backticks and language) [/^\s*```\s*((?:\w|[\/\-#\+])+)\s*$/, { token: 'string', next: '@codeblockgh', nextEmbedded: '$1' }], // github style code blocks (with backticks but no language) [/^\s*```\s*$/, { token: 'string', next: '@codeblock' }], // markup within lines { include: '@linecontent' }, ], displaymath: [ [/\\\$/, 'variable.source'], [/\$\$/, { token: 'string', next: '@pop' }], [/./, 'variable.source'] ], codeblock: [ [/^\s*~~~\s*$/, { token: 'string', next: '@pop' }], [/^\s*```\s*$/, { token: 'string', next: '@pop' }], [/.*$/, 'variable.source'], ], // github style code blocks codeblockgh: [ [/```\s*$/, { token: 'variable.source', next: '@pop', nextEmbedded: '@pop' }], [/[^`]+/, 'variable.source'], ], linecontent: [ // inline math [/\$/, { token: 'string', next: '@inlinemath' }], // escapes [/&\w+;/, 'string.escape'], [/@escapes/, 'escape'], // various markup [/\b__([^\\_]|@escapes|_(?!_))+__\b/, 'strong'], [/\*\*([^\\*]|@escapes|\*(?!\*))+\*\*/, 'strong'], [/\b_[^_]+_\b/, 'emphasis'], [/\*([^\\*]|@escapes)+\*/, 'emphasis'], [/`([^\\`]|@escapes)+`/, 'variable'], // links [/\{+[^}]+\}+/, 'string.target'], [/(!?\[)((?:[^\]\\]|@escapes)*)(\]\([^\)]+\))/, ['string.link', '', 'string.link']], [/(!?\[)((?:[^\]\\]|@escapes)*)(\])/, 'string.link'], // or html { include: 'html' }, ], inlinemath: [ [/\\\$/, 'variable.source'], [/\$/, { token: 'string', next: '@pop' }], [/./, 'variable.source'] ], // Note: it is tempting to rather switch to the real HTML mode instead of building our own here // but currently there is a limitation in Monarch that prevents us from doing it: The opening // '<' would start the HTML mode, however there is no way to jump 1 character back to let the // HTML mode also tokenize the opening angle bracket. Thus, even though we could jump to HTML, // we cannot correctly tokenize it in that mode yet. html: [ // html tags [/<(\w+)\/>/, 'tag'], [/<(\w+)/, { cases: { '@empty': { token: 'tag', next: '@tag.$1' }, '@default': { token: 'tag', next: '@tag.$1' } } }], [/<\/(\w+)\s*>/, { token: 'tag' }], [//, 'comment', '@pop'], [/