Mercurial
comparison .cms/lib/codemirror/mode/vb/vb.js @ 0:78edf6b517a0 draft
24.10
author | Coffee CMS <info@coffee-cms.ru> |
---|---|
date | Fri, 11 Oct 2024 22:40:23 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78edf6b517a0 |
---|---|
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others | |
2 // Distributed under an MIT license: https://codemirror.net/5/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', 'structure', 'synclock', 'using', 'with']; | |
29 var middleKeywords = ['else','elseif','case', 'catch', 'finally']; | |
30 var endKeywords = ['next','loop']; | |
31 | |
32 var operatorKeywords = ['and', "andalso", 'or', 'orelse', 'xor', 'in', 'not', 'is', 'isnot', 'like']; | |
33 var wordOperators = wordRegexp(operatorKeywords); | |
34 | |
35 var commonKeywords = ["#const", "#else", "#elseif", "#end", "#if", "#region", "addhandler", "addressof", "alias", "as", "byref", "byval", "cbool", "cbyte", "cchar", "cdate", "cdbl", "cdec", "cint", "clng", "cobj", "compare", "const", "continue", "csbyte", "cshort", "csng", "cstr", "cuint", "culng", "cushort", "declare", "default", "delegate", "dim", "directcast", "each", "erase", "error", "event", "exit", "explicit", "false", "for", "friend", "gettype", "goto", "handles", "implements", "imports", "infer", "inherits", "interface", "isfalse", "istrue", "lib", "me", "mod", "mustinherit", "mustoverride", "my", "mybase", "myclass", "namespace", "narrowing", "new", "nothing", "notinheritable", "notoverridable", "of", "off", "on", "operator", "option", "optional", "out", "overloads", "overridable", "overrides", "paramarray", "partial", "private", "protected", "public", "raiseevent", "readonly", "redim", "removehandler", "resume", "return", "shadows", "shared", "static", "step", "stop", "strict", "then", "throw", "to", "true", "trycast", "typeof", "until", "until", "when", "widening", "withevents", "writeonly"]; | |
36 | |
37 var commontypes = ['object', 'boolean', 'char', 'string', 'byte', 'sbyte', 'short', 'ushort', 'int16', 'uint16', 'integer', 'uinteger', 'int32', 'uint32', 'long', 'ulong', 'int64', 'uint64', 'decimal', 'single', 'double', 'float', 'date', 'datetime', 'intptr', 'uintptr']; | |
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 }); |