File modules/editor/codemirror/mode/vb/vb.js
Last commit: Sun Dec 17 01:14:09 2017 +0100 Jan Dankert Integration eines weiteren Code-Editors: Codemirror. Demnächst müssen wir hier mal aufräumen und andere Editoren rauswerfen.
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 // Distributed under an MIT license: http://codemirror.net/LICENSE 3 4 (function(mod) { 5 if (typeof exports == "object" && typeof module == "object") // CommonJS 6 mod(require("../../lib/codemirror")); 7 else if (typeof define == "function" && define.amd) // AMD 8 define(["../../lib/codemirror"], mod); 9 else // Plain browser env 10 mod(CodeMirror); 11 })(function(CodeMirror) { 12 "use strict"; 13 14 CodeMirror.defineMode("vb", function(conf, parserConf) { 15 var ERRORCLASS = 'error'; 16 17 function wordRegexp(words) { 18 return new RegExp("^((" + words.join(")|(") + "))\\b", "i"); 19 } 20 21 var singleOperators = new RegExp("^[\\+\\-\\*/%&\\\\|\\^~<>!]"); 22 var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]'); 23 var doubleOperators = new RegExp("^((==)|(<>)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))"); 24 var doubleDelimiters = new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))"); 25 var tripleDelimiters = new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))"); 26 var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*"); 27 28 var openingKeywords = ['class','module', 'sub','enum','select','while','if','function', 'get','set','property', 'try']; 29 var middleKeywords = ['else','elseif','case', 'catch']; 30 var endKeywords = ['next','loop']; 31 32 var operatorKeywords = ['and', 'or', 'not', 'xor', 'in']; 33 var wordOperators = wordRegexp(operatorKeywords); 34 var commonKeywords = ['as', 'dim', 'break', 'continue','optional', 'then', 'until', 35 'goto', 'byval','byref','new','handles','property', 'return', 36 'const','private', 'protected', 'friend', 'public', 'shared', 'static', 'true','false']; 37 var commontypes = ['integer','string','double','decimal','boolean','short','char', 'float','single']; 38 39 var keywords = wordRegexp(commonKeywords); 40 var types = wordRegexp(commontypes); 41 var stringPrefixes = '"'; 42 43 var opening = wordRegexp(openingKeywords); 44 var middle = wordRegexp(middleKeywords); 45 var closing = wordRegexp(endKeywords); 46 var doubleClosing = wordRegexp(['end']); 47 var doOpening = wordRegexp(['do']); 48 49 var indentInfo = null; 50 51 CodeMirror.registerHelper("hintWords", "vb", openingKeywords.concat(middleKeywords).concat(endKeywords) 52 .concat(operatorKeywords).concat(commonKeywords).concat(commontypes)); 53 54 function indent(_stream, state) { 55 state.currentIndent++; 56 } 57 58 function dedent(_stream, state) { 59 state.currentIndent--; 60 } 61 // tokenizers 62 function tokenBase(stream, state) { 63 if (stream.eatSpace()) { 64 return null; 65 } 66 67 var ch = stream.peek(); 68 69 // Handle Comments 70 if (ch === "'") { 71 stream.skipToEnd(); 72 return 'comment'; 73 } 74 75 76 // Handle Number Literals 77 if (stream.match(/^((&H)|(&O))?[0-9\.a-f]/i, false)) { 78 var floatLiteral = false; 79 // Floats 80 if (stream.match(/^\d*\.\d+F?/i)) { floatLiteral = true; } 81 else if (stream.match(/^\d+\.\d*F?/)) { floatLiteral = true; } 82 else if (stream.match(/^\.\d+F?/)) { floatLiteral = true; } 83 84 if (floatLiteral) { 85 // Float literals may be "imaginary" 86 stream.eat(/J/i); 87 return 'number'; 88 } 89 // Integers 90 var intLiteral = false; 91 // Hex 92 if (stream.match(/^&H[0-9a-f]+/i)) { intLiteral = true; } 93 // Octal 94 else if (stream.match(/^&O[0-7]+/i)) { intLiteral = true; } 95 // Decimal 96 else if (stream.match(/^[1-9]\d*F?/)) { 97 // Decimal literals may be "imaginary" 98 stream.eat(/J/i); 99 // TODO - Can you have imaginary longs? 100 intLiteral = true; 101 } 102 // Zero by itself with no other piece of number. 103 else if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; } 104 if (intLiteral) { 105 // Integer literals may be "long" 106 stream.eat(/L/i); 107 return 'number'; 108 } 109 } 110 111 // Handle Strings 112 if (stream.match(stringPrefixes)) { 113 state.tokenize = tokenStringFactory(stream.current()); 114 return state.tokenize(stream, state); 115 } 116 117 // Handle operators and Delimiters 118 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) { 119 return null; 120 } 121 if (stream.match(doubleOperators) 122 || stream.match(singleOperators) 123 || stream.match(wordOperators)) { 124 return 'operator'; 125 } 126 if (stream.match(singleDelimiters)) { 127 return null; 128 } 129 if (stream.match(doOpening)) { 130 indent(stream,state); 131 state.doInCurrentLine = true; 132 return 'keyword'; 133 } 134 if (stream.match(opening)) { 135 if (! state.doInCurrentLine) 136 indent(stream,state); 137 else 138 state.doInCurrentLine = false; 139 return 'keyword'; 140 } 141 if (stream.match(middle)) { 142 return 'keyword'; 143 } 144 145 if (stream.match(doubleClosing)) { 146 dedent(stream,state); 147 dedent(stream,state); 148 return 'keyword'; 149 } 150 if (stream.match(closing)) { 151 dedent(stream,state); 152 return 'keyword'; 153 } 154 155 if (stream.match(types)) { 156 return 'keyword'; 157 } 158 159 if (stream.match(keywords)) { 160 return 'keyword'; 161 } 162 163 if (stream.match(identifiers)) { 164 return 'variable'; 165 } 166 167 // Handle non-detected items 168 stream.next(); 169 return ERRORCLASS; 170 } 171 172 function tokenStringFactory(delimiter) { 173 var singleline = delimiter.length == 1; 174 var OUTCLASS = 'string'; 175 176 return function(stream, state) { 177 while (!stream.eol()) { 178 stream.eatWhile(/[^'"]/); 179 if (stream.match(delimiter)) { 180 state.tokenize = tokenBase; 181 return OUTCLASS; 182 } else { 183 stream.eat(/['"]/); 184 } 185 } 186 if (singleline) { 187 if (parserConf.singleLineStringErrors) { 188 return ERRORCLASS; 189 } else { 190 state.tokenize = tokenBase; 191 } 192 } 193 return OUTCLASS; 194 }; 195 } 196 197 198 function tokenLexer(stream, state) { 199 var style = state.tokenize(stream, state); 200 var current = stream.current(); 201 202 // Handle '.' connected identifiers 203 if (current === '.') { 204 style = state.tokenize(stream, state); 205 if (style === 'variable') { 206 return 'variable'; 207 } else { 208 return ERRORCLASS; 209 } 210 } 211 212 213 var delimiter_index = '[({'.indexOf(current); 214 if (delimiter_index !== -1) { 215 indent(stream, state ); 216 } 217 if (indentInfo === 'dedent') { 218 if (dedent(stream, state)) { 219 return ERRORCLASS; 220 } 221 } 222 delimiter_index = '])}'.indexOf(current); 223 if (delimiter_index !== -1) { 224 if (dedent(stream, state)) { 225 return ERRORCLASS; 226 } 227 } 228 229 return style; 230 } 231 232 var external = { 233 electricChars:"dDpPtTfFeE ", 234 startState: function() { 235 return { 236 tokenize: tokenBase, 237 lastToken: null, 238 currentIndent: 0, 239 nextLineIndent: 0, 240 doInCurrentLine: false 241 242 243 }; 244 }, 245 246 token: function(stream, state) { 247 if (stream.sol()) { 248 state.currentIndent += state.nextLineIndent; 249 state.nextLineIndent = 0; 250 state.doInCurrentLine = 0; 251 } 252 var style = tokenLexer(stream, state); 253 254 state.lastToken = {style:style, content: stream.current()}; 255 256 257 258 return style; 259 }, 260 261 indent: function(state, textAfter) { 262 var trueText = textAfter.replace(/^\s+|\s+$/g, '') ; 263 if (trueText.match(closing) || trueText.match(doubleClosing) || trueText.match(middle)) return conf.indentUnit*(state.currentIndent-1); 264 if(state.currentIndent < 0) return 0; 265 return state.currentIndent * conf.indentUnit; 266 }, 267 268 lineComment: "'" 269 }; 270 return external; 271 }); 272 273 CodeMirror.defineMIME("text/x-vb", "vb"); 274 275 });
Downloadmodules/editor/codemirror/mode/vb/vb.js
History Sun, 17 Dec 2017 01:14:09 +0100 Jan Dankert Integration eines weiteren Code-Editors: Codemirror. Demnächst müssen wir hier mal aufräumen und andere Editoren rauswerfen.