##// END OF EJS Templates
codemirror: update from 5.4.0 to 5.11.0, fixes #3154
marcink -
r346:1a48416d default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,405 +1,416 b''
1 1 /* BASICS */
2 2
3 3 .CodeMirror {
4 4 /* Set height, width, borders, and global font properties here */
5 5 font-family: monospace;
6 6 height: 300px;
7 7 color: black;
8 8 border-radius: @border-radius;
9 9 border: @border-thickness solid @grey6;
10 10 margin: 0 0 @padding;
11 11 }
12 12
13 13 /* PADDING */
14 14
15 15 .CodeMirror-lines {
16 16 padding: 4px 0; /* Vertical padding around content */
17 17 }
18 18 .CodeMirror pre {
19 19 padding: 0 4px; /* Horizontal padding of content */
20 20 }
21 21
22 22 .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
23 23 background-color: white; /* The little square between H and V scrollbars */
24 24 }
25 25
26 26 /* GUTTER */
27 27
28 28 .CodeMirror-gutters {
29 29 border-right: 1px solid #ddd;
30 30 background-color: @grey6;
31 31 white-space: nowrap;
32 32 }
33 33 .CodeMirror-linenumbers {}
34 34 .CodeMirror-linenumber {
35 35 padding: 0 3px 0 5px;
36 36 min-width: 20px;
37 37 text-align: right;
38 38 color: @grey4;
39 39 white-space: nowrap;
40 40 }
41 41
42 42 .CodeMirror-guttermarker { color: black; }
43 43 .CodeMirror-guttermarker-subtle { color: #999; }
44 44
45 45 /* CURSOR */
46 46
47 47 .CodeMirror div.CodeMirror-cursor {
48 48 border-left: 1px solid black;
49 49 }
50 50 /* Shown when moving in bi-directional text */
51 51 .CodeMirror div.CodeMirror-secondarycursor {
52 52 border-left: 1px solid silver;
53 53 }
54 54 .CodeMirror.cm-fat-cursor div.CodeMirror-cursor {
55 55 width: auto;
56 56 border: 0;
57 57 background: @grey6;
58 58 }
59 59 .CodeMirror.cm-fat-cursor div.CodeMirror-cursors {
60 60 z-index: 1;
61 61 }
62 62
63 63 .cm-animate-fat-cursor {
64 64 width: auto;
65 65 border: 0;
66 66 -webkit-animation: blink 1.06s steps(1) infinite;
67 67 -moz-animation: blink 1.06s steps(1) infinite;
68 68 animation: blink 1.06s steps(1) infinite;
69 69 }
70 70 @-moz-keyframes blink {
71 71 0% { background: #7e7; }
72 72 50% { background: none; }
73 73 100% { background: #7e7; }
74 74 }
75 75 @-webkit-keyframes blink {
76 76 0% { background: #7e7; }
77 77 50% { background: none; }
78 78 100% { background: #7e7; }
79 79 }
80 80 @keyframes blink {
81 81 0% { background: #7e7; }
82 82 50% { background: none; }
83 83 100% { background: #7e7; }
84 84 }
85 85
86 86 /* Can style cursor different in overwrite (non-insert) mode */
87 87 div.CodeMirror-overwrite div.CodeMirror-cursor {}
88 88
89 89 .cm-tab { display: inline-block; text-decoration: inherit; }
90 90
91 91 .CodeMirror-ruler {
92 92 border-left: 1px solid #ccc;
93 93 position: absolute;
94 94 }
95 95
96 96 /* DEFAULT THEME */
97 97
98 98 .cm-s-default .cm-header {color: blue;}
99 99 .cm-s-default .cm-quote {color: #090;}
100 100 .cm-negative {color: #d44;}
101 101 .cm-positive {color: #292;}
102 102 .cm-header, .cm-strong {font-weight: bold;}
103 103 .cm-em {font-style: italic;}
104 104 .cm-link {text-decoration: underline;}
105 105 .cm-strikethrough {text-decoration: line-through;}
106 106
107 107 .cm-s-default .cm-keyword {color: #708;}
108 108 .cm-s-default .cm-atom {color: #219;}
109 109 .cm-s-default .cm-number {color: #164;}
110 110 .cm-s-default .cm-def {color: #00f;}
111 111 .cm-s-default .cm-variable,
112 112 .cm-s-default .cm-punctuation,
113 113 .cm-s-default .cm-property,
114 114 .cm-s-default .cm-operator {}
115 115 .cm-s-default .cm-variable-2 {color: #05a;}
116 116 .cm-s-default .cm-variable-3 {color: #085;}
117 117 .cm-s-default .cm-comment {color: #a50;}
118 118 .cm-s-default .cm-string {color: #a11;}
119 119 .cm-s-default .cm-string-2 {color: #f50;}
120 120 .cm-s-default .cm-meta {color: #555;}
121 121 .cm-s-default .cm-qualifier {color: #555;}
122 122 .cm-s-default .cm-builtin {color: #30a;}
123 123 .cm-s-default .cm-bracket {color: #997;}
124 124 .cm-s-default .cm-tag {color: #170;}
125 125 .cm-s-default .cm-attribute {color: #00c;}
126 126 .cm-s-default .cm-hr {color: #999;}
127 127 .cm-s-default .cm-link {color: #00c;}
128 128
129 129 .cm-s-default .cm-error {color: #f00;}
130 130 .cm-invalidchar {color: #f00;}
131 131
132 132 .CodeMirror-composing { border-bottom: 2px solid; }
133 133
134 134 /* Default styles for common addons */
135 135
136 136 div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
137 137 div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
138 138 .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
139 139 .CodeMirror-activeline-background {background: #e8f2ff;}
140 140
141 141 /* STOP */
142 142
143 143 /* The rest of this file contains styles related to the mechanics of
144 144 the editor. You probably shouldn't touch them. */
145 145
146 146 .CodeMirror {
147 147 position: relative;
148 148 overflow: hidden;
149 149 background: white;
150 150 }
151 151
152 152 .CodeMirror-scroll {
153 153 overflow: scroll !important; /* Things will break if this is overridden */
154 154 /* 30px is the magic margin used to hide the element's real scrollbars */
155 155 /* See overflow: hidden in .CodeMirror */
156 156 margin-bottom: -30px; margin-right: -30px;
157 157 padding-bottom: 30px;
158 158 height: 100%;
159 159 outline: none; /* Prevent dragging from highlighting the element */
160 160 position: relative;
161 161 }
162 162 .CodeMirror-sizer {
163 163 position: relative;
164 164 border-right: 30px solid transparent;
165 165 }
166 166
167 167 /* The fake, visible scrollbars. Used to force redraw during scrolling
168 before actuall scrolling happens, thus preventing shaking and
168 before actual scrolling happens, thus preventing shaking and
169 169 flickering artifacts. */
170 170 .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
171 171 position: absolute;
172 172 z-index: 6;
173 173 display: none;
174 174 }
175 175 .CodeMirror-vscrollbar {
176 176 right: 0; top: 0;
177 177 overflow-x: hidden;
178 178 overflow-y: scroll;
179 179 }
180 180 .CodeMirror-hscrollbar {
181 181 bottom: 0; left: 0;
182 182 overflow-y: hidden;
183 183 overflow-x: scroll;
184 184 }
185 185 .CodeMirror-scrollbar-filler {
186 186 right: 0; bottom: 0;
187 187 }
188 188 .CodeMirror-gutter-filler {
189 189 left: 0; bottom: 0;
190 190 }
191 191
192 192 .CodeMirror-gutters {
193 193 position: absolute; left: 0; top: 0;
194 194 z-index: 3;
195 195 }
196 196 .CodeMirror-gutter {
197 197 white-space: normal;
198 198 height: 100%;
199 199 display: inline-block;
200 200 margin-bottom: -30px;
201 201 /* Hack to make IE7 behave */
202 202 *zoom:1;
203 203 *display:inline;
204 204 }
205 205 .CodeMirror-gutter-wrapper {
206 206 position: absolute;
207 207 z-index: 4;
208 208 height: 100%;
209 209 }
210 .CodeMirror-gutter-background {
211 position: absolute;
212 top: 0; bottom: 0;
213 z-index: 4;
214 }
210 215 .CodeMirror-gutter-elt {
211 216 position: absolute;
212 217 cursor: default;
213 218 z-index: 4;
214 219 }
215 220 .CodeMirror-gutter-wrapper {
216 221 -webkit-user-select: none;
217 222 -moz-user-select: none;
218 223 user-select: none;
219 224 }
220 225
221 226 .CodeMirror-lines {
222 227 cursor: text;
223 228 min-height: 1px; /* prevents collapsing before first draw */
224 229 }
225 230 .CodeMirror pre {
226 231 /* Reset some styles that the rest of the page might have set */
227 232 -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
228 233 border-width: 0;
229 234 background: transparent;
230 235 font-family: inherit;
231 236 font-size: inherit;
232 237 margin: 0;
233 238 white-space: pre;
234 239 word-wrap: normal;
235 240 line-height: inherit;
236 241 color: inherit;
237 242 z-index: 2;
238 243 position: relative;
239 244 overflow: visible;
240 245 -webkit-tap-highlight-color: transparent;
241 246 }
242 247 .CodeMirror-wrap pre {
243 248 word-wrap: break-word;
244 249 white-space: pre-wrap;
245 250 word-break: normal;
246 251 }
247 252
248 253 .CodeMirror-linebackground {
249 254 position: absolute;
250 255 left: 0; right: 0; top: 0; bottom: 0;
251 256 z-index: 0;
252 257 }
253 258
254 259 .CodeMirror-linewidget {
255 260 position: relative;
256 261 z-index: 2;
257 262 overflow: auto;
258 263 }
259 264
260 265 .CodeMirror-widget {}
261 266
262 267 .CodeMirror-code {
263 268 outline: none;
264 269 }
265 270
266 271 /* Force content-box sizing for the elements where we expect it */
267 272 .CodeMirror-scroll,
268 273 .CodeMirror-sizer,
269 274 .CodeMirror-gutter,
270 275 .CodeMirror-gutters,
271 276 .CodeMirror-linenumber {
272 277 -moz-box-sizing: content-box;
273 278 box-sizing: content-box;
274 279 }
275 280
276 281 .CodeMirror-measure {
277 282 position: absolute;
278 283 width: 100%;
279 284 height: 0;
280 285 overflow: hidden;
281 286 visibility: hidden;
282 287 }
283 .CodeMirror-measure pre { position: static; }
288
284 289
285 290 .CodeMirror div.CodeMirror-cursor {
286 291 position: absolute;
287 292 border-right: none;
288 293 width: 0;
289 294 }
290 295
296 .CodeMirror-measure pre { position: static; }
297
291 298 div.CodeMirror-cursors {
292 299 visibility: hidden;
293 300 position: relative;
294 301 z-index: 3;
295 302 }
303 div.CodeMirror-dragcursors {
304 visibility: visible;
305 }
306
296 307 .CodeMirror-focused div.CodeMirror-cursors {
297 308 visibility: visible;
298 309 }
299 310
300 311 .CodeMirror-selected { background: #d9d9d9; }
301 312 .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
302 313 .CodeMirror-crosshair { cursor: crosshair; }
303 .CodeMirror ::selection { background: #d7d4f0; }
304 .CodeMirror ::-moz-selection { background: #d7d4f0; }
314 .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
315 .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
305 316
306 317 .cm-searching {
307 318 background: #ffa;
308 319 background: rgba(255, 255, 0, .4);
309 320 }
310 321
311 322 /* IE7 hack to prevent it from returning funny offsetTops on the spans */
312 323 .CodeMirror span { *vertical-align: text-bottom; }
313 324
314 325 /* Used to force a border model for a node */
315 326 .cm-force-border { padding-right: .1px; }
316 327
317 328 @media print {
318 329 /* Hide the cursor when printing */
319 330 .CodeMirror div.CodeMirror-cursors {
320 331 visibility: hidden;
321 332 }
322 333 }
323 334
324 335 /* See issue #2901 */
325 336 .cm-tab-wrap-hack:after { content: ''; }
326 337
327 338 /* Help users use markselection to safely style text background */
328 339 span.CodeMirror-selectedtext { background: none; }
329 340
330 341 /* codemirror autocomplete widget */
331 342 .CodeMirror-hints {
332 343 position: absolute;
333 344 z-index: 10;
334 345 overflow: hidden;
335 346 list-style: none;
336 347
337 348 margin: 0;
338 349 padding: 0;
339 350
340 351 border-radius: @border-radius;
341 352 border: @border-thickness solid @rcblue;
342 353
343 354 color: @rcblue;
344 355 background-color: white;
345 356 font-size: 95%;
346 357
347 358 max-height: 20em;
348 359 overflow-y: auto;
349 360 }
350 361
351 362 .CodeMirror-hint {
352 363 margin: 0;
353 364 padding: 4px 8px;
354 365 max-width: 40em;
355 366 white-space: pre;
356 367 color: @rcblue;
357 368 cursor: pointer;
358 369 }
359 370
360 371 .CodeMirror-hint-active {
361 372 background: @rclightblue;
362 373 color: @rcblue;
363 374 }
364 375
365 376 .CodeMirror-hint-entry {
366 377 width: 38em;
367 378 color: @rcblue;
368 379 }
369 380
370 381 .CodeMirror-hint-entry .gravatar {
371 382 margin-right: 4px;
372 383 }
373 384
374 385 .CodeMirror-empty {
375 386 border: @border-thickness solid @grey5;
376 387 }
377 388
378 389 .CodeMirror-focused {
379 390 border: @border-thickness solid @grey5;
380 391 }
381 392
382 393 .CodeMirror-empty.CodeMirror-focused {
383 394 border: @border-thickness solid @grey5;
384 395 }
385 396
386 397 .CodeMirror pre.CodeMirror-placeholder {
387 398 color: @grey4;
388 399 }
389 400
390 401 /** RhodeCode Customizations **/
391 402
392 403 .CodeMirror.cm-s-rc-input {
393 404 border: @border-thickness solid @grey4;
394 405 }
395 406
396 407 .CodeMirror-code pre {
397 408 border-right: 30px solid transparent;
398 409 width: -webkit-fit-content;
399 410 width: -moz-fit-content;
400 411 width: fit-content;
401 412 }
402 413 .CodeMirror-wrap .CodeMirror-code pre {
403 414 border-right: none;
404 415 width: auto;
405 416 }
@@ -1,591 +1,772 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode("clike", function(config, parserConfig) {
15 15 var indentUnit = config.indentUnit,
16 16 statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
17 17 dontAlignCalls = parserConfig.dontAlignCalls,
18 18 keywords = parserConfig.keywords || {},
19 19 types = parserConfig.types || {},
20 20 builtin = parserConfig.builtin || {},
21 21 blockKeywords = parserConfig.blockKeywords || {},
22 22 defKeywords = parserConfig.defKeywords || {},
23 23 atoms = parserConfig.atoms || {},
24 24 hooks = parserConfig.hooks || {},
25 25 multiLineStrings = parserConfig.multiLineStrings,
26 26 indentStatements = parserConfig.indentStatements !== false,
27 27 indentSwitch = parserConfig.indentSwitch !== false,
28 namespaceSeparator = parserConfig.namespaceSeparator;
29 var isOperatorChar = /[+\-*&%=<>!?|\/]/;
28 namespaceSeparator = parserConfig.namespaceSeparator,
29 isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/,
30 numberStart = parserConfig.numberStart || /[\d\.]/,
31 number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
32 isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/,
33 endStatement = parserConfig.endStatement || /^[;:,]$/;
30 34
31 35 var curPunc, isDefKeyword;
32 36
33 37 function tokenBase(stream, state) {
34 38 var ch = stream.next();
35 39 if (hooks[ch]) {
36 40 var result = hooks[ch](stream, state);
37 41 if (result !== false) return result;
38 42 }
39 43 if (ch == '"' || ch == "'") {
40 44 state.tokenize = tokenString(ch);
41 45 return state.tokenize(stream, state);
42 46 }
43 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
47 if (isPunctuationChar.test(ch)) {
44 48 curPunc = ch;
45 49 return null;
46 50 }
47 if (/\d/.test(ch)) {
48 stream.eatWhile(/[\w\.]/);
49 return "number";
51 if (numberStart.test(ch)) {
52 stream.backUp(1)
53 if (stream.match(number)) return "number"
54 stream.next()
50 55 }
51 56 if (ch == "/") {
52 57 if (stream.eat("*")) {
53 58 state.tokenize = tokenComment;
54 59 return tokenComment(stream, state);
55 60 }
56 61 if (stream.eat("/")) {
57 62 stream.skipToEnd();
58 63 return "comment";
59 64 }
60 65 }
61 66 if (isOperatorChar.test(ch)) {
62 67 stream.eatWhile(isOperatorChar);
63 68 return "operator";
64 69 }
65 70 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
66 71 if (namespaceSeparator) while (stream.match(namespaceSeparator))
67 72 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
68 73
69 74 var cur = stream.current();
70 if (keywords.propertyIsEnumerable(cur)) {
71 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
72 if (defKeywords.propertyIsEnumerable(cur)) isDefKeyword = true;
75 if (contains(keywords, cur)) {
76 if (contains(blockKeywords, cur)) curPunc = "newstatement";
77 if (contains(defKeywords, cur)) isDefKeyword = true;
73 78 return "keyword";
74 79 }
75 if (types.propertyIsEnumerable(cur)) return "variable-3";
76 if (builtin.propertyIsEnumerable(cur)) {
77 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
80 if (contains(types, cur)) return "variable-3";
81 if (contains(builtin, cur)) {
82 if (contains(blockKeywords, cur)) curPunc = "newstatement";
78 83 return "builtin";
79 84 }
80 if (atoms.propertyIsEnumerable(cur)) return "atom";
85 if (contains(atoms, cur)) return "atom";
81 86 return "variable";
82 87 }
83 88
84 89 function tokenString(quote) {
85 90 return function(stream, state) {
86 91 var escaped = false, next, end = false;
87 92 while ((next = stream.next()) != null) {
88 93 if (next == quote && !escaped) {end = true; break;}
89 94 escaped = !escaped && next == "\\";
90 95 }
91 96 if (end || !(escaped || multiLineStrings))
92 97 state.tokenize = null;
93 98 return "string";
94 99 };
95 100 }
96 101
97 102 function tokenComment(stream, state) {
98 103 var maybeEnd = false, ch;
99 104 while (ch = stream.next()) {
100 105 if (ch == "/" && maybeEnd) {
101 106 state.tokenize = null;
102 107 break;
103 108 }
104 109 maybeEnd = (ch == "*");
105 110 }
106 111 return "comment";
107 112 }
108 113
109 114 function Context(indented, column, type, align, prev) {
110 115 this.indented = indented;
111 116 this.column = column;
112 117 this.type = type;
113 118 this.align = align;
114 119 this.prev = prev;
115 120 }
116 121 function isStatement(type) {
117 122 return type == "statement" || type == "switchstatement" || type == "namespace";
118 123 }
119 124 function pushContext(state, col, type) {
120 125 var indent = state.indented;
121 126 if (state.context && isStatement(state.context.type) && !isStatement(type))
122 127 indent = state.context.indented;
123 128 return state.context = new Context(indent, col, type, null, state.context);
124 129 }
125 130 function popContext(state) {
126 131 var t = state.context.type;
127 132 if (t == ")" || t == "]" || t == "}")
128 133 state.indented = state.context.indented;
129 134 return state.context = state.context.prev;
130 135 }
131 136
132 137 function typeBefore(stream, state) {
133 138 if (state.prevToken == "variable" || state.prevToken == "variable-3") return true;
134 139 if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, stream.start))) return true;
135 140 }
136 141
137 142 function isTopScope(context) {
138 143 for (;;) {
139 144 if (!context || context.type == "top") return true;
140 145 if (context.type == "}" && context.prev.type != "namespace") return false;
141 146 context = context.prev;
142 147 }
143 148 }
144 149
145 150 // Interface
146 151
147 152 return {
148 153 startState: function(basecolumn) {
149 154 return {
150 155 tokenize: null,
151 156 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
152 157 indented: 0,
153 158 startOfLine: true,
154 159 prevToken: null
155 160 };
156 161 },
157 162
158 163 token: function(stream, state) {
159 164 var ctx = state.context;
160 165 if (stream.sol()) {
161 166 if (ctx.align == null) ctx.align = false;
162 167 state.indented = stream.indentation();
163 168 state.startOfLine = true;
164 169 }
165 170 if (stream.eatSpace()) return null;
166 171 curPunc = isDefKeyword = null;
167 172 var style = (state.tokenize || tokenBase)(stream, state);
168 173 if (style == "comment" || style == "meta") return style;
169 174 if (ctx.align == null) ctx.align = true;
170 175
171 if ((curPunc == ";" || curPunc == ":" || curPunc == ","))
172 while (isStatement(state.context.type)) popContext(state);
176 if (endStatement.test(curPunc)) while (isStatement(state.context.type)) popContext(state);
173 177 else if (curPunc == "{") pushContext(state, stream.column(), "}");
174 178 else if (curPunc == "[") pushContext(state, stream.column(), "]");
175 179 else if (curPunc == "(") pushContext(state, stream.column(), ")");
176 180 else if (curPunc == "}") {
177 181 while (isStatement(ctx.type)) ctx = popContext(state);
178 182 if (ctx.type == "}") ctx = popContext(state);
179 183 while (isStatement(ctx.type)) ctx = popContext(state);
180 184 }
181 185 else if (curPunc == ctx.type) popContext(state);
182 186 else if (indentStatements &&
183 187 (((ctx.type == "}" || ctx.type == "top") && curPunc != ";") ||
184 188 (isStatement(ctx.type) && curPunc == "newstatement"))) {
185 189 var type = "statement";
186 190 if (curPunc == "newstatement" && indentSwitch && stream.current() == "switch")
187 191 type = "switchstatement";
188 192 else if (style == "keyword" && stream.current() == "namespace")
189 193 type = "namespace";
190 194 pushContext(state, stream.column(), type);
191 195 }
192 196
193 197 if (style == "variable" &&
194 198 ((state.prevToken == "def" ||
195 199 (parserConfig.typeFirstDefinitions && typeBefore(stream, state) &&
196 200 isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
197 201 style = "def";
198 202
199 203 if (hooks.token) {
200 204 var result = hooks.token(stream, state, style);
201 205 if (result !== undefined) style = result;
202 206 }
203 207
204 208 if (style == "def" && parserConfig.styleDefs === false) style = "variable";
205 209
206 210 state.startOfLine = false;
207 211 state.prevToken = isDefKeyword ? "def" : style || curPunc;
208 212 return style;
209 213 },
210 214
211 215 indent: function(state, textAfter) {
212 216 if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
213 217 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
214 218 if (isStatement(ctx.type) && firstChar == "}") ctx = ctx.prev;
219 if (hooks.indent) {
220 var hook = hooks.indent(state, ctx, textAfter);
221 if (typeof hook == "number") return hook
222 }
215 223 var closing = firstChar == ctx.type;
216 224 var switchBlock = ctx.prev && ctx.prev.type == "switchstatement";
225 if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
226 while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
227 return ctx.indented
228 }
217 229 if (isStatement(ctx.type))
218 230 return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
219 231 if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
220 232 return ctx.column + (closing ? 0 : 1);
221 233 if (ctx.type == ")" && !closing)
222 234 return ctx.indented + statementIndentUnit;
223 235
224 236 return ctx.indented + (closing ? 0 : indentUnit) +
225 237 (!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0);
226 238 },
227 239
228 240 electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
229 241 blockCommentStart: "/*",
230 242 blockCommentEnd: "*/",
231 243 lineComment: "//",
232 244 fold: "brace"
233 245 };
234 246 });
235 247
236 248 function words(str) {
237 249 var obj = {}, words = str.split(" ");
238 250 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
239 251 return obj;
240 252 }
253 function contains(words, word) {
254 if (typeof words === "function") {
255 return words(word);
256 } else {
257 return words.propertyIsEnumerable(word);
258 }
259 }
241 260 var cKeywords = "auto if break case register continue return default do sizeof " +
242 "static else struct switch extern typedef float union for " +
243 "goto while enum const volatile";
261 "static else struct switch extern typedef union for goto while enum const volatile";
244 262 var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
245 263
246 264 function cppHook(stream, state) {
247 if (!state.startOfLine) return false;
248 for (;;) {
249 if (stream.skipTo("\\")) {
250 stream.next();
251 if (stream.eol()) {
252 state.tokenize = cppHook;
253 break;
265 if (!state.startOfLine) return false
266 for (var ch, next = null; ch = stream.peek();) {
267 if (ch == "\\" && stream.match(/^.$/)) {
268 next = cppHook
269 break
270 } else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) {
271 break
254 272 }
255 } else {
256 stream.skipToEnd();
257 state.tokenize = null;
258 break;
273 stream.next()
259 274 }
260 }
261 return "meta";
275 state.tokenize = next
276 return "meta"
262 277 }
263 278
264 279 function pointerHook(_stream, state) {
265 280 if (state.prevToken == "variable-3") return "variable-3";
266 281 return false;
267 282 }
268 283
284 function cpp14Literal(stream) {
285 stream.eatWhile(/[\w\.']/);
286 return "number";
287 }
288
269 289 function cpp11StringHook(stream, state) {
270 290 stream.backUp(1);
271 291 // Raw strings.
272 292 if (stream.match(/(R|u8R|uR|UR|LR)/)) {
273 293 var match = stream.match(/"([^\s\\()]{0,16})\(/);
274 294 if (!match) {
275 295 return false;
276 296 }
277 297 state.cpp11RawStringDelim = match[1];
278 298 state.tokenize = tokenRawString;
279 299 return tokenRawString(stream, state);
280 300 }
281 301 // Unicode strings/chars.
282 302 if (stream.match(/(u8|u|U|L)/)) {
283 303 if (stream.match(/["']/, /* eat */ false)) {
284 304 return "string";
285 305 }
286 306 return false;
287 307 }
288 308 // Ignore this hook.
289 309 stream.next();
290 310 return false;
291 311 }
292 312
293 313 function cppLooksLikeConstructor(word) {
294 314 var lastTwo = /(\w+)::(\w+)$/.exec(word);
295 315 return lastTwo && lastTwo[1] == lastTwo[2];
296 316 }
297 317
298 318 // C#-style strings where "" escapes a quote.
299 319 function tokenAtString(stream, state) {
300 320 var next;
301 321 while ((next = stream.next()) != null) {
302 322 if (next == '"' && !stream.eat('"')) {
303 323 state.tokenize = null;
304 324 break;
305 325 }
306 326 }
307 327 return "string";
308 328 }
309 329
310 330 // C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
311 331 // <delim> can be a string up to 16 characters long.
312 332 function tokenRawString(stream, state) {
313 333 // Escape characters that have special regex meanings.
314 334 var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&');
315 335 var match = stream.match(new RegExp(".*?\\)" + delim + '"'));
316 336 if (match)
317 337 state.tokenize = null;
318 338 else
319 339 stream.skipToEnd();
320 340 return "string";
321 341 }
322 342
323 343 function def(mimes, mode) {
324 344 if (typeof mimes == "string") mimes = [mimes];
325 345 var words = [];
326 346 function add(obj) {
327 347 if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
328 348 words.push(prop);
329 349 }
330 350 add(mode.keywords);
331 351 add(mode.types);
332 352 add(mode.builtin);
333 353 add(mode.atoms);
334 354 if (words.length) {
335 355 mode.helperType = mimes[0];
336 356 CodeMirror.registerHelper("hintWords", mimes[0], words);
337 357 }
338 358
339 359 for (var i = 0; i < mimes.length; ++i)
340 360 CodeMirror.defineMIME(mimes[i], mode);
341 361 }
342 362
343 363 def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
344 364 name: "clike",
345 365 keywords: words(cKeywords),
346 366 types: words(cTypes + " bool _Complex _Bool float_t double_t intptr_t intmax_t " +
347 367 "int8_t int16_t int32_t int64_t uintptr_t uintmax_t uint8_t uint16_t " +
348 368 "uint32_t uint64_t"),
349 369 blockKeywords: words("case do else for if switch while struct"),
350 370 defKeywords: words("struct"),
351 371 typeFirstDefinitions: true,
352 372 atoms: words("null true false"),
353 373 hooks: {"#": cppHook, "*": pointerHook},
354 374 modeProps: {fold: ["brace", "include"]}
355 375 });
356 376
357 377 def(["text/x-c++src", "text/x-c++hdr"], {
358 378 name: "clike",
359 379 keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try explicit new " +
360 380 "static_cast typeid catch operator template typename class friend private " +
361 381 "this using const_cast inline public throw virtual delete mutable protected " +
362 382 "alignas alignof constexpr decltype nullptr noexcept thread_local final " +
363 383 "static_assert override"),
364 384 types: words(cTypes + " bool wchar_t"),
365 385 blockKeywords: words("catch class do else finally for if struct switch try while"),
366 386 defKeywords: words("class namespace struct enum union"),
367 387 typeFirstDefinitions: true,
368 388 atoms: words("true false null"),
369 389 hooks: {
370 390 "#": cppHook,
371 391 "*": pointerHook,
372 392 "u": cpp11StringHook,
373 393 "U": cpp11StringHook,
374 394 "L": cpp11StringHook,
375 395 "R": cpp11StringHook,
396 "0": cpp14Literal,
397 "1": cpp14Literal,
398 "2": cpp14Literal,
399 "3": cpp14Literal,
400 "4": cpp14Literal,
401 "5": cpp14Literal,
402 "6": cpp14Literal,
403 "7": cpp14Literal,
404 "8": cpp14Literal,
405 "9": cpp14Literal,
376 406 token: function(stream, state, style) {
377 407 if (style == "variable" && stream.peek() == "(" &&
378 408 (state.prevToken == ";" || state.prevToken == null ||
379 409 state.prevToken == "}") &&
380 410 cppLooksLikeConstructor(stream.current()))
381 411 return "def";
382 412 }
383 413 },
384 414 namespaceSeparator: "::",
385 415 modeProps: {fold: ["brace", "include"]}
386 416 });
387 417
388 418 def("text/x-java", {
389 419 name: "clike",
390 420 keywords: words("abstract assert break case catch class const continue default " +
391 421 "do else enum extends final finally float for goto if implements import " +
392 422 "instanceof interface native new package private protected public " +
393 423 "return static strictfp super switch synchronized this throw throws transient " +
394 424 "try volatile while"),
395 425 types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
396 426 "Integer Long Number Object Short String StringBuffer StringBuilder Void"),
397 427 blockKeywords: words("catch class do else finally for if switch try while"),
398 428 defKeywords: words("class interface package enum"),
399 429 typeFirstDefinitions: true,
400 430 atoms: words("true false null"),
431 endStatement: /^[;:]$/,
401 432 hooks: {
402 433 "@": function(stream) {
403 434 stream.eatWhile(/[\w\$_]/);
404 435 return "meta";
405 436 }
406 437 },
407 438 modeProps: {fold: ["brace", "import"]}
408 439 });
409 440
410 441 def("text/x-csharp", {
411 442 name: "clike",
412 443 keywords: words("abstract as async await base break case catch checked class const continue" +
413 444 " default delegate do else enum event explicit extern finally fixed for" +
414 445 " foreach goto if implicit in interface internal is lock namespace new" +
415 446 " operator out override params private protected public readonly ref return sealed" +
416 447 " sizeof stackalloc static struct switch this throw try typeof unchecked" +
417 448 " unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
418 449 " global group into join let orderby partial remove select set value var yield"),
419 450 types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" +
420 451 " Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" +
421 452 " UInt64 bool byte char decimal double short int long object" +
422 453 " sbyte float string ushort uint ulong"),
423 454 blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
424 455 defKeywords: words("class interface namespace struct var"),
425 456 typeFirstDefinitions: true,
426 457 atoms: words("true false null"),
427 458 hooks: {
428 459 "@": function(stream, state) {
429 460 if (stream.eat('"')) {
430 461 state.tokenize = tokenAtString;
431 462 return tokenAtString(stream, state);
432 463 }
433 464 stream.eatWhile(/[\w\$_]/);
434 465 return "meta";
435 466 }
436 467 }
437 468 });
438 469
439 470 function tokenTripleString(stream, state) {
440 471 var escaped = false;
441 472 while (!stream.eol()) {
442 473 if (!escaped && stream.match('"""')) {
443 474 state.tokenize = null;
444 475 break;
445 476 }
446 477 escaped = stream.next() == "\\" && !escaped;
447 478 }
448 479 return "string";
449 480 }
450 481
451 482 def("text/x-scala", {
452 483 name: "clike",
453 484 keywords: words(
454 485
455 486 /* scala */
456 "abstract case catch class def do else extends false final finally for forSome if " +
487 "abstract case catch class def do else extends final finally for forSome if " +
457 488 "implicit import lazy match new null object override package private protected return " +
458 489 "sealed super this throw trait try type val var while with yield _ : = => <- <: " +
459 490 "<% >: # @ " +
460 491
461 492 /* package scala */
462 493 "assert assume require print println printf readLine readBoolean readByte readShort " +
463 494 "readChar readInt readLong readFloat readDouble " +
464 495
465 496 ":: #:: "
466 497 ),
467 498 types: words(
468 499 "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
469 500 "Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " +
470 501 "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
471 502 "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
472 503 "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " +
473 504
474 505 /* package java.lang */
475 506 "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
476 507 "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
477 508 "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
478 509 "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
479 510 ),
480 511 multiLineStrings: true,
481 512 blockKeywords: words("catch class do else finally for forSome if match switch try while"),
482 513 defKeywords: words("class def object package trait type val var"),
483 514 atoms: words("true false null"),
484 515 indentStatements: false,
485 516 indentSwitch: false,
486 517 hooks: {
487 518 "@": function(stream) {
488 519 stream.eatWhile(/[\w\$_]/);
489 520 return "meta";
490 521 },
491 522 '"': function(stream, state) {
492 523 if (!stream.match('""')) return false;
493 524 state.tokenize = tokenTripleString;
494 525 return state.tokenize(stream, state);
495 526 },
496 527 "'": function(stream) {
497 528 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
498 529 return "atom";
499 530 }
500 531 },
501 532 modeProps: {closeBrackets: {triples: '"'}}
502 533 });
503 534
535 function tokenKotlinString(tripleString){
536 return function (stream, state) {
537 var escaped = false, next, end = false;
538 while (!stream.eol()) {
539 if (!tripleString && !escaped && stream.match('"') ) {end = true; break;}
540 if (tripleString && stream.match('"""')) {end = true; break;}
541 next = stream.next();
542 if(!escaped && next == "$" && stream.match('{'))
543 stream.skipTo("}");
544 escaped = !escaped && next == "\\" && !tripleString;
545 }
546 if (end || !tripleString)
547 state.tokenize = null;
548 return "string";
549 }
550 }
551
552 def("text/x-kotlin", {
553 name: "clike",
554 keywords: words(
555 /*keywords*/
556 "package as typealias class interface this super val " +
557 "var fun for is in This throw return " +
558 "break continue object if else while do try when !in !is as? " +
559
560 /*soft keywords*/
561 "file import where by get set abstract enum open inner override private public internal " +
562 "protected catch finally out final vararg reified dynamic companion constructor init " +
563 "sealed field property receiver param sparam lateinit data inline noinline tailrec " +
564 "external annotation crossinline const operator infix"
565 ),
566 types: words(
567 /* package java.lang */
568 "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
569 "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
570 "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
571 "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
572 ),
573 intendSwitch: false,
574 indentStatements: false,
575 multiLineStrings: true,
576 blockKeywords: words("catch class do else finally for if where try while enum"),
577 defKeywords: words("class val var object package interface fun"),
578 atoms: words("true false null this"),
579 hooks: {
580 '"': function(stream, state) {
581 state.tokenize = tokenKotlinString(stream.match('""'));
582 return state.tokenize(stream, state);
583 }
584 },
585 modeProps: {closeBrackets: {triples: '"'}}
586 });
587
504 588 def(["x-shader/x-vertex", "x-shader/x-fragment"], {
505 589 name: "clike",
506 590 keywords: words("sampler1D sampler2D sampler3D samplerCube " +
507 591 "sampler1DShadow sampler2DShadow " +
508 592 "const attribute uniform varying " +
509 593 "break continue discard return " +
510 594 "for while do if else struct " +
511 595 "in out inout"),
512 596 types: words("float int bool void " +
513 597 "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
514 598 "mat2 mat3 mat4"),
515 599 blockKeywords: words("for while do if else struct"),
516 600 builtin: words("radians degrees sin cos tan asin acos atan " +
517 601 "pow exp log exp2 sqrt inversesqrt " +
518 602 "abs sign floor ceil fract mod min max clamp mix step smoothstep " +
519 603 "length distance dot cross normalize ftransform faceforward " +
520 604 "reflect refract matrixCompMult " +
521 605 "lessThan lessThanEqual greaterThan greaterThanEqual " +
522 606 "equal notEqual any all not " +
523 607 "texture1D texture1DProj texture1DLod texture1DProjLod " +
524 608 "texture2D texture2DProj texture2DLod texture2DProjLod " +
525 609 "texture3D texture3DProj texture3DLod texture3DProjLod " +
526 610 "textureCube textureCubeLod " +
527 611 "shadow1D shadow2D shadow1DProj shadow2DProj " +
528 612 "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
529 613 "dFdx dFdy fwidth " +
530 614 "noise1 noise2 noise3 noise4"),
531 615 atoms: words("true false " +
532 616 "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
533 617 "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
534 618 "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
535 619 "gl_FogCoord gl_PointCoord " +
536 620 "gl_Position gl_PointSize gl_ClipVertex " +
537 621 "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
538 622 "gl_TexCoord gl_FogFragCoord " +
539 623 "gl_FragCoord gl_FrontFacing " +
540 624 "gl_FragData gl_FragDepth " +
541 625 "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
542 626 "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
543 627 "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
544 628 "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
545 629 "gl_ProjectionMatrixInverseTranspose " +
546 630 "gl_ModelViewProjectionMatrixInverseTranspose " +
547 631 "gl_TextureMatrixInverseTranspose " +
548 632 "gl_NormalScale gl_DepthRange gl_ClipPlane " +
549 633 "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
550 634 "gl_FrontLightModelProduct gl_BackLightModelProduct " +
551 635 "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
552 636 "gl_FogParameters " +
553 637 "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
554 638 "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
555 639 "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
556 640 "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
557 641 "gl_MaxDrawBuffers"),
558 642 indentSwitch: false,
559 643 hooks: {"#": cppHook},
560 644 modeProps: {fold: ["brace", "include"]}
561 645 });
562 646
563 647 def("text/x-nesc", {
564 648 name: "clike",
565 649 keywords: words(cKeywords + "as atomic async call command component components configuration event generic " +
566 650 "implementation includes interface module new norace nx_struct nx_union post provides " +
567 651 "signal task uses abstract extends"),
568 652 types: words(cTypes),
569 653 blockKeywords: words("case do else for if switch while struct"),
570 654 atoms: words("null true false"),
571 655 hooks: {"#": cppHook},
572 656 modeProps: {fold: ["brace", "include"]}
573 657 });
574 658
575 659 def("text/x-objectivec", {
576 660 name: "clike",
577 661 keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginery BOOL Class bycopy byref id IMP in " +
578 662 "inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),
579 663 types: words(cTypes),
580 664 atoms: words("YES NO NULL NILL ON OFF true false"),
581 665 hooks: {
582 666 "@": function(stream) {
583 667 stream.eatWhile(/[\w\$]/);
584 668 return "keyword";
585 669 },
586 "#": cppHook
670 "#": cppHook,
671 indent: function(_state, ctx, textAfter) {
672 if (ctx.type == "statement" && /^@\w/.test(textAfter)) return ctx.indented
673 }
587 674 },
588 675 modeProps: {fold: "brace"}
589 676 });
590 677
678 def("text/x-squirrel", {
679 name: "clike",
680 keywords: words("base break clone continue const default delete enum extends function in class" +
681 " foreach local resume return this throw typeof yield constructor instanceof static"),
682 types: words(cTypes),
683 blockKeywords: words("case catch class else for foreach if switch try while"),
684 defKeywords: words("function local class"),
685 typeFirstDefinitions: true,
686 atoms: words("true false null"),
687 hooks: {"#": cppHook},
688 modeProps: {fold: ["brace", "include"]}
591 689 });
690
691 // Ceylon Strings need to deal with interpolation
692 var stringTokenizer = null;
693 function tokenCeylonString(type) {
694 return function(stream, state) {
695 var escaped = false, next, end = false;
696 while (!stream.eol()) {
697 if (!escaped && stream.match('"') &&
698 (type == "single" || stream.match('""'))) {
699 end = true;
700 break;
701 }
702 if (!escaped && stream.match('``')) {
703 stringTokenizer = tokenCeylonString(type);
704 end = true;
705 break;
706 }
707 next = stream.next();
708 escaped = type == "single" && !escaped && next == "\\";
709 }
710 if (end)
711 state.tokenize = null;
712 return "string";
713 }
714 }
715
716 def("text/x-ceylon", {
717 name: "clike",
718 keywords: words("abstracts alias assembly assert assign break case catch class continue dynamic else" +
719 " exists extends finally for function given if import in interface is let module new" +
720 " nonempty object of out outer package return satisfies super switch then this throw" +
721 " try value void while"),
722 types: function(word) {
723 // In Ceylon all identifiers that start with an uppercase are types
724 var first = word.charAt(0);
725 return (first === first.toUpperCase() && first !== first.toLowerCase());
726 },
727 blockKeywords: words("case catch class dynamic else finally for function if interface module new object switch try while"),
728 defKeywords: words("class dynamic function interface module object package value"),
729 builtin: words("abstract actual aliased annotation by default deprecated doc final formal late license" +
730 " native optional sealed see serializable shared suppressWarnings tagged throws variable"),
731 isPunctuationChar: /[\[\]{}\(\),;\:\.`]/,
732 isOperatorChar: /[+\-*&%=<>!?|^~:\/]/,
733 numberStart: /[\d#$]/,
734 number: /^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i,
735 multiLineStrings: true,
736 typeFirstDefinitions: true,
737 atoms: words("true false null larger smaller equal empty finished"),
738 indentSwitch: false,
739 styleDefs: false,
740 hooks: {
741 "@": function(stream) {
742 stream.eatWhile(/[\w\$_]/);
743 return "meta";
744 },
745 '"': function(stream, state) {
746 state.tokenize = tokenCeylonString(stream.match('""') ? "triple" : "single");
747 return state.tokenize(stream, state);
748 },
749 '`': function(stream, state) {
750 if (!stringTokenizer || !stream.match('`')) return false;
751 state.tokenize = stringTokenizer;
752 stringTokenizer = null;
753 return state.tokenize(stream, state);
754 },
755 "'": function(stream) {
756 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
757 return "atom";
758 },
759 token: function(_stream, state, style) {
760 if ((style == "variable" || style == "variable-3") &&
761 state.prevToken == ".") {
762 return "variable-2";
763 }
764 }
765 },
766 modeProps: {
767 fold: ["brace", "import"],
768 closeBrackets: {triples: '"'}
769 }
770 });
771
772 });
@@ -1,244 +1,249 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 /**
5 5 * Author: Hans Engel
6 6 * Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun)
7 7 */
8 8
9 9 (function(mod) {
10 10 if (typeof exports == "object" && typeof module == "object") // CommonJS
11 11 mod(require("../../lib/codemirror"));
12 12 else if (typeof define == "function" && define.amd) // AMD
13 13 define(["../../lib/codemirror"], mod);
14 14 else // Plain browser env
15 15 mod(CodeMirror);
16 16 })(function(CodeMirror) {
17 17 "use strict";
18 18
19 19 CodeMirror.defineMode("clojure", function (options) {
20 20 var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", CHARACTER = "string-2",
21 21 ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD = "keyword", VAR = "variable";
22 22 var INDENT_WORD_SKIP = options.indentUnit || 2;
23 23 var NORMAL_INDENT_UNIT = options.indentUnit || 2;
24 24
25 25 function makeKeywords(str) {
26 26 var obj = {}, words = str.split(" ");
27 27 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
28 28 return obj;
29 29 }
30 30
31 31 var atoms = makeKeywords("true false nil");
32 32
33 33 var keywords = makeKeywords(
34 34 "defn defn- def def- defonce defmulti defmethod defmacro defstruct deftype defprotocol defrecord defproject deftest slice defalias defhinted defmacro- defn-memo defnk defnk defonce- defunbound defunbound- defvar defvar- let letfn do case cond condp for loop recur when when-not when-let when-first if if-let if-not . .. -> ->> doto and or dosync doseq dotimes dorun doall load import unimport ns in-ns refer try catch finally throw with-open with-local-vars binding gen-class gen-and-load-class gen-and-save-class handler-case handle");
35 35
36 36 var builtins = makeKeywords(
37 37 "* *' *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* *command-line-args* *compile-files* *compile-path* *compiler-options* *data-readers* *e *err* *file* *flush-on-newline* *fn-loader* *in* *math-context* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* *print-readably* *read-eval* *source-path* *unchecked-math* *use-context-classloader* *verbose-defrecords* *warn-on-reflection* + +' - -' -> ->> ->ArrayChunk ->Vec ->VecNode ->VecSeq -cache-protocol-fn -reset-methods .. / < <= = == > >= EMPTY-NODE accessor aclone add-classpath add-watch agent agent-error agent-errors aget alength alias all-ns alter alter-meta! alter-var-root amap ancestors and apply areduce array-map aset aset-boolean aset-byte aset-char aset-double aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in associative? atom await await-for await1 bases bean bigdec bigint biginteger binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array booleans bound-fn bound-fn* bound? butlast byte byte-array bytes case cast char char-array char-escape-string char-name-string char? chars chunk chunk-append chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class class? clear-agent-errors clojure-version coll? comment commute comp comparator compare compare-and-set! compile complement concat cond condp conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec dec' decimal? declare default-data-readers definline definterface defmacro defmethod defmulti defn defn- defonce defprotocol defrecord defstruct deftype delay delay? deliver denominator deref derive descendants destructure disj disj! dissoc dissoc! distinct distinct? doall dorun doseq dosync dotimes doto double double-array doubles drop drop-last drop-while empty empty? ensure enumeration-seq error-handler error-mode eval even? every-pred every? ex-data ex-info extend extend-protocol extend-type extenders extends? false? ffirst file-seq filter filterv find find-keyword find-ns find-protocol-impl find-protocol-method find-var first flatten float float-array float? floats flush fn fn? fnext fnil for force format frequencies future future-call future-cancel future-cancelled? future-done? future? gen-class gen-interface gensym get get-in get-method get-proxy-class get-thread-bindings get-validator group-by hash hash-combine hash-map hash-set identical? identity if-let if-not ifn? import in-ns inc inc' init-proxy instance? int int-array integer? interleave intern interpose into into-array ints io! isa? iterate iterator-seq juxt keep keep-indexed key keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* list? load load-file load-reader load-string loaded-libs locking long long-array longs loop macroexpand macroexpand-1 make-array make-hierarchy map map-indexed map? mapcat mapv max max-key memfn memoize merge merge-with meta method-sig methods min min-key mod munge name namespace namespace-munge neg? newline next nfirst nil? nnext not not-any? not-empty not-every? not= ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias ns-unmap nth nthnext nthrest num number? numerator object-array odd? or parents partial partition partition-all partition-by pcalls peek persistent! pmap pop pop! pop-thread-bindings pos? pr pr-str prefer-method prefers primitives-classnames print print-ctor print-dup print-method print-simple print-str printf println println-str prn prn-str promise proxy proxy-call-with-super proxy-mappings proxy-name proxy-super push-thread-bindings pvalues quot rand rand-int rand-nth range ratio? rational? rationalize re-find re-groups re-matcher re-matches re-pattern re-seq read read-line read-string realized? reduce reduce-kv reductions ref ref-history-count ref-max-history ref-min-history ref-set refer refer-clojure reify release-pending-sends rem remove remove-all-methods remove-method remove-ns remove-watch repeat repeatedly replace replicate require reset! reset-meta! resolve rest restart-agent resultset-seq reverse reversible? rseq rsubseq satisfies? second select-keys send send-off seq seq? seque sequence sequential? set set-error-handler! set-error-mode! set-validator! set? short short-array shorts shuffle shutdown-agents slurp some some-fn sort sort-by sorted-map sorted-map-by sorted-set sorted-set-by sorted? special-symbol? spit split-at split-with str string? struct struct-map subs subseq subvec supers swap! symbol symbol? sync take take-last take-nth take-while test the-ns thread-bound? time to-array to-array-2d trampoline transient tree-seq true? type unchecked-add unchecked-add-int unchecked-byte unchecked-char unchecked-dec unchecked-dec-int unchecked-divide-int unchecked-double unchecked-float unchecked-inc unchecked-inc-int unchecked-int unchecked-long unchecked-multiply unchecked-multiply-int unchecked-negate unchecked-negate-int unchecked-remainder-int unchecked-short unchecked-subtract unchecked-subtract-int underive unquote unquote-splicing update-in update-proxy use val vals var-get var-set var? vary-meta vec vector vector-of vector? when when-first when-let when-not while with-bindings with-bindings* with-in-str with-loading-context with-local-vars with-meta with-open with-out-str with-precision with-redefs with-redefs-fn xml-seq zero? zipmap *default-data-reader-fn* as-> cond-> cond->> reduced reduced? send-via set-agent-send-executor! set-agent-send-off-executor! some-> some->>");
38 38
39 39 var indentKeys = makeKeywords(
40 40 // Built-ins
41 41 "ns fn def defn defmethod bound-fn if if-not case condp when while when-not when-first do future comment doto locking proxy with-open with-precision reify deftype defrecord defprotocol extend extend-protocol extend-type try catch " +
42 42
43 43 // Binding forms
44 44 "let letfn binding loop for doseq dotimes when-let if-let " +
45 45
46 46 // Data structures
47 47 "defstruct struct-map assoc " +
48 48
49 49 // clojure.test
50 50 "testing deftest " +
51 51
52 52 // contrib
53 53 "handler-case handle dotrace deftrace");
54 54
55 55 var tests = {
56 56 digit: /\d/,
57 57 digit_or_colon: /[\d:]/,
58 58 hex: /[0-9a-f]/i,
59 59 sign: /[+-]/,
60 60 exponent: /e/i,
61 61 keyword_char: /[^\s\(\[\;\)\]]/,
62 symbol: /[\w*+!\-\._?:<>\/\xa1-\uffff]/
62 symbol: /[\w*+!\-\._?:<>\/\xa1-\uffff]/,
63 block_indent: /^(?:def|with)[^\/]+$|\/(?:def|with)/
63 64 };
64 65
65 66 function stateStack(indent, type, prev) { // represents a state stack object
66 67 this.indent = indent;
67 68 this.type = type;
68 69 this.prev = prev;
69 70 }
70 71
71 72 function pushStack(state, indent, type) {
72 73 state.indentStack = new stateStack(indent, type, state.indentStack);
73 74 }
74 75
75 76 function popStack(state) {
76 77 state.indentStack = state.indentStack.prev;
77 78 }
78 79
79 80 function isNumber(ch, stream){
80 81 // hex
81 82 if ( ch === '0' && stream.eat(/x/i) ) {
82 83 stream.eatWhile(tests.hex);
83 84 return true;
84 85 }
85 86
86 87 // leading sign
87 88 if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
88 89 stream.eat(tests.sign);
89 90 ch = stream.next();
90 91 }
91 92
92 93 if ( tests.digit.test(ch) ) {
93 94 stream.eat(ch);
94 95 stream.eatWhile(tests.digit);
95 96
96 97 if ( '.' == stream.peek() ) {
97 98 stream.eat('.');
98 99 stream.eatWhile(tests.digit);
100 } else if ('/' == stream.peek() ) {
101 stream.eat('/');
102 stream.eatWhile(tests.digit);
99 103 }
100 104
101 105 if ( stream.eat(tests.exponent) ) {
102 106 stream.eat(tests.sign);
103 107 stream.eatWhile(tests.digit);
104 108 }
105 109
106 110 return true;
107 111 }
108 112
109 113 return false;
110 114 }
111 115
112 116 // Eat character that starts after backslash \
113 117 function eatCharacter(stream) {
114 118 var first = stream.next();
115 119 // Read special literals: backspace, newline, space, return.
116 120 // Just read all lowercase letters.
117 121 if (first && first.match(/[a-z]/) && stream.match(/[a-z]+/, true)) {
118 122 return;
119 123 }
120 124 // Read unicode character: \u1000 \uA0a1
121 125 if (first === "u") {
122 126 stream.match(/[0-9a-z]{4}/i, true);
123 127 }
124 128 }
125 129
126 130 return {
127 131 startState: function () {
128 132 return {
129 133 indentStack: null,
130 134 indentation: 0,
131 135 mode: false
132 136 };
133 137 },
134 138
135 139 token: function (stream, state) {
136 140 if (state.indentStack == null && stream.sol()) {
137 141 // update indentation, but only if indentStack is empty
138 142 state.indentation = stream.indentation();
139 143 }
140 144
141 145 // skip spaces
142 if (stream.eatSpace()) {
146 if (state.mode != "string" && stream.eatSpace()) {
143 147 return null;
144 148 }
145 149 var returnType = null;
146 150
147 151 switch(state.mode){
148 152 case "string": // multi-line string parsing mode
149 153 var next, escaped = false;
150 154 while ((next = stream.next()) != null) {
151 155 if (next == "\"" && !escaped) {
152 156
153 157 state.mode = false;
154 158 break;
155 159 }
156 160 escaped = !escaped && next == "\\";
157 161 }
158 162 returnType = STRING; // continue on in string mode
159 163 break;
160 164 default: // default parsing mode
161 165 var ch = stream.next();
162 166
163 167 if (ch == "\"") {
164 168 state.mode = "string";
165 169 returnType = STRING;
166 170 } else if (ch == "\\") {
167 171 eatCharacter(stream);
168 172 returnType = CHARACTER;
169 173 } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
170 174 returnType = ATOM;
171 175 } else if (ch == ";") { // comment
172 176 stream.skipToEnd(); // rest of the line is a comment
173 177 returnType = COMMENT;
174 178 } else if (isNumber(ch,stream)){
175 179 returnType = NUMBER;
176 180 } else if (ch == "(" || ch == "[" || ch == "{" ) {
177 181 var keyWord = '', indentTemp = stream.column(), letter;
178 182 /**
179 183 Either
180 184 (indent-word ..
181 185 (non-indent-word ..
182 186 (;something else, bracket, etc.
183 187 */
184 188
185 189 if (ch == "(") while ((letter = stream.eat(tests.keyword_char)) != null) {
186 190 keyWord += letter;
187 191 }
188 192
189 193 if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) ||
190 /^(?:def|with)/.test(keyWord))) { // indent-word
194 tests.block_indent.test(keyWord))) { // indent-word
191 195 pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
192 196 } else { // non-indent word
193 197 // we continue eating the spaces
194 198 stream.eatSpace();
195 199 if (stream.eol() || stream.peek() == ";") {
196 200 // nothing significant after
197 201 // we restart indentation the user defined spaces after
198 202 pushStack(state, indentTemp + NORMAL_INDENT_UNIT, ch);
199 203 } else {
200 204 pushStack(state, indentTemp + stream.current().length, ch); // else we match
201 205 }
202 206 }
203 207 stream.backUp(stream.current().length - 1); // undo all the eating
204 208
205 209 returnType = BRACKET;
206 210 } else if (ch == ")" || ch == "]" || ch == "}") {
207 211 returnType = BRACKET;
208 212 if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : (ch == "]" ? "[" :"{"))) {
209 213 popStack(state);
210 214 }
211 215 } else if ( ch == ":" ) {
212 216 stream.eatWhile(tests.symbol);
213 217 return ATOM;
214 218 } else {
215 219 stream.eatWhile(tests.symbol);
216 220
217 221 if (keywords && keywords.propertyIsEnumerable(stream.current())) {
218 222 returnType = KEYWORD;
219 223 } else if (builtins && builtins.propertyIsEnumerable(stream.current())) {
220 224 returnType = BUILTIN;
221 225 } else if (atoms && atoms.propertyIsEnumerable(stream.current())) {
222 226 returnType = ATOM;
223 227 } else {
224 228 returnType = VAR;
225 229 }
226 230 }
227 231 }
228 232
229 233 return returnType;
230 234 },
231 235
232 236 indent: function (state) {
233 237 if (state.indentStack == null) return state.indentation;
234 238 return state.indentStack.indent;
235 239 },
236 240
237 241 closeBrackets: {pairs: "()[]{}\"\""},
238 242 lineComment: ";;"
239 243 };
240 244 });
241 245
242 246 CodeMirror.defineMIME("text/x-clojure", "clojure");
247 CodeMirror.defineMIME("text/x-clojurescript", "clojure");
243 248
244 249 });
@@ -1,369 +1,355 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 /**
5 5 * Link to the project's GitHub page:
6 6 * https://github.com/pickhardt/coffeescript-codemirror-mode
7 7 */
8 8 (function(mod) {
9 9 if (typeof exports == "object" && typeof module == "object") // CommonJS
10 10 mod(require("../../lib/codemirror"));
11 11 else if (typeof define == "function" && define.amd) // AMD
12 12 define(["../../lib/codemirror"], mod);
13 13 else // Plain browser env
14 14 mod(CodeMirror);
15 15 })(function(CodeMirror) {
16 16 "use strict";
17 17
18 18 CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
19 19 var ERRORCLASS = "error";
20 20
21 21 function wordRegexp(words) {
22 22 return new RegExp("^((" + words.join(")|(") + "))\\b");
23 23 }
24 24
25 25 var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;
26 26 var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
27 27 var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
28 var properties = /^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/;
28 var atProp = /^@[_A-Za-z$][_A-Za-z$0-9]*/;
29 29
30 30 var wordOperators = wordRegexp(["and", "or", "not",
31 31 "is", "isnt", "in",
32 32 "instanceof", "typeof"]);
33 33 var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
34 34 "switch", "try", "catch", "finally", "class"];
35 35 var commonKeywords = ["break", "by", "continue", "debugger", "delete",
36 36 "do", "in", "of", "new", "return", "then",
37 37 "this", "@", "throw", "when", "until", "extends"];
38 38
39 39 var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
40 40
41 41 indentKeywords = wordRegexp(indentKeywords);
42 42
43 43
44 44 var stringPrefixes = /^('{3}|\"{3}|['\"])/;
45 45 var regexPrefixes = /^(\/{3}|\/)/;
46 46 var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
47 47 var constants = wordRegexp(commonConstants);
48 48
49 49 // Tokenizers
50 50 function tokenBase(stream, state) {
51 51 // Handle scope changes
52 52 if (stream.sol()) {
53 53 if (state.scope.align === null) state.scope.align = false;
54 54 var scopeOffset = state.scope.offset;
55 55 if (stream.eatSpace()) {
56 56 var lineOffset = stream.indentation();
57 57 if (lineOffset > scopeOffset && state.scope.type == "coffee") {
58 58 return "indent";
59 59 } else if (lineOffset < scopeOffset) {
60 60 return "dedent";
61 61 }
62 62 return null;
63 63 } else {
64 64 if (scopeOffset > 0) {
65 65 dedent(stream, state);
66 66 }
67 67 }
68 68 }
69 69 if (stream.eatSpace()) {
70 70 return null;
71 71 }
72 72
73 73 var ch = stream.peek();
74 74
75 75 // Handle docco title comment (single line)
76 76 if (stream.match("####")) {
77 77 stream.skipToEnd();
78 78 return "comment";
79 79 }
80 80
81 81 // Handle multi line comments
82 82 if (stream.match("###")) {
83 83 state.tokenize = longComment;
84 84 return state.tokenize(stream, state);
85 85 }
86 86
87 87 // Single line comment
88 88 if (ch === "#") {
89 89 stream.skipToEnd();
90 90 return "comment";
91 91 }
92 92
93 93 // Handle number literals
94 94 if (stream.match(/^-?[0-9\.]/, false)) {
95 95 var floatLiteral = false;
96 96 // Floats
97 97 if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
98 98 floatLiteral = true;
99 99 }
100 100 if (stream.match(/^-?\d+\.\d*/)) {
101 101 floatLiteral = true;
102 102 }
103 103 if (stream.match(/^-?\.\d+/)) {
104 104 floatLiteral = true;
105 105 }
106 106
107 107 if (floatLiteral) {
108 108 // prevent from getting extra . on 1..
109 109 if (stream.peek() == "."){
110 110 stream.backUp(1);
111 111 }
112 112 return "number";
113 113 }
114 114 // Integers
115 115 var intLiteral = false;
116 116 // Hex
117 117 if (stream.match(/^-?0x[0-9a-f]+/i)) {
118 118 intLiteral = true;
119 119 }
120 120 // Decimal
121 121 if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
122 122 intLiteral = true;
123 123 }
124 124 // Zero by itself with no other piece of number.
125 125 if (stream.match(/^-?0(?![\dx])/i)) {
126 126 intLiteral = true;
127 127 }
128 128 if (intLiteral) {
129 129 return "number";
130 130 }
131 131 }
132 132
133 133 // Handle strings
134 134 if (stream.match(stringPrefixes)) {
135 135 state.tokenize = tokenFactory(stream.current(), false, "string");
136 136 return state.tokenize(stream, state);
137 137 }
138 138 // Handle regex literals
139 139 if (stream.match(regexPrefixes)) {
140 140 if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
141 141 state.tokenize = tokenFactory(stream.current(), true, "string-2");
142 142 return state.tokenize(stream, state);
143 143 } else {
144 144 stream.backUp(1);
145 145 }
146 146 }
147 147
148
149
148 150 // Handle operators and delimiters
149 151 if (stream.match(operators) || stream.match(wordOperators)) {
150 152 return "operator";
151 153 }
152 154 if (stream.match(delimiters)) {
153 155 return "punctuation";
154 156 }
155 157
156 158 if (stream.match(constants)) {
157 159 return "atom";
158 160 }
159 161
162 if (stream.match(atProp) || state.prop && stream.match(identifiers)) {
163 return "property";
164 }
165
160 166 if (stream.match(keywords)) {
161 167 return "keyword";
162 168 }
163 169
164 170 if (stream.match(identifiers)) {
165 171 return "variable";
166 172 }
167 173
168 if (stream.match(properties)) {
169 return "property";
170 }
171
172 174 // Handle non-detected items
173 175 stream.next();
174 176 return ERRORCLASS;
175 177 }
176 178
177 179 function tokenFactory(delimiter, singleline, outclass) {
178 180 return function(stream, state) {
179 181 while (!stream.eol()) {
180 182 stream.eatWhile(/[^'"\/\\]/);
181 183 if (stream.eat("\\")) {
182 184 stream.next();
183 185 if (singleline && stream.eol()) {
184 186 return outclass;
185 187 }
186 188 } else if (stream.match(delimiter)) {
187 189 state.tokenize = tokenBase;
188 190 return outclass;
189 191 } else {
190 192 stream.eat(/['"\/]/);
191 193 }
192 194 }
193 195 if (singleline) {
194 196 if (parserConf.singleLineStringErrors) {
195 197 outclass = ERRORCLASS;
196 198 } else {
197 199 state.tokenize = tokenBase;
198 200 }
199 201 }
200 202 return outclass;
201 203 };
202 204 }
203 205
204 206 function longComment(stream, state) {
205 207 while (!stream.eol()) {
206 208 stream.eatWhile(/[^#]/);
207 209 if (stream.match("###")) {
208 210 state.tokenize = tokenBase;
209 211 break;
210 212 }
211 213 stream.eatWhile("#");
212 214 }
213 215 return "comment";
214 216 }
215 217
216 218 function indent(stream, state, type) {
217 219 type = type || "coffee";
218 220 var offset = 0, align = false, alignOffset = null;
219 221 for (var scope = state.scope; scope; scope = scope.prev) {
220 222 if (scope.type === "coffee" || scope.type == "}") {
221 223 offset = scope.offset + conf.indentUnit;
222 224 break;
223 225 }
224 226 }
225 227 if (type !== "coffee") {
226 228 align = null;
227 229 alignOffset = stream.column() + stream.current().length;
228 230 } else if (state.scope.align) {
229 231 state.scope.align = false;
230 232 }
231 233 state.scope = {
232 234 offset: offset,
233 235 type: type,
234 236 prev: state.scope,
235 237 align: align,
236 238 alignOffset: alignOffset
237 239 };
238 240 }
239 241
240 242 function dedent(stream, state) {
241 243 if (!state.scope.prev) return;
242 244 if (state.scope.type === "coffee") {
243 245 var _indent = stream.indentation();
244 246 var matched = false;
245 247 for (var scope = state.scope; scope; scope = scope.prev) {
246 248 if (_indent === scope.offset) {
247 249 matched = true;
248 250 break;
249 251 }
250 252 }
251 253 if (!matched) {
252 254 return true;
253 255 }
254 256 while (state.scope.prev && state.scope.offset !== _indent) {
255 257 state.scope = state.scope.prev;
256 258 }
257 259 return false;
258 260 } else {
259 261 state.scope = state.scope.prev;
260 262 return false;
261 263 }
262 264 }
263 265
264 266 function tokenLexer(stream, state) {
265 267 var style = state.tokenize(stream, state);
266 268 var current = stream.current();
267 269
268 // Handle "." connected identifiers
269 if (current === ".") {
270 style = state.tokenize(stream, state);
271 current = stream.current();
272 if (/^\.[\w$]+$/.test(current)) {
273 return "variable";
274 } else {
275 return ERRORCLASS;
276 }
277 }
278
279 270 // Handle scope changes.
280 271 if (current === "return") {
281 272 state.dedent = true;
282 273 }
283 if (((current === "->" || current === "=>") &&
284 !state.lambda &&
285 !stream.peek())
274 if (((current === "->" || current === "=>") && stream.eol())
286 275 || style === "indent") {
287 276 indent(stream, state);
288 277 }
289 278 var delimiter_index = "[({".indexOf(current);
290 279 if (delimiter_index !== -1) {
291 280 indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
292 281 }
293 282 if (indentKeywords.exec(current)){
294 283 indent(stream, state);
295 284 }
296 285 if (current == "then"){
297 286 dedent(stream, state);
298 287 }
299 288
300 289
301 290 if (style === "dedent") {
302 291 if (dedent(stream, state)) {
303 292 return ERRORCLASS;
304 293 }
305 294 }
306 295 delimiter_index = "])}".indexOf(current);
307 296 if (delimiter_index !== -1) {
308 297 while (state.scope.type == "coffee" && state.scope.prev)
309 298 state.scope = state.scope.prev;
310 299 if (state.scope.type == current)
311 300 state.scope = state.scope.prev;
312 301 }
313 302 if (state.dedent && stream.eol()) {
314 303 if (state.scope.type == "coffee" && state.scope.prev)
315 304 state.scope = state.scope.prev;
316 305 state.dedent = false;
317 306 }
318 307
319 308 return style;
320 309 }
321 310
322 311 var external = {
323 312 startState: function(basecolumn) {
324 313 return {
325 314 tokenize: tokenBase,
326 315 scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
327 lastToken: null,
328 lambda: false,
316 prop: false,
329 317 dedent: 0
330 318 };
331 319 },
332 320
333 321 token: function(stream, state) {
334 322 var fillAlign = state.scope.align === null && state.scope;
335 323 if (fillAlign && stream.sol()) fillAlign.align = false;
336 324
337 325 var style = tokenLexer(stream, state);
338 if (fillAlign && style && style != "comment") fillAlign.align = true;
339
340 state.lastToken = {style:style, content: stream.current()};
341
342 if (stream.eol() && stream.lambda) {
343 state.lambda = false;
326 if (style && style != "comment") {
327 if (fillAlign) fillAlign.align = true;
328 state.prop = style == "punctuation" && stream.current() == "."
344 329 }
345 330
346 331 return style;
347 332 },
348 333
349 334 indent: function(state, text) {
350 335 if (state.tokenize != tokenBase) return 0;
351 336 var scope = state.scope;
352 337 var closer = text && "])}".indexOf(text.charAt(0)) > -1;
353 338 if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
354 339 var closes = closer && scope.type === text.charAt(0);
355 340 if (scope.align)
356 341 return scope.alignOffset - (closes ? 1 : 0);
357 342 else
358 343 return (closes ? scope.prev : scope).offset;
359 344 },
360 345
361 346 lineComment: "#",
362 347 fold: "indent"
363 348 };
364 349 return external;
365 350 });
366 351
367 352 CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
353 CodeMirror.defineMIME("text/coffeescript", "coffeescript");
368 354
369 355 });
@@ -1,754 +1,825 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode("css", function(config, parserConfig) {
15 var inline = parserConfig.inline
15 16 if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
16 17
17 18 var indentUnit = config.indentUnit,
18 19 tokenHooks = parserConfig.tokenHooks,
19 20 documentTypes = parserConfig.documentTypes || {},
20 21 mediaTypes = parserConfig.mediaTypes || {},
21 22 mediaFeatures = parserConfig.mediaFeatures || {},
23 mediaValueKeywords = parserConfig.mediaValueKeywords || {},
22 24 propertyKeywords = parserConfig.propertyKeywords || {},
23 25 nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
24 26 fontProperties = parserConfig.fontProperties || {},
25 27 counterDescriptors = parserConfig.counterDescriptors || {},
26 28 colorKeywords = parserConfig.colorKeywords || {},
27 29 valueKeywords = parserConfig.valueKeywords || {},
28 allowNested = parserConfig.allowNested;
30 allowNested = parserConfig.allowNested,
31 supportsAtComponent = parserConfig.supportsAtComponent === true;
29 32
30 33 var type, override;
31 34 function ret(style, tp) { type = tp; return style; }
32 35
33 36 // Tokenizers
34 37
35 38 function tokenBase(stream, state) {
36 39 var ch = stream.next();
37 40 if (tokenHooks[ch]) {
38 41 var result = tokenHooks[ch](stream, state);
39 42 if (result !== false) return result;
40 43 }
41 44 if (ch == "@") {
42 45 stream.eatWhile(/[\w\\\-]/);
43 46 return ret("def", stream.current());
44 47 } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
45 48 return ret(null, "compare");
46 49 } else if (ch == "\"" || ch == "'") {
47 50 state.tokenize = tokenString(ch);
48 51 return state.tokenize(stream, state);
49 52 } else if (ch == "#") {
50 53 stream.eatWhile(/[\w\\\-]/);
51 54 return ret("atom", "hash");
52 55 } else if (ch == "!") {
53 56 stream.match(/^\s*\w*/);
54 57 return ret("keyword", "important");
55 58 } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
56 59 stream.eatWhile(/[\w.%]/);
57 60 return ret("number", "unit");
58 61 } else if (ch === "-") {
59 62 if (/[\d.]/.test(stream.peek())) {
60 63 stream.eatWhile(/[\w.%]/);
61 64 return ret("number", "unit");
62 65 } else if (stream.match(/^-[\w\\\-]+/)) {
63 66 stream.eatWhile(/[\w\\\-]/);
64 67 if (stream.match(/^\s*:/, false))
65 68 return ret("variable-2", "variable-definition");
66 69 return ret("variable-2", "variable");
67 70 } else if (stream.match(/^\w+-/)) {
68 71 return ret("meta", "meta");
69 72 }
70 73 } else if (/[,+>*\/]/.test(ch)) {
71 74 return ret(null, "select-op");
72 75 } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
73 76 return ret("qualifier", "qualifier");
74 77 } else if (/[:;{}\[\]\(\)]/.test(ch)) {
75 78 return ret(null, ch);
76 79 } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
77 80 (ch == "d" && stream.match("omain(")) ||
78 81 (ch == "r" && stream.match("egexp("))) {
79 82 stream.backUp(1);
80 83 state.tokenize = tokenParenthesized;
81 84 return ret("property", "word");
82 85 } else if (/[\w\\\-]/.test(ch)) {
83 86 stream.eatWhile(/[\w\\\-]/);
84 87 return ret("property", "word");
85 88 } else {
86 89 return ret(null, null);
87 90 }
88 91 }
89 92
90 93 function tokenString(quote) {
91 94 return function(stream, state) {
92 95 var escaped = false, ch;
93 96 while ((ch = stream.next()) != null) {
94 97 if (ch == quote && !escaped) {
95 98 if (quote == ")") stream.backUp(1);
96 99 break;
97 100 }
98 101 escaped = !escaped && ch == "\\";
99 102 }
100 103 if (ch == quote || !escaped && quote != ")") state.tokenize = null;
101 104 return ret("string", "string");
102 105 };
103 106 }
104 107
105 108 function tokenParenthesized(stream, state) {
106 109 stream.next(); // Must be '('
107 110 if (!stream.match(/\s*[\"\')]/, false))
108 111 state.tokenize = tokenString(")");
109 112 else
110 113 state.tokenize = null;
111 114 return ret(null, "(");
112 115 }
113 116
114 117 // Context management
115 118
116 119 function Context(type, indent, prev) {
117 120 this.type = type;
118 121 this.indent = indent;
119 122 this.prev = prev;
120 123 }
121 124
122 function pushContext(state, stream, type) {
123 state.context = new Context(type, stream.indentation() + indentUnit, state.context);
125 function pushContext(state, stream, type, indent) {
126 state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
124 127 return type;
125 128 }
126 129
127 130 function popContext(state) {
131 if (state.context.prev)
128 132 state.context = state.context.prev;
129 133 return state.context.type;
130 134 }
131 135
132 136 function pass(type, stream, state) {
133 137 return states[state.context.type](type, stream, state);
134 138 }
135 139 function popAndPass(type, stream, state, n) {
136 140 for (var i = n || 1; i > 0; i--)
137 141 state.context = state.context.prev;
138 142 return pass(type, stream, state);
139 143 }
140 144
141 145 // Parser
142 146
143 147 function wordAsValue(stream) {
144 148 var word = stream.current().toLowerCase();
145 149 if (valueKeywords.hasOwnProperty(word))
146 150 override = "atom";
147 151 else if (colorKeywords.hasOwnProperty(word))
148 152 override = "keyword";
149 153 else
150 154 override = "variable";
151 155 }
152 156
153 157 var states = {};
154 158
155 159 states.top = function(type, stream, state) {
156 160 if (type == "{") {
157 161 return pushContext(state, stream, "block");
158 162 } else if (type == "}" && state.context.prev) {
159 163 return popContext(state);
160 } else if (/@(media|supports|(-moz-)?document)/.test(type)) {
164 } else if (supportsAtComponent && /@component/.test(type)) {
165 return pushContext(state, stream, "atComponentBlock");
166 } else if (/^@(-moz-)?document$/.test(type)) {
167 return pushContext(state, stream, "documentTypes");
168 } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
161 169 return pushContext(state, stream, "atBlock");
162 } else if (/@(font-face|counter-style)/.test(type)) {
170 } else if (/^@(font-face|counter-style)/.test(type)) {
163 171 state.stateArg = type;
164 172 return "restricted_atBlock_before";
165 173 } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
166 174 return "keyframes";
167 175 } else if (type && type.charAt(0) == "@") {
168 176 return pushContext(state, stream, "at");
169 177 } else if (type == "hash") {
170 178 override = "builtin";
171 179 } else if (type == "word") {
172 180 override = "tag";
173 181 } else if (type == "variable-definition") {
174 182 return "maybeprop";
175 183 } else if (type == "interpolation") {
176 184 return pushContext(state, stream, "interpolation");
177 185 } else if (type == ":") {
178 186 return "pseudo";
179 187 } else if (allowNested && type == "(") {
180 188 return pushContext(state, stream, "parens");
181 189 }
182 190 return state.context.type;
183 191 };
184 192
185 193 states.block = function(type, stream, state) {
186 194 if (type == "word") {
187 195 var word = stream.current().toLowerCase();
188 196 if (propertyKeywords.hasOwnProperty(word)) {
189 197 override = "property";
190 198 return "maybeprop";
191 199 } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
192 200 override = "string-2";
193 201 return "maybeprop";
194 202 } else if (allowNested) {
195 203 override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
196 204 return "block";
197 205 } else {
198 206 override += " error";
199 207 return "maybeprop";
200 208 }
201 209 } else if (type == "meta") {
202 210 return "block";
203 211 } else if (!allowNested && (type == "hash" || type == "qualifier")) {
204 212 override = "error";
205 213 return "block";
206 214 } else {
207 215 return states.top(type, stream, state);
208 216 }
209 217 };
210 218
211 219 states.maybeprop = function(type, stream, state) {
212 220 if (type == ":") return pushContext(state, stream, "prop");
213 221 return pass(type, stream, state);
214 222 };
215 223
216 224 states.prop = function(type, stream, state) {
217 225 if (type == ";") return popContext(state);
218 226 if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
219 227 if (type == "}" || type == "{") return popAndPass(type, stream, state);
220 228 if (type == "(") return pushContext(state, stream, "parens");
221 229
222 if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
230 if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
223 231 override += " error";
224 232 } else if (type == "word") {
225 233 wordAsValue(stream);
226 234 } else if (type == "interpolation") {
227 235 return pushContext(state, stream, "interpolation");
228 236 }
229 237 return "prop";
230 238 };
231 239
232 240 states.propBlock = function(type, _stream, state) {
233 241 if (type == "}") return popContext(state);
234 242 if (type == "word") { override = "property"; return "maybeprop"; }
235 243 return state.context.type;
236 244 };
237 245
238 246 states.parens = function(type, stream, state) {
239 247 if (type == "{" || type == "}") return popAndPass(type, stream, state);
240 248 if (type == ")") return popContext(state);
241 249 if (type == "(") return pushContext(state, stream, "parens");
242 250 if (type == "interpolation") return pushContext(state, stream, "interpolation");
243 251 if (type == "word") wordAsValue(stream);
244 252 return "parens";
245 253 };
246 254
247 255 states.pseudo = function(type, stream, state) {
248 256 if (type == "word") {
249 257 override = "variable-3";
250 258 return state.context.type;
251 259 }
252 260 return pass(type, stream, state);
253 261 };
254 262
263 states.documentTypes = function(type, stream, state) {
264 if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
265 override = "tag";
266 return state.context.type;
267 } else {
268 return states.atBlock(type, stream, state);
269 }
270 };
271
255 272 states.atBlock = function(type, stream, state) {
256 273 if (type == "(") return pushContext(state, stream, "atBlock_parens");
257 if (type == "}") return popAndPass(type, stream, state);
274 if (type == "}" || type == ";") return popAndPass(type, stream, state);
258 275 if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
259 276
277 if (type == "interpolation") return pushContext(state, stream, "interpolation");
278
260 279 if (type == "word") {
261 280 var word = stream.current().toLowerCase();
262 281 if (word == "only" || word == "not" || word == "and" || word == "or")
263 282 override = "keyword";
264 else if (documentTypes.hasOwnProperty(word))
265 override = "tag";
266 283 else if (mediaTypes.hasOwnProperty(word))
267 284 override = "attribute";
268 285 else if (mediaFeatures.hasOwnProperty(word))
269 286 override = "property";
287 else if (mediaValueKeywords.hasOwnProperty(word))
288 override = "keyword";
270 289 else if (propertyKeywords.hasOwnProperty(word))
271 290 override = "property";
272 291 else if (nonStandardPropertyKeywords.hasOwnProperty(word))
273 292 override = "string-2";
274 293 else if (valueKeywords.hasOwnProperty(word))
275 294 override = "atom";
295 else if (colorKeywords.hasOwnProperty(word))
296 override = "keyword";
276 297 else
277 298 override = "error";
278 299 }
279 300 return state.context.type;
280 301 };
281 302
303 states.atComponentBlock = function(type, stream, state) {
304 if (type == "}")
305 return popAndPass(type, stream, state);
306 if (type == "{")
307 return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
308 if (type == "word")
309 override = "error";
310 return state.context.type;
311 };
312
282 313 states.atBlock_parens = function(type, stream, state) {
283 314 if (type == ")") return popContext(state);
284 315 if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
285 316 return states.atBlock(type, stream, state);
286 317 };
287 318
288 319 states.restricted_atBlock_before = function(type, stream, state) {
289 320 if (type == "{")
290 321 return pushContext(state, stream, "restricted_atBlock");
291 322 if (type == "word" && state.stateArg == "@counter-style") {
292 323 override = "variable";
293 324 return "restricted_atBlock_before";
294 325 }
295 326 return pass(type, stream, state);
296 327 };
297 328
298 329 states.restricted_atBlock = function(type, stream, state) {
299 330 if (type == "}") {
300 331 state.stateArg = null;
301 332 return popContext(state);
302 333 }
303 334 if (type == "word") {
304 335 if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
305 336 (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
306 337 override = "error";
307 338 else
308 339 override = "property";
309 340 return "maybeprop";
310 341 }
311 342 return "restricted_atBlock";
312 343 };
313 344
314 345 states.keyframes = function(type, stream, state) {
315 346 if (type == "word") { override = "variable"; return "keyframes"; }
316 347 if (type == "{") return pushContext(state, stream, "top");
317 348 return pass(type, stream, state);
318 349 };
319 350
320 351 states.at = function(type, stream, state) {
321 352 if (type == ";") return popContext(state);
322 353 if (type == "{" || type == "}") return popAndPass(type, stream, state);
323 354 if (type == "word") override = "tag";
324 355 else if (type == "hash") override = "builtin";
325 356 return "at";
326 357 };
327 358
328 359 states.interpolation = function(type, stream, state) {
329 360 if (type == "}") return popContext(state);
330 361 if (type == "{" || type == ";") return popAndPass(type, stream, state);
331 362 if (type == "word") override = "variable";
332 363 else if (type != "variable" && type != "(" && type != ")") override = "error";
333 364 return "interpolation";
334 365 };
335 366
336 367 return {
337 368 startState: function(base) {
338 369 return {tokenize: null,
339 state: "top",
370 state: inline ? "block" : "top",
340 371 stateArg: null,
341 context: new Context("top", base || 0, null)};
372 context: new Context(inline ? "block" : "top", base || 0, null)};
342 373 },
343 374
344 375 token: function(stream, state) {
345 376 if (!state.tokenize && stream.eatSpace()) return null;
346 377 var style = (state.tokenize || tokenBase)(stream, state);
347 378 if (style && typeof style == "object") {
348 379 type = style[1];
349 380 style = style[0];
350 381 }
351 382 override = style;
352 383 state.state = states[state.state](type, stream, state);
353 384 return override;
354 385 },
355 386
356 387 indent: function(state, textAfter) {
357 388 var cx = state.context, ch = textAfter && textAfter.charAt(0);
358 389 var indent = cx.indent;
359 390 if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
360 if (cx.prev &&
361 (ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "restricted_atBlock") ||
362 ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
363 ch == "{" && (cx.type == "at" || cx.type == "atBlock"))) {
364 indent = cx.indent - indentUnit;
391 if (cx.prev) {
392 if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
393 cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
394 // Resume indentation from parent context.
365 395 cx = cx.prev;
396 indent = cx.indent;
397 } else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
398 ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
399 // Dedent relative to current context.
400 indent = Math.max(0, cx.indent - indentUnit);
401 cx = cx.prev;
402 }
366 403 }
367 404 return indent;
368 405 },
369 406
370 407 electricChars: "}",
371 408 blockCommentStart: "/*",
372 409 blockCommentEnd: "*/",
373 410 fold: "brace"
374 411 };
375 412 });
376 413
377 414 function keySet(array) {
378 415 var keys = {};
379 416 for (var i = 0; i < array.length; ++i) {
380 417 keys[array[i]] = true;
381 418 }
382 419 return keys;
383 420 }
384 421
385 422 var documentTypes_ = [
386 423 "domain", "regexp", "url", "url-prefix"
387 424 ], documentTypes = keySet(documentTypes_);
388 425
389 426 var mediaTypes_ = [
390 427 "all", "aural", "braille", "handheld", "print", "projection", "screen",
391 428 "tty", "tv", "embossed"
392 429 ], mediaTypes = keySet(mediaTypes_);
393 430
394 431 var mediaFeatures_ = [
395 432 "width", "min-width", "max-width", "height", "min-height", "max-height",
396 433 "device-width", "min-device-width", "max-device-width", "device-height",
397 434 "min-device-height", "max-device-height", "aspect-ratio",
398 435 "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
399 436 "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
400 437 "max-color", "color-index", "min-color-index", "max-color-index",
401 438 "monochrome", "min-monochrome", "max-monochrome", "resolution",
402 "min-resolution", "max-resolution", "scan", "grid"
439 "min-resolution", "max-resolution", "scan", "grid", "orientation",
440 "device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
441 "pointer", "any-pointer", "hover", "any-hover"
403 442 ], mediaFeatures = keySet(mediaFeatures_);
404 443
444 var mediaValueKeywords_ = [
445 "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
446 "interlace", "progressive"
447 ], mediaValueKeywords = keySet(mediaValueKeywords_);
448
405 449 var propertyKeywords_ = [
406 450 "align-content", "align-items", "align-self", "alignment-adjust",
407 451 "alignment-baseline", "anchor-point", "animation", "animation-delay",
408 452 "animation-direction", "animation-duration", "animation-fill-mode",
409 453 "animation-iteration-count", "animation-name", "animation-play-state",
410 454 "animation-timing-function", "appearance", "azimuth", "backface-visibility",
411 "background", "background-attachment", "background-clip", "background-color",
412 "background-image", "background-origin", "background-position",
455 "background", "background-attachment", "background-blend-mode", "background-clip",
456 "background-color", "background-image", "background-origin", "background-position",
413 457 "background-repeat", "background-size", "baseline-shift", "binding",
414 458 "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
415 459 "bookmark-target", "border", "border-bottom", "border-bottom-color",
416 460 "border-bottom-left-radius", "border-bottom-right-radius",
417 461 "border-bottom-style", "border-bottom-width", "border-collapse",
418 462 "border-color", "border-image", "border-image-outset",
419 463 "border-image-repeat", "border-image-slice", "border-image-source",
420 464 "border-image-width", "border-left", "border-left-color",
421 465 "border-left-style", "border-left-width", "border-radius", "border-right",
422 466 "border-right-color", "border-right-style", "border-right-width",
423 467 "border-spacing", "border-style", "border-top", "border-top-color",
424 468 "border-top-left-radius", "border-top-right-radius", "border-top-style",
425 469 "border-top-width", "border-width", "bottom", "box-decoration-break",
426 470 "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
427 471 "caption-side", "clear", "clip", "color", "color-profile", "column-count",
428 472 "column-fill", "column-gap", "column-rule", "column-rule-color",
429 473 "column-rule-style", "column-rule-width", "column-span", "column-width",
430 474 "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
431 475 "cue-after", "cue-before", "cursor", "direction", "display",
432 476 "dominant-baseline", "drop-initial-after-adjust",
433 477 "drop-initial-after-align", "drop-initial-before-adjust",
434 478 "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
435 479 "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
436 480 "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
437 481 "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
438 482 "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
439 483 "font-stretch", "font-style", "font-synthesis", "font-variant",
440 484 "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
441 485 "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
442 486 "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
443 487 "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
444 488 "grid-column-start", "grid-row", "grid-row-end", "grid-row-start",
445 489 "grid-template", "grid-template-areas", "grid-template-columns",
446 490 "grid-template-rows", "hanging-punctuation", "height", "hyphens",
447 491 "icon", "image-orientation", "image-rendering", "image-resolution",
448 492 "inline-box-align", "justify-content", "left", "letter-spacing",
449 493 "line-break", "line-height", "line-stacking", "line-stacking-ruby",
450 494 "line-stacking-shift", "line-stacking-strategy", "list-style",
451 495 "list-style-image", "list-style-position", "list-style-type", "margin",
452 496 "margin-bottom", "margin-left", "margin-right", "margin-top",
453 497 "marker-offset", "marks", "marquee-direction", "marquee-loop",
454 498 "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
455 499 "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
456 500 "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
457 501 "opacity", "order", "orphans", "outline",
458 502 "outline-color", "outline-offset", "outline-style", "outline-width",
459 503 "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
460 504 "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
461 505 "page", "page-break-after", "page-break-before", "page-break-inside",
462 506 "page-policy", "pause", "pause-after", "pause-before", "perspective",
463 507 "perspective-origin", "pitch", "pitch-range", "play-during", "position",
464 508 "presentation-level", "punctuation-trim", "quotes", "region-break-after",
465 509 "region-break-before", "region-break-inside", "region-fragment",
466 510 "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
467 511 "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
468 512 "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
469 513 "shape-outside", "size", "speak", "speak-as", "speak-header",
470 514 "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
471 515 "tab-size", "table-layout", "target", "target-name", "target-new",
472 516 "target-position", "text-align", "text-align-last", "text-decoration",
473 517 "text-decoration-color", "text-decoration-line", "text-decoration-skip",
474 518 "text-decoration-style", "text-emphasis", "text-emphasis-color",
475 519 "text-emphasis-position", "text-emphasis-style", "text-height",
476 520 "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
477 521 "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
478 522 "text-wrap", "top", "transform", "transform-origin", "transform-style",
479 523 "transition", "transition-delay", "transition-duration",
480 524 "transition-property", "transition-timing-function", "unicode-bidi",
481 525 "vertical-align", "visibility", "voice-balance", "voice-duration",
482 526 "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
483 527 "voice-volume", "volume", "white-space", "widows", "width", "word-break",
484 528 "word-spacing", "word-wrap", "z-index",
485 529 // SVG-specific
486 530 "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
487 531 "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
488 532 "color-interpolation", "color-interpolation-filters",
489 533 "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
490 534 "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
491 535 "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
492 536 "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
493 537 "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
494 538 "glyph-orientation-vertical", "text-anchor", "writing-mode"
495 539 ], propertyKeywords = keySet(propertyKeywords_);
496 540
497 541 var nonStandardPropertyKeywords_ = [
498 542 "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
499 543 "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
500 544 "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
501 545 "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
502 546 "searchfield-results-decoration", "zoom"
503 547 ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
504 548
505 549 var fontProperties_ = [
506 550 "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
507 551 "font-stretch", "font-weight", "font-style"
508 552 ], fontProperties = keySet(fontProperties_);
509 553
510 554 var counterDescriptors_ = [
511 555 "additive-symbols", "fallback", "negative", "pad", "prefix", "range",
512 556 "speak-as", "suffix", "symbols", "system"
513 557 ], counterDescriptors = keySet(counterDescriptors_);
514 558
515 559 var colorKeywords_ = [
516 560 "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
517 561 "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
518 562 "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
519 563 "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
520 564 "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
521 565 "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
522 566 "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
523 567 "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
524 568 "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
525 569 "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
526 570 "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
527 571 "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
528 572 "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
529 573 "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
530 574 "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
531 575 "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
532 576 "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
533 577 "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
534 578 "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
535 579 "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
536 580 "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
537 581 "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
538 582 "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
539 583 "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
540 584 "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
541 585 "whitesmoke", "yellow", "yellowgreen"
542 586 ], colorKeywords = keySet(colorKeywords_);
543 587
544 588 var valueKeywords_ = [
545 589 "above", "absolute", "activeborder", "additive", "activecaption", "afar",
546 590 "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
547 591 "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
548 592 "arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page",
549 593 "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
550 594 "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
551 595 "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
552 596 "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
553 597 "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
554 598 "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
555 599 "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
556 "col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
600 "col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
601 "compact", "condensed", "contain", "content",
557 602 "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
558 "cross", "crosshair", "currentcolor", "cursive", "cyclic", "dashed", "decimal",
603 "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
559 604 "decimal-leading-zero", "default", "default-button", "destination-atop",
560 "destination-in", "destination-out", "destination-over", "devanagari",
605 "destination-in", "destination-out", "destination-over", "devanagari", "difference",
561 606 "disc", "discard", "disclosure-closed", "disclosure-open", "document",
562 607 "dot-dash", "dot-dot-dash",
563 608 "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
564 609 "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
565 610 "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
566 611 "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
567 612 "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
568 613 "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
569 614 "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
570 615 "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
571 "ethiopic-numeric", "ew-resize", "expanded", "extends", "extra-condensed",
572 "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "footnotes",
616 "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
617 "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
573 618 "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
574 "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
619 "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
575 620 "help", "hidden", "hide", "higher", "highlight", "highlighttext",
576 "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
621 "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
577 622 "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
578 623 "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
579 624 "inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
580 625 "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
581 626 "katakana", "katakana-iroha", "keep-all", "khmer",
582 627 "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
583 "landscape", "lao", "large", "larger", "left", "level", "lighter",
628 "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
584 629 "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
585 630 "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
586 631 "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
587 "lower-roman", "lowercase", "ltr", "malayalam", "match", "matrix", "matrix3d",
632 "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
588 633 "media-controls-background", "media-current-time-display",
589 634 "media-fullscreen-button", "media-mute-button", "media-play-button",
590 635 "media-return-to-realtime-button", "media-rewind-button",
591 636 "media-seek-back-button", "media-seek-forward-button", "media-slider",
592 637 "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
593 638 "media-volume-slider-container", "media-volume-sliderthumb", "medium",
594 639 "menu", "menulist", "menulist-button", "menulist-text",
595 640 "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
596 "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
641 "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
597 642 "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
598 643 "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
599 644 "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
600 645 "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
601 646 "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
602 647 "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
603 648 "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
604 649 "progress", "push-button", "radial-gradient", "radio", "read-only",
605 650 "read-write", "read-write-plaintext-only", "rectangle", "region",
606 651 "relative", "repeat", "repeating-linear-gradient",
607 652 "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
608 653 "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
609 "rotateZ", "round", "row-resize", "rtl", "run-in", "running",
610 "s-resize", "sans-serif", "scale", "scale3d", "scaleX", "scaleY", "scaleZ",
654 "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
655 "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
611 656 "scroll", "scrollbar", "se-resize", "searchfield",
612 657 "searchfield-cancel-button", "searchfield-decoration",
613 658 "searchfield-results-button", "searchfield-results-decoration",
614 659 "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
615 660 "simp-chinese-formal", "simp-chinese-informal", "single",
616 661 "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
617 662 "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
618 "small", "small-caps", "small-caption", "smaller", "solid", "somali",
619 "source-atop", "source-in", "source-out", "source-over", "space", "spell-out", "square",
663 "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
664 "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square",
620 665 "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
621 666 "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
622 667 "table-caption", "table-cell", "table-column", "table-column-group",
623 668 "table-footer-group", "table-header-group", "table-row", "table-row-group",
624 669 "tamil",
625 670 "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
626 671 "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
627 672 "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
628 673 "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
629 674 "trad-chinese-formal", "trad-chinese-informal",
630 675 "translate", "translate3d", "translateX", "translateY", "translateZ",
631 676 "transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
632 677 "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
633 678 "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
634 679 "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
635 680 "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
636 "window", "windowframe", "windowtext", "words", "x-large", "x-small", "xor",
681 "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
637 682 "xx-large", "xx-small"
638 683 ], valueKeywords = keySet(valueKeywords_);
639 684
640 var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(propertyKeywords_)
641 .concat(nonStandardPropertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
685 var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
686 .concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
687 .concat(valueKeywords_);
642 688 CodeMirror.registerHelper("hintWords", "css", allWords);
643 689
644 690 function tokenCComment(stream, state) {
645 691 var maybeEnd = false, ch;
646 692 while ((ch = stream.next()) != null) {
647 693 if (maybeEnd && ch == "/") {
648 694 state.tokenize = null;
649 695 break;
650 696 }
651 697 maybeEnd = (ch == "*");
652 698 }
653 699 return ["comment", "comment"];
654 700 }
655 701
656 702 CodeMirror.defineMIME("text/css", {
657 703 documentTypes: documentTypes,
658 704 mediaTypes: mediaTypes,
659 705 mediaFeatures: mediaFeatures,
706 mediaValueKeywords: mediaValueKeywords,
660 707 propertyKeywords: propertyKeywords,
661 708 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
662 709 fontProperties: fontProperties,
663 710 counterDescriptors: counterDescriptors,
664 711 colorKeywords: colorKeywords,
665 712 valueKeywords: valueKeywords,
666 713 tokenHooks: {
667 714 "/": function(stream, state) {
668 715 if (!stream.eat("*")) return false;
669 716 state.tokenize = tokenCComment;
670 717 return tokenCComment(stream, state);
671 718 }
672 719 },
673 720 name: "css"
674 721 });
675 722
676 723 CodeMirror.defineMIME("text/x-scss", {
677 724 mediaTypes: mediaTypes,
678 725 mediaFeatures: mediaFeatures,
726 mediaValueKeywords: mediaValueKeywords,
679 727 propertyKeywords: propertyKeywords,
680 728 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
681 729 colorKeywords: colorKeywords,
682 730 valueKeywords: valueKeywords,
683 731 fontProperties: fontProperties,
684 732 allowNested: true,
685 733 tokenHooks: {
686 734 "/": function(stream, state) {
687 735 if (stream.eat("/")) {
688 736 stream.skipToEnd();
689 737 return ["comment", "comment"];
690 738 } else if (stream.eat("*")) {
691 739 state.tokenize = tokenCComment;
692 740 return tokenCComment(stream, state);
693 741 } else {
694 742 return ["operator", "operator"];
695 743 }
696 744 },
697 745 ":": function(stream) {
698 746 if (stream.match(/\s*\{/))
699 747 return [null, "{"];
700 748 return false;
701 749 },
702 750 "$": function(stream) {
703 751 stream.match(/^[\w-]+/);
704 752 if (stream.match(/^\s*:/, false))
705 753 return ["variable-2", "variable-definition"];
706 754 return ["variable-2", "variable"];
707 755 },
708 756 "#": function(stream) {
709 757 if (!stream.eat("{")) return false;
710 758 return [null, "interpolation"];
711 759 }
712 760 },
713 761 name: "css",
714 762 helperType: "scss"
715 763 });
716 764
717 765 CodeMirror.defineMIME("text/x-less", {
718 766 mediaTypes: mediaTypes,
719 767 mediaFeatures: mediaFeatures,
768 mediaValueKeywords: mediaValueKeywords,
720 769 propertyKeywords: propertyKeywords,
721 770 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
722 771 colorKeywords: colorKeywords,
723 772 valueKeywords: valueKeywords,
724 773 fontProperties: fontProperties,
725 774 allowNested: true,
726 775 tokenHooks: {
727 776 "/": function(stream, state) {
728 777 if (stream.eat("/")) {
729 778 stream.skipToEnd();
730 779 return ["comment", "comment"];
731 780 } else if (stream.eat("*")) {
732 781 state.tokenize = tokenCComment;
733 782 return tokenCComment(stream, state);
734 783 } else {
735 784 return ["operator", "operator"];
736 785 }
737 786 },
738 787 "@": function(stream) {
739 788 if (stream.eat("{")) return [null, "interpolation"];
740 789 if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
741 790 stream.eatWhile(/[\w\\\-]/);
742 791 if (stream.match(/^\s*:/, false))
743 792 return ["variable-2", "variable-definition"];
744 793 return ["variable-2", "variable"];
745 794 },
746 795 "&": function() {
747 796 return ["atom", "atom"];
748 797 }
749 798 },
750 799 name: "css",
751 800 helperType: "less"
752 801 });
753 802
803 CodeMirror.defineMIME("text/x-gss", {
804 documentTypes: documentTypes,
805 mediaTypes: mediaTypes,
806 mediaFeatures: mediaFeatures,
807 propertyKeywords: propertyKeywords,
808 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
809 fontProperties: fontProperties,
810 counterDescriptors: counterDescriptors,
811 colorKeywords: colorKeywords,
812 valueKeywords: valueKeywords,
813 supportsAtComponent: true,
814 tokenHooks: {
815 "/": function(stream, state) {
816 if (!stream.eat("*")) return false;
817 state.tokenize = tokenCComment;
818 return tokenCComment(stream, state);
819 }
820 },
821 name: "css",
822 helperType: "gss"
754 823 });
824
825 });
@@ -1,146 +1,146 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 // By the Neo4j Team and contributors.
5 5 // https://github.com/neo4j-contrib/CodeMirror
6 6
7 7 (function(mod) {
8 8 if (typeof exports == "object" && typeof module == "object") // CommonJS
9 9 mod(require("../../lib/codemirror"));
10 10 else if (typeof define == "function" && define.amd) // AMD
11 11 define(["../../lib/codemirror"], mod);
12 12 else // Plain browser env
13 13 mod(CodeMirror);
14 14 })(function(CodeMirror) {
15 15 "use strict";
16 16 var wordRegexp = function(words) {
17 17 return new RegExp("^(?:" + words.join("|") + ")$", "i");
18 18 };
19 19
20 20 CodeMirror.defineMode("cypher", function(config) {
21 21 var tokenBase = function(stream/*, state*/) {
22 22 var ch = stream.next();
23 23 if (ch === "\"" || ch === "'") {
24 24 stream.match(/.+?["']/);
25 25 return "string";
26 26 }
27 27 if (/[{}\(\),\.;\[\]]/.test(ch)) {
28 28 curPunc = ch;
29 29 return "node";
30 30 } else if (ch === "/" && stream.eat("/")) {
31 31 stream.skipToEnd();
32 32 return "comment";
33 33 } else if (operatorChars.test(ch)) {
34 34 stream.eatWhile(operatorChars);
35 35 return null;
36 36 } else {
37 37 stream.eatWhile(/[_\w\d]/);
38 38 if (stream.eat(":")) {
39 39 stream.eatWhile(/[\w\d_\-]/);
40 40 return "atom";
41 41 }
42 42 var word = stream.current();
43 43 if (funcs.test(word)) return "builtin";
44 44 if (preds.test(word)) return "def";
45 45 if (keywords.test(word)) return "keyword";
46 46 return "variable";
47 47 }
48 48 };
49 49 var pushContext = function(state, type, col) {
50 50 return state.context = {
51 51 prev: state.context,
52 52 indent: state.indent,
53 53 col: col,
54 54 type: type
55 55 };
56 56 };
57 57 var popContext = function(state) {
58 58 state.indent = state.context.indent;
59 59 return state.context = state.context.prev;
60 60 };
61 61 var indentUnit = config.indentUnit;
62 62 var curPunc;
63 var funcs = wordRegexp(["abs", "acos", "allShortestPaths", "asin", "atan", "atan2", "avg", "ceil", "coalesce", "collect", "cos", "cot", "count", "degrees", "e", "endnode", "exp", "extract", "filter", "floor", "haversin", "head", "id", "keys", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "right", "round", "rtrim", "shortestPath", "sign", "sin", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "trim", "type", "upper"]);
64 var preds = wordRegexp(["all", "and", "any", "has", "in", "none", "not", "or", "single", "xor"]);
65 var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "distinct", "drop", "else", "end", "explain", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "profile", "remove", "return", "scan", "set", "skip", "start", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with"]);
63 var funcs = wordRegexp(["abs", "acos", "allShortestPaths", "asin", "atan", "atan2", "avg", "ceil", "coalesce", "collect", "cos", "cot", "count", "degrees", "e", "endnode", "exp", "extract", "filter", "floor", "haversin", "head", "id", "keys", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "reverse", "right", "round", "rtrim", "shortestPath", "sign", "sin", "size", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "toString", "trim", "type", "upper"]);
64 var preds = wordRegexp(["all", "and", "any", "contains", "exists", "has", "in", "none", "not", "or", "single", "xor"]);
65 var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "detach", "distinct", "drop", "else", "end", "ends", "explain", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "join", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "profile", "remove", "return", "scan", "set", "skip", "start", "starts", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with"]);
66 66 var operatorChars = /[*+\-<>=&|~%^]/;
67 67
68 68 return {
69 69 startState: function(/*base*/) {
70 70 return {
71 71 tokenize: tokenBase,
72 72 context: null,
73 73 indent: 0,
74 74 col: 0
75 75 };
76 76 },
77 77 token: function(stream, state) {
78 78 if (stream.sol()) {
79 79 if (state.context && (state.context.align == null)) {
80 80 state.context.align = false;
81 81 }
82 82 state.indent = stream.indentation();
83 83 }
84 84 if (stream.eatSpace()) {
85 85 return null;
86 86 }
87 87 var style = state.tokenize(stream, state);
88 88 if (style !== "comment" && state.context && (state.context.align == null) && state.context.type !== "pattern") {
89 89 state.context.align = true;
90 90 }
91 91 if (curPunc === "(") {
92 92 pushContext(state, ")", stream.column());
93 93 } else if (curPunc === "[") {
94 94 pushContext(state, "]", stream.column());
95 95 } else if (curPunc === "{") {
96 96 pushContext(state, "}", stream.column());
97 97 } else if (/[\]\}\)]/.test(curPunc)) {
98 98 while (state.context && state.context.type === "pattern") {
99 99 popContext(state);
100 100 }
101 101 if (state.context && curPunc === state.context.type) {
102 102 popContext(state);
103 103 }
104 104 } else if (curPunc === "." && state.context && state.context.type === "pattern") {
105 105 popContext(state);
106 106 } else if (/atom|string|variable/.test(style) && state.context) {
107 107 if (/[\}\]]/.test(state.context.type)) {
108 108 pushContext(state, "pattern", stream.column());
109 109 } else if (state.context.type === "pattern" && !state.context.align) {
110 110 state.context.align = true;
111 111 state.context.col = stream.column();
112 112 }
113 113 }
114 114 return style;
115 115 },
116 116 indent: function(state, textAfter) {
117 117 var firstChar = textAfter && textAfter.charAt(0);
118 118 var context = state.context;
119 119 if (/[\]\}]/.test(firstChar)) {
120 120 while (context && context.type === "pattern") {
121 121 context = context.prev;
122 122 }
123 123 }
124 124 var closing = context && firstChar === context.type;
125 125 if (!context) return 0;
126 126 if (context.type === "keywords") return CodeMirror.commands.newlineAndIndent;
127 127 if (context.align) return context.col + (closing ? 0 : 1);
128 128 return context.indent + (closing ? 0 : indentUnit);
129 129 }
130 130 };
131 131 });
132 132
133 133 CodeMirror.modeExtensions["cypher"] = {
134 134 autoFormatLineBreaks: function(text) {
135 135 var i, lines, reProcessedPortion;
136 136 var lines = text.split("\n");
137 137 var reProcessedPortion = /\s+\b(return|where|order by|match|with|skip|limit|create|delete|set)\b\s/g;
138 138 for (var i = 0; i < lines.length; i++)
139 139 lines[i] = lines[i].replace(reProcessedPortion, " \n$1 ").trim();
140 140 return lines.join("\n");
141 141 }
142 142 };
143 143
144 144 CodeMirror.defineMIME("application/x-cypher-query", "cypher");
145 145
146 146 });
@@ -1,50 +1,130 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"), require("../clike/clike"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror", "../clike/clike"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 var keywords = ("this super static final const abstract class extends external factory " +
15 15 "implements get native operator set typedef with enum throw rethrow " +
16 16 "assert break case continue default in return new deferred async await " +
17 17 "try catch finally do else for if switch while import library export " +
18 "part of show hide is").split(" ");
18 "part of show hide is as").split(" ");
19 19 var blockKeywords = "try catch finally do else for if switch while".split(" ");
20 20 var atoms = "true false null".split(" ");
21 21 var builtins = "void bool num int double dynamic var String".split(" ");
22 22
23 23 function set(words) {
24 24 var obj = {};
25 25 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
26 26 return obj;
27 27 }
28 28
29 function pushInterpolationStack(state) {
30 (state.interpolationStack || (state.interpolationStack = [])).push(state.tokenize);
31 }
32
33 function popInterpolationStack(state) {
34 return (state.interpolationStack || (state.interpolationStack = [])).pop();
35 }
36
37 function sizeInterpolationStack(state) {
38 return state.interpolationStack ? state.interpolationStack.length : 0;
39 }
40
29 41 CodeMirror.defineMIME("application/dart", {
30 42 name: "clike",
31 43 keywords: set(keywords),
32 multiLineStrings: true,
33 44 blockKeywords: set(blockKeywords),
34 45 builtin: set(builtins),
35 46 atoms: set(atoms),
36 47 hooks: {
37 48 "@": function(stream) {
38 stream.eatWhile(/[\w\$_]/);
49 stream.eatWhile(/[\w\$_\.]/);
39 50 return "meta";
51 },
52
53 // custom string handling to deal with triple-quoted strings and string interpolation
54 "'": function(stream, state) {
55 return tokenString("'", stream, state, false);
56 },
57 "\"": function(stream, state) {
58 return tokenString("\"", stream, state, false);
59 },
60 "r": function(stream, state) {
61 var peek = stream.peek();
62 if (peek == "'" || peek == "\"") {
63 return tokenString(stream.next(), stream, state, true);
64 }
65 return false;
66 },
67
68 "}": function(_stream, state) {
69 // "}" is end of interpolation, if interpolation stack is non-empty
70 if (sizeInterpolationStack(state) > 0) {
71 state.tokenize = popInterpolationStack(state);
72 return null;
73 }
74 return false;
40 75 }
41 76 }
42 77 });
43 78
79 function tokenString(quote, stream, state, raw) {
80 var tripleQuoted = false;
81 if (stream.eat(quote)) {
82 if (stream.eat(quote)) tripleQuoted = true;
83 else return "string"; //empty string
84 }
85 function tokenStringHelper(stream, state) {
86 var escaped = false;
87 while (!stream.eol()) {
88 if (!raw && !escaped && stream.peek() == "$") {
89 pushInterpolationStack(state);
90 state.tokenize = tokenInterpolation;
91 return "string";
92 }
93 var next = stream.next();
94 if (next == quote && !escaped && (!tripleQuoted || stream.match(quote + quote))) {
95 state.tokenize = null;
96 break;
97 }
98 escaped = !raw && !escaped && next == "\\";
99 }
100 return "string";
101 }
102 state.tokenize = tokenStringHelper;
103 return tokenStringHelper(stream, state);
104 }
105
106 function tokenInterpolation(stream, state) {
107 stream.eat("$");
108 if (stream.eat("{")) {
109 // let clike handle the content of ${...},
110 // we take over again when "}" appears (see hooks).
111 state.tokenize = null;
112 } else {
113 state.tokenize = tokenInterpolationIdentifier;
114 }
115 return null;
116 }
117
118 function tokenInterpolationIdentifier(stream, state) {
119 stream.eatWhile(/[\w_]/);
120 state.tokenize = popInterpolationStack(state);
121 return "variable";
122 }
123
44 124 CodeMirror.registerHelper("hintWords", "application/dart", keywords.concat(atoms).concat(builtins));
45 125
46 126 // This is needed to make loading through meta.js work.
47 127 CodeMirror.defineMode("dart", function(conf) {
48 128 return CodeMirror.getMode(conf, "application/dart");
49 129 }, "clike");
50 130 });
@@ -1,350 +1,356 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
7 7 require("../../addon/mode/overlay"));
8 8 else if (typeof define == "function" && define.amd) // AMD
9 9 define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
10 10 "../../addon/mode/overlay"], mod);
11 11 else // Plain browser env
12 12 mod(CodeMirror);
13 13 })(function(CodeMirror) {
14 14 "use strict";
15 15
16 16 CodeMirror.defineMode("django:inner", function() {
17 var keywords = ["block", "endblock", "for", "endfor", "true", "false",
18 "loop", "none", "self", "super", "if", "endif", "as",
19 "else", "import", "with", "endwith", "without", "context", "ifequal", "endifequal",
20 "ifnotequal", "endifnotequal", "extends", "include", "load", "comment",
21 "endcomment", "empty", "url", "static", "trans", "blocktrans", "now", "regroup",
22 "lorem", "ifchanged", "endifchanged", "firstof", "debug", "cycle", "csrf_token",
23 "autoescape", "endautoescape", "spaceless", "ssi", "templatetag",
24 "verbatim", "endverbatim", "widthratio"],
17 var keywords = ["block", "endblock", "for", "endfor", "true", "false", "filter", "endfilter",
18 "loop", "none", "self", "super", "if", "elif", "endif", "as", "else", "import",
19 "with", "endwith", "without", "context", "ifequal", "endifequal", "ifnotequal",
20 "endifnotequal", "extends", "include", "load", "comment", "endcomment",
21 "empty", "url", "static", "trans", "blocktrans", "endblocktrans", "now",
22 "regroup", "lorem", "ifchanged", "endifchanged", "firstof", "debug", "cycle",
23 "csrf_token", "autoescape", "endautoescape", "spaceless", "endspaceless",
24 "ssi", "templatetag", "verbatim", "endverbatim", "widthratio"],
25 25 filters = ["add", "addslashes", "capfirst", "center", "cut", "date",
26 26 "default", "default_if_none", "dictsort",
27 27 "dictsortreversed", "divisibleby", "escape", "escapejs",
28 28 "filesizeformat", "first", "floatformat", "force_escape",
29 29 "get_digit", "iriencode", "join", "last", "length",
30 30 "length_is", "linebreaks", "linebreaksbr", "linenumbers",
31 31 "ljust", "lower", "make_list", "phone2numeric", "pluralize",
32 32 "pprint", "random", "removetags", "rjust", "safe",
33 33 "safeseq", "slice", "slugify", "stringformat", "striptags",
34 34 "time", "timesince", "timeuntil", "title", "truncatechars",
35 35 "truncatechars_html", "truncatewords", "truncatewords_html",
36 36 "unordered_list", "upper", "urlencode", "urlize",
37 37 "urlizetrunc", "wordcount", "wordwrap", "yesno"],
38 operators = ["==", "!=", "<", ">", "<=", ">=", "in", "not", "or", "and"];
38 operators = ["==", "!=", "<", ">", "<=", ">="],
39 wordOperators = ["in", "not", "or", "and"];
39 40
40 41 keywords = new RegExp("^\\b(" + keywords.join("|") + ")\\b");
41 42 filters = new RegExp("^\\b(" + filters.join("|") + ")\\b");
42 43 operators = new RegExp("^\\b(" + operators.join("|") + ")\\b");
44 wordOperators = new RegExp("^\\b(" + wordOperators.join("|") + ")\\b");
43 45
44 46 // We have to return "null" instead of null, in order to avoid string
45 47 // styling as the default, when using Django templates inside HTML
46 48 // element attributes
47 49 function tokenBase (stream, state) {
48 50 // Attempt to identify a variable, template or comment tag respectively
49 51 if (stream.match("{{")) {
50 52 state.tokenize = inVariable;
51 53 return "tag";
52 54 } else if (stream.match("{%")) {
53 55 state.tokenize = inTag;
54 56 return "tag";
55 57 } else if (stream.match("{#")) {
56 58 state.tokenize = inComment;
57 59 return "comment";
58 60 }
59 61
60 62 // Ignore completely any stream series that do not match the
61 63 // Django template opening tags.
62 while (stream.next() != null && !stream.match("{{", false) && !stream.match("{%", false)) {}
64 while (stream.next() != null && !stream.match(/\{[{%#]/, false)) {}
63 65 return null;
64 66 }
65 67
66 68 // A string can be included in either single or double quotes (this is
67 69 // the delimeter). Mark everything as a string until the start delimeter
68 70 // occurs again.
69 71 function inString (delimeter, previousTokenizer) {
70 72 return function (stream, state) {
71 73 if (!state.escapeNext && stream.eat(delimeter)) {
72 74 state.tokenize = previousTokenizer;
73 75 } else {
74 76 if (state.escapeNext) {
75 77 state.escapeNext = false;
76 78 }
77 79
78 80 var ch = stream.next();
79 81
80 82 // Take into account the backslash for escaping characters, such as
81 83 // the string delimeter.
82 84 if (ch == "\\") {
83 85 state.escapeNext = true;
84 86 }
85 87 }
86 88
87 89 return "string";
88 90 };
89 91 }
90 92
91 93 // Apply Django template variable syntax highlighting
92 94 function inVariable (stream, state) {
93 95 // Attempt to match a dot that precedes a property
94 96 if (state.waitDot) {
95 97 state.waitDot = false;
96 98
97 99 if (stream.peek() != ".") {
98 100 return "null";
99 101 }
100 102
101 103 // Dot folowed by a non-word character should be considered an error.
102 104 if (stream.match(/\.\W+/)) {
103 105 return "error";
104 106 } else if (stream.eat(".")) {
105 107 state.waitProperty = true;
106 108 return "null";
107 109 } else {
108 110 throw Error ("Unexpected error while waiting for property.");
109 111 }
110 112 }
111 113
112 114 // Attempt to match a pipe that precedes a filter
113 115 if (state.waitPipe) {
114 116 state.waitPipe = false;
115 117
116 118 if (stream.peek() != "|") {
117 119 return "null";
118 120 }
119 121
120 122 // Pipe folowed by a non-word character should be considered an error.
121 123 if (stream.match(/\.\W+/)) {
122 124 return "error";
123 125 } else if (stream.eat("|")) {
124 126 state.waitFilter = true;
125 127 return "null";
126 128 } else {
127 129 throw Error ("Unexpected error while waiting for filter.");
128 130 }
129 131 }
130 132
131 133 // Highlight properties
132 134 if (state.waitProperty) {
133 135 state.waitProperty = false;
134 136 if (stream.match(/\b(\w+)\b/)) {
135 137 state.waitDot = true; // A property can be followed by another property
136 138 state.waitPipe = true; // A property can be followed by a filter
137 139 return "property";
138 140 }
139 141 }
140 142
141 143 // Highlight filters
142 144 if (state.waitFilter) {
143 145 state.waitFilter = false;
144 146 if (stream.match(filters)) {
145 147 return "variable-2";
146 148 }
147 149 }
148 150
149 151 // Ignore all white spaces
150 152 if (stream.eatSpace()) {
151 153 state.waitProperty = false;
152 154 return "null";
153 155 }
154 156
155 157 // Identify numbers
156 158 if (stream.match(/\b\d+(\.\d+)?\b/)) {
157 159 return "number";
158 160 }
159 161
160 162 // Identify strings
161 163 if (stream.match("'")) {
162 164 state.tokenize = inString("'", state.tokenize);
163 165 return "string";
164 166 } else if (stream.match('"')) {
165 167 state.tokenize = inString('"', state.tokenize);
166 168 return "string";
167 169 }
168 170
169 171 // Attempt to find the variable
170 172 if (stream.match(/\b(\w+)\b/) && !state.foundVariable) {
171 173 state.waitDot = true;
172 174 state.waitPipe = true; // A property can be followed by a filter
173 175 return "variable";
174 176 }
175 177
176 178 // If found closing tag reset
177 179 if (stream.match("}}")) {
178 180 state.waitProperty = null;
179 181 state.waitFilter = null;
180 182 state.waitDot = null;
181 183 state.waitPipe = null;
182 184 state.tokenize = tokenBase;
183 185 return "tag";
184 186 }
185 187
186 188 // If nothing was found, advance to the next character
187 189 stream.next();
188 190 return "null";
189 191 }
190 192
191 193 function inTag (stream, state) {
192 194 // Attempt to match a dot that precedes a property
193 195 if (state.waitDot) {
194 196 state.waitDot = false;
195 197
196 198 if (stream.peek() != ".") {
197 199 return "null";
198 200 }
199 201
200 202 // Dot folowed by a non-word character should be considered an error.
201 203 if (stream.match(/\.\W+/)) {
202 204 return "error";
203 205 } else if (stream.eat(".")) {
204 206 state.waitProperty = true;
205 207 return "null";
206 208 } else {
207 209 throw Error ("Unexpected error while waiting for property.");
208 210 }
209 211 }
210 212
211 213 // Attempt to match a pipe that precedes a filter
212 214 if (state.waitPipe) {
213 215 state.waitPipe = false;
214 216
215 217 if (stream.peek() != "|") {
216 218 return "null";
217 219 }
218 220
219 221 // Pipe folowed by a non-word character should be considered an error.
220 222 if (stream.match(/\.\W+/)) {
221 223 return "error";
222 224 } else if (stream.eat("|")) {
223 225 state.waitFilter = true;
224 226 return "null";
225 227 } else {
226 228 throw Error ("Unexpected error while waiting for filter.");
227 229 }
228 230 }
229 231
230 232 // Highlight properties
231 233 if (state.waitProperty) {
232 234 state.waitProperty = false;
233 235 if (stream.match(/\b(\w+)\b/)) {
234 236 state.waitDot = true; // A property can be followed by another property
235 237 state.waitPipe = true; // A property can be followed by a filter
236 238 return "property";
237 239 }
238 240 }
239 241
240 242 // Highlight filters
241 243 if (state.waitFilter) {
242 244 state.waitFilter = false;
243 245 if (stream.match(filters)) {
244 246 return "variable-2";
245 247 }
246 248 }
247 249
248 250 // Ignore all white spaces
249 251 if (stream.eatSpace()) {
250 252 state.waitProperty = false;
251 253 return "null";
252 254 }
253 255
254 256 // Identify numbers
255 257 if (stream.match(/\b\d+(\.\d+)?\b/)) {
256 258 return "number";
257 259 }
258 260
259 261 // Identify strings
260 262 if (stream.match("'")) {
261 263 state.tokenize = inString("'", state.tokenize);
262 264 return "string";
263 265 } else if (stream.match('"')) {
264 266 state.tokenize = inString('"', state.tokenize);
265 267 return "string";
266 268 }
267 269
268 270 // Attempt to match an operator
269 271 if (stream.match(operators)) {
270 272 return "operator";
271 273 }
272 274
275 // Attempt to match a word operator
276 if (stream.match(wordOperators)) {
277 return "keyword";
278 }
279
273 280 // Attempt to match a keyword
274 281 var keywordMatch = stream.match(keywords);
275 282 if (keywordMatch) {
276 283 if (keywordMatch[0] == "comment") {
277 284 state.blockCommentTag = true;
278 285 }
279 286 return "keyword";
280 287 }
281 288
282 289 // Attempt to match a variable
283 290 if (stream.match(/\b(\w+)\b/)) {
284 291 state.waitDot = true;
285 292 state.waitPipe = true; // A property can be followed by a filter
286 293 return "variable";
287 294 }
288 295
289 296 // If found closing tag reset
290 297 if (stream.match("%}")) {
291 298 state.waitProperty = null;
292 299 state.waitFilter = null;
293 300 state.waitDot = null;
294 301 state.waitPipe = null;
295 302 // If the tag that closes is a block comment tag, we want to mark the
296 303 // following code as comment, until the tag closes.
297 304 if (state.blockCommentTag) {
298 305 state.blockCommentTag = false; // Release the "lock"
299 306 state.tokenize = inBlockComment;
300 307 } else {
301 308 state.tokenize = tokenBase;
302 309 }
303 310 return "tag";
304 311 }
305 312
306 313 // If nothing was found, advance to the next character
307 314 stream.next();
308 315 return "null";
309 316 }
310 317
311 318 // Mark everything as comment inside the tag and the tag itself.
312 319 function inComment (stream, state) {
313 if (stream.match("#}")) {
314 state.tokenize = tokenBase;
315 }
320 if (stream.match(/^.*?#\}/)) state.tokenize = tokenBase
321 else stream.skipToEnd()
316 322 return "comment";
317 323 }
318 324
319 325 // Mark everything as a comment until the `blockcomment` tag closes.
320 326 function inBlockComment (stream, state) {
321 327 if (stream.match(/\{%\s*endcomment\s*%\}/, false)) {
322 328 state.tokenize = inTag;
323 329 stream.match("{%");
324 330 return "tag";
325 331 } else {
326 332 stream.next();
327 333 return "comment";
328 334 }
329 335 }
330 336
331 337 return {
332 338 startState: function () {
333 339 return {tokenize: tokenBase};
334 340 },
335 341 token: function (stream, state) {
336 342 return state.tokenize(stream, state);
337 343 },
338 344 blockCommentStart: "{% comment %}",
339 345 blockCommentEnd: "{% endcomment %}"
340 346 };
341 347 });
342 348
343 349 CodeMirror.defineMode("django", function(config) {
344 350 var htmlBase = CodeMirror.getMode(config, "text/html");
345 351 var djangoInner = CodeMirror.getMode(config, "django:inner");
346 352 return CodeMirror.overlayMode(htmlBase, djangoInner);
347 353 });
348 354
349 355 CodeMirror.defineMIME("text/x-django", "django");
350 356 });
@@ -1,76 +1,79 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 // Collect all Dockerfile directives
15 15 var instructions = ["from", "maintainer", "run", "cmd", "expose", "env",
16 16 "add", "copy", "entrypoint", "volume", "user",
17 17 "workdir", "onbuild"],
18 18 instructionRegex = "(" + instructions.join('|') + ")",
19 19 instructionOnlyLine = new RegExp(instructionRegex + "\\s*$", "i"),
20 20 instructionWithArguments = new RegExp(instructionRegex + "(\\s+)", "i");
21 21
22 22 CodeMirror.defineSimpleMode("dockerfile", {
23 23 start: [
24 24 // Block comment: This is a line starting with a comment
25 25 {
26 26 regex: /#.*$/,
27 27 token: "comment"
28 28 },
29 29 // Highlight an instruction without any arguments (for convenience)
30 30 {
31 31 regex: instructionOnlyLine,
32 32 token: "variable-2"
33 33 },
34 34 // Highlight an instruction followed by arguments
35 35 {
36 36 regex: instructionWithArguments,
37 37 token: ["variable-2", null],
38 38 next: "arguments"
39 39 },
40 40 {
41 41 regex: /./,
42 42 token: null
43 43 }
44 44 ],
45 45 arguments: [
46 46 {
47 47 // Line comment without instruction arguments is an error
48 48 regex: /#.*$/,
49 49 token: "error",
50 50 next: "start"
51 51 },
52 52 {
53 53 regex: /[^#]+\\$/,
54 54 token: null
55 55 },
56 56 {
57 57 // Match everything except for the inline comment
58 58 regex: /[^#]+/,
59 59 token: null,
60 60 next: "start"
61 61 },
62 62 {
63 63 regex: /$/,
64 64 token: null,
65 65 next: "start"
66 66 },
67 67 // Fail safe return to start
68 68 {
69 69 token: null,
70 70 next: "start"
71 71 }
72 ]
72 ],
73 meta: {
74 lineComment: "#"
75 }
73 76 });
74 77
75 78 CodeMirror.defineMIME("text/x-dockerfile", "dockerfile");
76 79 });
@@ -1,205 +1,205 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode("elm", function() {
15 15
16 16 function switchState(source, setState, f) {
17 17 setState(f);
18 18 return f(source, setState);
19 19 }
20 20
21 21 // These should all be Unicode extended, as per the Haskell 2010 report
22 22 var smallRE = /[a-z_]/;
23 23 var largeRE = /[A-Z]/;
24 24 var digitRE = /[0-9]/;
25 25 var hexitRE = /[0-9A-Fa-f]/;
26 26 var octitRE = /[0-7]/;
27 27 var idRE = /[a-z_A-Z0-9\']/;
28 28 var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/;
29 29 var specialRE = /[(),;[\]`{}]/;
30 30 var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer
31 31
32 32 function normal() {
33 33 return function (source, setState) {
34 34 if (source.eatWhile(whiteCharRE)) {
35 35 return null;
36 36 }
37 37
38 38 var ch = source.next();
39 39 if (specialRE.test(ch)) {
40 40 if (ch == '{' && source.eat('-')) {
41 41 var t = "comment";
42 42 if (source.eat('#')) t = "meta";
43 43 return switchState(source, setState, ncomment(t, 1));
44 44 }
45 45 return null;
46 46 }
47 47
48 48 if (ch == '\'') {
49 49 if (source.eat('\\'))
50 50 source.next(); // should handle other escapes here
51 51 else
52 52 source.next();
53 53
54 54 if (source.eat('\''))
55 55 return "string";
56 56 return "error";
57 57 }
58 58
59 59 if (ch == '"') {
60 60 return switchState(source, setState, stringLiteral);
61 61 }
62 62
63 63 if (largeRE.test(ch)) {
64 64 source.eatWhile(idRE);
65 65 if (source.eat('.'))
66 66 return "qualifier";
67 67 return "variable-2";
68 68 }
69 69
70 70 if (smallRE.test(ch)) {
71 71 var isDef = source.pos === 1;
72 72 source.eatWhile(idRE);
73 73 return isDef ? "variable-3" : "variable";
74 74 }
75 75
76 76 if (digitRE.test(ch)) {
77 77 if (ch == '0') {
78 78 if (source.eat(/[xX]/)) {
79 79 source.eatWhile(hexitRE); // should require at least 1
80 80 return "integer";
81 81 }
82 82 if (source.eat(/[oO]/)) {
83 83 source.eatWhile(octitRE); // should require at least 1
84 84 return "number";
85 85 }
86 86 }
87 87 source.eatWhile(digitRE);
88 88 var t = "number";
89 89 if (source.eat('.')) {
90 90 t = "number";
91 91 source.eatWhile(digitRE); // should require at least 1
92 92 }
93 93 if (source.eat(/[eE]/)) {
94 94 t = "number";
95 95 source.eat(/[-+]/);
96 96 source.eatWhile(digitRE); // should require at least 1
97 97 }
98 98 return t;
99 99 }
100 100
101 101 if (symbolRE.test(ch)) {
102 102 if (ch == '-' && source.eat(/-/)) {
103 103 source.eatWhile(/-/);
104 104 if (!source.eat(symbolRE)) {
105 105 source.skipToEnd();
106 106 return "comment";
107 107 }
108 108 }
109 109 source.eatWhile(symbolRE);
110 110 return "builtin";
111 111 }
112 112
113 113 return "error";
114 114 }
115 115 }
116 116
117 117 function ncomment(type, nest) {
118 118 if (nest == 0) {
119 119 return normal();
120 120 }
121 121 return function(source, setState) {
122 122 var currNest = nest;
123 123 while (!source.eol()) {
124 124 var ch = source.next();
125 125 if (ch == '{' && source.eat('-')) {
126 126 ++currNest;
127 127 } else if (ch == '-' && source.eat('}')) {
128 128 --currNest;
129 129 if (currNest == 0) {
130 130 setState(normal());
131 131 return type;
132 132 }
133 133 }
134 134 }
135 135 setState(ncomment(type, currNest));
136 136 return type;
137 137 }
138 138 }
139 139
140 140 function stringLiteral(source, setState) {
141 141 while (!source.eol()) {
142 142 var ch = source.next();
143 143 if (ch == '"') {
144 144 setState(normal());
145 145 return "string";
146 146 }
147 147 if (ch == '\\') {
148 148 if (source.eol() || source.eat(whiteCharRE)) {
149 149 setState(stringGap);
150 150 return "string";
151 151 }
152 152 if (!source.eat('&')) source.next(); // should handle other escapes here
153 153 }
154 154 }
155 155 setState(normal());
156 156 return "error";
157 157 }
158 158
159 159 function stringGap(source, setState) {
160 160 if (source.eat('\\')) {
161 161 return switchState(source, setState, stringLiteral);
162 162 }
163 163 source.next();
164 164 setState(normal());
165 165 return "error";
166 166 }
167 167
168 168
169 169 var wellKnownWords = (function() {
170 170 var wkw = {};
171 171
172 172 var keywords = [
173 173 "case", "of", "as",
174 174 "if", "then", "else",
175 175 "let", "in",
176 176 "infix", "infixl", "infixr",
177 177 "type", "alias",
178 178 "input", "output", "foreign", "loopback",
179 179 "module", "where", "import", "exposing",
180 180 "_", "..", "|", ":", "=", "\\", "\"", "->", "<-"
181 181 ];
182 182
183 183 for (var i = keywords.length; i--;)
184 184 wkw[keywords[i]] = "keyword";
185 185
186 186 return wkw;
187 187 })();
188 188
189 189
190 190
191 191 return {
192 192 startState: function () { return { f: normal() }; },
193 193 copyState: function (s) { return { f: s.f }; },
194 194
195 195 token: function(stream, state) {
196 196 var t = state.f(stream, function(s) { state.f = s; });
197 197 var w = stream.current();
198 198 return (wellKnownWords.hasOwnProperty(w)) ? wellKnownWords[w] : t;
199 199 }
200 200 };
201 201
202 202 });
203 203
204 204 CodeMirror.defineMIME("text/x-elm", "elm");
205 })();
205 });
@@ -1,622 +1,618 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 /*jshint unused:true, eqnull:true, curly:true, bitwise:true */
5 5 /*jshint undef:true, latedef:true, trailing:true */
6 6 /*global CodeMirror:true */
7 7
8 8 // erlang mode.
9 9 // tokenizer -> token types -> CodeMirror styles
10 10 // tokenizer maintains a parse stack
11 11 // indenter uses the parse stack
12 12
13 13 // TODO indenter:
14 14 // bit syntax
15 15 // old guard/bif/conversion clashes (e.g. "float/1")
16 16 // type/spec/opaque
17 17
18 18 (function(mod) {
19 19 if (typeof exports == "object" && typeof module == "object") // CommonJS
20 20 mod(require("../../lib/codemirror"));
21 21 else if (typeof define == "function" && define.amd) // AMD
22 22 define(["../../lib/codemirror"], mod);
23 23 else // Plain browser env
24 24 mod(CodeMirror);
25 25 })(function(CodeMirror) {
26 26 "use strict";
27 27
28 28 CodeMirror.defineMIME("text/x-erlang", "erlang");
29 29
30 30 CodeMirror.defineMode("erlang", function(cmCfg) {
31 31 "use strict";
32 32
33 33 /////////////////////////////////////////////////////////////////////////////
34 34 // constants
35 35
36 36 var typeWords = [
37 37 "-type", "-spec", "-export_type", "-opaque"];
38 38
39 39 var keywordWords = [
40 40 "after","begin","catch","case","cond","end","fun","if",
41 41 "let","of","query","receive","try","when"];
42 42
43 43 var separatorRE = /[\->,;]/;
44 44 var separatorWords = [
45 45 "->",";",","];
46 46
47 47 var operatorAtomWords = [
48 48 "and","andalso","band","bnot","bor","bsl","bsr","bxor",
49 49 "div","not","or","orelse","rem","xor"];
50 50
51 51 var operatorSymbolRE = /[\+\-\*\/<>=\|:!]/;
52 52 var operatorSymbolWords = [
53 53 "=","+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-","!"];
54 54
55 55 var openParenRE = /[<\(\[\{]/;
56 56 var openParenWords = [
57 57 "<<","(","[","{"];
58 58
59 59 var closeParenRE = /[>\)\]\}]/;
60 60 var closeParenWords = [
61 61 "}","]",")",">>"];
62 62
63 63 var guardWords = [
64 64 "is_atom","is_binary","is_bitstring","is_boolean","is_float",
65 65 "is_function","is_integer","is_list","is_number","is_pid",
66 66 "is_port","is_record","is_reference","is_tuple",
67 67 "atom","binary","bitstring","boolean","function","integer","list",
68 68 "number","pid","port","record","reference","tuple"];
69 69
70 70 var bifWords = [
71 71 "abs","adler32","adler32_combine","alive","apply","atom_to_binary",
72 72 "atom_to_list","binary_to_atom","binary_to_existing_atom",
73 73 "binary_to_list","binary_to_term","bit_size","bitstring_to_list",
74 74 "byte_size","check_process_code","contact_binary","crc32",
75 75 "crc32_combine","date","decode_packet","delete_module",
76 76 "disconnect_node","element","erase","exit","float","float_to_list",
77 77 "garbage_collect","get","get_keys","group_leader","halt","hd",
78 78 "integer_to_list","internal_bif","iolist_size","iolist_to_binary",
79 79 "is_alive","is_atom","is_binary","is_bitstring","is_boolean",
80 80 "is_float","is_function","is_integer","is_list","is_number","is_pid",
81 81 "is_port","is_process_alive","is_record","is_reference","is_tuple",
82 82 "length","link","list_to_atom","list_to_binary","list_to_bitstring",
83 83 "list_to_existing_atom","list_to_float","list_to_integer",
84 84 "list_to_pid","list_to_tuple","load_module","make_ref","module_loaded",
85 85 "monitor_node","node","node_link","node_unlink","nodes","notalive",
86 86 "now","open_port","pid_to_list","port_close","port_command",
87 87 "port_connect","port_control","pre_loaded","process_flag",
88 88 "process_info","processes","purge_module","put","register",
89 89 "registered","round","self","setelement","size","spawn","spawn_link",
90 90 "spawn_monitor","spawn_opt","split_binary","statistics",
91 91 "term_to_binary","time","throw","tl","trunc","tuple_size",
92 92 "tuple_to_list","unlink","unregister","whereis"];
93 93
94 94 // upper case: [A-Z] [Ø-Þ] [À-Ö]
95 95 // lower case: [a-z] [ß-ö] [ø-ÿ]
96 96 var anumRE = /[\w@Ø-ÞÀ-Öß-öø-ÿ]/;
97 97 var escapesRE =
98 98 /[0-7]{1,3}|[bdefnrstv\\"']|\^[a-zA-Z]|x[0-9a-zA-Z]{2}|x{[0-9a-zA-Z]+}/;
99 99
100 100 /////////////////////////////////////////////////////////////////////////////
101 101 // tokenizer
102 102
103 103 function tokenizer(stream,state) {
104 104 // in multi-line string
105 105 if (state.in_string) {
106 106 state.in_string = (!doubleQuote(stream));
107 107 return rval(state,stream,"string");
108 108 }
109 109
110 110 // in multi-line atom
111 111 if (state.in_atom) {
112 112 state.in_atom = (!singleQuote(stream));
113 113 return rval(state,stream,"atom");
114 114 }
115 115
116 116 // whitespace
117 117 if (stream.eatSpace()) {
118 118 return rval(state,stream,"whitespace");
119 119 }
120 120
121 121 // attributes and type specs
122 122 if (!peekToken(state) &&
123 123 stream.match(/-\s*[a-zß-öø-ÿ][\wØ-ÞÀ-Öß-öø-ÿ]*/)) {
124 124 if (is_member(stream.current(),typeWords)) {
125 125 return rval(state,stream,"type");
126 126 }else{
127 127 return rval(state,stream,"attribute");
128 128 }
129 129 }
130 130
131 131 var ch = stream.next();
132 132
133 133 // comment
134 134 if (ch == '%') {
135 135 stream.skipToEnd();
136 136 return rval(state,stream,"comment");
137 137 }
138 138
139 139 // colon
140 140 if (ch == ":") {
141 141 return rval(state,stream,"colon");
142 142 }
143 143
144 144 // macro
145 145 if (ch == '?') {
146 146 stream.eatSpace();
147 147 stream.eatWhile(anumRE);
148 148 return rval(state,stream,"macro");
149 149 }
150 150
151 151 // record
152 152 if (ch == "#") {
153 153 stream.eatSpace();
154 154 stream.eatWhile(anumRE);
155 155 return rval(state,stream,"record");
156 156 }
157 157
158 158 // dollar escape
159 159 if (ch == "$") {
160 160 if (stream.next() == "\\" && !stream.match(escapesRE)) {
161 161 return rval(state,stream,"error");
162 162 }
163 163 return rval(state,stream,"number");
164 164 }
165 165
166 166 // dot
167 167 if (ch == ".") {
168 168 return rval(state,stream,"dot");
169 169 }
170 170
171 171 // quoted atom
172 172 if (ch == '\'') {
173 173 if (!(state.in_atom = (!singleQuote(stream)))) {
174 174 if (stream.match(/\s*\/\s*[0-9]/,false)) {
175 175 stream.match(/\s*\/\s*[0-9]/,true);
176 176 return rval(state,stream,"fun"); // 'f'/0 style fun
177 177 }
178 178 if (stream.match(/\s*\(/,false) || stream.match(/\s*:/,false)) {
179 179 return rval(state,stream,"function");
180 180 }
181 181 }
182 182 return rval(state,stream,"atom");
183 183 }
184 184
185 185 // string
186 186 if (ch == '"') {
187 187 state.in_string = (!doubleQuote(stream));
188 188 return rval(state,stream,"string");
189 189 }
190 190
191 191 // variable
192 192 if (/[A-Z_Ø-ÞÀ-Ö]/.test(ch)) {
193 193 stream.eatWhile(anumRE);
194 194 return rval(state,stream,"variable");
195 195 }
196 196
197 197 // atom/keyword/BIF/function
198 198 if (/[a-z_ß-öø-ÿ]/.test(ch)) {
199 199 stream.eatWhile(anumRE);
200 200
201 201 if (stream.match(/\s*\/\s*[0-9]/,false)) {
202 202 stream.match(/\s*\/\s*[0-9]/,true);
203 203 return rval(state,stream,"fun"); // f/0 style fun
204 204 }
205 205
206 206 var w = stream.current();
207 207
208 208 if (is_member(w,keywordWords)) {
209 209 return rval(state,stream,"keyword");
210 210 }else if (is_member(w,operatorAtomWords)) {
211 211 return rval(state,stream,"operator");
212 212 }else if (stream.match(/\s*\(/,false)) {
213 213 // 'put' and 'erlang:put' are bifs, 'foo:put' is not
214 214 if (is_member(w,bifWords) &&
215 215 ((peekToken(state).token != ":") ||
216 216 (peekToken(state,2).token == "erlang"))) {
217 217 return rval(state,stream,"builtin");
218 218 }else if (is_member(w,guardWords)) {
219 219 return rval(state,stream,"guard");
220 220 }else{
221 221 return rval(state,stream,"function");
222 222 }
223 }else if (is_member(w,operatorAtomWords)) {
224 return rval(state,stream,"operator");
225 223 }else if (lookahead(stream) == ":") {
226 224 if (w == "erlang") {
227 225 return rval(state,stream,"builtin");
228 226 } else {
229 227 return rval(state,stream,"function");
230 228 }
231 229 }else if (is_member(w,["true","false"])) {
232 230 return rval(state,stream,"boolean");
233 }else if (is_member(w,["true","false"])) {
234 return rval(state,stream,"boolean");
235 231 }else{
236 232 return rval(state,stream,"atom");
237 233 }
238 234 }
239 235
240 236 // number
241 237 var digitRE = /[0-9]/;
242 238 var radixRE = /[0-9a-zA-Z]/; // 36#zZ style int
243 239 if (digitRE.test(ch)) {
244 240 stream.eatWhile(digitRE);
245 241 if (stream.eat('#')) { // 36#aZ style integer
246 242 if (!stream.eatWhile(radixRE)) {
247 243 stream.backUp(1); //"36#" - syntax error
248 244 }
249 245 } else if (stream.eat('.')) { // float
250 246 if (!stream.eatWhile(digitRE)) {
251 247 stream.backUp(1); // "3." - probably end of function
252 248 } else {
253 249 if (stream.eat(/[eE]/)) { // float with exponent
254 250 if (stream.eat(/[-+]/)) {
255 251 if (!stream.eatWhile(digitRE)) {
256 252 stream.backUp(2); // "2e-" - syntax error
257 253 }
258 254 } else {
259 255 if (!stream.eatWhile(digitRE)) {
260 256 stream.backUp(1); // "2e" - syntax error
261 257 }
262 258 }
263 259 }
264 260 }
265 261 }
266 262 return rval(state,stream,"number"); // normal integer
267 263 }
268 264
269 265 // open parens
270 266 if (nongreedy(stream,openParenRE,openParenWords)) {
271 267 return rval(state,stream,"open_paren");
272 268 }
273 269
274 270 // close parens
275 271 if (nongreedy(stream,closeParenRE,closeParenWords)) {
276 272 return rval(state,stream,"close_paren");
277 273 }
278 274
279 275 // separators
280 276 if (greedy(stream,separatorRE,separatorWords)) {
281 277 return rval(state,stream,"separator");
282 278 }
283 279
284 280 // operators
285 281 if (greedy(stream,operatorSymbolRE,operatorSymbolWords)) {
286 282 return rval(state,stream,"operator");
287 283 }
288 284
289 285 return rval(state,stream,null);
290 286 }
291 287
292 288 /////////////////////////////////////////////////////////////////////////////
293 289 // utilities
294 290 function nongreedy(stream,re,words) {
295 291 if (stream.current().length == 1 && re.test(stream.current())) {
296 292 stream.backUp(1);
297 293 while (re.test(stream.peek())) {
298 294 stream.next();
299 295 if (is_member(stream.current(),words)) {
300 296 return true;
301 297 }
302 298 }
303 299 stream.backUp(stream.current().length-1);
304 300 }
305 301 return false;
306 302 }
307 303
308 304 function greedy(stream,re,words) {
309 305 if (stream.current().length == 1 && re.test(stream.current())) {
310 306 while (re.test(stream.peek())) {
311 307 stream.next();
312 308 }
313 309 while (0 < stream.current().length) {
314 310 if (is_member(stream.current(),words)) {
315 311 return true;
316 312 }else{
317 313 stream.backUp(1);
318 314 }
319 315 }
320 316 stream.next();
321 317 }
322 318 return false;
323 319 }
324 320
325 321 function doubleQuote(stream) {
326 322 return quote(stream, '"', '\\');
327 323 }
328 324
329 325 function singleQuote(stream) {
330 326 return quote(stream,'\'','\\');
331 327 }
332 328
333 329 function quote(stream,quoteChar,escapeChar) {
334 330 while (!stream.eol()) {
335 331 var ch = stream.next();
336 332 if (ch == quoteChar) {
337 333 return true;
338 334 }else if (ch == escapeChar) {
339 335 stream.next();
340 336 }
341 337 }
342 338 return false;
343 339 }
344 340
345 341 function lookahead(stream) {
346 342 var m = stream.match(/([\n\s]+|%[^\n]*\n)*(.)/,false);
347 343 return m ? m.pop() : "";
348 344 }
349 345
350 346 function is_member(element,list) {
351 347 return (-1 < list.indexOf(element));
352 348 }
353 349
354 350 function rval(state,stream,type) {
355 351
356 352 // parse stack
357 353 pushToken(state,realToken(type,stream));
358 354
359 355 // map erlang token type to CodeMirror style class
360 356 // erlang -> CodeMirror tag
361 357 switch (type) {
362 358 case "atom": return "atom";
363 359 case "attribute": return "attribute";
364 360 case "boolean": return "atom";
365 361 case "builtin": return "builtin";
366 362 case "close_paren": return null;
367 363 case "colon": return null;
368 364 case "comment": return "comment";
369 365 case "dot": return null;
370 366 case "error": return "error";
371 367 case "fun": return "meta";
372 368 case "function": return "tag";
373 369 case "guard": return "property";
374 370 case "keyword": return "keyword";
375 371 case "macro": return "variable-2";
376 372 case "number": return "number";
377 373 case "open_paren": return null;
378 374 case "operator": return "operator";
379 375 case "record": return "bracket";
380 376 case "separator": return null;
381 377 case "string": return "string";
382 378 case "type": return "def";
383 379 case "variable": return "variable";
384 380 default: return null;
385 381 }
386 382 }
387 383
388 384 function aToken(tok,col,ind,typ) {
389 385 return {token: tok,
390 386 column: col,
391 387 indent: ind,
392 388 type: typ};
393 389 }
394 390
395 391 function realToken(type,stream) {
396 392 return aToken(stream.current(),
397 393 stream.column(),
398 394 stream.indentation(),
399 395 type);
400 396 }
401 397
402 398 function fakeToken(type) {
403 399 return aToken(type,0,0,type);
404 400 }
405 401
406 402 function peekToken(state,depth) {
407 403 var len = state.tokenStack.length;
408 404 var dep = (depth ? depth : 1);
409 405
410 406 if (len < dep) {
411 407 return false;
412 408 }else{
413 409 return state.tokenStack[len-dep];
414 410 }
415 411 }
416 412
417 413 function pushToken(state,token) {
418 414
419 415 if (!(token.type == "comment" || token.type == "whitespace")) {
420 416 state.tokenStack = maybe_drop_pre(state.tokenStack,token);
421 417 state.tokenStack = maybe_drop_post(state.tokenStack);
422 418 }
423 419 }
424 420
425 421 function maybe_drop_pre(s,token) {
426 422 var last = s.length-1;
427 423
428 424 if (0 < last && s[last].type === "record" && token.type === "dot") {
429 425 s.pop();
430 426 }else if (0 < last && s[last].type === "group") {
431 427 s.pop();
432 428 s.push(token);
433 429 }else{
434 430 s.push(token);
435 431 }
436 432 return s;
437 433 }
438 434
439 435 function maybe_drop_post(s) {
440 436 var last = s.length-1;
441 437
442 438 if (s[last].type === "dot") {
443 439 return [];
444 440 }
445 441 if (s[last].type === "fun" && s[last-1].token === "fun") {
446 442 return s.slice(0,last-1);
447 443 }
448 444 switch (s[s.length-1].token) {
449 445 case "}": return d(s,{g:["{"]});
450 446 case "]": return d(s,{i:["["]});
451 447 case ")": return d(s,{i:["("]});
452 448 case ">>": return d(s,{i:["<<"]});
453 449 case "end": return d(s,{i:["begin","case","fun","if","receive","try"]});
454 450 case ",": return d(s,{e:["begin","try","when","->",
455 451 ",","(","[","{","<<"]});
456 452 case "->": return d(s,{r:["when"],
457 453 m:["try","if","case","receive"]});
458 454 case ";": return d(s,{E:["case","fun","if","receive","try","when"]});
459 455 case "catch":return d(s,{e:["try"]});
460 456 case "of": return d(s,{e:["case"]});
461 457 case "after":return d(s,{e:["receive","try"]});
462 458 default: return s;
463 459 }
464 460 }
465 461
466 462 function d(stack,tt) {
467 463 // stack is a stack of Token objects.
468 464 // tt is an object; {type:tokens}
469 465 // type is a char, tokens is a list of token strings.
470 466 // The function returns (possibly truncated) stack.
471 467 // It will descend the stack, looking for a Token such that Token.token
472 468 // is a member of tokens. If it does not find that, it will normally (but
473 469 // see "E" below) return stack. If it does find a match, it will remove
474 470 // all the Tokens between the top and the matched Token.
475 471 // If type is "m", that is all it does.
476 472 // If type is "i", it will also remove the matched Token and the top Token.
477 473 // If type is "g", like "i", but add a fake "group" token at the top.
478 474 // If type is "r", it will remove the matched Token, but not the top Token.
479 475 // If type is "e", it will keep the matched Token but not the top Token.
480 476 // If type is "E", it behaves as for type "e", except if there is no match,
481 477 // in which case it will return an empty stack.
482 478
483 479 for (var type in tt) {
484 480 var len = stack.length-1;
485 481 var tokens = tt[type];
486 482 for (var i = len-1; -1 < i ; i--) {
487 483 if (is_member(stack[i].token,tokens)) {
488 484 var ss = stack.slice(0,i);
489 485 switch (type) {
490 486 case "m": return ss.concat(stack[i]).concat(stack[len]);
491 487 case "r": return ss.concat(stack[len]);
492 488 case "i": return ss;
493 489 case "g": return ss.concat(fakeToken("group"));
494 490 case "E": return ss.concat(stack[i]);
495 491 case "e": return ss.concat(stack[i]);
496 492 }
497 493 }
498 494 }
499 495 }
500 496 return (type == "E" ? [] : stack);
501 497 }
502 498
503 499 /////////////////////////////////////////////////////////////////////////////
504 500 // indenter
505 501
506 502 function indenter(state,textAfter) {
507 503 var t;
508 504 var unit = cmCfg.indentUnit;
509 505 var wordAfter = wordafter(textAfter);
510 506 var currT = peekToken(state,1);
511 507 var prevT = peekToken(state,2);
512 508
513 509 if (state.in_string || state.in_atom) {
514 510 return CodeMirror.Pass;
515 511 }else if (!prevT) {
516 512 return 0;
517 513 }else if (currT.token == "when") {
518 514 return currT.column+unit;
519 515 }else if (wordAfter === "when" && prevT.type === "function") {
520 516 return prevT.indent+unit;
521 517 }else if (wordAfter === "(" && currT.token === "fun") {
522 518 return currT.column+3;
523 519 }else if (wordAfter === "catch" && (t = getToken(state,["try"]))) {
524 520 return t.column;
525 521 }else if (is_member(wordAfter,["end","after","of"])) {
526 522 t = getToken(state,["begin","case","fun","if","receive","try"]);
527 523 return t ? t.column : CodeMirror.Pass;
528 524 }else if (is_member(wordAfter,closeParenWords)) {
529 525 t = getToken(state,openParenWords);
530 526 return t ? t.column : CodeMirror.Pass;
531 527 }else if (is_member(currT.token,[",","|","||"]) ||
532 528 is_member(wordAfter,[",","|","||"])) {
533 529 t = postcommaToken(state);
534 530 return t ? t.column+t.token.length : unit;
535 531 }else if (currT.token == "->") {
536 532 if (is_member(prevT.token, ["receive","case","if","try"])) {
537 533 return prevT.column+unit+unit;
538 534 }else{
539 535 return prevT.column+unit;
540 536 }
541 537 }else if (is_member(currT.token,openParenWords)) {
542 538 return currT.column+currT.token.length;
543 539 }else{
544 540 t = defaultToken(state);
545 541 return truthy(t) ? t.column+unit : 0;
546 542 }
547 543 }
548 544
549 545 function wordafter(str) {
550 546 var m = str.match(/,|[a-z]+|\}|\]|\)|>>|\|+|\(/);
551 547
552 548 return truthy(m) && (m.index === 0) ? m[0] : "";
553 549 }
554 550
555 551 function postcommaToken(state) {
556 552 var objs = state.tokenStack.slice(0,-1);
557 553 var i = getTokenIndex(objs,"type",["open_paren"]);
558 554
559 555 return truthy(objs[i]) ? objs[i] : false;
560 556 }
561 557
562 558 function defaultToken(state) {
563 559 var objs = state.tokenStack;
564 560 var stop = getTokenIndex(objs,"type",["open_paren","separator","keyword"]);
565 561 var oper = getTokenIndex(objs,"type",["operator"]);
566 562
567 563 if (truthy(stop) && truthy(oper) && stop < oper) {
568 564 return objs[stop+1];
569 565 } else if (truthy(stop)) {
570 566 return objs[stop];
571 567 } else {
572 568 return false;
573 569 }
574 570 }
575 571
576 572 function getToken(state,tokens) {
577 573 var objs = state.tokenStack;
578 574 var i = getTokenIndex(objs,"token",tokens);
579 575
580 576 return truthy(objs[i]) ? objs[i] : false;
581 577 }
582 578
583 579 function getTokenIndex(objs,propname,propvals) {
584 580
585 581 for (var i = objs.length-1; -1 < i ; i--) {
586 582 if (is_member(objs[i][propname],propvals)) {
587 583 return i;
588 584 }
589 585 }
590 586 return false;
591 587 }
592 588
593 589 function truthy(x) {
594 590 return (x !== false) && (x != null);
595 591 }
596 592
597 593 /////////////////////////////////////////////////////////////////////////////
598 594 // this object defines the mode
599 595
600 596 return {
601 597 startState:
602 598 function() {
603 599 return {tokenStack: [],
604 600 in_string: false,
605 601 in_atom: false};
606 602 },
607 603
608 604 token:
609 605 function(stream, state) {
610 606 return tokenizer(stream, state);
611 607 },
612 608
613 609 indent:
614 610 function(state, textAfter) {
615 611 return indenter(state,textAfter);
616 612 },
617 613
618 614 lineComment: "%"
619 615 };
620 616 });
621 617
622 618 });
@@ -1,123 +1,130 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"), require("../markdown/markdown"), require("../../addon/mode/overlay"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror", "../markdown/markdown", "../../addon/mode/overlay"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 var urlRE = /^((?:(?:aaas?|about|acap|adiumxtra|af[ps]|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|cap|chrome(?:-extension)?|cid|coap|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-(?:playcontainer|playsingle)|dns|doi|dtn|dvb|ed2k|facetime|feed|file|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|hcp|https?|iax|icap|icon|im|imap|info|ipn|ipp|irc[6s]?|iris(?:\.beep|\.lwz|\.xpc|\.xpcs)?|itms|jar|javascript|jms|keyparc|lastfm|ldaps?|magnet|mailto|maps|market|message|mid|mms|ms-help|msnim|msrps?|mtqp|mumble|mupdate|mvn|news|nfs|nih?|nntp|notes|oid|opaquelocktoken|palm|paparazzi|platform|pop|pres|proxy|psyc|query|res(?:ource)?|rmi|rsync|rtmp|rtsp|secondlife|service|session|sftp|sgn|shttp|sieve|sips?|skype|sm[bs]|snmp|soap\.beeps?|soldat|spotify|ssh|steam|svn|tag|teamspeak|tel(?:net)?|tftp|things|thismessage|tip|tn3270|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|view-source|webcal|wss?|wtai|wyciwyg|xcon(?:-userid)?|xfire|xmlrpc\.beeps?|xmpp|xri|ymsgr|z39\.50[rs]?):(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i
15
14 16 CodeMirror.defineMode("gfm", function(config, modeConfig) {
15 17 var codeDepth = 0;
16 18 function blankLine(state) {
17 19 state.code = false;
18 20 return null;
19 21 }
20 22 var gfmOverlay = {
21 23 startState: function() {
22 24 return {
23 25 code: false,
24 26 codeBlock: false,
25 27 ateSpace: false
26 28 };
27 29 },
28 30 copyState: function(s) {
29 31 return {
30 32 code: s.code,
31 33 codeBlock: s.codeBlock,
32 34 ateSpace: s.ateSpace
33 35 };
34 36 },
35 37 token: function(stream, state) {
36 38 state.combineTokens = null;
37 39
38 40 // Hack to prevent formatting override inside code blocks (block and inline)
39 41 if (state.codeBlock) {
40 if (stream.match(/^```/)) {
42 if (stream.match(/^```+/)) {
41 43 state.codeBlock = false;
42 44 return null;
43 45 }
44 46 stream.skipToEnd();
45 47 return null;
46 48 }
47 49 if (stream.sol()) {
48 50 state.code = false;
49 51 }
50 if (stream.sol() && stream.match(/^```/)) {
52 if (stream.sol() && stream.match(/^```+/)) {
51 53 stream.skipToEnd();
52 54 state.codeBlock = true;
53 55 return null;
54 56 }
55 57 // If this block is changed, it may need to be updated in Markdown mode
56 58 if (stream.peek() === '`') {
57 59 stream.next();
58 60 var before = stream.pos;
59 61 stream.eatWhile('`');
60 62 var difference = 1 + stream.pos - before;
61 63 if (!state.code) {
62 64 codeDepth = difference;
63 65 state.code = true;
64 66 } else {
65 67 if (difference === codeDepth) { // Must be exact
66 68 state.code = false;
67 69 }
68 70 }
69 71 return null;
70 72 } else if (state.code) {
71 73 stream.next();
72 74 return null;
73 75 }
74 76 // Check if space. If so, links can be formatted later on
75 77 if (stream.eatSpace()) {
76 78 state.ateSpace = true;
77 79 return null;
78 80 }
79 81 if (stream.sol() || state.ateSpace) {
80 82 state.ateSpace = false;
83 if (modeConfig.gitHubSpice !== false) {
81 84 if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) {
82 85 // User/Project@SHA
83 86 // User@SHA
84 87 // SHA
85 88 state.combineTokens = true;
86 89 return "link";
87 90 } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) {
88 91 // User/Project#Num
89 92 // User#Num
90 93 // #Num
91 94 state.combineTokens = true;
92 95 return "link";
93 96 }
94 97 }
95 if (stream.match(/^((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i) &&
96 stream.string.slice(stream.start - 2, stream.start) != "](") {
98 }
99 if (stream.match(urlRE) &&
100 stream.string.slice(stream.start - 2, stream.start) != "](" &&
101 (stream.start == 0 || /\W/.test(stream.string.charAt(stream.start - 1)))) {
97 102 // URLs
98 103 // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
99 104 // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine
105 // And then limited url schemes to the CommonMark list, so foo:bar isn't matched as a URL
100 106 state.combineTokens = true;
101 107 return "link";
102 108 }
103 109 stream.next();
104 110 return null;
105 111 },
106 112 blankLine: blankLine
107 113 };
108 114
109 115 var markdownConfig = {
110 116 underscoresBreakWords: false,
111 117 taskLists: true,
112 fencedCodeBlocks: true,
118 fencedCodeBlocks: '```',
113 119 strikethrough: true
114 120 };
115 121 for (var attr in modeConfig) {
116 122 markdownConfig[attr] = modeConfig[attr];
117 123 }
118 124 markdownConfig.name = "markdown";
119 CodeMirror.defineMIME("gfmBase", markdownConfig);
120 return CodeMirror.overlayMode(CodeMirror.getMode(config, "gfmBase"), gfmOverlay);
125 return CodeMirror.overlayMode(CodeMirror.getMode(config, markdownConfig), gfmOverlay);
126
121 127 }, "markdown");
122 128
129 CodeMirror.defineMIME("text/x-gfm", "gfm");
123 130 });
@@ -1,185 +1,185 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode("go", function(config) {
15 15 var indentUnit = config.indentUnit;
16 16
17 17 var keywords = {
18 18 "break":true, "case":true, "chan":true, "const":true, "continue":true,
19 19 "default":true, "defer":true, "else":true, "fallthrough":true, "for":true,
20 20 "func":true, "go":true, "goto":true, "if":true, "import":true,
21 21 "interface":true, "map":true, "package":true, "range":true, "return":true,
22 22 "select":true, "struct":true, "switch":true, "type":true, "var":true,
23 23 "bool":true, "byte":true, "complex64":true, "complex128":true,
24 24 "float32":true, "float64":true, "int8":true, "int16":true, "int32":true,
25 25 "int64":true, "string":true, "uint8":true, "uint16":true, "uint32":true,
26 26 "uint64":true, "int":true, "uint":true, "uintptr":true
27 27 };
28 28
29 29 var atoms = {
30 30 "true":true, "false":true, "iota":true, "nil":true, "append":true,
31 31 "cap":true, "close":true, "complex":true, "copy":true, "imag":true,
32 32 "len":true, "make":true, "new":true, "panic":true, "print":true,
33 33 "println":true, "real":true, "recover":true
34 34 };
35 35
36 36 var isOperatorChar = /[+\-*&^%:=<>!|\/]/;
37 37
38 38 var curPunc;
39 39
40 40 function tokenBase(stream, state) {
41 41 var ch = stream.next();
42 42 if (ch == '"' || ch == "'" || ch == "`") {
43 43 state.tokenize = tokenString(ch);
44 44 return state.tokenize(stream, state);
45 45 }
46 46 if (/[\d\.]/.test(ch)) {
47 47 if (ch == ".") {
48 48 stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/);
49 49 } else if (ch == "0") {
50 50 stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/);
51 51 } else {
52 52 stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/);
53 53 }
54 54 return "number";
55 55 }
56 56 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
57 57 curPunc = ch;
58 58 return null;
59 59 }
60 60 if (ch == "/") {
61 61 if (stream.eat("*")) {
62 62 state.tokenize = tokenComment;
63 63 return tokenComment(stream, state);
64 64 }
65 65 if (stream.eat("/")) {
66 66 stream.skipToEnd();
67 67 return "comment";
68 68 }
69 69 }
70 70 if (isOperatorChar.test(ch)) {
71 71 stream.eatWhile(isOperatorChar);
72 72 return "operator";
73 73 }
74 74 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
75 75 var cur = stream.current();
76 76 if (keywords.propertyIsEnumerable(cur)) {
77 77 if (cur == "case" || cur == "default") curPunc = "case";
78 78 return "keyword";
79 79 }
80 80 if (atoms.propertyIsEnumerable(cur)) return "atom";
81 81 return "variable";
82 82 }
83 83
84 84 function tokenString(quote) {
85 85 return function(stream, state) {
86 86 var escaped = false, next, end = false;
87 87 while ((next = stream.next()) != null) {
88 88 if (next == quote && !escaped) {end = true; break;}
89 escaped = !escaped && next == "\\";
89 escaped = !escaped && quote != "`" && next == "\\";
90 90 }
91 91 if (end || !(escaped || quote == "`"))
92 92 state.tokenize = tokenBase;
93 93 return "string";
94 94 };
95 95 }
96 96
97 97 function tokenComment(stream, state) {
98 98 var maybeEnd = false, ch;
99 99 while (ch = stream.next()) {
100 100 if (ch == "/" && maybeEnd) {
101 101 state.tokenize = tokenBase;
102 102 break;
103 103 }
104 104 maybeEnd = (ch == "*");
105 105 }
106 106 return "comment";
107 107 }
108 108
109 109 function Context(indented, column, type, align, prev) {
110 110 this.indented = indented;
111 111 this.column = column;
112 112 this.type = type;
113 113 this.align = align;
114 114 this.prev = prev;
115 115 }
116 116 function pushContext(state, col, type) {
117 117 return state.context = new Context(state.indented, col, type, null, state.context);
118 118 }
119 119 function popContext(state) {
120 120 if (!state.context.prev) return;
121 121 var t = state.context.type;
122 122 if (t == ")" || t == "]" || t == "}")
123 123 state.indented = state.context.indented;
124 124 return state.context = state.context.prev;
125 125 }
126 126
127 127 // Interface
128 128
129 129 return {
130 130 startState: function(basecolumn) {
131 131 return {
132 132 tokenize: null,
133 133 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
134 134 indented: 0,
135 135 startOfLine: true
136 136 };
137 137 },
138 138
139 139 token: function(stream, state) {
140 140 var ctx = state.context;
141 141 if (stream.sol()) {
142 142 if (ctx.align == null) ctx.align = false;
143 143 state.indented = stream.indentation();
144 144 state.startOfLine = true;
145 145 if (ctx.type == "case") ctx.type = "}";
146 146 }
147 147 if (stream.eatSpace()) return null;
148 148 curPunc = null;
149 149 var style = (state.tokenize || tokenBase)(stream, state);
150 150 if (style == "comment") return style;
151 151 if (ctx.align == null) ctx.align = true;
152 152
153 153 if (curPunc == "{") pushContext(state, stream.column(), "}");
154 154 else if (curPunc == "[") pushContext(state, stream.column(), "]");
155 155 else if (curPunc == "(") pushContext(state, stream.column(), ")");
156 156 else if (curPunc == "case") ctx.type = "case";
157 157 else if (curPunc == "}" && ctx.type == "}") ctx = popContext(state);
158 158 else if (curPunc == ctx.type) popContext(state);
159 159 state.startOfLine = false;
160 160 return style;
161 161 },
162 162
163 163 indent: function(state, textAfter) {
164 164 if (state.tokenize != tokenBase && state.tokenize != null) return 0;
165 165 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
166 166 if (ctx.type == "case" && /^(?:case|default)\b/.test(textAfter)) {
167 167 state.context.type = "}";
168 168 return ctx.indented;
169 169 }
170 170 var closing = firstChar == ctx.type;
171 171 if (ctx.align) return ctx.column + (closing ? 0 : 1);
172 172 else return ctx.indented + (closing ? 0 : indentUnit);
173 173 },
174 174
175 175 electricChars: "{}):",
176 176 fold: "brace",
177 177 blockCommentStart: "/*",
178 178 blockCommentEnd: "*/",
179 179 lineComment: "//"
180 180 };
181 181 });
182 182
183 183 CodeMirror.defineMIME("text/x-go", "go");
184 184
185 185 });
@@ -1,159 +1,161 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../ruby/ruby"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../ruby/ruby"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 // full haml mode. This handled embeded ruby and html fragments too
15 15 CodeMirror.defineMode("haml", function(config) {
16 16 var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"});
17 17 var rubyMode = CodeMirror.getMode(config, "ruby");
18 18
19 19 function rubyInQuote(endQuote) {
20 20 return function(stream, state) {
21 21 var ch = stream.peek();
22 22 if (ch == endQuote && state.rubyState.tokenize.length == 1) {
23 23 // step out of ruby context as it seems to complete processing all the braces
24 24 stream.next();
25 25 state.tokenize = html;
26 26 return "closeAttributeTag";
27 27 } else {
28 28 return ruby(stream, state);
29 29 }
30 30 };
31 31 }
32 32
33 33 function ruby(stream, state) {
34 34 if (stream.match("-#")) {
35 35 stream.skipToEnd();
36 36 return "comment";
37 37 }
38 38 return rubyMode.token(stream, state.rubyState);
39 39 }
40 40
41 41 function html(stream, state) {
42 42 var ch = stream.peek();
43 43
44 44 // handle haml declarations. All declarations that cant be handled here
45 45 // will be passed to html mode
46 46 if (state.previousToken.style == "comment" ) {
47 47 if (state.indented > state.previousToken.indented) {
48 48 stream.skipToEnd();
49 49 return "commentLine";
50 50 }
51 51 }
52 52
53 53 if (state.startOfLine) {
54 54 if (ch == "!" && stream.match("!!")) {
55 55 stream.skipToEnd();
56 56 return "tag";
57 57 } else if (stream.match(/^%[\w:#\.]+=/)) {
58 58 state.tokenize = ruby;
59 59 return "hamlTag";
60 60 } else if (stream.match(/^%[\w:]+/)) {
61 61 return "hamlTag";
62 62 } else if (ch == "/" ) {
63 63 stream.skipToEnd();
64 64 return "comment";
65 65 }
66 66 }
67 67
68 68 if (state.startOfLine || state.previousToken.style == "hamlTag") {
69 69 if ( ch == "#" || ch == ".") {
70 70 stream.match(/[\w-#\.]*/);
71 71 return "hamlAttribute";
72 72 }
73 73 }
74 74
75 75 // donot handle --> as valid ruby, make it HTML close comment instead
76 76 if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) {
77 77 state.tokenize = ruby;
78 78 return state.tokenize(stream, state);
79 79 }
80 80
81 81 if (state.previousToken.style == "hamlTag" ||
82 82 state.previousToken.style == "closeAttributeTag" ||
83 83 state.previousToken.style == "hamlAttribute") {
84 84 if (ch == "(") {
85 85 state.tokenize = rubyInQuote(")");
86 86 return state.tokenize(stream, state);
87 87 } else if (ch == "{") {
88 if (!stream.match(/^\{%.*/)) {
88 89 state.tokenize = rubyInQuote("}");
89 90 return state.tokenize(stream, state);
90 91 }
91 92 }
93 }
92 94
93 95 return htmlMode.token(stream, state.htmlState);
94 96 }
95 97
96 98 return {
97 99 // default to html mode
98 100 startState: function() {
99 101 var htmlState = htmlMode.startState();
100 102 var rubyState = rubyMode.startState();
101 103 return {
102 104 htmlState: htmlState,
103 105 rubyState: rubyState,
104 106 indented: 0,
105 107 previousToken: { style: null, indented: 0},
106 108 tokenize: html
107 109 };
108 110 },
109 111
110 112 copyState: function(state) {
111 113 return {
112 114 htmlState : CodeMirror.copyState(htmlMode, state.htmlState),
113 115 rubyState: CodeMirror.copyState(rubyMode, state.rubyState),
114 116 indented: state.indented,
115 117 previousToken: state.previousToken,
116 118 tokenize: state.tokenize
117 119 };
118 120 },
119 121
120 122 token: function(stream, state) {
121 123 if (stream.sol()) {
122 124 state.indented = stream.indentation();
123 125 state.startOfLine = true;
124 126 }
125 127 if (stream.eatSpace()) return null;
126 128 var style = state.tokenize(stream, state);
127 129 state.startOfLine = false;
128 130 // dont record comment line as we only want to measure comment line with
129 131 // the opening comment block
130 132 if (style && style != "commentLine") {
131 133 state.previousToken = { style: style, indented: state.indented };
132 134 }
133 135 // if current state is ruby and the previous token is not `,` reset the
134 136 // tokenize to html
135 137 if (stream.eol() && state.tokenize == ruby) {
136 138 stream.backUp(1);
137 139 var ch = stream.peek();
138 140 stream.next();
139 141 if (ch && ch != ",") {
140 142 state.tokenize = html;
141 143 }
142 144 }
143 145 // reprocess some of the specific style tag when finish setting previousToken
144 146 if (style == "hamlTag") {
145 147 style = "tag";
146 148 } else if (style == "commentLine") {
147 149 style = "comment";
148 150 } else if (style == "hamlAttribute") {
149 151 style = "attribute";
150 152 } else if (style == "closeAttributeTag") {
151 153 style = null;
152 154 }
153 155 return style;
154 156 }
155 157 };
156 158 }, "htmlmixed", "ruby");
157 159
158 160 CodeMirror.defineMIME("text/x-haml", "haml");
159 161 });
@@ -1,53 +1,62 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
6 mod(require("../../lib/codemirror"), require("../../addon/mode/simple"), require("../../addon/mode/multiplex"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
8 define(["../../lib/codemirror", "../../addon/mode/simple", "../../addon/mode/multiplex"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 CodeMirror.defineSimpleMode("handlebars", {
14 CodeMirror.defineSimpleMode("handlebars-tags", {
15 15 start: [
16 16 { regex: /\{\{!--/, push: "dash_comment", token: "comment" },
17 17 { regex: /\{\{!/, push: "comment", token: "comment" },
18 18 { regex: /\{\{/, push: "handlebars", token: "tag" }
19 19 ],
20 20 handlebars: [
21 21 { regex: /\}\}/, pop: true, token: "tag" },
22 22
23 23 // Double and single quotes
24 { regex: /"(?:[^\\]|\\.)*?"/, token: "string" },
25 { regex: /'(?:[^\\]|\\.)*?'/, token: "string" },
24 { regex: /"(?:[^\\"]|\\.)*"?/, token: "string" },
25 { regex: /'(?:[^\\']|\\.)*'?/, token: "string" },
26 26
27 27 // Handlebars keywords
28 28 { regex: />|[#\/]([A-Za-z_]\w*)/, token: "keyword" },
29 29 { regex: /(?:else|this)\b/, token: "keyword" },
30 30
31 31 // Numeral
32 32 { regex: /\d+/i, token: "number" },
33 33
34 34 // Atoms like = and .
35 35 { regex: /=|~|@|true|false/, token: "atom" },
36 36
37 37 // Paths
38 38 { regex: /(?:\.\.\/)*(?:[A-Za-z_][\w\.]*)+/, token: "variable-2" }
39 39 ],
40 40 dash_comment: [
41 41 { regex: /--\}\}/, pop: true, token: "comment" },
42 42
43 43 // Commented code
44 44 { regex: /./, token: "comment"}
45 45 ],
46 46 comment: [
47 47 { regex: /\}\}/, pop: true, token: "comment" },
48 48 { regex: /./, token: "comment" }
49 49 ]
50 50 });
51 51
52 CodeMirror.defineMode("handlebars", function(config, parserConfig) {
53 var handlebars = CodeMirror.getMode(config, "handlebars-tags");
54 if (!parserConfig || !parserConfig.base) return handlebars;
55 return CodeMirror.multiplexingMode(
56 CodeMirror.getMode(config, parserConfig.base),
57 {open: "{{", close: "}}", mode: handlebars, parseDelimiters: true}
58 );
59 });
60
52 61 CodeMirror.defineMIME("text/x-handlebars-template", "handlebars");
53 62 });
@@ -1,518 +1,515 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode("haxe", function(config, parserConfig) {
15 15 var indentUnit = config.indentUnit;
16 16
17 17 // Tokenizer
18 18
19 var keywords = function(){
20 19 function kw(type) {return {type: type, style: "keyword"};}
21 20 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
22 21 var operator = kw("operator"), atom = {type: "atom", style: "atom"}, attribute = {type:"attribute", style: "attribute"};
23 22 var type = kw("typedef");
24 return {
23 var keywords = {
25 24 "if": A, "while": A, "else": B, "do": B, "try": B,
26 25 "return": C, "break": C, "continue": C, "new": C, "throw": C,
27 26 "var": kw("var"), "inline":attribute, "static": attribute, "using":kw("import"),
28 27 "public": attribute, "private": attribute, "cast": kw("cast"), "import": kw("import"), "macro": kw("macro"),
29 28 "function": kw("function"), "catch": kw("catch"), "untyped": kw("untyped"), "callback": kw("cb"),
30 29 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
31 30 "in": operator, "never": kw("property_access"), "trace":kw("trace"),
32 31 "class": type, "abstract":type, "enum":type, "interface":type, "typedef":type, "extends":type, "implements":type, "dynamic":type,
33 32 "true": atom, "false": atom, "null": atom
34 33 };
35 }();
36 34
37 35 var isOperatorChar = /[+\-*&%=<>!?|]/;
38 36
39 37 function chain(stream, state, f) {
40 38 state.tokenize = f;
41 39 return f(stream, state);
42 40 }
43 41
44 function nextUntilUnescaped(stream, end) {
42 function toUnescaped(stream, end) {
45 43 var escaped = false, next;
46 44 while ((next = stream.next()) != null) {
47 45 if (next == end && !escaped)
48 return false;
46 return true;
49 47 escaped = !escaped && next == "\\";
50 48 }
51 return escaped;
52 49 }
53 50
54 51 // Used as scratch variables to communicate multiple values without
55 52 // consing up tons of objects.
56 53 var type, content;
57 54 function ret(tp, style, cont) {
58 55 type = tp; content = cont;
59 56 return style;
60 57 }
61 58
62 59 function haxeTokenBase(stream, state) {
63 60 var ch = stream.next();
64 if (ch == '"' || ch == "'")
61 if (ch == '"' || ch == "'") {
65 62 return chain(stream, state, haxeTokenString(ch));
66 else if (/[\[\]{}\(\),;\:\.]/.test(ch))
63 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
67 64 return ret(ch);
68 else if (ch == "0" && stream.eat(/x/i)) {
65 } else if (ch == "0" && stream.eat(/x/i)) {
69 66 stream.eatWhile(/[\da-f]/i);
70 67 return ret("number", "number");
71 }
72 else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
73 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
68 } else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
69 stream.match(/^\d*(?:\.\d*(?!\.))?(?:[eE][+\-]?\d+)?/);
74 70 return ret("number", "number");
75 }
76 else if (state.reAllowed && (ch == "~" && stream.eat(/\//))) {
77 nextUntilUnescaped(stream, "/");
71 } else if (state.reAllowed && (ch == "~" && stream.eat(/\//))) {
72 toUnescaped(stream, "/");
78 73 stream.eatWhile(/[gimsu]/);
79 74 return ret("regexp", "string-2");
80 }
81 else if (ch == "/") {
75 } else if (ch == "/") {
82 76 if (stream.eat("*")) {
83 77 return chain(stream, state, haxeTokenComment);
84 }
85 else if (stream.eat("/")) {
78 } else if (stream.eat("/")) {
86 79 stream.skipToEnd();
87 80 return ret("comment", "comment");
88 }
89 else {
81 } else {
90 82 stream.eatWhile(isOperatorChar);
91 83 return ret("operator", null, stream.current());
92 84 }
93 }
94 else if (ch == "#") {
85 } else if (ch == "#") {
95 86 stream.skipToEnd();
96 87 return ret("conditional", "meta");
97 }
98 else if (ch == "@") {
88 } else if (ch == "@") {
99 89 stream.eat(/:/);
100 90 stream.eatWhile(/[\w_]/);
101 91 return ret ("metadata", "meta");
102 }
103 else if (isOperatorChar.test(ch)) {
92 } else if (isOperatorChar.test(ch)) {
104 93 stream.eatWhile(isOperatorChar);
105 94 return ret("operator", null, stream.current());
106 }
107 else {
95 } else {
108 96 var word;
109 if(/[A-Z]/.test(ch))
110 {
97 if(/[A-Z]/.test(ch)) {
111 98 stream.eatWhile(/[\w_<>]/);
112 99 word = stream.current();
113 100 return ret("type", "variable-3", word);
114 }
115 else
116 {
101 } else {
117 102 stream.eatWhile(/[\w_]/);
118 103 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
119 104 return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
120 105 ret("variable", "variable", word);
121 106 }
122 107 }
123 108 }
124 109
125 110 function haxeTokenString(quote) {
126 111 return function(stream, state) {
127 if (!nextUntilUnescaped(stream, quote))
112 if (toUnescaped(stream, quote))
128 113 state.tokenize = haxeTokenBase;
129 114 return ret("string", "string");
130 115 };
131 116 }
132 117
133 118 function haxeTokenComment(stream, state) {
134 119 var maybeEnd = false, ch;
135 120 while (ch = stream.next()) {
136 121 if (ch == "/" && maybeEnd) {
137 122 state.tokenize = haxeTokenBase;
138 123 break;
139 124 }
140 125 maybeEnd = (ch == "*");
141 126 }
142 127 return ret("comment", "comment");
143 128 }
144 129
145 130 // Parser
146 131
147 132 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
148 133
149 134 function HaxeLexical(indented, column, type, align, prev, info) {
150 135 this.indented = indented;
151 136 this.column = column;
152 137 this.type = type;
153 138 this.prev = prev;
154 139 this.info = info;
155 140 if (align != null) this.align = align;
156 141 }
157 142
158 143 function inScope(state, varname) {
159 144 for (var v = state.localVars; v; v = v.next)
160 145 if (v.name == varname) return true;
161 146 }
162 147
163 148 function parseHaxe(state, style, type, content, stream) {
164 149 var cc = state.cc;
165 150 // Communicate our context to the combinators.
166 151 // (Less wasteful than consing up a hundred closures on every call.)
167 152 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
168 153
169 154 if (!state.lexical.hasOwnProperty("align"))
170 155 state.lexical.align = true;
171 156
172 157 while(true) {
173 158 var combinator = cc.length ? cc.pop() : statement;
174 159 if (combinator(type, content)) {
175 160 while(cc.length && cc[cc.length - 1].lex)
176 161 cc.pop()();
177 162 if (cx.marked) return cx.marked;
178 163 if (type == "variable" && inScope(state, content)) return "variable-2";
179 164 if (type == "variable" && imported(state, content)) return "variable-3";
180 165 return style;
181 166 }
182 167 }
183 168 }
184 169
185 function imported(state, typename)
186 {
170 function imported(state, typename) {
187 171 if (/[a-z]/.test(typename.charAt(0)))
188 172 return false;
189 173 var len = state.importedtypes.length;
190 174 for (var i = 0; i<len; i++)
191 175 if(state.importedtypes[i]==typename) return true;
192 176 }
193 177
194
195 178 function registerimport(importname) {
196 179 var state = cx.state;
197 180 for (var t = state.importedtypes; t; t = t.next)
198 181 if(t.name == importname) return;
199 182 state.importedtypes = { name: importname, next: state.importedtypes };
200 183 }
201 184 // Combinator utils
202 185
203 186 var cx = {state: null, column: null, marked: null, cc: null};
204 187 function pass() {
205 188 for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
206 189 }
207 190 function cont() {
208 191 pass.apply(null, arguments);
209 192 return true;
210 193 }
194 function inList(name, list) {
195 for (var v = list; v; v = v.next)
196 if (v.name == name) return true;
197 return false;
198 }
211 199 function register(varname) {
212 200 var state = cx.state;
213 201 if (state.context) {
214 202 cx.marked = "def";
215 for (var v = state.localVars; v; v = v.next)
216 if (v.name == varname) return;
203 if (inList(varname, state.localVars)) return;
217 204 state.localVars = {name: varname, next: state.localVars};
205 } else if (state.globalVars) {
206 if (inList(varname, state.globalVars)) return;
207 state.globalVars = {name: varname, next: state.globalVars};
218 208 }
219 209 }
220 210
221 211 // Combinators
222 212
223 213 var defaultVars = {name: "this", next: null};
224 214 function pushcontext() {
225 215 if (!cx.state.context) cx.state.localVars = defaultVars;
226 216 cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
227 217 }
228 218 function popcontext() {
229 219 cx.state.localVars = cx.state.context.vars;
230 220 cx.state.context = cx.state.context.prev;
231 221 }
222 popcontext.lex = true;
232 223 function pushlex(type, info) {
233 224 var result = function() {
234 225 var state = cx.state;
235 226 state.lexical = new HaxeLexical(state.indented, cx.stream.column(), type, null, state.lexical, info);
236 227 };
237 228 result.lex = true;
238 229 return result;
239 230 }
240 231 function poplex() {
241 232 var state = cx.state;
242 233 if (state.lexical.prev) {
243 234 if (state.lexical.type == ")")
244 235 state.indented = state.lexical.indented;
245 236 state.lexical = state.lexical.prev;
246 237 }
247 238 }
248 239 poplex.lex = true;
249 240
250 241 function expect(wanted) {
251 242 function f(type) {
252 243 if (type == wanted) return cont();
253 244 else if (wanted == ";") return pass();
254 245 else return cont(f);
255 };
246 }
256 247 return f;
257 248 }
258 249
259 250 function statement(type) {
260 251 if (type == "@") return cont(metadef);
261 252 if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
262 253 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
263 254 if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
264 255 if (type == "{") return cont(pushlex("}"), pushcontext, block, poplex, popcontext);
265 256 if (type == ";") return cont();
266 257 if (type == "attribute") return cont(maybeattribute);
267 258 if (type == "function") return cont(functiondef);
268 259 if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
269 260 poplex, statement, poplex);
270 261 if (type == "variable") return cont(pushlex("stat"), maybelabel);
271 262 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
272 263 block, poplex, poplex);
273 264 if (type == "case") return cont(expression, expect(":"));
274 265 if (type == "default") return cont(expect(":"));
275 266 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
276 267 statement, poplex, popcontext);
277 268 if (type == "import") return cont(importdef, expect(";"));
278 269 if (type == "typedef") return cont(typedef);
279 270 return pass(pushlex("stat"), expression, expect(";"), poplex);
280 271 }
281 272 function expression(type) {
282 273 if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
274 if (type == "type" ) return cont(maybeoperator);
283 275 if (type == "function") return cont(functiondef);
284 276 if (type == "keyword c") return cont(maybeexpression);
285 277 if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
286 278 if (type == "operator") return cont(expression);
287 if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
279 if (type == "[") return cont(pushlex("]"), commasep(maybeexpression, "]"), poplex, maybeoperator);
288 280 if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
289 281 return cont();
290 282 }
291 283 function maybeexpression(type) {
292 284 if (type.match(/[;\}\)\],]/)) return pass();
293 285 return pass(expression);
294 286 }
295 287
296 288 function maybeoperator(type, value) {
297 289 if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
298 290 if (type == "operator" || type == ":") return cont(expression);
299 291 if (type == ";") return;
300 292 if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
301 293 if (type == ".") return cont(property, maybeoperator);
302 294 if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
303 295 }
304 296
305 297 function maybeattribute(type) {
306 298 if (type == "attribute") return cont(maybeattribute);
307 299 if (type == "function") return cont(functiondef);
308 300 if (type == "var") return cont(vardef1);
309 301 }
310 302
311 303 function metadef(type) {
312 304 if(type == ":") return cont(metadef);
313 305 if(type == "variable") return cont(metadef);
314 306 if(type == "(") return cont(pushlex(")"), commasep(metaargs, ")"), poplex, statement);
315 307 }
316 308 function metaargs(type) {
317 309 if(type == "variable") return cont();
318 310 }
319 311
320 312 function importdef (type, value) {
321 313 if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }
322 314 else if(type == "variable" || type == "property" || type == "." || value == "*") return cont(importdef);
323 315 }
324 316
325 317 function typedef (type, value)
326 318 {
327 319 if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }
328 320 else if (type == "type" && /[A-Z]/.test(value.charAt(0))) { return cont(); }
329 321 }
330 322
331 323 function maybelabel(type) {
332 324 if (type == ":") return cont(poplex, statement);
333 325 return pass(maybeoperator, expect(";"), poplex);
334 326 }
335 327 function property(type) {
336 328 if (type == "variable") {cx.marked = "property"; return cont();}
337 329 }
338 330 function objprop(type) {
339 331 if (type == "variable") cx.marked = "property";
340 332 if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
341 333 }
342 334 function commasep(what, end) {
343 335 function proceed(type) {
344 336 if (type == ",") return cont(what, proceed);
345 337 if (type == end) return cont();
346 338 return cont(expect(end));
347 339 }
348 340 return function(type) {
349 341 if (type == end) return cont();
350 342 else return pass(what, proceed);
351 343 };
352 344 }
353 345 function block(type) {
354 346 if (type == "}") return cont();
355 347 return pass(statement, block);
356 348 }
357 349 function vardef1(type, value) {
358 350 if (type == "variable"){register(value); return cont(typeuse, vardef2);}
359 351 return cont();
360 352 }
361 353 function vardef2(type, value) {
362 354 if (value == "=") return cont(expression, vardef2);
363 355 if (type == ",") return cont(vardef1);
364 356 }
365 357 function forspec1(type, value) {
366 358 if (type == "variable") {
367 359 register(value);
360 return cont(forin, expression)
361 } else {
362 return pass()
368 363 }
369 return cont(pushlex(")"), pushcontext, forin, expression, poplex, statement, popcontext);
370 364 }
371 365 function forin(_type, value) {
372 366 if (value == "in") return cont();
373 367 }
374 368 function functiondef(type, value) {
375 if (type == "variable") {register(value); return cont(functiondef);}
369 //function names starting with upper-case letters are recognised as types, so cludging them together here.
370 if (type == "variable" || type == "type") {register(value); return cont(functiondef);}
376 371 if (value == "new") return cont(functiondef);
377 372 if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, typeuse, statement, popcontext);
378 373 }
379 374 function typeuse(type) {
380 375 if(type == ":") return cont(typestring);
381 376 }
382 377 function typestring(type) {
383 378 if(type == "type") return cont();
384 379 if(type == "variable") return cont();
385 380 if(type == "{") return cont(pushlex("}"), commasep(typeprop, "}"), poplex);
386 381 }
387 382 function typeprop(type) {
388 383 if(type == "variable") return cont(typeuse);
389 384 }
390 385 function funarg(type, value) {
391 386 if (type == "variable") {register(value); return cont(typeuse);}
392 387 }
393 388
394 389 // Interface
395
396 390 return {
397 391 startState: function(basecolumn) {
398 392 var defaulttypes = ["Int", "Float", "String", "Void", "Std", "Bool", "Dynamic", "Array"];
399 return {
393 var state = {
400 394 tokenize: haxeTokenBase,
401 395 reAllowed: true,
402 396 kwAllowed: true,
403 397 cc: [],
404 398 lexical: new HaxeLexical((basecolumn || 0) - indentUnit, 0, "block", false),
405 399 localVars: parserConfig.localVars,
406 400 importedtypes: defaulttypes,
407 401 context: parserConfig.localVars && {vars: parserConfig.localVars},
408 402 indented: 0
409 403 };
404 if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
405 state.globalVars = parserConfig.globalVars;
406 return state;
410 407 },
411 408
412 409 token: function(stream, state) {
413 410 if (stream.sol()) {
414 411 if (!state.lexical.hasOwnProperty("align"))
415 412 state.lexical.align = false;
416 413 state.indented = stream.indentation();
417 414 }
418 415 if (stream.eatSpace()) return null;
419 416 var style = state.tokenize(stream, state);
420 417 if (type == "comment") return style;
421 418 state.reAllowed = !!(type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/));
422 419 state.kwAllowed = type != '.';
423 420 return parseHaxe(state, style, type, content, stream);
424 421 },
425 422
426 423 indent: function(state, textAfter) {
427 424 if (state.tokenize != haxeTokenBase) return 0;
428 425 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
429 426 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
430 427 var type = lexical.type, closing = firstChar == type;
431 428 if (type == "vardef") return lexical.indented + 4;
432 429 else if (type == "form" && firstChar == "{") return lexical.indented;
433 430 else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
434 431 else if (lexical.info == "switch" && !closing)
435 432 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
436 433 else if (lexical.align) return lexical.column + (closing ? 0 : 1);
437 434 else return lexical.indented + (closing ? 0 : indentUnit);
438 435 },
439 436
440 437 electricChars: "{}",
441 438 blockCommentStart: "/*",
442 439 blockCommentEnd: "*/",
443 440 lineComment: "//"
444 441 };
445 442 });
446 443
447 444 CodeMirror.defineMIME("text/x-haxe", "haxe");
448 445
449 446 CodeMirror.defineMode("hxml", function () {
450 447
451 448 return {
452 449 startState: function () {
453 450 return {
454 451 define: false,
455 452 inString: false
456 453 };
457 454 },
458 455 token: function (stream, state) {
459 456 var ch = stream.peek();
460 457 var sol = stream.sol();
461 458
462 459 ///* comments */
463 460 if (ch == "#") {
464 461 stream.skipToEnd();
465 462 return "comment";
466 463 }
467 464 if (sol && ch == "-") {
468 465 var style = "variable-2";
469 466
470 467 stream.eat(/-/);
471 468
472 469 if (stream.peek() == "-") {
473 470 stream.eat(/-/);
474 471 style = "keyword a";
475 472 }
476 473
477 474 if (stream.peek() == "D") {
478 475 stream.eat(/[D]/);
479 476 style = "keyword c";
480 477 state.define = true;
481 478 }
482 479
483 480 stream.eatWhile(/[A-Z]/i);
484 481 return style;
485 482 }
486 483
487 484 var ch = stream.peek();
488 485
489 486 if (state.inString == false && ch == "'") {
490 487 state.inString = true;
491 488 ch = stream.next();
492 489 }
493 490
494 491 if (state.inString == true) {
495 492 if (stream.skipTo("'")) {
496 493
497 494 } else {
498 495 stream.skipToEnd();
499 496 }
500 497
501 498 if (stream.peek() == "'") {
502 499 stream.next();
503 500 state.inString = false;
504 501 }
505 502
506 503 return "string";
507 504 }
508 505
509 506 stream.next();
510 507 return null;
511 508 },
512 509 lineComment: "#"
513 510 };
514 511 });
515 512
516 513 CodeMirror.defineMIME("text/x-hxml", "hxml");
517 514
518 515 });
@@ -1,121 +1,150 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
15 var htmlMode = CodeMirror.getMode(config, {name: "xml",
16 htmlMode: true,
17 multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
18 multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag});
19 var cssMode = CodeMirror.getMode(config, "css");
20
21 var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
22 scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
23 mode: CodeMirror.getMode(config, "javascript")});
24 if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) {
25 var conf = scriptTypesConf[i];
26 scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)});
27 }
28 scriptTypes.push({matches: /./,
29 mode: CodeMirror.getMode(config, "text/plain")});
14 var defaultTags = {
15 script: [
16 ["lang", /(javascript|babel)/i, "javascript"],
17 ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, "javascript"],
18 ["type", /./, "text/plain"],
19 [null, null, "javascript"]
20 ],
21 style: [
22 ["lang", /^css$/i, "css"],
23 ["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"],
24 ["type", /./, "text/plain"],
25 [null, null, "css"]
26 ]
27 };
30 28
31 function html(stream, state) {
32 var tagName = state.htmlState.tagName;
33 if (tagName) tagName = tagName.toLowerCase();
34 var style = htmlMode.token(stream, state.htmlState);
35 if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
36 // Script block: mode to change to depends on type attribute
37 var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
38 scriptType = scriptType ? scriptType[1] : "";
39 if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
40 for (var i = 0; i < scriptTypes.length; ++i) {
41 var tp = scriptTypes[i];
42 if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
43 if (tp.mode) {
44 state.token = script;
45 state.localMode = tp.mode;
46 state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
47 }
48 break;
49 }
50 }
51 } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
52 state.token = css;
53 state.localMode = cssMode;
54 state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
55 }
56 return style;
57 }
58 29 function maybeBackup(stream, pat, style) {
59 var cur = stream.current();
60 var close = cur.search(pat);
61 if (close > -1) stream.backUp(cur.length - close);
62 else if (cur.match(/<\/?$/)) {
30 var cur = stream.current(), close = cur.search(pat);
31 if (close > -1) {
32 stream.backUp(cur.length - close);
33 } else if (cur.match(/<\/?$/)) {
63 34 stream.backUp(cur.length);
64 35 if (!stream.match(pat, false)) stream.match(cur);
65 36 }
66 37 return style;
67 38 }
68 function script(stream, state) {
69 if (stream.match(/^<\/\s*script\s*>/i, false)) {
39
40 var attrRegexpCache = {};
41 function getAttrRegexp(attr) {
42 var regexp = attrRegexpCache[attr];
43 if (regexp) return regexp;
44 return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*");
45 }
46
47 function getAttrValue(stream, attr) {
48 var pos = stream.pos, match;
49 while (pos >= 0 && stream.string.charAt(pos) !== "<") pos--;
50 if (pos < 0) return pos;
51 if (match = stream.string.slice(pos, stream.pos).match(getAttrRegexp(attr)))
52 return match[2];
53 return "";
54 }
55
56 function getTagRegexp(tagName, anchored) {
57 return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i");
58 }
59
60 function addTags(from, to) {
61 for (var tag in from) {
62 var dest = to[tag] || (to[tag] = []);
63 var source = from[tag];
64 for (var i = source.length - 1; i >= 0; i--)
65 dest.unshift(source[i])
66 }
67 }
68
69 function findMatchingMode(tagInfo, stream) {
70 for (var i = 0; i < tagInfo.length; i++) {
71 var spec = tagInfo[i];
72 if (!spec[0] || spec[1].test(getAttrValue(stream, spec[0]))) return spec[2];
73 }
74 }
75
76 CodeMirror.defineMode("htmlmixed", function (config, parserConfig) {
77 var htmlMode = CodeMirror.getMode(config, {
78 name: "xml",
79 htmlMode: true,
80 multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
81 multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag
82 });
83
84 var tags = {};
85 var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes;
86 addTags(defaultTags, tags);
87 if (configTags) addTags(configTags, tags);
88 if (configScript) for (var i = configScript.length - 1; i >= 0; i--)
89 tags.script.unshift(["type", configScript[i].matches, configScript[i].mode])
90
91 function html(stream, state) {
92 var tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase();
93 var tagInfo = tagName && tags.hasOwnProperty(tagName) && tags[tagName];
94
95 var style = htmlMode.token(stream, state.htmlState), modeSpec;
96
97 if (tagInfo && /\btag\b/.test(style) && stream.current() === ">" &&
98 (modeSpec = findMatchingMode(tagInfo, stream))) {
99 var mode = CodeMirror.getMode(config, modeSpec);
100 var endTagA = getTagRegexp(tagName, true), endTag = getTagRegexp(tagName, false);
101 state.token = function (stream, state) {
102 if (stream.match(endTagA, false)) {
70 103 state.token = html;
71 104 state.localState = state.localMode = null;
72 105 return null;
73 106 }
74 return maybeBackup(stream, /<\/\s*script\s*>/,
75 state.localMode.token(stream, state.localState));
107 return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState));
108 };
109 state.localMode = mode;
110 state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, ""));
76 111 }
77 function css(stream, state) {
78 if (stream.match(/^<\/\s*style\s*>/i, false)) {
79 state.token = html;
80 state.localState = state.localMode = null;
81 return null;
82 }
83 return maybeBackup(stream, /<\/\s*style\s*>/,
84 cssMode.token(stream, state.localState));
85 }
112 return style;
113 };
86 114
87 115 return {
88 116 startState: function() {
89 117 var state = htmlMode.startState();
90 118 return {token: html, localMode: null, localState: null, htmlState: state};
91 119 },
92 120
93 121 copyState: function(state) {
94 if (state.localState)
95 var local = CodeMirror.copyState(state.localMode, state.localState);
122 var local;
123 if (state.localState) {
124 local = CodeMirror.copyState(state.localMode, state.localState);
125 }
96 126 return {token: state.token, localMode: state.localMode, localState: local,
97 127 htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
98 128 },
99 129
100 130 token: function(stream, state) {
101 131 return state.token(stream, state);
102 132 },
103 133
104 134 indent: function(state, textAfter) {
105 135 if (!state.localMode || /^\s*<\//.test(textAfter))
106 136 return htmlMode.indent(state.htmlState, textAfter);
107 137 else if (state.localMode.indent)
108 138 return state.localMode.indent(state.localState, textAfter);
109 139 else
110 140 return CodeMirror.Pass;
111 141 },
112 142
113 143 innerMode: function(state) {
114 144 return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
115 145 }
116 146 };
117 147 }, "xml", "javascript", "css");
118 148
119 149 CodeMirror.defineMIME("text/html", "htmlmixed");
120
121 150 });
@@ -1,590 +1,590 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"), require("../javascript/javascript"), require("../css/css"), require("../htmlmixed/htmlmixed"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror", "../javascript/javascript", "../css/css", "../htmlmixed/htmlmixed"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode('jade', function (config) {
15 15 // token types
16 16 var KEYWORD = 'keyword';
17 17 var DOCTYPE = 'meta';
18 18 var ID = 'builtin';
19 19 var CLASS = 'qualifier';
20 20
21 21 var ATTRS_NEST = {
22 22 '{': '}',
23 23 '(': ')',
24 24 '[': ']'
25 25 };
26 26
27 27 var jsMode = CodeMirror.getMode(config, 'javascript');
28 28
29 29 function State() {
30 30 this.javaScriptLine = false;
31 31 this.javaScriptLineExcludesColon = false;
32 32
33 33 this.javaScriptArguments = false;
34 34 this.javaScriptArgumentsDepth = 0;
35 35
36 36 this.isInterpolating = false;
37 37 this.interpolationNesting = 0;
38 38
39 39 this.jsState = jsMode.startState();
40 40
41 41 this.restOfLine = '';
42 42
43 43 this.isIncludeFiltered = false;
44 44 this.isEach = false;
45 45
46 46 this.lastTag = '';
47 47 this.scriptType = '';
48 48
49 49 // Attributes Mode
50 50 this.isAttrs = false;
51 51 this.attrsNest = [];
52 52 this.inAttributeName = true;
53 53 this.attributeIsType = false;
54 54 this.attrValue = '';
55 55
56 56 // Indented Mode
57 57 this.indentOf = Infinity;
58 58 this.indentToken = '';
59 59
60 60 this.innerMode = null;
61 61 this.innerState = null;
62 62
63 63 this.innerModeForLine = false;
64 64 }
65 65 /**
66 66 * Safely copy a state
67 67 *
68 68 * @return {State}
69 69 */
70 70 State.prototype.copy = function () {
71 71 var res = new State();
72 72 res.javaScriptLine = this.javaScriptLine;
73 73 res.javaScriptLineExcludesColon = this.javaScriptLineExcludesColon;
74 74 res.javaScriptArguments = this.javaScriptArguments;
75 75 res.javaScriptArgumentsDepth = this.javaScriptArgumentsDepth;
76 76 res.isInterpolating = this.isInterpolating;
77 res.interpolationNesting = this.intpolationNesting;
77 res.interpolationNesting = this.interpolationNesting;
78 78
79 79 res.jsState = CodeMirror.copyState(jsMode, this.jsState);
80 80
81 81 res.innerMode = this.innerMode;
82 82 if (this.innerMode && this.innerState) {
83 83 res.innerState = CodeMirror.copyState(this.innerMode, this.innerState);
84 84 }
85 85
86 86 res.restOfLine = this.restOfLine;
87 87
88 88 res.isIncludeFiltered = this.isIncludeFiltered;
89 89 res.isEach = this.isEach;
90 90 res.lastTag = this.lastTag;
91 91 res.scriptType = this.scriptType;
92 92 res.isAttrs = this.isAttrs;
93 93 res.attrsNest = this.attrsNest.slice();
94 94 res.inAttributeName = this.inAttributeName;
95 95 res.attributeIsType = this.attributeIsType;
96 96 res.attrValue = this.attrValue;
97 97 res.indentOf = this.indentOf;
98 98 res.indentToken = this.indentToken;
99 99
100 100 res.innerModeForLine = this.innerModeForLine;
101 101
102 102 return res;
103 103 };
104 104
105 105 function javaScript(stream, state) {
106 106 if (stream.sol()) {
107 107 // if javaScriptLine was set at end of line, ignore it
108 108 state.javaScriptLine = false;
109 109 state.javaScriptLineExcludesColon = false;
110 110 }
111 111 if (state.javaScriptLine) {
112 112 if (state.javaScriptLineExcludesColon && stream.peek() === ':') {
113 113 state.javaScriptLine = false;
114 114 state.javaScriptLineExcludesColon = false;
115 115 return;
116 116 }
117 117 var tok = jsMode.token(stream, state.jsState);
118 118 if (stream.eol()) state.javaScriptLine = false;
119 119 return tok || true;
120 120 }
121 121 }
122 122 function javaScriptArguments(stream, state) {
123 123 if (state.javaScriptArguments) {
124 124 if (state.javaScriptArgumentsDepth === 0 && stream.peek() !== '(') {
125 125 state.javaScriptArguments = false;
126 126 return;
127 127 }
128 128 if (stream.peek() === '(') {
129 129 state.javaScriptArgumentsDepth++;
130 130 } else if (stream.peek() === ')') {
131 131 state.javaScriptArgumentsDepth--;
132 132 }
133 133 if (state.javaScriptArgumentsDepth === 0) {
134 134 state.javaScriptArguments = false;
135 135 return;
136 136 }
137 137
138 138 var tok = jsMode.token(stream, state.jsState);
139 139 return tok || true;
140 140 }
141 141 }
142 142
143 143 function yieldStatement(stream) {
144 144 if (stream.match(/^yield\b/)) {
145 145 return 'keyword';
146 146 }
147 147 }
148 148
149 149 function doctype(stream) {
150 150 if (stream.match(/^(?:doctype) *([^\n]+)?/)) {
151 151 return DOCTYPE;
152 152 }
153 153 }
154 154
155 155 function interpolation(stream, state) {
156 156 if (stream.match('#{')) {
157 157 state.isInterpolating = true;
158 158 state.interpolationNesting = 0;
159 159 return 'punctuation';
160 160 }
161 161 }
162 162
163 163 function interpolationContinued(stream, state) {
164 164 if (state.isInterpolating) {
165 165 if (stream.peek() === '}') {
166 166 state.interpolationNesting--;
167 167 if (state.interpolationNesting < 0) {
168 168 stream.next();
169 169 state.isInterpolating = false;
170 return 'puncutation';
170 return 'punctuation';
171 171 }
172 172 } else if (stream.peek() === '{') {
173 173 state.interpolationNesting++;
174 174 }
175 175 return jsMode.token(stream, state.jsState) || true;
176 176 }
177 177 }
178 178
179 179 function caseStatement(stream, state) {
180 180 if (stream.match(/^case\b/)) {
181 181 state.javaScriptLine = true;
182 182 return KEYWORD;
183 183 }
184 184 }
185 185
186 186 function when(stream, state) {
187 187 if (stream.match(/^when\b/)) {
188 188 state.javaScriptLine = true;
189 189 state.javaScriptLineExcludesColon = true;
190 190 return KEYWORD;
191 191 }
192 192 }
193 193
194 194 function defaultStatement(stream) {
195 195 if (stream.match(/^default\b/)) {
196 196 return KEYWORD;
197 197 }
198 198 }
199 199
200 200 function extendsStatement(stream, state) {
201 201 if (stream.match(/^extends?\b/)) {
202 202 state.restOfLine = 'string';
203 203 return KEYWORD;
204 204 }
205 205 }
206 206
207 207 function append(stream, state) {
208 208 if (stream.match(/^append\b/)) {
209 209 state.restOfLine = 'variable';
210 210 return KEYWORD;
211 211 }
212 212 }
213 213 function prepend(stream, state) {
214 214 if (stream.match(/^prepend\b/)) {
215 215 state.restOfLine = 'variable';
216 216 return KEYWORD;
217 217 }
218 218 }
219 219 function block(stream, state) {
220 220 if (stream.match(/^block\b *(?:(prepend|append)\b)?/)) {
221 221 state.restOfLine = 'variable';
222 222 return KEYWORD;
223 223 }
224 224 }
225 225
226 226 function include(stream, state) {
227 227 if (stream.match(/^include\b/)) {
228 228 state.restOfLine = 'string';
229 229 return KEYWORD;
230 230 }
231 231 }
232 232
233 233 function includeFiltered(stream, state) {
234 234 if (stream.match(/^include:([a-zA-Z0-9\-]+)/, false) && stream.match('include')) {
235 235 state.isIncludeFiltered = true;
236 236 return KEYWORD;
237 237 }
238 238 }
239 239
240 240 function includeFilteredContinued(stream, state) {
241 241 if (state.isIncludeFiltered) {
242 242 var tok = filter(stream, state);
243 243 state.isIncludeFiltered = false;
244 244 state.restOfLine = 'string';
245 245 return tok;
246 246 }
247 247 }
248 248
249 249 function mixin(stream, state) {
250 250 if (stream.match(/^mixin\b/)) {
251 251 state.javaScriptLine = true;
252 252 return KEYWORD;
253 253 }
254 254 }
255 255
256 256 function call(stream, state) {
257 257 if (stream.match(/^\+([-\w]+)/)) {
258 258 if (!stream.match(/^\( *[-\w]+ *=/, false)) {
259 259 state.javaScriptArguments = true;
260 260 state.javaScriptArgumentsDepth = 0;
261 261 }
262 262 return 'variable';
263 263 }
264 264 if (stream.match(/^\+#{/, false)) {
265 265 stream.next();
266 266 state.mixinCallAfter = true;
267 267 return interpolation(stream, state);
268 268 }
269 269 }
270 270 function callArguments(stream, state) {
271 271 if (state.mixinCallAfter) {
272 272 state.mixinCallAfter = false;
273 273 if (!stream.match(/^\( *[-\w]+ *=/, false)) {
274 274 state.javaScriptArguments = true;
275 275 state.javaScriptArgumentsDepth = 0;
276 276 }
277 277 return true;
278 278 }
279 279 }
280 280
281 281 function conditional(stream, state) {
282 282 if (stream.match(/^(if|unless|else if|else)\b/)) {
283 283 state.javaScriptLine = true;
284 284 return KEYWORD;
285 285 }
286 286 }
287 287
288 288 function each(stream, state) {
289 289 if (stream.match(/^(- *)?(each|for)\b/)) {
290 290 state.isEach = true;
291 291 return KEYWORD;
292 292 }
293 293 }
294 294 function eachContinued(stream, state) {
295 295 if (state.isEach) {
296 296 if (stream.match(/^ in\b/)) {
297 297 state.javaScriptLine = true;
298 298 state.isEach = false;
299 299 return KEYWORD;
300 300 } else if (stream.sol() || stream.eol()) {
301 301 state.isEach = false;
302 302 } else if (stream.next()) {
303 303 while (!stream.match(/^ in\b/, false) && stream.next());
304 304 return 'variable';
305 305 }
306 306 }
307 307 }
308 308
309 309 function whileStatement(stream, state) {
310 310 if (stream.match(/^while\b/)) {
311 311 state.javaScriptLine = true;
312 312 return KEYWORD;
313 313 }
314 314 }
315 315
316 316 function tag(stream, state) {
317 317 var captures;
318 318 if (captures = stream.match(/^(\w(?:[-:\w]*\w)?)\/?/)) {
319 319 state.lastTag = captures[1].toLowerCase();
320 320 if (state.lastTag === 'script') {
321 321 state.scriptType = 'application/javascript';
322 322 }
323 323 return 'tag';
324 324 }
325 325 }
326 326
327 327 function filter(stream, state) {
328 328 if (stream.match(/^:([\w\-]+)/)) {
329 329 var innerMode;
330 330 if (config && config.innerModes) {
331 331 innerMode = config.innerModes(stream.current().substring(1));
332 332 }
333 333 if (!innerMode) {
334 334 innerMode = stream.current().substring(1);
335 335 }
336 336 if (typeof innerMode === 'string') {
337 337 innerMode = CodeMirror.getMode(config, innerMode);
338 338 }
339 339 setInnerMode(stream, state, innerMode);
340 340 return 'atom';
341 341 }
342 342 }
343 343
344 344 function code(stream, state) {
345 345 if (stream.match(/^(!?=|-)/)) {
346 346 state.javaScriptLine = true;
347 347 return 'punctuation';
348 348 }
349 349 }
350 350
351 351 function id(stream) {
352 352 if (stream.match(/^#([\w-]+)/)) {
353 353 return ID;
354 354 }
355 355 }
356 356
357 357 function className(stream) {
358 358 if (stream.match(/^\.([\w-]+)/)) {
359 359 return CLASS;
360 360 }
361 361 }
362 362
363 363 function attrs(stream, state) {
364 364 if (stream.peek() == '(') {
365 365 stream.next();
366 366 state.isAttrs = true;
367 367 state.attrsNest = [];
368 368 state.inAttributeName = true;
369 369 state.attrValue = '';
370 370 state.attributeIsType = false;
371 371 return 'punctuation';
372 372 }
373 373 }
374 374
375 375 function attrsContinued(stream, state) {
376 376 if (state.isAttrs) {
377 377 if (ATTRS_NEST[stream.peek()]) {
378 378 state.attrsNest.push(ATTRS_NEST[stream.peek()]);
379 379 }
380 380 if (state.attrsNest[state.attrsNest.length - 1] === stream.peek()) {
381 381 state.attrsNest.pop();
382 382 } else if (stream.eat(')')) {
383 383 state.isAttrs = false;
384 384 return 'punctuation';
385 385 }
386 386 if (state.inAttributeName && stream.match(/^[^=,\)!]+/)) {
387 387 if (stream.peek() === '=' || stream.peek() === '!') {
388 388 state.inAttributeName = false;
389 389 state.jsState = jsMode.startState();
390 390 if (state.lastTag === 'script' && stream.current().trim().toLowerCase() === 'type') {
391 391 state.attributeIsType = true;
392 392 } else {
393 393 state.attributeIsType = false;
394 394 }
395 395 }
396 396 return 'attribute';
397 397 }
398 398
399 399 var tok = jsMode.token(stream, state.jsState);
400 400 if (state.attributeIsType && tok === 'string') {
401 401 state.scriptType = stream.current().toString();
402 402 }
403 403 if (state.attrsNest.length === 0 && (tok === 'string' || tok === 'variable' || tok === 'keyword')) {
404 404 try {
405 405 Function('', 'var x ' + state.attrValue.replace(/,\s*$/, '').replace(/^!/, ''));
406 406 state.inAttributeName = true;
407 407 state.attrValue = '';
408 408 stream.backUp(stream.current().length);
409 409 return attrsContinued(stream, state);
410 410 } catch (ex) {
411 411 //not the end of an attribute
412 412 }
413 413 }
414 414 state.attrValue += stream.current();
415 415 return tok || true;
416 416 }
417 417 }
418 418
419 419 function attributesBlock(stream, state) {
420 420 if (stream.match(/^&attributes\b/)) {
421 421 state.javaScriptArguments = true;
422 422 state.javaScriptArgumentsDepth = 0;
423 423 return 'keyword';
424 424 }
425 425 }
426 426
427 427 function indent(stream) {
428 428 if (stream.sol() && stream.eatSpace()) {
429 429 return 'indent';
430 430 }
431 431 }
432 432
433 433 function comment(stream, state) {
434 434 if (stream.match(/^ *\/\/(-)?([^\n]*)/)) {
435 435 state.indentOf = stream.indentation();
436 436 state.indentToken = 'comment';
437 437 return 'comment';
438 438 }
439 439 }
440 440
441 441 function colon(stream) {
442 442 if (stream.match(/^: */)) {
443 443 return 'colon';
444 444 }
445 445 }
446 446
447 447 function text(stream, state) {
448 448 if (stream.match(/^(?:\| ?| )([^\n]+)/)) {
449 449 return 'string';
450 450 }
451 451 if (stream.match(/^(<[^\n]*)/, false)) {
452 452 // html string
453 453 setInnerMode(stream, state, 'htmlmixed');
454 454 state.innerModeForLine = true;
455 455 return innerMode(stream, state, true);
456 456 }
457 457 }
458 458
459 459 function dot(stream, state) {
460 460 if (stream.eat('.')) {
461 461 var innerMode = null;
462 462 if (state.lastTag === 'script' && state.scriptType.toLowerCase().indexOf('javascript') != -1) {
463 463 innerMode = state.scriptType.toLowerCase().replace(/"|'/g, '');
464 464 } else if (state.lastTag === 'style') {
465 465 innerMode = 'css';
466 466 }
467 467 setInnerMode(stream, state, innerMode);
468 468 return 'dot';
469 469 }
470 470 }
471 471
472 472 function fail(stream) {
473 473 stream.next();
474 474 return null;
475 475 }
476 476
477 477
478 478 function setInnerMode(stream, state, mode) {
479 479 mode = CodeMirror.mimeModes[mode] || mode;
480 480 mode = config.innerModes ? config.innerModes(mode) || mode : mode;
481 481 mode = CodeMirror.mimeModes[mode] || mode;
482 482 mode = CodeMirror.getMode(config, mode);
483 483 state.indentOf = stream.indentation();
484 484
485 485 if (mode && mode.name !== 'null') {
486 486 state.innerMode = mode;
487 487 } else {
488 488 state.indentToken = 'string';
489 489 }
490 490 }
491 491 function innerMode(stream, state, force) {
492 492 if (stream.indentation() > state.indentOf || (state.innerModeForLine && !stream.sol()) || force) {
493 493 if (state.innerMode) {
494 494 if (!state.innerState) {
495 495 state.innerState = state.innerMode.startState ? state.innerMode.startState(stream.indentation()) : {};
496 496 }
497 497 return stream.hideFirstChars(state.indentOf + 2, function () {
498 498 return state.innerMode.token(stream, state.innerState) || true;
499 499 });
500 500 } else {
501 501 stream.skipToEnd();
502 502 return state.indentToken;
503 503 }
504 504 } else if (stream.sol()) {
505 505 state.indentOf = Infinity;
506 506 state.indentToken = null;
507 507 state.innerMode = null;
508 508 state.innerState = null;
509 509 }
510 510 }
511 511 function restOfLine(stream, state) {
512 512 if (stream.sol()) {
513 513 // if restOfLine was set at end of line, ignore it
514 514 state.restOfLine = '';
515 515 }
516 516 if (state.restOfLine) {
517 517 stream.skipToEnd();
518 518 var tok = state.restOfLine;
519 519 state.restOfLine = '';
520 520 return tok;
521 521 }
522 522 }
523 523
524 524
525 525 function startState() {
526 526 return new State();
527 527 }
528 528 function copyState(state) {
529 529 return state.copy();
530 530 }
531 531 /**
532 532 * Get the next token in the stream
533 533 *
534 534 * @param {Stream} stream
535 535 * @param {State} state
536 536 */
537 537 function nextToken(stream, state) {
538 538 var tok = innerMode(stream, state)
539 539 || restOfLine(stream, state)
540 540 || interpolationContinued(stream, state)
541 541 || includeFilteredContinued(stream, state)
542 542 || eachContinued(stream, state)
543 543 || attrsContinued(stream, state)
544 544 || javaScript(stream, state)
545 545 || javaScriptArguments(stream, state)
546 546 || callArguments(stream, state)
547 547
548 548 || yieldStatement(stream, state)
549 549 || doctype(stream, state)
550 550 || interpolation(stream, state)
551 551 || caseStatement(stream, state)
552 552 || when(stream, state)
553 553 || defaultStatement(stream, state)
554 554 || extendsStatement(stream, state)
555 555 || append(stream, state)
556 556 || prepend(stream, state)
557 557 || block(stream, state)
558 558 || include(stream, state)
559 559 || includeFiltered(stream, state)
560 560 || mixin(stream, state)
561 561 || call(stream, state)
562 562 || conditional(stream, state)
563 563 || each(stream, state)
564 564 || whileStatement(stream, state)
565 565 || tag(stream, state)
566 566 || filter(stream, state)
567 567 || code(stream, state)
568 568 || id(stream, state)
569 569 || className(stream, state)
570 570 || attrs(stream, state)
571 571 || attributesBlock(stream, state)
572 572 || indent(stream, state)
573 573 || text(stream, state)
574 574 || comment(stream, state)
575 575 || colon(stream, state)
576 576 || dot(stream, state)
577 577 || fail(stream, state);
578 578
579 579 return tok === true ? null : tok;
580 580 }
581 581 return {
582 582 startState: startState,
583 583 copyState: copyState,
584 584 token: nextToken
585 585 };
586 });
586 }, 'javascript', 'css', 'htmlmixed');
587 587
588 588 CodeMirror.defineMIME('text/x-jade', 'jade');
589 589
590 590 });
@@ -1,704 +1,742 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 // TODO actually recognize syntax of TypeScript constructs
5 5
6 6 (function(mod) {
7 7 if (typeof exports == "object" && typeof module == "object") // CommonJS
8 8 mod(require("../../lib/codemirror"));
9 9 else if (typeof define == "function" && define.amd) // AMD
10 10 define(["../../lib/codemirror"], mod);
11 11 else // Plain browser env
12 12 mod(CodeMirror);
13 13 })(function(CodeMirror) {
14 14 "use strict";
15 15
16 function expressionAllowed(stream, state, backUp) {
17 return /^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
18 (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
19 }
20
16 21 CodeMirror.defineMode("javascript", function(config, parserConfig) {
17 22 var indentUnit = config.indentUnit;
18 23 var statementIndent = parserConfig.statementIndent;
19 24 var jsonldMode = parserConfig.jsonld;
20 25 var jsonMode = parserConfig.json || jsonldMode;
21 26 var isTS = parserConfig.typescript;
22 27 var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
23 28
24 29 // Tokenizer
25 30
26 31 var keywords = function(){
27 32 function kw(type) {return {type: type, style: "keyword"};}
28 33 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
29 34 var operator = kw("operator"), atom = {type: "atom", style: "atom"};
30 35
31 36 var jsKeywords = {
32 37 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
33 "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
38 "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C,
34 39 "var": kw("var"), "const": kw("var"), "let": kw("var"),
35 40 "function": kw("function"), "catch": kw("catch"),
36 41 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
37 42 "in": operator, "typeof": operator, "instanceof": operator,
38 43 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
39 "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
44 "this": kw("this"), "class": kw("class"), "super": kw("atom"),
40 45 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
41 46 };
42 47
43 48 // Extend the 'normal' keywords with the TypeScript language extensions
44 49 if (isTS) {
45 50 var type = {type: "variable", style: "variable-3"};
46 51 var tsKeywords = {
47 52 // object-like things
48 "interface": kw("interface"),
49 "extends": kw("extends"),
50 "constructor": kw("constructor"),
53 "interface": kw("class"),
54 "implements": C,
55 "namespace": C,
56 "module": kw("module"),
57 "enum": kw("module"),
51 58
52 59 // scope modifiers
53 "public": kw("public"),
54 "private": kw("private"),
55 "protected": kw("protected"),
56 "static": kw("static"),
60 "public": kw("modifier"),
61 "private": kw("modifier"),
62 "protected": kw("modifier"),
63 "abstract": kw("modifier"),
64
65 // operators
66 "as": operator,
57 67
58 68 // types
59 "string": type, "number": type, "bool": type, "any": type
69 "string": type, "number": type, "boolean": type, "any": type
60 70 };
61 71
62 72 for (var attr in tsKeywords) {
63 73 jsKeywords[attr] = tsKeywords[attr];
64 74 }
65 75 }
66 76
67 77 return jsKeywords;
68 78 }();
69 79
70 80 var isOperatorChar = /[+\-*&%=<>!?|~^]/;
71 81 var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
72 82
73 83 function readRegexp(stream) {
74 84 var escaped = false, next, inSet = false;
75 85 while ((next = stream.next()) != null) {
76 86 if (!escaped) {
77 87 if (next == "/" && !inSet) return;
78 88 if (next == "[") inSet = true;
79 89 else if (inSet && next == "]") inSet = false;
80 90 }
81 91 escaped = !escaped && next == "\\";
82 92 }
83 93 }
84 94
85 95 // Used as scratch variables to communicate multiple values without
86 96 // consing up tons of objects.
87 97 var type, content;
88 98 function ret(tp, style, cont) {
89 99 type = tp; content = cont;
90 100 return style;
91 101 }
92 102 function tokenBase(stream, state) {
93 103 var ch = stream.next();
94 104 if (ch == '"' || ch == "'") {
95 105 state.tokenize = tokenString(ch);
96 106 return state.tokenize(stream, state);
97 107 } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
98 108 return ret("number", "number");
99 109 } else if (ch == "." && stream.match("..")) {
100 110 return ret("spread", "meta");
101 111 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
102 112 return ret(ch);
103 113 } else if (ch == "=" && stream.eat(">")) {
104 114 return ret("=>", "operator");
105 115 } else if (ch == "0" && stream.eat(/x/i)) {
106 116 stream.eatWhile(/[\da-f]/i);
107 117 return ret("number", "number");
118 } else if (ch == "0" && stream.eat(/o/i)) {
119 stream.eatWhile(/[0-7]/i);
120 return ret("number", "number");
121 } else if (ch == "0" && stream.eat(/b/i)) {
122 stream.eatWhile(/[01]/i);
123 return ret("number", "number");
108 124 } else if (/\d/.test(ch)) {
109 125 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
110 126 return ret("number", "number");
111 127 } else if (ch == "/") {
112 128 if (stream.eat("*")) {
113 129 state.tokenize = tokenComment;
114 130 return tokenComment(stream, state);
115 131 } else if (stream.eat("/")) {
116 132 stream.skipToEnd();
117 133 return ret("comment", "comment");
118 } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
119 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
134 } else if (expressionAllowed(stream, state, 1)) {
120 135 readRegexp(stream);
121 136 stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
122 137 return ret("regexp", "string-2");
123 138 } else {
124 139 stream.eatWhile(isOperatorChar);
125 140 return ret("operator", "operator", stream.current());
126 141 }
127 142 } else if (ch == "`") {
128 143 state.tokenize = tokenQuasi;
129 144 return tokenQuasi(stream, state);
130 145 } else if (ch == "#") {
131 146 stream.skipToEnd();
132 147 return ret("error", "error");
133 148 } else if (isOperatorChar.test(ch)) {
134 149 stream.eatWhile(isOperatorChar);
135 150 return ret("operator", "operator", stream.current());
136 151 } else if (wordRE.test(ch)) {
137 152 stream.eatWhile(wordRE);
138 153 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
139 154 return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
140 155 ret("variable", "variable", word);
141 156 }
142 157 }
143 158
144 159 function tokenString(quote) {
145 160 return function(stream, state) {
146 161 var escaped = false, next;
147 162 if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
148 163 state.tokenize = tokenBase;
149 164 return ret("jsonld-keyword", "meta");
150 165 }
151 166 while ((next = stream.next()) != null) {
152 167 if (next == quote && !escaped) break;
153 168 escaped = !escaped && next == "\\";
154 169 }
155 170 if (!escaped) state.tokenize = tokenBase;
156 171 return ret("string", "string");
157 172 };
158 173 }
159 174
160 175 function tokenComment(stream, state) {
161 176 var maybeEnd = false, ch;
162 177 while (ch = stream.next()) {
163 178 if (ch == "/" && maybeEnd) {
164 179 state.tokenize = tokenBase;
165 180 break;
166 181 }
167 182 maybeEnd = (ch == "*");
168 183 }
169 184 return ret("comment", "comment");
170 185 }
171 186
172 187 function tokenQuasi(stream, state) {
173 188 var escaped = false, next;
174 189 while ((next = stream.next()) != null) {
175 190 if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
176 191 state.tokenize = tokenBase;
177 192 break;
178 193 }
179 194 escaped = !escaped && next == "\\";
180 195 }
181 196 return ret("quasi", "string-2", stream.current());
182 197 }
183 198
184 199 var brackets = "([{}])";
185 200 // This is a crude lookahead trick to try and notice that we're
186 201 // parsing the argument patterns for a fat-arrow function before we
187 202 // actually hit the arrow token. It only works if the arrow is on
188 203 // the same line as the arguments and there's no strange noise
189 204 // (comments) in between. Fallback is to only notice when we hit the
190 205 // arrow, and not declare the arguments as locals for the arrow
191 206 // body.
192 207 function findFatArrow(stream, state) {
193 208 if (state.fatArrowAt) state.fatArrowAt = null;
194 209 var arrow = stream.string.indexOf("=>", stream.start);
195 210 if (arrow < 0) return;
196 211
197 212 var depth = 0, sawSomething = false;
198 213 for (var pos = arrow - 1; pos >= 0; --pos) {
199 214 var ch = stream.string.charAt(pos);
200 215 var bracket = brackets.indexOf(ch);
201 216 if (bracket >= 0 && bracket < 3) {
202 217 if (!depth) { ++pos; break; }
203 218 if (--depth == 0) break;
204 219 } else if (bracket >= 3 && bracket < 6) {
205 220 ++depth;
206 221 } else if (wordRE.test(ch)) {
207 222 sawSomething = true;
208 223 } else if (/["'\/]/.test(ch)) {
209 224 return;
210 225 } else if (sawSomething && !depth) {
211 226 ++pos;
212 227 break;
213 228 }
214 229 }
215 230 if (sawSomething && !depth) state.fatArrowAt = pos;
216 231 }
217 232
218 233 // Parser
219 234
220 235 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
221 236
222 237 function JSLexical(indented, column, type, align, prev, info) {
223 238 this.indented = indented;
224 239 this.column = column;
225 240 this.type = type;
226 241 this.prev = prev;
227 242 this.info = info;
228 243 if (align != null) this.align = align;
229 244 }
230 245
231 246 function inScope(state, varname) {
232 247 for (var v = state.localVars; v; v = v.next)
233 248 if (v.name == varname) return true;
234 249 for (var cx = state.context; cx; cx = cx.prev) {
235 250 for (var v = cx.vars; v; v = v.next)
236 251 if (v.name == varname) return true;
237 252 }
238 253 }
239 254
240 255 function parseJS(state, style, type, content, stream) {
241 256 var cc = state.cc;
242 257 // Communicate our context to the combinators.
243 258 // (Less wasteful than consing up a hundred closures on every call.)
244 259 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
245 260
246 261 if (!state.lexical.hasOwnProperty("align"))
247 262 state.lexical.align = true;
248 263
249 264 while(true) {
250 265 var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
251 266 if (combinator(type, content)) {
252 267 while(cc.length && cc[cc.length - 1].lex)
253 268 cc.pop()();
254 269 if (cx.marked) return cx.marked;
255 270 if (type == "variable" && inScope(state, content)) return "variable-2";
256 271 return style;
257 272 }
258 273 }
259 274 }
260 275
261 276 // Combinator utils
262 277
263 278 var cx = {state: null, column: null, marked: null, cc: null};
264 279 function pass() {
265 280 for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
266 281 }
267 282 function cont() {
268 283 pass.apply(null, arguments);
269 284 return true;
270 285 }
271 286 function register(varname) {
272 287 function inList(list) {
273 288 for (var v = list; v; v = v.next)
274 289 if (v.name == varname) return true;
275 290 return false;
276 291 }
277 292 var state = cx.state;
293 cx.marked = "def";
278 294 if (state.context) {
279 cx.marked = "def";
280 295 if (inList(state.localVars)) return;
281 296 state.localVars = {name: varname, next: state.localVars};
282 297 } else {
283 298 if (inList(state.globalVars)) return;
284 299 if (parserConfig.globalVars)
285 300 state.globalVars = {name: varname, next: state.globalVars};
286 301 }
287 302 }
288 303
289 304 // Combinators
290 305
291 306 var defaultVars = {name: "this", next: {name: "arguments"}};
292 307 function pushcontext() {
293 308 cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
294 309 cx.state.localVars = defaultVars;
295 310 }
296 311 function popcontext() {
297 312 cx.state.localVars = cx.state.context.vars;
298 313 cx.state.context = cx.state.context.prev;
299 314 }
300 315 function pushlex(type, info) {
301 316 var result = function() {
302 317 var state = cx.state, indent = state.indented;
303 318 if (state.lexical.type == "stat") indent = state.lexical.indented;
304 319 else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
305 320 indent = outer.indented;
306 321 state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
307 322 };
308 323 result.lex = true;
309 324 return result;
310 325 }
311 326 function poplex() {
312 327 var state = cx.state;
313 328 if (state.lexical.prev) {
314 329 if (state.lexical.type == ")")
315 330 state.indented = state.lexical.indented;
316 331 state.lexical = state.lexical.prev;
317 332 }
318 333 }
319 334 poplex.lex = true;
320 335
321 336 function expect(wanted) {
322 337 function exp(type) {
323 338 if (type == wanted) return cont();
324 339 else if (wanted == ";") return pass();
325 340 else return cont(exp);
326 341 };
327 342 return exp;
328 343 }
329 344
330 345 function statement(type, value) {
331 346 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
332 347 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
333 348 if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
334 349 if (type == "{") return cont(pushlex("}"), block, poplex);
335 350 if (type == ";") return cont();
336 351 if (type == "if") {
337 352 if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
338 353 cx.state.cc.pop()();
339 354 return cont(pushlex("form"), expression, statement, poplex, maybeelse);
340 355 }
341 356 if (type == "function") return cont(functiondef);
342 357 if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
343 358 if (type == "variable") return cont(pushlex("stat"), maybelabel);
344 359 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
345 360 block, poplex, poplex);
346 361 if (type == "case") return cont(expression, expect(":"));
347 362 if (type == "default") return cont(expect(":"));
348 363 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
349 364 statement, poplex, popcontext);
350 if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
351 365 if (type == "class") return cont(pushlex("form"), className, poplex);
352 if (type == "export") return cont(pushlex("form"), afterExport, poplex);
353 if (type == "import") return cont(pushlex("form"), afterImport, poplex);
366 if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
367 if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
368 if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex)
354 369 return pass(pushlex("stat"), expression, expect(";"), poplex);
355 370 }
356 371 function expression(type) {
357 372 return expressionInner(type, false);
358 373 }
359 374 function expressionNoComma(type) {
360 375 return expressionInner(type, true);
361 376 }
362 377 function expressionInner(type, noComma) {
363 378 if (cx.state.fatArrowAt == cx.stream.start) {
364 379 var body = noComma ? arrowBodyNoComma : arrowBody;
365 380 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
366 381 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
367 382 }
368 383
369 384 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
370 385 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
371 386 if (type == "function") return cont(functiondef, maybeop);
372 387 if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
373 388 if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
374 389 if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
375 390 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
376 391 if (type == "{") return contCommasep(objprop, "}", null, maybeop);
377 if (type == "quasi") { return pass(quasi, maybeop); }
392 if (type == "quasi") return pass(quasi, maybeop);
393 if (type == "new") return cont(maybeTarget(noComma));
378 394 return cont();
379 395 }
380 396 function maybeexpression(type) {
381 397 if (type.match(/[;\}\)\],]/)) return pass();
382 398 return pass(expression);
383 399 }
384 400 function maybeexpressionNoComma(type) {
385 401 if (type.match(/[;\}\)\],]/)) return pass();
386 402 return pass(expressionNoComma);
387 403 }
388 404
389 405 function maybeoperatorComma(type, value) {
390 406 if (type == ",") return cont(expression);
391 407 return maybeoperatorNoComma(type, value, false);
392 408 }
393 409 function maybeoperatorNoComma(type, value, noComma) {
394 410 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
395 411 var expr = noComma == false ? expression : expressionNoComma;
396 412 if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
397 413 if (type == "operator") {
398 414 if (/\+\+|--/.test(value)) return cont(me);
399 415 if (value == "?") return cont(expression, expect(":"), expr);
400 416 return cont(expr);
401 417 }
402 418 if (type == "quasi") { return pass(quasi, me); }
403 419 if (type == ";") return;
404 420 if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
405 421 if (type == ".") return cont(property, me);
406 422 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
407 423 }
408 424 function quasi(type, value) {
409 425 if (type != "quasi") return pass();
410 426 if (value.slice(value.length - 2) != "${") return cont(quasi);
411 427 return cont(expression, continueQuasi);
412 428 }
413 429 function continueQuasi(type) {
414 430 if (type == "}") {
415 431 cx.marked = "string-2";
416 432 cx.state.tokenize = tokenQuasi;
417 433 return cont(quasi);
418 434 }
419 435 }
420 436 function arrowBody(type) {
421 437 findFatArrow(cx.stream, cx.state);
422 438 return pass(type == "{" ? statement : expression);
423 439 }
424 440 function arrowBodyNoComma(type) {
425 441 findFatArrow(cx.stream, cx.state);
426 442 return pass(type == "{" ? statement : expressionNoComma);
427 443 }
444 function maybeTarget(noComma) {
445 return function(type) {
446 if (type == ".") return cont(noComma ? targetNoComma : target);
447 else return pass(noComma ? expressionNoComma : expression);
448 };
449 }
450 function target(_, value) {
451 if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
452 }
453 function targetNoComma(_, value) {
454 if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
455 }
428 456 function maybelabel(type) {
429 457 if (type == ":") return cont(poplex, statement);
430 458 return pass(maybeoperatorComma, expect(";"), poplex);
431 459 }
432 460 function property(type) {
433 461 if (type == "variable") {cx.marked = "property"; return cont();}
434 462 }
435 463 function objprop(type, value) {
436 464 if (type == "variable" || cx.style == "keyword") {
437 465 cx.marked = "property";
438 466 if (value == "get" || value == "set") return cont(getterSetter);
439 467 return cont(afterprop);
440 468 } else if (type == "number" || type == "string") {
441 469 cx.marked = jsonldMode ? "property" : (cx.style + " property");
442 470 return cont(afterprop);
443 471 } else if (type == "jsonld-keyword") {
444 472 return cont(afterprop);
473 } else if (type == "modifier") {
474 return cont(objprop)
445 475 } else if (type == "[") {
446 476 return cont(expression, expect("]"), afterprop);
477 } else if (type == "spread") {
478 return cont(expression);
447 479 }
448 480 }
449 481 function getterSetter(type) {
450 482 if (type != "variable") return pass(afterprop);
451 483 cx.marked = "property";
452 484 return cont(functiondef);
453 485 }
454 486 function afterprop(type) {
455 487 if (type == ":") return cont(expressionNoComma);
456 488 if (type == "(") return pass(functiondef);
457 489 }
458 490 function commasep(what, end) {
459 491 function proceed(type) {
460 492 if (type == ",") {
461 493 var lex = cx.state.lexical;
462 494 if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
463 495 return cont(what, proceed);
464 496 }
465 497 if (type == end) return cont();
466 498 return cont(expect(end));
467 499 }
468 500 return function(type) {
469 501 if (type == end) return cont();
470 502 return pass(what, proceed);
471 503 };
472 504 }
473 505 function contCommasep(what, end, info) {
474 506 for (var i = 3; i < arguments.length; i++)
475 507 cx.cc.push(arguments[i]);
476 508 return cont(pushlex(end, info), commasep(what, end), poplex);
477 509 }
478 510 function block(type) {
479 511 if (type == "}") return cont();
480 512 return pass(statement, block);
481 513 }
482 514 function maybetype(type) {
483 515 if (isTS && type == ":") return cont(typedef);
484 516 }
485 517 function maybedefault(_, value) {
486 518 if (value == "=") return cont(expressionNoComma);
487 519 }
488 520 function typedef(type) {
489 521 if (type == "variable") {cx.marked = "variable-3"; return cont();}
490 522 }
491 523 function vardef() {
492 524 return pass(pattern, maybetype, maybeAssign, vardefCont);
493 525 }
494 526 function pattern(type, value) {
527 if (type == "modifier") return cont(pattern)
495 528 if (type == "variable") { register(value); return cont(); }
529 if (type == "spread") return cont(pattern);
496 530 if (type == "[") return contCommasep(pattern, "]");
497 531 if (type == "{") return contCommasep(proppattern, "}");
498 532 }
499 533 function proppattern(type, value) {
500 534 if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
501 535 register(value);
502 536 return cont(maybeAssign);
503 537 }
504 538 if (type == "variable") cx.marked = "property";
539 if (type == "spread") return cont(pattern);
540 if (type == "}") return pass();
505 541 return cont(expect(":"), pattern, maybeAssign);
506 542 }
507 543 function maybeAssign(_type, value) {
508 544 if (value == "=") return cont(expressionNoComma);
509 545 }
510 546 function vardefCont(type) {
511 547 if (type == ",") return cont(vardef);
512 548 }
513 549 function maybeelse(type, value) {
514 550 if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
515 551 }
516 552 function forspec(type) {
517 553 if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
518 554 }
519 555 function forspec1(type) {
520 556 if (type == "var") return cont(vardef, expect(";"), forspec2);
521 557 if (type == ";") return cont(forspec2);
522 558 if (type == "variable") return cont(formaybeinof);
523 559 return pass(expression, expect(";"), forspec2);
524 560 }
525 561 function formaybeinof(_type, value) {
526 562 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
527 563 return cont(maybeoperatorComma, forspec2);
528 564 }
529 565 function forspec2(type, value) {
530 566 if (type == ";") return cont(forspec3);
531 567 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
532 568 return pass(expression, expect(";"), forspec3);
533 569 }
534 570 function forspec3(type) {
535 571 if (type != ")") cont(expression);
536 572 }
537 573 function functiondef(type, value) {
538 574 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
539 575 if (type == "variable") {register(value); return cont(functiondef);}
540 576 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
541 577 }
542 578 function funarg(type) {
543 579 if (type == "spread") return cont(funarg);
544 580 return pass(pattern, maybetype, maybedefault);
545 581 }
546 582 function className(type, value) {
547 583 if (type == "variable") {register(value); return cont(classNameAfter);}
548 584 }
549 585 function classNameAfter(type, value) {
550 586 if (value == "extends") return cont(expression, classNameAfter);
551 587 if (type == "{") return cont(pushlex("}"), classBody, poplex);
552 588 }
553 589 function classBody(type, value) {
554 590 if (type == "variable" || cx.style == "keyword") {
555 591 if (value == "static") {
556 592 cx.marked = "keyword";
557 593 return cont(classBody);
558 594 }
559 595 cx.marked = "property";
560 596 if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
561 597 return cont(functiondef, classBody);
562 598 }
563 599 if (value == "*") {
564 600 cx.marked = "keyword";
565 601 return cont(classBody);
566 602 }
567 603 if (type == ";") return cont(classBody);
568 604 if (type == "}") return cont();
569 605 }
570 606 function classGetterSetter(type) {
571 607 if (type != "variable") return pass();
572 608 cx.marked = "property";
573 609 return cont();
574 610 }
575 function afterModule(type, value) {
576 if (type == "string") return cont(statement);
577 if (type == "variable") { register(value); return cont(maybeFrom); }
578 }
579 611 function afterExport(_type, value) {
580 612 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
581 613 if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
582 614 return pass(statement);
583 615 }
584 616 function afterImport(type) {
585 617 if (type == "string") return cont();
586 618 return pass(importSpec, maybeFrom);
587 619 }
588 620 function importSpec(type, value) {
589 621 if (type == "{") return contCommasep(importSpec, "}");
590 622 if (type == "variable") register(value);
591 623 if (value == "*") cx.marked = "keyword";
592 624 return cont(maybeAs);
593 625 }
594 626 function maybeAs(_type, value) {
595 627 if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
596 628 }
597 629 function maybeFrom(_type, value) {
598 630 if (value == "from") { cx.marked = "keyword"; return cont(expression); }
599 631 }
600 632 function arrayLiteral(type) {
601 633 if (type == "]") return cont();
602 634 return pass(expressionNoComma, maybeArrayComprehension);
603 635 }
604 636 function maybeArrayComprehension(type) {
605 637 if (type == "for") return pass(comprehension, expect("]"));
606 638 if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
607 639 return pass(commasep(expressionNoComma, "]"));
608 640 }
609 641 function comprehension(type) {
610 642 if (type == "for") return cont(forspec, comprehension);
611 643 if (type == "if") return cont(expression, comprehension);
612 644 }
613 645
614 646 function isContinuedStatement(state, textAfter) {
615 647 return state.lastType == "operator" || state.lastType == "," ||
616 648 isOperatorChar.test(textAfter.charAt(0)) ||
617 649 /[,.]/.test(textAfter.charAt(0));
618 650 }
619 651
620 652 // Interface
621 653
622 654 return {
623 655 startState: function(basecolumn) {
624 656 var state = {
625 657 tokenize: tokenBase,
626 658 lastType: "sof",
627 659 cc: [],
628 660 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
629 661 localVars: parserConfig.localVars,
630 662 context: parserConfig.localVars && {vars: parserConfig.localVars},
631 indented: 0
663 indented: basecolumn || 0
632 664 };
633 665 if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
634 666 state.globalVars = parserConfig.globalVars;
635 667 return state;
636 668 },
637 669
638 670 token: function(stream, state) {
639 671 if (stream.sol()) {
640 672 if (!state.lexical.hasOwnProperty("align"))
641 673 state.lexical.align = false;
642 674 state.indented = stream.indentation();
643 675 findFatArrow(stream, state);
644 676 }
645 677 if (state.tokenize != tokenComment && stream.eatSpace()) return null;
646 678 var style = state.tokenize(stream, state);
647 679 if (type == "comment") return style;
648 680 state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
649 681 return parseJS(state, style, type, content, stream);
650 682 },
651 683
652 684 indent: function(state, textAfter) {
653 685 if (state.tokenize == tokenComment) return CodeMirror.Pass;
654 686 if (state.tokenize != tokenBase) return 0;
655 687 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
656 688 // Kludge to prevent 'maybelse' from blocking lexical scope pops
657 689 if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
658 690 var c = state.cc[i];
659 691 if (c == poplex) lexical = lexical.prev;
660 692 else if (c != maybeelse) break;
661 693 }
662 694 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
663 695 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
664 696 lexical = lexical.prev;
665 697 var type = lexical.type, closing = firstChar == type;
666 698
667 699 if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
668 700 else if (type == "form" && firstChar == "{") return lexical.indented;
669 701 else if (type == "form") return lexical.indented + indentUnit;
670 702 else if (type == "stat")
671 703 return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
672 704 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
673 705 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
674 706 else if (lexical.align) return lexical.column + (closing ? 0 : 1);
675 707 else return lexical.indented + (closing ? 0 : indentUnit);
676 708 },
677 709
678 710 electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
679 711 blockCommentStart: jsonMode ? null : "/*",
680 712 blockCommentEnd: jsonMode ? null : "*/",
681 713 lineComment: jsonMode ? null : "//",
682 714 fold: "brace",
683 715 closeBrackets: "()[]{}''\"\"``",
684 716
685 717 helperType: jsonMode ? "json" : "javascript",
686 718 jsonldMode: jsonldMode,
687 jsonMode: jsonMode
719 jsonMode: jsonMode,
720
721 expressionAllowed: expressionAllowed,
722 skipExpression: function(state) {
723 var top = state.cc[state.cc.length - 1]
724 if (top == expression || top == expressionNoComma) state.cc.pop()
725 }
688 726 };
689 727 });
690 728
691 729 CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
692 730
693 731 CodeMirror.defineMIME("text/javascript", "javascript");
694 732 CodeMirror.defineMIME("text/ecmascript", "javascript");
695 733 CodeMirror.defineMIME("application/javascript", "javascript");
696 734 CodeMirror.defineMIME("application/x-javascript", "javascript");
697 735 CodeMirror.defineMIME("application/ecmascript", "javascript");
698 736 CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
699 737 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
700 738 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
701 739 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
702 740 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
703 741
704 742 });
@@ -1,299 +1,364 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode("julia", function(_conf, parserConf) {
15 15 var ERRORCLASS = 'error';
16 16
17 17 function wordRegexp(words) {
18 18 return new RegExp("^((" + words.join(")|(") + "))\\b");
19 19 }
20 20
21 var operators = parserConf.operators || /^\.?[|&^\\%*+\-<>!=\/]=?|\?|~|:|\$|\.[<>]|<<=?|>>>?=?|\.[<>=]=|->?|\/\/|\bin\b/;
21 var operators = parserConf.operators || /^\.?[|&^\\%*+\-<>!=\/]=?|\?|~|:|\$|\.[<>]|<<=?|>>>?=?|\.[<>=]=|->?|\/\/|\bin\b(?!\()|[\u2208\u2209](?!\()/;
22 22 var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
23 23 var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*!*/;
24 24 var blockOpeners = ["begin", "function", "type", "immutable", "let", "macro", "for", "while", "quote", "if", "else", "elseif", "try", "finally", "catch", "do"];
25 25 var blockClosers = ["end", "else", "elseif", "catch", "finally"];
26 var keywordList = ['if', 'else', 'elseif', 'while', 'for', 'begin', 'let', 'end', 'do', 'try', 'catch', 'finally', 'return', 'break', 'continue', 'global', 'local', 'const', 'export', 'import', 'importall', 'using', 'function', 'macro', 'module', 'baremodule', 'type', 'immutable', 'quote', 'typealias', 'abstract', 'bitstype', 'ccall'];
27 var builtinList = ['true', 'false', 'enumerate', 'open', 'close', 'nothing', 'NaN', 'Inf', 'print', 'println', 'Int', 'Int8', 'Uint8', 'Int16', 'Uint16', 'Int32', 'Uint32', 'Int64', 'Uint64', 'Int128', 'Uint128', 'Bool', 'Char', 'Float16', 'Float32', 'Float64', 'Array', 'Vector', 'Matrix', 'String', 'UTF8String', 'ASCIIString', 'error', 'warn', 'info', '@printf'];
26 var keywordList = ['if', 'else', 'elseif', 'while', 'for', 'begin', 'let', 'end', 'do', 'try', 'catch', 'finally', 'return', 'break', 'continue', 'global', 'local', 'const', 'export', 'import', 'importall', 'using', 'function', 'macro', 'module', 'baremodule', 'type', 'immutable', 'quote', 'typealias', 'abstract', 'bitstype'];
27 var builtinList = ['true', 'false', 'nothing', 'NaN', 'Inf'];
28 28
29 29 //var stringPrefixes = new RegExp("^[br]?('|\")")
30 var stringPrefixes = /^(`|'|"{3}|([br]?"))/;
30 var stringPrefixes = /^(`|'|"{3}|([brv]?"))/;
31 31 var keywords = wordRegexp(keywordList);
32 32 var builtins = wordRegexp(builtinList);
33 33 var openers = wordRegexp(blockOpeners);
34 34 var closers = wordRegexp(blockClosers);
35 35 var macro = /^@[_A-Za-z][_A-Za-z0-9]*/;
36 var symbol = /^:[_A-Za-z][_A-Za-z0-9]*/;
36 var symbol = /^:[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*!*/;
37 var typeAnnotation = /^::[^.,;"{()=$\s]+({[^}]*}+)*/;
37 38
38 function in_array(state) {
39 var ch = cur_scope(state);
40 if(ch=="[" || ch=="{") {
39 function inArray(state) {
40 var ch = currentScope(state);
41 if (ch == '[') {
41 42 return true;
42 43 }
43 else {
44 44 return false;
45 45 }
46 }
47 46
48 function cur_scope(state) {
47 function currentScope(state) {
49 48 if(state.scopes.length==0) {
50 49 return null;
51 50 }
52 51 return state.scopes[state.scopes.length - 1];
53 52 }
54 53
55 54 // tokenizers
56 55 function tokenBase(stream, state) {
56 //Handle multiline comments
57 if (stream.match(/^#=\s*/)) {
58 state.scopes.push('#=');
59 }
60 if (currentScope(state) == '#=' && stream.match(/^=#/)) {
61 state.scopes.pop();
62 return 'comment';
63 }
64 if (state.scopes.indexOf('#=') >= 0) {
65 if (!stream.match(/.*?(?=(#=|=#))/)) {
66 stream.skipToEnd();
67 }
68 return 'comment';
69 }
70
57 71 // Handle scope changes
58 var leaving_expr = state.leaving_expr;
72 var leavingExpr = state.leavingExpr;
59 73 if(stream.sol()) {
60 leaving_expr = false;
74 leavingExpr = false;
61 75 }
62 state.leaving_expr = false;
63 if(leaving_expr) {
76 state.leavingExpr = false;
77 if (leavingExpr) {
64 78 if(stream.match(/^'+/)) {
65 79 return 'operator';
66 80 }
67
68 81 }
69 82
70 83 if(stream.match(/^\.{2,3}/)) {
71 84 return 'operator';
72 85 }
73 86
74 87 if (stream.eatSpace()) {
75 88 return null;
76 89 }
77 90
78 91 var ch = stream.peek();
79 // Handle Comments
92
93 // Handle single line comments
80 94 if (ch === '#') {
81 95 stream.skipToEnd();
82 96 return 'comment';
83 97 }
98
84 99 if(ch==='[') {
85 state.scopes.push("[");
86 }
87
88 if(ch==='{') {
89 state.scopes.push("{");
100 state.scopes.push('[');
90 101 }
91 102
92 var scope=cur_scope(state);
103 var scope = currentScope(state);
93 104
94 if(scope==='[' && ch===']') {
105 if (scope == '[' && ch === ']') {
95 106 state.scopes.pop();
96 state.leaving_expr=true;
107 state.leavingExpr = true;
97 108 }
98 109
99 if(scope==='{' && ch==='}') {
110 if (scope == '(' && ch === ')') {
100 111 state.scopes.pop();
101 state.leaving_expr=true;
102 }
103
104 if(ch===')') {
105 state.leaving_expr = true;
112 state.leavingExpr = true;
106 113 }
107 114
108 115 var match;
109 if(!in_array(state) && (match=stream.match(openers, false))) {
116 if (!inArray(state) && (match=stream.match(openers, false))) {
110 117 state.scopes.push(match);
111 118 }
112 119
113 if(!in_array(state) && stream.match(closers, false)) {
120 if (!inArray(state) && stream.match(closers, false)) {
114 121 state.scopes.pop();
115 122 }
116 123
117 if(in_array(state)) {
124 if (inArray(state)) {
125 if (state.lastToken == 'end' && stream.match(/^:/)) {
126 return 'operator';
127 }
118 128 if(stream.match(/^end/)) {
119 129 return 'number';
120 130 }
121
122 131 }
123 132
124 133 if(stream.match(/^=>/)) {
125 134 return 'operator';
126 135 }
127 136
128
129 137 // Handle Number Literals
130 138 if (stream.match(/^[0-9\.]/, false)) {
131 139 var imMatcher = RegExp(/^im\b/);
132 140 var floatLiteral = false;
133 141 // Floats
134 142 if (stream.match(/^\d*\.(?!\.)\d+([ef][\+\-]?\d+)?/i)) { floatLiteral = true; }
135 143 if (stream.match(/^\d+\.(?!\.)\d*/)) { floatLiteral = true; }
136 144 if (stream.match(/^\.\d+/)) { floatLiteral = true; }
145 if (stream.match(/^0x\.[0-9a-f]+p[\+\-]?\d+/i)) { floatLiteral = true; }
137 146 if (floatLiteral) {
138 147 // Float literals may be "imaginary"
139 148 stream.match(imMatcher);
140 state.leaving_expr = true;
149 state.leavingExpr = true;
141 150 return 'number';
142 151 }
143 152 // Integers
144 153 var intLiteral = false;
145 154 // Hex
146 155 if (stream.match(/^0x[0-9a-f]+/i)) { intLiteral = true; }
147 156 // Binary
148 157 if (stream.match(/^0b[01]+/i)) { intLiteral = true; }
149 158 // Octal
150 159 if (stream.match(/^0o[0-7]+/i)) { intLiteral = true; }
151 160 // Decimal
152 161 if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
153 162 intLiteral = true;
154 163 }
155 164 // Zero by itself with no other piece of number.
156 165 if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
157 166 if (intLiteral) {
158 167 // Integer literals may be "long"
159 168 stream.match(imMatcher);
160 state.leaving_expr = true;
169 state.leavingExpr = true;
161 170 return 'number';
162 171 }
163 172 }
164 173
165 if(stream.match(/^(::)|(<:)/)) {
174 if (stream.match(/^<:/)) {
166 175 return 'operator';
167 176 }
168 177
178 if (stream.match(typeAnnotation)) {
179 return 'builtin';
180 }
181
169 182 // Handle symbols
170 if(!leaving_expr && stream.match(symbol)) {
171 return 'string';
183 if (!leavingExpr && stream.match(symbol) || stream.match(/:\./)) {
184 return 'builtin';
185 }
186
187 // Handle parametric types
188 if (stream.match(/^{[^}]*}(?=\()/)) {
189 return 'builtin';
172 190 }
173 191
174 192 // Handle operators and Delimiters
175 193 if (stream.match(operators)) {
176 194 return 'operator';
177 195 }
178 196
179
180 197 // Handle Strings
181 198 if (stream.match(stringPrefixes)) {
182 199 state.tokenize = tokenStringFactory(stream.current());
183 200 return state.tokenize(stream, state);
184 201 }
185 202
186 203 if (stream.match(macro)) {
187 204 return 'meta';
188 205 }
189 206
190
191 207 if (stream.match(delimiters)) {
192 208 return null;
193 209 }
194 210
195 211 if (stream.match(keywords)) {
196 212 return 'keyword';
197 213 }
198 214
199 215 if (stream.match(builtins)) {
200 216 return 'builtin';
201 217 }
202 218
219 var isDefinition = state.isDefinition ||
220 state.lastToken == 'function' ||
221 state.lastToken == 'macro' ||
222 state.lastToken == 'type' ||
223 state.lastToken == 'immutable';
203 224
204 225 if (stream.match(identifiers)) {
205 state.leaving_expr=true;
226 if (isDefinition) {
227 if (stream.peek() === '.') {
228 state.isDefinition = true;
206 229 return 'variable';
207 230 }
231 state.isDefinition = false;
232 return 'def';
233 }
234 if (stream.match(/^({[^}]*})*\(/, false)) {
235 return callOrDef(stream, state);
236 }
237 state.leavingExpr = true;
238 return 'variable';
239 }
240
208 241 // Handle non-detected items
209 242 stream.next();
210 243 return ERRORCLASS;
211 244 }
212 245
246 function callOrDef(stream, state) {
247 var match = stream.match(/^(\(\s*)/);
248 if (match) {
249 if (state.firstParenPos < 0)
250 state.firstParenPos = state.scopes.length;
251 state.scopes.push('(');
252 state.charsAdvanced += match[1].length;
253 }
254 if (currentScope(state) == '(' && stream.match(/^\)/)) {
255 state.scopes.pop();
256 state.charsAdvanced += 1;
257 if (state.scopes.length <= state.firstParenPos) {
258 var isDefinition = stream.match(/^\s*?=(?!=)/, false);
259 stream.backUp(state.charsAdvanced);
260 state.firstParenPos = -1;
261 state.charsAdvanced = 0;
262 if (isDefinition)
263 return 'def';
264 return 'builtin';
265 }
266 }
267 // Unfortunately javascript does not support multiline strings, so we have
268 // to undo anything done upto here if a function call or definition splits
269 // over two or more lines.
270 if (stream.match(/^$/g, false)) {
271 stream.backUp(state.charsAdvanced);
272 while (state.scopes.length > state.firstParenPos + 1)
273 state.scopes.pop();
274 state.firstParenPos = -1;
275 state.charsAdvanced = 0;
276 return 'builtin';
277 }
278 state.charsAdvanced += stream.match(/^([^()]*)/)[1].length;
279 return callOrDef(stream, state);
280 }
281
213 282 function tokenStringFactory(delimiter) {
214 while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
283 while ('bruv'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
215 284 delimiter = delimiter.substr(1);
216 285 }
217 var singleline = delimiter.length == 1;
286 var singleline = delimiter == "'";
218 287 var OUTCLASS = 'string';
219 288
220 289 function tokenString(stream, state) {
221 290 while (!stream.eol()) {
222 291 stream.eatWhile(/[^'"\\]/);
223 292 if (stream.eat('\\')) {
224 293 stream.next();
225 294 if (singleline && stream.eol()) {
226 295 return OUTCLASS;
227 296 }
228 297 } else if (stream.match(delimiter)) {
229 298 state.tokenize = tokenBase;
230 299 return OUTCLASS;
231 300 } else {
232 301 stream.eat(/['"]/);
233 302 }
234 303 }
235 304 if (singleline) {
236 305 if (parserConf.singleLineStringErrors) {
237 306 return ERRORCLASS;
238 307 } else {
239 308 state.tokenize = tokenBase;
240 309 }
241 310 }
242 311 return OUTCLASS;
243 312 }
244 313 tokenString.isString = true;
245 314 return tokenString;
246 315 }
247 316
248 function tokenLexer(stream, state) {
249 var style = state.tokenize(stream, state);
250 var current = stream.current();
251
252 // Handle '.' connected identifiers
253 if (current === '.') {
254 style = stream.match(identifiers, false) ? null : ERRORCLASS;
255 if (style === null && state.lastStyle === 'meta') {
256 // Apply 'meta' style to '.' connected identifiers when
257 // appropriate.
258 style = 'meta';
259 }
260 return style;
261 }
262
263 return style;
264 }
265
266 317 var external = {
267 318 startState: function() {
268 319 return {
269 320 tokenize: tokenBase,
270 321 scopes: [],
271 leaving_expr: false
322 lastToken: null,
323 leavingExpr: false,
324 isDefinition: false,
325 charsAdvanced: 0,
326 firstParenPos: -1
272 327 };
273 328 },
274 329
275 330 token: function(stream, state) {
276 var style = tokenLexer(stream, state);
277 state.lastStyle = style;
331 var style = state.tokenize(stream, state);
332 var current = stream.current();
333
334 if (current && style) {
335 state.lastToken = current;
336 }
337
338 // Handle '.' connected identifiers
339 if (current === '.') {
340 style = stream.match(identifiers, false) || stream.match(macro, false) ||
341 stream.match(/\(/, false) ? 'operator' : ERRORCLASS;
342 }
278 343 return style;
279 344 },
280 345
281 346 indent: function(state, textAfter) {
282 347 var delta = 0;
283 348 if(textAfter=="end" || textAfter=="]" || textAfter=="}" || textAfter=="else" || textAfter=="elseif" || textAfter=="catch" || textAfter=="finally") {
284 349 delta = -1;
285 350 }
286 return (state.scopes.length + delta) * 4;
351 return (state.scopes.length + delta) * _conf.indentUnit;
287 352 },
288 353
289 354 lineComment: "#",
290 355 fold: "indent",
291 356 electricChars: "edlsifyh]}"
292 357 };
293 358 return external;
294 359 });
295 360
296 361
297 362 CodeMirror.defineMIME("text/x-julia", "julia");
298 363
299 364 });
@@ -1,781 +1,803 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror", "../xml/xml", "../meta"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
15 15
16 16 var htmlFound = CodeMirror.modes.hasOwnProperty("xml");
17 17 var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? {name: "xml", htmlMode: true} : "text/plain");
18 18
19 19 function getMode(name) {
20 20 if (CodeMirror.findModeByName) {
21 21 var found = CodeMirror.findModeByName(name);
22 22 if (found) name = found.mime || found.mimes[0];
23 23 }
24 24 var mode = CodeMirror.getMode(cmCfg, name);
25 25 return mode.name == "null" ? null : mode;
26 26 }
27 27
28 28 // Should characters that affect highlighting be highlighted separate?
29 29 // Does not include characters that will be output (such as `1.` and `-` for lists)
30 30 if (modeCfg.highlightFormatting === undefined)
31 31 modeCfg.highlightFormatting = false;
32 32
33 33 // Maximum number of nested blockquotes. Set to 0 for infinite nesting.
34 34 // Excess `>` will emit `error` token.
35 35 if (modeCfg.maxBlockquoteDepth === undefined)
36 36 modeCfg.maxBlockquoteDepth = 0;
37 37
38 38 // Should underscores in words open/close em/strong?
39 39 if (modeCfg.underscoresBreakWords === undefined)
40 40 modeCfg.underscoresBreakWords = true;
41 41
42 // Turn on fenced code blocks? ("```" to start/end)
43 if (modeCfg.fencedCodeBlocks === undefined) modeCfg.fencedCodeBlocks = false;
42 // Use `fencedCodeBlocks` to configure fenced code blocks. false to
43 // disable, string to specify a precise regexp that the fence should
44 // match, and true to allow three or more backticks or tildes (as
45 // per CommonMark).
44 46
45 47 // Turn on task lists? ("- [ ] " and "- [x] ")
46 48 if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
47 49
48 50 // Turn on strikethrough syntax
49 51 if (modeCfg.strikethrough === undefined)
50 52 modeCfg.strikethrough = false;
51 53
54 // Allow token types to be overridden by user-provided token types.
55 if (modeCfg.tokenTypeOverrides === undefined)
56 modeCfg.tokenTypeOverrides = {};
57
52 58 var codeDepth = 0;
53 59
54 var header = 'header'
55 , code = 'comment'
56 , quote = 'quote'
57 , list1 = 'variable-2'
58 , list2 = 'variable-3'
59 , list3 = 'keyword'
60 , hr = 'hr'
61 , image = 'tag'
62 , formatting = 'formatting'
63 , linkinline = 'link'
64 , linkemail = 'link'
65 , linktext = 'link'
66 , linkhref = 'string'
67 , em = 'em'
68 , strong = 'strong'
69 , strikethrough = 'strikethrough';
60 var tokenTypes = {
61 header: "header",
62 code: "comment",
63 quote: "quote",
64 list1: "variable-2",
65 list2: "variable-3",
66 list3: "keyword",
67 hr: "hr",
68 image: "tag",
69 formatting: "formatting",
70 linkInline: "link",
71 linkEmail: "link",
72 linkText: "link",
73 linkHref: "string",
74 em: "em",
75 strong: "strong",
76 strikethrough: "strikethrough"
77 };
78
79 for (var tokenType in tokenTypes) {
80 if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) {
81 tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType];
82 }
83 }
70 84
71 85 var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
72 86 , ulRE = /^[*\-+]\s+/
73 87 , olRE = /^[0-9]+([.)])\s+/
74 88 , taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
75 , atxHeaderRE = /^(#+)(?: |$)/
89 , atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
76 90 , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
77 , textRE = /^[^#!\[\]*_\\<>` "'(~]+/;
91 , textRE = /^[^#!\[\]*_\\<>` "'(~]+/
92 , fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
93 ")[ \\t]*([\\w+#]*)");
78 94
79 95 function switchInline(stream, state, f) {
80 96 state.f = state.inline = f;
81 97 return f(stream, state);
82 98 }
83 99
84 100 function switchBlock(stream, state, f) {
85 101 state.f = state.block = f;
86 102 return f(stream, state);
87 103 }
88 104
105 function lineIsEmpty(line) {
106 return !line || !/\S/.test(line.string)
107 }
89 108
90 109 // Blocks
91 110
92 111 function blankLine(state) {
93 112 // Reset linkTitle state
94 113 state.linkTitle = false;
95 114 // Reset EM state
96 115 state.em = false;
97 116 // Reset STRONG state
98 117 state.strong = false;
99 118 // Reset strikethrough state
100 119 state.strikethrough = false;
101 120 // Reset state.quote
102 121 state.quote = 0;
103 122 // Reset state.indentedCode
104 123 state.indentedCode = false;
105 124 if (!htmlFound && state.f == htmlBlock) {
106 125 state.f = inlineNormal;
107 126 state.block = blockNormal;
108 127 }
109 128 // Reset state.trailingSpace
110 129 state.trailingSpace = 0;
111 130 state.trailingSpaceNewLine = false;
112 131 // Mark this line as blank
113 state.thisLineHasContent = false;
132 state.prevLine = state.thisLine
133 state.thisLine = null
114 134 return null;
115 135 }
116 136
117 137 function blockNormal(stream, state) {
118 138
119 139 var sol = stream.sol();
120 140
121 141 var prevLineIsList = state.list !== false,
122 142 prevLineIsIndentedCode = state.indentedCode;
123 143
124 144 state.indentedCode = false;
125 145
126 146 if (prevLineIsList) {
127 147 if (state.indentationDiff >= 0) { // Continued list
128 148 if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
129 149 state.indentation -= state.indentationDiff;
130 150 }
131 151 state.list = null;
132 152 } else if (state.indentation > 0) {
133 153 state.list = null;
134 154 state.listDepth = Math.floor(state.indentation / 4);
135 155 } else { // No longer a list
136 156 state.list = false;
137 157 state.listDepth = 0;
138 158 }
139 159 }
140 160
141 161 var match = null;
142 162 if (state.indentationDiff >= 4) {
143 163 stream.skipToEnd();
144 if (prevLineIsIndentedCode || !state.prevLineHasContent) {
164 if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) {
145 165 state.indentation -= 4;
146 166 state.indentedCode = true;
147 return code;
167 return tokenTypes.code;
148 168 } else {
149 169 return null;
150 170 }
151 171 } else if (stream.eatSpace()) {
152 172 return null;
153 173 } else if ((match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
154 174 state.header = match[1].length;
155 175 if (modeCfg.highlightFormatting) state.formatting = "header";
156 176 state.f = state.inline;
157 177 return getType(state);
158 } else if (state.prevLineHasContent && !state.quote && !prevLineIsList && !prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) {
178 } else if (!lineIsEmpty(state.prevLine) && !state.quote && !prevLineIsList &&
179 !prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) {
159 180 state.header = match[0].charAt(0) == '=' ? 1 : 2;
160 181 if (modeCfg.highlightFormatting) state.formatting = "header";
161 182 state.f = state.inline;
162 183 return getType(state);
163 184 } else if (stream.eat('>')) {
164 185 state.quote = sol ? 1 : state.quote + 1;
165 186 if (modeCfg.highlightFormatting) state.formatting = "quote";
166 187 stream.eatSpace();
167 188 return getType(state);
168 189 } else if (stream.peek() === '[') {
169 190 return switchInline(stream, state, footnoteLink);
170 191 } else if (stream.match(hrRE, true)) {
171 192 state.hr = true;
172 return hr;
173 } else if ((!state.prevLineHasContent || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
193 return tokenTypes.hr;
194 } else if ((lineIsEmpty(state.prevLine) || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
174 195 var listType = null;
175 196 if (stream.match(ulRE, true)) {
176 197 listType = 'ul';
177 198 } else {
178 199 stream.match(olRE, true);
179 200 listType = 'ol';
180 201 }
181 state.indentation += 4;
202 state.indentation = stream.column() + stream.current().length;
182 203 state.list = true;
183 204 state.listDepth++;
184 205 if (modeCfg.taskLists && stream.match(taskListRE, false)) {
185 206 state.taskList = true;
186 207 }
187 208 state.f = state.inline;
188 209 if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
189 210 return getType(state);
190 } else if (modeCfg.fencedCodeBlocks && stream.match(/^```[ \t]*([\w+#]*)/, true)) {
211 } else if (modeCfg.fencedCodeBlocks && (match = stream.match(fencedCodeRE, true))) {
212 state.fencedChars = match[1]
191 213 // try switching mode
192 state.localMode = getMode(RegExp.$1);
214 state.localMode = getMode(match[2]);
193 215 if (state.localMode) state.localState = state.localMode.startState();
194 216 state.f = state.block = local;
195 217 if (modeCfg.highlightFormatting) state.formatting = "code-block";
196 218 state.code = true;
197 219 return getType(state);
198 220 }
199 221
200 222 return switchInline(stream, state, state.inline);
201 223 }
202 224
203 225 function htmlBlock(stream, state) {
204 226 var style = htmlMode.token(stream, state.htmlState);
205 if ((htmlFound && state.htmlState.tagStart === null && !state.htmlState.context) ||
227 if ((htmlFound && state.htmlState.tagStart === null &&
228 (!state.htmlState.context && state.htmlState.tokenize.isInText)) ||
206 229 (state.md_inside && stream.current().indexOf(">") > -1)) {
207 230 state.f = inlineNormal;
208 231 state.block = blockNormal;
209 232 state.htmlState = null;
210 233 }
211 234 return style;
212 235 }
213 236
214 237 function local(stream, state) {
215 if (stream.sol() && stream.match("```", false)) {
238 if (state.fencedChars && stream.match(state.fencedChars, false)) {
216 239 state.localMode = state.localState = null;
217 240 state.f = state.block = leavingLocal;
218 241 return null;
219 242 } else if (state.localMode) {
220 243 return state.localMode.token(stream, state.localState);
221 244 } else {
222 245 stream.skipToEnd();
223 return code;
246 return tokenTypes.code;
224 247 }
225 248 }
226 249
227 250 function leavingLocal(stream, state) {
228 stream.match("```");
251 stream.match(state.fencedChars);
229 252 state.block = blockNormal;
230 253 state.f = inlineNormal;
254 state.fencedChars = null;
231 255 if (modeCfg.highlightFormatting) state.formatting = "code-block";
232 256 state.code = true;
233 257 var returnType = getType(state);
234 258 state.code = false;
235 259 return returnType;
236 260 }
237 261
238 262 // Inline
239 263 function getType(state) {
240 264 var styles = [];
241 265
242 266 if (state.formatting) {
243 styles.push(formatting);
267 styles.push(tokenTypes.formatting);
244 268
245 269 if (typeof state.formatting === "string") state.formatting = [state.formatting];
246 270
247 271 for (var i = 0; i < state.formatting.length; i++) {
248 styles.push(formatting + "-" + state.formatting[i]);
272 styles.push(tokenTypes.formatting + "-" + state.formatting[i]);
249 273
250 274 if (state.formatting[i] === "header") {
251 styles.push(formatting + "-" + state.formatting[i] + "-" + state.header);
275 styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header);
252 276 }
253 277
254 278 // Add `formatting-quote` and `formatting-quote-#` for blockquotes
255 279 // Add `error` instead if the maximum blockquote nesting depth is passed
256 280 if (state.formatting[i] === "quote") {
257 281 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
258 styles.push(formatting + "-" + state.formatting[i] + "-" + state.quote);
282 styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote);
259 283 } else {
260 284 styles.push("error");
261 285 }
262 286 }
263 287 }
264 288 }
265 289
266 290 if (state.taskOpen) {
267 291 styles.push("meta");
268 292 return styles.length ? styles.join(' ') : null;
269 293 }
270 294 if (state.taskClosed) {
271 295 styles.push("property");
272 296 return styles.length ? styles.join(' ') : null;
273 297 }
274 298
275 299 if (state.linkHref) {
276 styles.push(linkhref, "url");
300 styles.push(tokenTypes.linkHref, "url");
277 301 } else { // Only apply inline styles to non-url text
278 if (state.strong) { styles.push(strong); }
279 if (state.em) { styles.push(em); }
280 if (state.strikethrough) { styles.push(strikethrough); }
281
282 if (state.linkText) { styles.push(linktext); }
283
284 if (state.code) { styles.push(code); }
302 if (state.strong) { styles.push(tokenTypes.strong); }
303 if (state.em) { styles.push(tokenTypes.em); }
304 if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
305 if (state.linkText) { styles.push(tokenTypes.linkText); }
306 if (state.code) { styles.push(tokenTypes.code); }
285 307 }
286 308
287 if (state.header) { styles.push(header); styles.push(header + "-" + state.header); }
309 if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
288 310
289 311 if (state.quote) {
290 styles.push(quote);
312 styles.push(tokenTypes.quote);
291 313
292 314 // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
293 315 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
294 styles.push(quote + "-" + state.quote);
316 styles.push(tokenTypes.quote + "-" + state.quote);
295 317 } else {
296 styles.push(quote + "-" + modeCfg.maxBlockquoteDepth);
318 styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth);
297 319 }
298 320 }
299 321
300 322 if (state.list !== false) {
301 323 var listMod = (state.listDepth - 1) % 3;
302 324 if (!listMod) {
303 styles.push(list1);
325 styles.push(tokenTypes.list1);
304 326 } else if (listMod === 1) {
305 styles.push(list2);
327 styles.push(tokenTypes.list2);
306 328 } else {
307 styles.push(list3);
329 styles.push(tokenTypes.list3);
308 330 }
309 331 }
310 332
311 333 if (state.trailingSpaceNewLine) {
312 334 styles.push("trailing-space-new-line");
313 335 } else if (state.trailingSpace) {
314 336 styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
315 337 }
316 338
317 339 return styles.length ? styles.join(' ') : null;
318 340 }
319 341
320 342 function handleText(stream, state) {
321 343 if (stream.match(textRE, true)) {
322 344 return getType(state);
323 345 }
324 346 return undefined;
325 347 }
326 348
327 349 function inlineNormal(stream, state) {
328 350 var style = state.text(stream, state);
329 351 if (typeof style !== 'undefined')
330 352 return style;
331 353
332 354 if (state.list) { // List marker (*, +, -, 1., etc)
333 355 state.list = null;
334 356 return getType(state);
335 357 }
336 358
337 359 if (state.taskList) {
338 360 var taskOpen = stream.match(taskListRE, true)[1] !== "x";
339 361 if (taskOpen) state.taskOpen = true;
340 362 else state.taskClosed = true;
341 363 if (modeCfg.highlightFormatting) state.formatting = "task";
342 364 state.taskList = false;
343 365 return getType(state);
344 366 }
345 367
346 368 state.taskOpen = false;
347 369 state.taskClosed = false;
348 370
349 371 if (state.header && stream.match(/^#+$/, true)) {
350 372 if (modeCfg.highlightFormatting) state.formatting = "header";
351 373 return getType(state);
352 374 }
353 375
354 376 // Get sol() value now, before character is consumed
355 377 var sol = stream.sol();
356 378
357 379 var ch = stream.next();
358 380
359 381 if (ch === '\\') {
360 382 stream.next();
361 383 if (modeCfg.highlightFormatting) {
362 384 var type = getType(state);
363 return type ? type + " formatting-escape" : "formatting-escape";
385 var formattingEscape = tokenTypes.formatting + "-escape";
386 return type ? type + " " + formattingEscape : formattingEscape;
364 387 }
365 388 }
366 389
367 390 // Matches link titles present on next line
368 391 if (state.linkTitle) {
369 392 state.linkTitle = false;
370 393 var matchCh = ch;
371 394 if (ch === '(') {
372 395 matchCh = ')';
373 396 }
374 397 matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
375 398 var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
376 399 if (stream.match(new RegExp(regex), true)) {
377 return linkhref;
400 return tokenTypes.linkHref;
378 401 }
379 402 }
380 403
381 404 // If this block is changed, it may need to be updated in GFM mode
382 405 if (ch === '`') {
383 406 var previousFormatting = state.formatting;
384 407 if (modeCfg.highlightFormatting) state.formatting = "code";
385 408 var t = getType(state);
386 409 var before = stream.pos;
387 410 stream.eatWhile('`');
388 411 var difference = 1 + stream.pos - before;
389 412 if (!state.code) {
390 413 codeDepth = difference;
391 414 state.code = true;
392 415 return getType(state);
393 416 } else {
394 417 if (difference === codeDepth) { // Must be exact
395 418 state.code = false;
396 419 return t;
397 420 }
398 421 state.formatting = previousFormatting;
399 422 return getType(state);
400 423 }
401 424 } else if (state.code) {
402 425 return getType(state);
403 426 }
404 427
405 428 if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
406 429 stream.match(/\[[^\]]*\]/);
407 430 state.inline = state.f = linkHref;
408 return image;
431 return tokenTypes.image;
409 432 }
410 433
411 434 if (ch === '[' && stream.match(/.*\](\(.*\)| ?\[.*\])/, false)) {
412 435 state.linkText = true;
413 436 if (modeCfg.highlightFormatting) state.formatting = "link";
414 437 return getType(state);
415 438 }
416 439
417 440 if (ch === ']' && state.linkText && stream.match(/\(.*\)| ?\[.*\]/, false)) {
418 441 if (modeCfg.highlightFormatting) state.formatting = "link";
419 442 var type = getType(state);
420 443 state.linkText = false;
421 444 state.inline = state.f = linkHref;
422 445 return type;
423 446 }
424 447
425 448 if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
426 449 state.f = state.inline = linkInline;
427 450 if (modeCfg.highlightFormatting) state.formatting = "link";
428 451 var type = getType(state);
429 452 if (type){
430 453 type += " ";
431 454 } else {
432 455 type = "";
433 456 }
434 return type + linkinline;
457 return type + tokenTypes.linkInline;
435 458 }
436 459
437 460 if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
438 461 state.f = state.inline = linkInline;
439 462 if (modeCfg.highlightFormatting) state.formatting = "link";
440 463 var type = getType(state);
441 464 if (type){
442 465 type += " ";
443 466 } else {
444 467 type = "";
445 468 }
446 return type + linkemail;
469 return type + tokenTypes.linkEmail;
447 470 }
448 471
449 if (ch === '<' && stream.match(/^\w/, false)) {
450 if (stream.string.indexOf(">") != -1) {
451 var atts = stream.string.substring(1,stream.string.indexOf(">"));
452 if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) {
453 state.md_inside = true;
454 }
472 if (ch === '<' && stream.match(/^(!--|\w)/, false)) {
473 var end = stream.string.indexOf(">", stream.pos);
474 if (end != -1) {
475 var atts = stream.string.substring(stream.start, end);
476 if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true;
455 477 }
456 478 stream.backUp(1);
457 479 state.htmlState = CodeMirror.startState(htmlMode);
458 480 return switchBlock(stream, state, htmlBlock);
459 481 }
460 482
461 483 if (ch === '<' && stream.match(/^\/\w*?>/)) {
462 484 state.md_inside = false;
463 485 return "tag";
464 486 }
465 487
466 488 var ignoreUnderscore = false;
467 489 if (!modeCfg.underscoresBreakWords) {
468 490 if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
469 491 var prevPos = stream.pos - 2;
470 492 if (prevPos >= 0) {
471 493 var prevCh = stream.string.charAt(prevPos);
472 494 if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
473 495 ignoreUnderscore = true;
474 496 }
475 497 }
476 498 }
477 499 }
478 500 if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
479 501 if (sol && stream.peek() === ' ') {
480 502 // Do nothing, surrounded by newline and space
481 503 } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
482 504 if (modeCfg.highlightFormatting) state.formatting = "strong";
483 505 var t = getType(state);
484 506 state.strong = false;
485 507 return t;
486 508 } else if (!state.strong && stream.eat(ch)) { // Add STRONG
487 509 state.strong = ch;
488 510 if (modeCfg.highlightFormatting) state.formatting = "strong";
489 511 return getType(state);
490 512 } else if (state.em === ch) { // Remove EM
491 513 if (modeCfg.highlightFormatting) state.formatting = "em";
492 514 var t = getType(state);
493 515 state.em = false;
494 516 return t;
495 517 } else if (!state.em) { // Add EM
496 518 state.em = ch;
497 519 if (modeCfg.highlightFormatting) state.formatting = "em";
498 520 return getType(state);
499 521 }
500 522 } else if (ch === ' ') {
501 523 if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
502 524 if (stream.peek() === ' ') { // Surrounded by spaces, ignore
503 525 return getType(state);
504 526 } else { // Not surrounded by spaces, back up pointer
505 527 stream.backUp(1);
506 528 }
507 529 }
508 530 }
509 531
510 532 if (modeCfg.strikethrough) {
511 533 if (ch === '~' && stream.eatWhile(ch)) {
512 534 if (state.strikethrough) {// Remove strikethrough
513 535 if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
514 536 var t = getType(state);
515 537 state.strikethrough = false;
516 538 return t;
517 539 } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough
518 540 state.strikethrough = true;
519 541 if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
520 542 return getType(state);
521 543 }
522 544 } else if (ch === ' ') {
523 545 if (stream.match(/^~~/, true)) { // Probably surrounded by space
524 546 if (stream.peek() === ' ') { // Surrounded by spaces, ignore
525 547 return getType(state);
526 548 } else { // Not surrounded by spaces, back up pointer
527 549 stream.backUp(2);
528 550 }
529 551 }
530 552 }
531 553 }
532 554
533 555 if (ch === ' ') {
534 556 if (stream.match(/ +$/, false)) {
535 557 state.trailingSpace++;
536 558 } else if (state.trailingSpace) {
537 559 state.trailingSpaceNewLine = true;
538 560 }
539 561 }
540 562
541 563 return getType(state);
542 564 }
543 565
544 566 function linkInline(stream, state) {
545 567 var ch = stream.next();
546 568
547 569 if (ch === ">") {
548 570 state.f = state.inline = inlineNormal;
549 571 if (modeCfg.highlightFormatting) state.formatting = "link";
550 572 var type = getType(state);
551 573 if (type){
552 574 type += " ";
553 575 } else {
554 576 type = "";
555 577 }
556 return type + linkinline;
578 return type + tokenTypes.linkInline;
557 579 }
558 580
559 581 stream.match(/^[^>]+/, true);
560 582
561 return linkinline;
583 return tokenTypes.linkInline;
562 584 }
563 585
564 586 function linkHref(stream, state) {
565 587 // Check if space, and return NULL if so (to avoid marking the space)
566 588 if(stream.eatSpace()){
567 589 return null;
568 590 }
569 591 var ch = stream.next();
570 592 if (ch === '(' || ch === '[') {
571 593 state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
572 594 if (modeCfg.highlightFormatting) state.formatting = "link-string";
573 595 state.linkHref = true;
574 596 return getType(state);
575 597 }
576 598 return 'error';
577 599 }
578 600
579 601 function getLinkHrefInside(endChar) {
580 602 return function(stream, state) {
581 603 var ch = stream.next();
582 604
583 605 if (ch === endChar) {
584 606 state.f = state.inline = inlineNormal;
585 607 if (modeCfg.highlightFormatting) state.formatting = "link-string";
586 608 var returnState = getType(state);
587 609 state.linkHref = false;
588 610 return returnState;
589 611 }
590 612
591 613 if (stream.match(inlineRE(endChar), true)) {
592 614 stream.backUp(1);
593 615 }
594 616
595 617 state.linkHref = true;
596 618 return getType(state);
597 619 };
598 620 }
599 621
600 622 function footnoteLink(stream, state) {
601 if (stream.match(/^[^\]]*\]:/, false)) {
623 if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) {
602 624 state.f = footnoteLinkInside;
603 625 stream.next(); // Consume [
604 626 if (modeCfg.highlightFormatting) state.formatting = "link";
605 627 state.linkText = true;
606 628 return getType(state);
607 629 }
608 630 return switchInline(stream, state, inlineNormal);
609 631 }
610 632
611 633 function footnoteLinkInside(stream, state) {
612 634 if (stream.match(/^\]:/, true)) {
613 635 state.f = state.inline = footnoteUrl;
614 636 if (modeCfg.highlightFormatting) state.formatting = "link";
615 637 var returnType = getType(state);
616 638 state.linkText = false;
617 639 return returnType;
618 640 }
619 641
620 stream.match(/^[^\]]+/, true);
642 stream.match(/^([^\]\\]|\\.)+/, true);
621 643
622 return linktext;
644 return tokenTypes.linkText;
623 645 }
624 646
625 647 function footnoteUrl(stream, state) {
626 648 // Check if space, and return NULL if so (to avoid marking the space)
627 649 if(stream.eatSpace()){
628 650 return null;
629 651 }
630 652 // Match URL
631 653 stream.match(/^[^\s]+/, true);
632 654 // Check for link title
633 655 if (stream.peek() === undefined) { // End of line, set flag to check next line
634 656 state.linkTitle = true;
635 657 } else { // More content on line, check if link title
636 658 stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
637 659 }
638 660 state.f = state.inline = inlineNormal;
639 return linkhref + " url";
661 return tokenTypes.linkHref + " url";
640 662 }
641 663
642 664 var savedInlineRE = [];
643 665 function inlineRE(endChar) {
644 666 if (!savedInlineRE[endChar]) {
645 667 // Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741)
646 668 endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
647 669 // Match any non-endChar, escaped character, as well as the closing
648 670 // endChar.
649 671 savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')');
650 672 }
651 673 return savedInlineRE[endChar];
652 674 }
653 675
654 676 var mode = {
655 677 startState: function() {
656 678 return {
657 679 f: blockNormal,
658 680
659 prevLineHasContent: false,
660 thisLineHasContent: false,
681 prevLine: null,
682 thisLine: null,
661 683
662 684 block: blockNormal,
663 685 htmlState: null,
664 686 indentation: 0,
665 687
666 688 inline: inlineNormal,
667 689 text: handleText,
668 690
669 691 formatting: false,
670 692 linkText: false,
671 693 linkHref: false,
672 694 linkTitle: false,
673 695 em: false,
674 696 strong: false,
675 697 header: 0,
676 698 hr: false,
677 699 taskList: false,
678 700 list: false,
679 701 listDepth: 0,
680 702 quote: 0,
681 703 trailingSpace: 0,
682 704 trailingSpaceNewLine: false,
683 strikethrough: false
705 strikethrough: false,
706 fencedChars: null
684 707 };
685 708 },
686 709
687 710 copyState: function(s) {
688 711 return {
689 712 f: s.f,
690 713
691 prevLineHasContent: s.prevLineHasContent,
692 thisLineHasContent: s.thisLineHasContent,
714 prevLine: s.prevLine,
715 thisLine: s.thisLine,
693 716
694 717 block: s.block,
695 718 htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
696 719 indentation: s.indentation,
697 720
698 721 localMode: s.localMode,
699 722 localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
700 723
701 724 inline: s.inline,
702 725 text: s.text,
703 726 formatting: false,
704 727 linkTitle: s.linkTitle,
728 code: s.code,
705 729 em: s.em,
706 730 strong: s.strong,
707 731 strikethrough: s.strikethrough,
708 732 header: s.header,
709 733 hr: s.hr,
710 734 taskList: s.taskList,
711 735 list: s.list,
712 736 listDepth: s.listDepth,
713 737 quote: s.quote,
714 738 indentedCode: s.indentedCode,
715 739 trailingSpace: s.trailingSpace,
716 740 trailingSpaceNewLine: s.trailingSpaceNewLine,
717 md_inside: s.md_inside
741 md_inside: s.md_inside,
742 fencedChars: s.fencedChars
718 743 };
719 744 },
720 745
721 746 token: function(stream, state) {
722 747
723 748 // Reset state.formatting
724 749 state.formatting = false;
725 750
726 if (stream.sol()) {
727 var forceBlankLine = !!state.header || state.hr;
751 if (stream != state.thisLine) {
752 var forceBlankLine = state.header || state.hr;
728 753
729 754 // Reset state.header and state.hr
730 755 state.header = 0;
731 756 state.hr = false;
732 757
733 758 if (stream.match(/^\s*$/, true) || forceBlankLine) {
734 state.prevLineHasContent = false;
735 759 blankLine(state);
736 return forceBlankLine ? this.token(stream, state) : null;
737 } else {
738 state.prevLineHasContent = state.thisLineHasContent;
739 state.thisLineHasContent = true;
760 if (!forceBlankLine) return null
761 state.prevLine = null
740 762 }
741 763
764 state.prevLine = state.thisLine
765 state.thisLine = stream
766
742 767 // Reset state.taskList
743 768 state.taskList = false;
744 769
745 // Reset state.code
746 state.code = false;
747
748 770 // Reset state.trailingSpace
749 771 state.trailingSpace = 0;
750 772 state.trailingSpaceNewLine = false;
751 773
752 774 state.f = state.block;
753 775 var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
754 776 var difference = Math.floor((indentation - state.indentation) / 4) * 4;
755 777 if (difference > 4) difference = 4;
756 778 var adjustedIndentation = state.indentation + difference;
757 779 state.indentationDiff = adjustedIndentation - state.indentation;
758 780 state.indentation = adjustedIndentation;
759 781 if (indentation > 0) return null;
760 782 }
761 783 return state.f(stream, state);
762 784 },
763 785
764 786 innerMode: function(state) {
765 787 if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
766 788 if (state.localState) return {state: state.localState, mode: state.localMode};
767 789 return {state: state, mode: mode};
768 790 },
769 791
770 792 blankLine: blankLine,
771 793
772 794 getType: getType,
773 795
774 796 fold: "markdown"
775 797 };
776 798 return mode;
777 799 }, "xml");
778 800
779 801 CodeMirror.defineMIME("text/x-markdown", "markdown");
780 802
781 803 });
@@ -1,188 +1,201 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.modeInfo = [
15 15 {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]},
16 16 {name: "PGP", mimes: ["application/pgp", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["pgp"]},
17 {name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn, asn1"]},
17 {name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn", "asn1"]},
18 18 {name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i},
19 {name: "Brainfuck", mime: "text/x-brainfuck", mode: "brainfuck", ext: ["b", "bf"]},
19 20 {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h"]},
20 21 {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]},
21 22 {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]},
22 23 {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp"]},
23 24 {name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj"]},
25 {name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]},
26 {name: "Closure Stylesheets (GSS)", mime: "text/x-gss", mode: "css", ext: ["gss"]},
24 27 {name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/},
25 28 {name: "CoffeeScript", mime: "text/x-coffeescript", mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]},
26 29 {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]},
27 30 {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]},
28 31 {name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]},
32 {name: "Crystal", mime: "text/x-crystal", mode: "crystal", ext: ["cr"]},
29 33 {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]},
30 34 {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]},
31 35 {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]},
32 36 {name: "Dart", mimes: ["application/dart", "text/x-dart"], mode: "dart", ext: ["dart"]},
33 37 {name: "diff", mime: "text/x-diff", mode: "diff", ext: ["diff", "patch"]},
34 38 {name: "Django", mime: "text/x-django", mode: "django"},
35 39 {name: "Dockerfile", mime: "text/x-dockerfile", mode: "dockerfile", file: /^Dockerfile$/},
36 40 {name: "DTD", mime: "application/xml-dtd", mode: "dtd", ext: ["dtd"]},
37 41 {name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]},
38 42 {name: "EBNF", mime: "text/x-ebnf", mode: "ebnf"},
39 43 {name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]},
40 44 {name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]},
41 45 {name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]},
42 46 {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]},
43 47 {name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]},
44 48 {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]},
45 49 {name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]},
46 50 {name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]},
47 51 {name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90"]},
48 52 {name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]},
49 53 {name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]},
50 54 {name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]},
51 55 {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history).md$/i},
52 56 {name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]},
53 57 {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy"]},
54 58 {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]},
55 59 {name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]},
60 {name: "Haskell (Literate)", mime: "text/x-literate-haskell", mode: "haskell-literate", ext: ["lhs"]},
56 61 {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]},
57 62 {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]},
58 63 {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]},
59 64 {name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm"], alias: ["xhtml"]},
60 65 {name: "HTTP", mime: "message/http", mode: "http"},
61 66 {name: "IDL", mime: "text/x-idl", mode: "idl", ext: ["pro"]},
62 67 {name: "Jade", mime: "text/x-jade", mode: "jade", ext: ["jade"]},
63 68 {name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]},
64 69 {name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"], alias: ["jsp"]},
65 70 {name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"],
66 71 mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]},
67 72 {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]},
68 73 {name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]},
74 {name: "JSX", mime: "text/jsx", mode: "jsx", ext: ["jsx"]},
69 75 {name: "Jinja2", mime: "null", mode: "jinja2"},
70 76 {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]},
71 {name: "Kotlin", mime: "text/x-kotlin", mode: "kotlin", ext: ["kt"]},
77 {name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]},
72 78 {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]},
73 79 {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]},
74 80 {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]},
75 81 {name: "Markdown", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]},
76 82 {name: "mIRC", mime: "text/mirc", mode: "mirc"},
77 83 {name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"},
78 84 {name: "Mathematica", mime: "text/x-mathematica", mode: "mathematica", ext: ["m", "nb"]},
79 85 {name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]},
80 86 {name: "MUMPS", mime: "text/x-mumps", mode: "mumps"},
81 87 {name: "MS SQL", mime: "text/x-mssql", mode: "sql"},
82 88 {name: "MySQL", mime: "text/x-mysql", mode: "sql"},
83 89 {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i},
90 {name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]},
84 91 {name: "NTriples", mime: "text/n-triples", mode: "ntriples", ext: ["nt"]},
85 92 {name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"]},
86 93 {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]},
87 94 {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]},
95 {name: "Oz", mime: "text/x-oz", mode: "oz", ext: ["oz"]},
88 96 {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]},
89 97 {name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]},
90 98 {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]},
91 99 {name: "PHP", mime: "application/x-httpd-php", mode: "php", ext: ["php", "php3", "php4", "php5", "phtml"]},
92 100 {name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]},
93 101 {name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]},
94 102 {name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]},
95 103 {name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"], alias: ["ini", "properties"]},
96 104 {name: "Python", mime: "text/x-python", mode: "python", ext: ["py", "pyw"]},
97 105 {name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]},
98 106 {name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]},
99 107 {name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r"], alias: ["rscript"]},
100 108 {name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"], alias: ["rst"]},
101 109 {name: "RPM Changes", mime: "text/x-rpm-changes", mode: "rpm"},
102 110 {name: "RPM Spec", mime: "text/x-rpm-spec", mode: "rpm", ext: ["spec"]},
103 111 {name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"], alias: ["jruby", "macruby", "rake", "rb", "rbx"]},
104 112 {name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]},
105 113 {name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]},
106 114 {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]},
107 115 {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]},
108 116 {name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]},
109 {name: "Shell", mime: "text/x-sh", mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"]},
117 {name: "Shell", mime: "text/x-sh", mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/},
110 118 {name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]},
111 119 {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]},
112 120 {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]},
113 121 {name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]},
114 122 {name: "Solr", mime: "text/x-solr", mode: "solr"},
115 123 {name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]},
116 124 {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]},
117 125 {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]},
118 126 {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]},
127 {name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]},
119 128 {name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]},
120 129 {name: "MariaDB", mime: "text/x-mariadb", mode: "sql"},
121 130 {name: "sTeX", mime: "text/x-stex", mode: "stex"},
122 131 {name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx"], alias: ["tex"]},
123 132 {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v"]},
124 133 {name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]},
125 134 {name: "Textile", mime: "text/x-textile", mode: "textile", ext: ["textile"]},
126 135 {name: "TiddlyWiki ", mime: "text/x-tiddlywiki", mode: "tiddlywiki"},
127 136 {name: "Tiki wiki", mime: "text/tiki", mode: "tiki"},
128 137 {name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]},
129 138 {name: "Tornado", mime: "text/x-tornado", mode: "tornado"},
130 139 {name: "troff", mime: "troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]},
131 140 {name: "TTCN", mime: "text/x-ttcn", mode: "ttcn", ext: ["ttcn", "ttcn3", "ttcnpp"]},
132 141 {name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]},
133 142 {name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]},
134 143 {name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]},
135 144 {name: "Twig", mime: "text/x-twig", mode: "twig"},
136 145 {name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]},
137 146 {name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]},
138 147 {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]},
139 148 {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]},
149 {name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]},
140 150 {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd"], alias: ["rss", "wsdl", "xsd"]},
141 151 {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]},
142 152 {name: "YAML", mime: "text/x-yaml", mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]},
143 {name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]}
153 {name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]},
154 {name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]},
155 {name: "xu", mime: "text/x-xu", mode: "mscgen", ext: ["xu"]},
156 {name: "msgenny", mime: "text/x-msgenny", mode: "mscgen", ext: ["msgenny"]}
144 157 ];
145 158 // Ensure all modes have a mime property for backwards compatibility
146 159 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
147 160 var info = CodeMirror.modeInfo[i];
148 161 if (info.mimes) info.mime = info.mimes[0];
149 162 }
150 163
151 164 CodeMirror.findModeByMIME = function(mime) {
152 165 mime = mime.toLowerCase();
153 166 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
154 167 var info = CodeMirror.modeInfo[i];
155 168 if (info.mime == mime) return info;
156 169 if (info.mimes) for (var j = 0; j < info.mimes.length; j++)
157 170 if (info.mimes[j] == mime) return info;
158 171 }
159 172 };
160 173
161 174 CodeMirror.findModeByExtension = function(ext) {
162 175 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
163 176 var info = CodeMirror.modeInfo[i];
164 177 if (info.ext) for (var j = 0; j < info.ext.length; j++)
165 178 if (info.ext[j] == ext) return info;
166 179 }
167 180 };
168 181
169 182 CodeMirror.findModeByFileName = function(filename) {
170 183 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
171 184 var info = CodeMirror.modeInfo[i];
172 185 if (info.file && info.file.test(filename)) return info;
173 186 }
174 187 var dot = filename.lastIndexOf(".");
175 188 var ext = dot > -1 && filename.substring(dot + 1, filename.length);
176 189 if (ext) return CodeMirror.findModeByExtension(ext);
177 190 };
178 191
179 192 CodeMirror.findModeByName = function(name) {
180 193 name = name.toLowerCase();
181 194 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
182 195 var info = CodeMirror.modeInfo[i];
183 196 if (info.name.toLowerCase() == name) return info;
184 197 if (info.alias) for (var j = 0; j < info.alias.length; j++)
185 198 if (info.alias[j].toLowerCase() == name) return info;
186 199 }
187 200 };
188 201 });
@@ -1,336 +1,336 b''
1 1 var _EMPTY_EXT = {'exts': [], 'mode': 'plain'};
2 2
3 3 MIME_TO_EXT = {
4 4 "application/json": {"exts": ["*.json","*.map"], "mode": "javascript"},
5 5 "application/postscript": {"exts": ["*.ps","*.eps"], "mode": ""},
6 6 "application/sieve": {"exts": ["*.siv","*.sieve"], "mode": "sieve"},
7 7 "application/typescript": {"exts": ["*.ts"], "mode": "javascript"},
8 8 "application/x-actionscript": {"exts": ["*.as"], "mode": ""},
9 9 "application/x-actionscript3": {"exts": ["*.as"], "mode": ""},
10 10 "application/x-aspx": {"exts": ["*.aspx"], "mode": "htmlembedded"},
11 11 "application/x-awk": {"exts": ["*.awk"], "mode": ""},
12 12 "application/x-befunge": {"exts": ["*.befunge"], "mode": ""},
13 13 "application/x-brainfuck": {"exts": ["*.bf","*.b"], "mode": ""},
14 14 "application/x-cheetah": {"exts": ["*.tmpl","*.spt"], "mode": ""},
15 15 "application/x-coldfusion": {"exts": ["*.cfm","*.cfml","*.cfc"], "mode": ""},
16 16 "application/x-csh": {"exts": ["*.tcsh","*.csh"], "mode": ""},
17 17 "application/x-dos-batch": {"exts": ["*.bat","*.cmd"], "mode": ""},
18 18 "application/x-ecl": {"exts": ["*.ecl"], "mode": ""},
19 19 "application/x-ejs": {"exts": ["*.ejs"], "mode": "htmlembedded"},
20 20 "application/x-evoque": {"exts": ["*.evoque"], "mode": ""},
21 21 "application/x-fantom": {"exts": ["*.fan"], "mode": ""},
22 22 "application/x-genshi": {"exts": ["*.kid"], "mode": ""},
23 23 "application/x-gettext": {"exts": ["*.pot","*.po"], "mode": ""},
24 24 "application/x-json": {"exts": ["*.json"], "mode": ""},
25 25 "application/x-jsp": {"exts": ["*.jsp"], "mode": "htmlembedded"},
26 26 "application/x-mako": {"exts": ["*.mako"], "mode": ""},
27 27 "application/x-mason": {"exts": ["*.m","*.mhtml","*.mc","*.mi","autohandler","dhandler"], "mode": ""},
28 28 "application/x-myghty": {"exts": ["*.myt","autodelegate"], "mode": ""},
29 29 "application/x-php": {"exts": ["*.phtml"], "mode": ""},
30 30 "application/x-pypylog": {"exts": ["*.pypylog"], "mode": ""},
31 31 "application/x-qml": {"exts": ["*.qml"], "mode": ""},
32 32 "application/x-sh-session": {"exts": ["*.shell-session"], "mode": ""},
33 33 "application/x-shell-session": {"exts": ["*.sh-session"], "mode": ""},
34 34 "application/x-smarty": {"exts": ["*.tpl"], "mode": ""},
35 35 "application/x-sparql-query": {"exts": [], "mode": "sparql"},
36 36 "application/x-ssp": {"exts": ["*.ssp"], "mode": ""},
37 37 "application/x-troff": {"exts": ["*.[1234567]","*.man"], "mode": ""},
38 38 "application/x-urbiscript": {"exts": ["*.u"], "mode": ""},
39 39 "application/xml": {"exts": ["*.xml","*.xsl","*.rss","*.xslt","*.xsd","*.wsdl"], "mode": "xml"},
40 40 "application/xml+evoque": {"exts": ["*.xml"], "mode": ""},
41 41 "application/xml-dtd": {"exts": ["*.dtd"], "mode": "dtd"},
42 42 "application/xquery": {"exts": ["*.xqy","*.xquery","*.xq","*.xql","*.xqm","*.xy"], "mode": "xquery"},
43 43 "application/xsl+xml": {"exts": ["*.xsl","*.xslt","*.xpl"], "mode": ""},
44 44 "jinja2": {"exts": [".jinja2"], "mode": "jinja2"},
45 45 "message/http": {"exts": [], "mode": "http"},
46 46 "text/S-plus": {"exts": ["*.S","*.R",".Rhistory",".Rprofile"], "mode": ""},
47 47 "text/apl": {"exts": ["*.dyalog","*.pgp","*.apl"], "mode": "apl"},
48 48 "text/coffeescript": {"exts": ["*.coffee"], "mode": ""},
49 49 "text/css": {"exts": ["*.css"], "mode": "css"},
50 50 "text/haxe": {"exts": ["*.hx"], "mode": ""},
51 51 "text/html": {"exts": ["*.html","*.htm","*.xhtml","*.xslt"], "mode": "htmlmixed"},
52 52 "text/html+evoque": {"exts": ["*.html"], "mode": ""},
53 53 "text/html+ruby": {"exts": ["*.rhtml"], "mode": ""},
54 54 "text/idl": {"exts": ["*.pro"], "mode": ""},
55 55 "text/javascript": {"exts": ["*.js"], "mode": "javascript"},
56 56 "text/livescript": {"exts": ["*.ls"], "mode": ""},
57 57 "text/matlab": {"exts": ["*.m"], "mode": ""},
58 58 "text/mirc": {"exts": [], "mode": "mirc"},
59 59 "text/n-triples": {"exts": ["*.nt"], "mode": "ntriples"},
60 60 "text/octave": {"exts": ["*.m"], "mode": ""},
61 61 "text/plain": {"exts": ["*.txt","*.text","*.conf","*.def","*.list","*.log"], "mode": "null"},
62 62 "text/scilab": {"exts": ["*.sci","*.sce","*.tst"], "mode": ""},
63 63 "text/smali": {"exts": ["*.smali"], "mode": ""},
64 64 "text/tiki": {"exts": [], "mode": "tiki"},
65 65 "text/vbscript": {"exts": ["*.vb","*.vbs"], "mode": "vbscript"},
66 66 "text/velocity": {"exts": ["*.vtl"], "mode": "velocity"},
67 67 "text/x-abap": {"exts": ["*.abap"], "mode": ""},
68 68 "text/x-ada": {"exts": ["*.adb","*.ads","*.ada"], "mode": ""},
69 69 "text/x-apacheconf": {"exts": [".htaccess","apache.conf","apache2.conf"], "mode": ""},
70 70 "text/x-aspectj": {"exts": ["*.aj"], "mode": ""},
71 71 "text/x-asterisk": {"exts": [], "mode": "asterisk"},
72 72 "text/x-asymptote": {"exts": ["*.asy"], "mode": ""},
73 73 "text/x-autohotkey": {"exts": ["*.ahk","*.ahkl"], "mode": ""},
74 74 "text/x-autoit": {"exts": ["*.au3"], "mode": ""},
75 75 "text/x-bmx": {"exts": ["*.bmx"], "mode": ""},
76 76 "text/x-boo": {"exts": ["*.boo"], "mode": ""},
77 77 "text/x-c": {"exts": ["*.c"], "mode": "clike"},
78 78 "text/x-c++hdr": {"exts": ["*.cpp","*.hpp","*.c++","*.h++","*.cc","*.hh","*.cxx","*.hxx","*.C","*.H","*.cp","*.CPP"], "mode": "clike"},
79 79 "text/x-c++src": {"exts": ["*.cpp","*.c++","*.cc","*.cxx","*.hpp","*.h++","*.hh","*.hxx"], "mode": "clike"},
80 80 "text/x-c-objdump": {"exts": ["*.c-objdump"], "mode": ""},
81 81 "text/x-ceylon": {"exts": ["*.ceylon"], "mode": ""},
82 82 "text/x-chdr": {"exts": ["*.c","*.h","*.idc"], "mode": "clike"},
83 83 "text/x-clojure": {"exts": ["*.clj"], "mode": "clojure"},
84 84 "text/x-cmake": {"exts": ["*.cmake","CMakeLists.txt","*.cmake.in"], "mode": "cmake"},
85 85 "text/x-cobol": {"exts": ["*.cob","*.COB","*.cpy","*.CPY"], "mode": "cobol"},
86 86 "text/x-coffeescript": {"exts": ["*.coffee"], "mode": "coffeescript"},
87 87 "text/x-common-lisp": {"exts": ["*.cl","*.lisp","*.el"], "mode": "commonlisp"},
88 88 "text/x-coq": {"exts": ["*.v"], "mode": ""},
89 89 "text/x-cpp-objdump": {"exts": ["*.cpp-objdump","*.c++-objdump","*.cxx-objdump"], "mode": ""},
90 90 "text/x-crocsrc": {"exts": ["*.croc"], "mode": ""},
91 91 "text/x-csharp": {"exts": ["*.cs"], "mode": "clike"},
92 92 "text/x-csrc": {"exts": ["*.c","*.h"], "mode": "clike"},
93 93 "text/x-cuda": {"exts": ["*.cu","*.cuh"], "mode": ""},
94 94 "text/x-cython": {"exts": ["*.pyx","*.pxd","*.pxi"], "mode": "python"},
95 95 "text/x-d": {"exts": ["*.d"], "mode": "d"},
96 96 "text/x-d-objdump": {"exts": ["*.d-objdump"], "mode": ""},
97 97 "text/x-dart": {"exts": ["*.dart"], "mode": ""},
98 98 "text/x-dg": {"exts": ["*.dg"], "mode": ""},
99 99 "text/x-diff": {"exts": ["*.diff","*.patch"], "mode": "diff"},
100 100 "text/x-dsrc": {"exts": ["*.d","*.di"], "mode": ""},
101 101 "text/x-duel": {"exts": ["*.duel","*.jbst"], "mode": ""},
102 102 "text/x-dylan": {"exts": ["*.dylan","*.dyl","*.intr"], "mode": "dylan"},
103 103 "text/x-dylan-console": {"exts": ["*.dylan-console"], "mode": ""},
104 104 "text/x-dylan-lid": {"exts": ["*.lid","*.hdp"], "mode": ""},
105 105 "text/x-echdr": {"exts": ["*.ec","*.eh"], "mode": ""},
106 106 "text/x-ecl": {"exts": ["*.ecl"], "mode": "ecl"},
107 107 "text/x-elixir": {"exts": ["*.ex","*.exs"], "mode": ""},
108 108 "text/x-erl-shellsession": {"exts": ["*.erl-sh"], "mode": ""},
109 109 "text/x-erlang": {"exts": ["*.erl","*.hrl","*.es","*.escript"], "mode": "erlang"},
110 110 "text/x-factor": {"exts": ["*.factor"], "mode": "factor"},
111 111 "text/x-fancysrc": {"exts": ["*.fy","*.fancypack"], "mode": ""},
112 112 "text/x-felix": {"exts": ["*.flx","*.flxh"], "mode": ""},
113 113 "text/x-fortran": {"exts": ["*.f","*.f90","*.F","*.F90","*.for","*.f77"], "mode": "fortran"},
114 114 "text/x-fsharp": {"exts": ["*.fs","*.fsi"], "mode": "mllike"},
115 115 "text/x-gas": {"exts": ["*.s","*.S"], "mode": "gas"},
116 "text/x-gfm": {"exts": ["*.md","*.MD"], "mode": "markdown"},
116 "text/x-gfm": {"exts": ["*.md","*.MD"], "mode": "gfm"},
117 117 "text/x-gherkin": {"exts": ["*.feature"], "mode": ""},
118 118 "text/x-glslsrc": {"exts": ["*.vert","*.frag","*.geo"], "mode": ""},
119 119 "text/x-gnuplot": {"exts": ["*.plot","*.plt"], "mode": ""},
120 120 "text/x-go": {"exts": ["*.go"], "mode": "go"},
121 121 "text/x-gooddata-cl": {"exts": ["*.gdc"], "mode": ""},
122 122 "text/x-gooddata-maql": {"exts": ["*.maql"], "mode": ""},
123 123 "text/x-gosrc": {"exts": ["*.go"], "mode": ""},
124 124 "text/x-gosu": {"exts": ["*.gs","*.gsx","*.gsp","*.vark"], "mode": ""},
125 125 "text/x-gosu-template": {"exts": ["*.gst"], "mode": ""},
126 126 "text/x-groovy": {"exts": ["*.groovy"], "mode": "groovy"},
127 127 "text/x-haml": {"exts": ["*.haml"], "mode": "haml"},
128 128 "text/x-haskell": {"exts": ["*.hs"], "mode": "haskell"},
129 129 "text/x-haxe": {"exts": ["*.hx"], "mode": "haxe"},
130 130 "text/x-hybris": {"exts": ["*.hy","*.hyb"], "mode": ""},
131 131 "text/x-ini": {"exts": ["*.ini","*.cfg"], "mode": ""},
132 132 "text/x-iokesrc": {"exts": ["*.ik"], "mode": ""},
133 133 "text/x-iosrc": {"exts": ["*.io"], "mode": ""},
134 134 "text/x-irclog": {"exts": ["*.weechatlog"], "mode": ""},
135 135 "text/x-jade": {"exts": ["*.jade"], "mode": "jade"},
136 136 "text/x-java": {"exts": ["*.java"], "mode": "clike"},
137 137 "text/x-julia": {"exts": ["*.jl"], "mode": "julia"},
138 138 "text/x-kconfig": {"exts": ["Kconfig","*Config.in*","external.in*","standard-modules.in"], "mode": ""},
139 139 "text/x-koka": {"exts": ["*.kk","*.kki"], "mode": ""},
140 "text/x-kotlin": {"exts": ["*.kt"], "mode": "kotlin"},
140 "text/x-kotlin": {"exts": ["*.kt"], "mode": "clike"},
141 141 "text/x-lasso": {"exts": ["*.lasso","*.lasso[89]"], "mode": ""},
142 142 "text/x-latex": {"exts": ["*.ltx","*.text"], "mode": "stex"},
143 143 "text/x-less": {"exts": ["*.less"], "mode": "css"},
144 "text/x-literate-haskell": {"exts": ["*.lhs"], "mode": ""},
144 "text/x-literate-haskell": {"exts": ["*.lhs"], "mode": "haskell-literate"},
145 145 "text/x-livescript": {"exts": ["*.ls"], "mode": "livescript"},
146 146 "text/x-llvm": {"exts": ["*.ll"], "mode": ""},
147 147 "text/x-logos": {"exts": ["*.x","*.xi","*.xm","*.xmi"], "mode": ""},
148 148 "text/x-logtalk": {"exts": ["*.lgt"], "mode": ""},
149 149 "text/x-lua": {"exts": ["*.lua","*.wlua"], "mode": "lua"},
150 150 "text/x-makefile": {"exts": ["*.mak","Makefile","makefile","Makefile.*","GNUmakefile"], "mode": ""},
151 151 "text/x-mariadb": {"exts": ["*.sql"], "mode": "sql"},
152 152 "text/x-markdown": {"exts": ["*.md","*.markdown","*.mdown","*.mkd"], "mode": "gfm"},
153 153 "text/x-minidsrc": {"exts": ["*.md"], "mode": "gfm"},
154 154 "text/x-modelica": {"exts": ["*.mo"], "mode": "modelica"},
155 155 "text/x-modula2": {"exts": ["*.def","*.mod"], "mode": ""},
156 156 "text/x-monkey": {"exts": ["*.monkey"], "mode": ""},
157 157 "text/x-moocode": {"exts": ["*.moo"], "mode": ""},
158 158 "text/x-moonscript": {"exts": ["*.moon"], "mode": ""},
159 159 "text/x-nasm": {"exts": ["*.asm","*.ASM"], "mode": ""},
160 160 "text/x-nemerle": {"exts": ["*.n"], "mode": ""},
161 161 "text/x-newlisp": {"exts": ["*.lsp","*.nl"], "mode": ""},
162 162 "text/x-newspeak": {"exts": ["*.ns2"], "mode": ""},
163 163 "text/x-nginx-conf": {"exts": ["*.conf"], "mode": "nginx"},
164 164 "text/x-nimrod": {"exts": ["*.nim","*.nimrod"], "mode": ""},
165 "text/x-nsis": {"exts": ["*.nsi","*.nsh"], "mode": ""},
165 "text/x-nsis": {"exts": ["*.nsi","*.nsh"], "mode": "nsis"},
166 166 "text/x-objdump": {"exts": ["*.objdump"], "mode": ""},
167 167 "text/x-objective-c": {"exts": ["*.m","*.h"], "mode": ""},
168 168 "text/x-objective-c++": {"exts": ["*.mm","*.hh"], "mode": ""},
169 169 "text/x-objective-j": {"exts": ["*.j"], "mode": ""},
170 170 "text/x-ocaml": {"exts": ["*.ml","*.mli","*.mll","*.mly"], "mode": "mllike"},
171 171 "text/x-ooc": {"exts": ["*.ooc"], "mode": ""},
172 172 "text/x-opa": {"exts": ["*.opa"], "mode": ""},
173 173 "text/x-openedge": {"exts": ["*.p","*.cls"], "mode": ""},
174 174 "text/x-pascal": {"exts": ["*.pas","*.p"], "mode": "pascal"},
175 175 "text/x-perl": {"exts": ["*.pl","*.pm"], "mode": "perl"},
176 176 "text/x-php": {"exts": ["*.php","*.php[345]","*.inc"], "mode": "php"},
177 177 "text/x-pig": {"exts": ["*.pig"], "mode": "pig"},
178 178 "text/x-povray": {"exts": ["*.pov","*.inc"], "mode": ""},
179 179 "text/x-powershell": {"exts": ["*.ps1"], "mode": ""},
180 180 "text/x-prolog": {"exts": ["*.prolog","*.pro","*.pl"], "mode": ""},
181 181 "text/x-properties": {"exts": ["*.properties","*.ini","*.in"], "mode": "properties"},
182 182 "text/x-python": {"exts": ["*.py","*.pyw","*.sc","SConstruct","SConscript","*.tac","*.sage"], "mode": "python"},
183 183 "text/x-python-traceback": {"exts": ["*.pytb"], "mode": ""},
184 184 "text/x-python3-traceback": {"exts": ["*.py3tb"], "mode": ""},
185 185 "text/x-r-doc": {"exts": ["*.Rd"], "mode": ""},
186 186 "text/x-racket": {"exts": ["*.rkt","*.rktl"], "mode": ""},
187 187 "text/x-rebol": {"exts": ["*.r","*.r3"], "mode": ""},
188 188 "text/x-robotframework": {"exts": ["*.txt","*.robot"], "mode": ""},
189 189 "text/x-rpm-spec": {"exts": ["*.spec"], "mode": "rpm"},
190 190 "text/x-rsrc": {"exts": ["*.r"], "mode": "r"},
191 191 "text/x-rst": {"exts": ["*.rst","*.rest"], "mode": "rst"},
192 192 "text/x-ruby": {"exts": ["*.rb","*.rbw","Rakefile","*.rake","*.gemspec","*.rbx","*.duby"], "mode": "ruby"},
193 193 "text/x-rustsrc": {"exts": ["*.rs","*.rc"], "mode": "rust"},
194 194 "text/x-sass": {"exts": ["*.sass"], "mode": "sass"},
195 195 "text/x-scala": {"exts": ["*.scala"], "mode": "clike"},
196 196 "text/x-scaml": {"exts": ["*.scaml"], "mode": ""},
197 197 "text/x-scheme": {"exts": ["*.scm","*.ss"], "mode": "scheme"},
198 198 "text/x-scss": {"exts": ["*.scss"], "mode": "css"},
199 199 "text/x-sh": {"exts": ["*.sh","*.ksh","*.bash","*.ebuild","*.eclass",".bashrc","bashrc",".bash_*","bash_*"], "mode": "shell"},
200 200 "text/x-smalltalk": {"exts": ["*.st"], "mode": ""},
201 201 "text/x-smarty": {"exts": ["*.tpl"], "mode": "smarty"},
202 202 "text/x-snobol": {"exts": ["*.snobol"], "mode": ""},
203 203 "text/x-sourcepawn": {"exts": ["*.sp"], "mode": ""},
204 204 "text/x-sql": {"exts": ["*.sql"], "mode": "sql"},
205 205 "text/x-sqlite3-console": {"exts": ["*.sqlite3-console"], "mode": ""},
206 206 "text/x-squidconf": {"exts": ["squid.conf"], "mode": ""},
207 207 "text/x-standardml": {"exts": ["*.sml","*.sig","*.fun"], "mode": ""},
208 208 "text/x-stex": {"exts": [], "mode": "stex"},
209 209 "text/x-stsrc": {"exts": ["*.rs","*.rc","*.st"], "mode": "smalltalk"},
210 210 "text/x-systemverilog": {"exts": ["*.sv","*.svh","*.v"], "mode": "verilog"},
211 211 "text/x-tcl": {"exts": ["*.tcl"], "mode": "tcl"},
212 212 "text/x-tea": {"exts": ["*.tea"], "mode": ""},
213 213 "text/x-tex": {"exts": ["*.tex","*.aux","*.toc"], "mode": ""},
214 214 "text/x-tiddlywiki": {"exts": [], "mode": "tiddlywiki"},
215 215 "text/x-typescript": {"exts": ["*.ts"], "mode": ""},
216 216 "text/x-vala": {"exts": ["*.vala","*.vapi"], "mode": ""},
217 217 "text/x-vb": {"exts": ["*.vb"], "mode": "vb"},
218 218 "text/x-vbnet": {"exts": ["*.vb","*.bas"], "mode": ""},
219 219 "text/x-verilog": {"exts": ["*.v"], "mode": "verilog"},
220 "text/x-vhdl": {"exts": ["*.vhdl","*.vhd"], "mode": ""},
220 "text/x-vhdl": {"exts": ["*.vhdl","*.vhd"], "mode": "vhdl"},
221 221 "text/x-vim": {"exts": ["*.vim",".vimrc",".exrc",".gvimrc","_vimrc","_exrc","_gvimrc","vimrc","gvimrc"], "mode": ""},
222 222 "text/x-windows-registry": {"exts": ["*.reg"], "mode": ""},
223 223 "text/x-xtend": {"exts": ["*.xtend"], "mode": ""},
224 224 "text/x-yaml": {"exts": ["*.yaml","*.yml"], "mode": "yaml"},
225 225 "text/x-z80": {"exts": ["*.z80"], "mode": "z80"},
226 226 "text/xml": {"exts": ["*.xml","*.xsl","*.rss","*.xslt","*.xsd","*.wsdl"], "mode": ""},
227 227 "text/xquery": {"exts": ["*.xqy","*.xquery","*.xq","*.xql","*.xqm"], "mode": ""}
228 228 };
229 229
230 230 /* Special case for overriding mode by file extensions
231 231 * key is extensions, value is codemirror mode
232 232 * */
233 233 _SPECIAL_CASES = {
234 234 "md": "markdown",
235 235 "markdown": "markdown"
236 236 };
237 237
238 238 /**
239 239 * Get's proposed extension based on given mimetype
240 240 *
241 241 * @param mimetype
242 242 * @returns extensions (default .txt)
243 243 */
244 244 var getExtFromMimeType = function(mimetype){
245 245
246 246 var proposed_exts = MIME_TO_EXT[mimetype] || _EMPTY_EXT;
247 247 if(proposed_exts.exts.length < 1){
248 248 //fallback to text/plain
249 249 proposed_exts = {'exts': ['*.txt'], 'mode': '' }
250 250 }
251 251 // get the first
252 252 var ext = proposed_exts.exts[0];
253 253 if(ext[0] == '*'){
254 254 ext = ext.substr(1)
255 255 }
256 256
257 257 return ext
258 258 };
259 259
260 260 var getMimeTypeFromExt = function(ext, multiple){
261 261 mimetypes = [];
262 262 for (k in MIME_TO_EXT){
263 263 var mode = MIME_TO_EXT[k];
264 264 if ($.inArray("*."+ext, mode.exts) != -1){
265 265 mimetypes.push(k)
266 266 }
267 267 }
268 268 if(multiple){
269 269 return mimetypes
270 270 }
271 271 if(mimetypes.length > 0){
272 272 return mimetypes[0]
273 273 }
274 274
275 275 };
276 276
277 277 var getFilenameAndExt = function(filename){
278 278 var parts = filename.split('.');
279 279 var ext = null;
280 280 var filename = null;
281 281
282 282 if (parts.length > 1){
283 283 var ext = parts.pop();
284 284 var filename = parts.join("");
285 285 }
286 286 return {"filename": filename, "ext": ext}
287 287 }
288 288
289 289 /**
290 290 * Detect mode from extension, this is mostly used to override the
291 291 * detection by mimetype
292 292 *
293 293 * @param filename
294 294 */
295 295 var detectCodeMirrorModeFromExt = function(filename, fallback){
296 296 var ext = filename.split('.');
297 297 if (ext){
298 298 var ext = ext[ext.length-1];
299 299 }
300 300 // try to do a lookup by extension
301 301 var _special_mode = _SPECIAL_CASES[ext];
302 302 if (_special_mode){
303 303 return _special_mode
304 304 }
305 305 if(fallback !== undefined && fallback === true){
306 306 var mimetype = getMimeTypeFromExt(ext);
307 307 if(mimetype){
308 308 return MIME_TO_EXT[mimetype].mode;
309 309 }
310 310
311 311 }
312 312 }
313 313
314 314
315 315 /**
316 316 * Try to detect a codemirror mode based on a filename and mimetype
317 317 *
318 318 * @param filename
319 319 * @param mimetype
320 320 * @returns mode or undefined
321 321 */
322 322 var detectCodeMirrorMode = function(filename, mimetype, fallback){
323 323 // just use _SPECIAL_CASES for detection here, as we usually got mimetype
324 324 // and it's faster to lookup by mimetype.
325 325 var do_fallback = fallback || false;
326 326 var _mode_from_ext = detectCodeMirrorModeFromExt(filename, do_fallback);
327 327 if(_mode_from_ext){
328 328 return _mode_from_ext
329 329 }
330 330
331 331 // first try to match by exact mimetype
332 332 var mode = MIME_TO_EXT[mimetype];
333 333 if(mode && mode.mode){
334 334 return mode.mode;
335 335 }
336 336 }
@@ -1,178 +1,178 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode("nginx", function(config) {
15 15
16 16 function words(str) {
17 17 var obj = {}, words = str.split(" ");
18 18 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
19 19 return obj;
20 20 }
21 21
22 22 var keywords = words(
23 23 /* ngxDirectiveControl */ "break return rewrite set" +
24 24 /* ngxDirective */ " accept_mutex accept_mutex_delay access_log add_after_body add_before_body add_header addition_types aio alias allow ancient_browser ancient_browser_value auth_basic auth_basic_user_file auth_http auth_http_header auth_http_timeout autoindex autoindex_exact_size autoindex_localtime charset charset_types client_body_buffer_size client_body_in_file_only client_body_in_single_buffer client_body_temp_path client_body_timeout client_header_buffer_size client_header_timeout client_max_body_size connection_pool_size create_full_put_path daemon dav_access dav_methods debug_connection debug_points default_type degradation degrade deny devpoll_changes devpoll_events directio directio_alignment empty_gif env epoll_events error_log eventport_events expires fastcgi_bind fastcgi_buffer_size fastcgi_buffers fastcgi_busy_buffers_size fastcgi_cache fastcgi_cache_key fastcgi_cache_methods fastcgi_cache_min_uses fastcgi_cache_path fastcgi_cache_use_stale fastcgi_cache_valid fastcgi_catch_stderr fastcgi_connect_timeout fastcgi_hide_header fastcgi_ignore_client_abort fastcgi_ignore_headers fastcgi_index fastcgi_intercept_errors fastcgi_max_temp_file_size fastcgi_next_upstream fastcgi_param fastcgi_pass_header fastcgi_pass_request_body fastcgi_pass_request_headers fastcgi_read_timeout fastcgi_send_lowat fastcgi_send_timeout fastcgi_split_path_info fastcgi_store fastcgi_store_access fastcgi_temp_file_write_size fastcgi_temp_path fastcgi_upstream_fail_timeout fastcgi_upstream_max_fails flv geoip_city geoip_country google_perftools_profiles gzip gzip_buffers gzip_comp_level gzip_disable gzip_hash gzip_http_version gzip_min_length gzip_no_buffer gzip_proxied gzip_static gzip_types gzip_vary gzip_window if_modified_since ignore_invalid_headers image_filter image_filter_buffer image_filter_jpeg_quality image_filter_transparency imap_auth imap_capabilities imap_client_buffer index ip_hash keepalive_requests keepalive_timeout kqueue_changes kqueue_events large_client_header_buffers limit_conn limit_conn_log_level limit_rate limit_rate_after limit_req limit_req_log_level limit_req_zone limit_zone lingering_time lingering_timeout lock_file log_format log_not_found log_subrequest map_hash_bucket_size map_hash_max_size master_process memcached_bind memcached_buffer_size memcached_connect_timeout memcached_next_upstream memcached_read_timeout memcached_send_timeout memcached_upstream_fail_timeout memcached_upstream_max_fails merge_slashes min_delete_depth modern_browser modern_browser_value msie_padding msie_refresh multi_accept open_file_cache open_file_cache_errors open_file_cache_events open_file_cache_min_uses open_file_cache_valid open_log_file_cache output_buffers override_charset perl perl_modules perl_require perl_set pid pop3_auth pop3_capabilities port_in_redirect postpone_gzipping postpone_output protocol proxy proxy_bind proxy_buffer proxy_buffer_size proxy_buffering proxy_buffers proxy_busy_buffers_size proxy_cache proxy_cache_key proxy_cache_methods proxy_cache_min_uses proxy_cache_path proxy_cache_use_stale proxy_cache_valid proxy_connect_timeout proxy_headers_hash_bucket_size proxy_headers_hash_max_size proxy_hide_header proxy_ignore_client_abort proxy_ignore_headers proxy_intercept_errors proxy_max_temp_file_size proxy_method proxy_next_upstream proxy_pass_error_message proxy_pass_header proxy_pass_request_body proxy_pass_request_headers proxy_read_timeout proxy_redirect proxy_send_lowat proxy_send_timeout proxy_set_body proxy_set_header proxy_ssl_session_reuse proxy_store proxy_store_access proxy_temp_file_write_size proxy_temp_path proxy_timeout proxy_upstream_fail_timeout proxy_upstream_max_fails random_index read_ahead real_ip_header recursive_error_pages request_pool_size reset_timedout_connection resolver resolver_timeout rewrite_log rtsig_overflow_events rtsig_overflow_test rtsig_overflow_threshold rtsig_signo satisfy secure_link_secret send_lowat send_timeout sendfile sendfile_max_chunk server_name_in_redirect server_names_hash_bucket_size server_names_hash_max_size server_tokens set_real_ip_from smtp_auth smtp_capabilities smtp_client_buffer smtp_greeting_delay so_keepalive source_charset ssi ssi_ignore_recycled_buffers ssi_min_file_chunk ssi_silent_errors ssi_types ssi_value_length ssl ssl_certificate ssl_certificate_key ssl_ciphers ssl_client_certificate ssl_crl ssl_dhparam ssl_engine ssl_prefer_server_ciphers ssl_protocols ssl_session_cache ssl_session_timeout ssl_verify_client ssl_verify_depth starttls stub_status sub_filter sub_filter_once sub_filter_types tcp_nodelay tcp_nopush thread_stack_size timeout timer_resolution types_hash_bucket_size types_hash_max_size underscores_in_headers uninitialized_variable_warn use user userid userid_domain userid_expires userid_mark userid_name userid_p3p userid_path userid_service valid_referers variables_hash_bucket_size variables_hash_max_size worker_connections worker_cpu_affinity worker_priority worker_processes worker_rlimit_core worker_rlimit_nofile worker_rlimit_sigpending worker_threads working_directory xclient xml_entities xslt_stylesheet xslt_typesdrew@li229-23"
25 25 );
26 26
27 27 var keywords_block = words(
28 28 /* ngxDirectiveBlock */ "http mail events server types location upstream charset_map limit_except if geo map"
29 29 );
30 30
31 31 var keywords_important = words(
32 32 /* ngxDirectiveImportant */ "include root server server_name listen internal proxy_pass memcached_pass fastcgi_pass try_files"
33 33 );
34 34
35 35 var indentUnit = config.indentUnit, type;
36 36 function ret(style, tp) {type = tp; return style;}
37 37
38 38 function tokenBase(stream, state) {
39 39
40 40
41 41 stream.eatWhile(/[\w\$_]/);
42 42
43 43 var cur = stream.current();
44 44
45 45
46 46 if (keywords.propertyIsEnumerable(cur)) {
47 47 return "keyword";
48 48 }
49 49 else if (keywords_block.propertyIsEnumerable(cur)) {
50 50 return "variable-2";
51 51 }
52 52 else if (keywords_important.propertyIsEnumerable(cur)) {
53 53 return "string-2";
54 54 }
55 55 /**/
56 56
57 57 var ch = stream.next();
58 58 if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
59 59 else if (ch == "/" && stream.eat("*")) {
60 60 state.tokenize = tokenCComment;
61 61 return tokenCComment(stream, state);
62 62 }
63 63 else if (ch == "<" && stream.eat("!")) {
64 64 state.tokenize = tokenSGMLComment;
65 65 return tokenSGMLComment(stream, state);
66 66 }
67 67 else if (ch == "=") ret(null, "compare");
68 68 else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
69 69 else if (ch == "\"" || ch == "'") {
70 70 state.tokenize = tokenString(ch);
71 71 return state.tokenize(stream, state);
72 72 }
73 73 else if (ch == "#") {
74 74 stream.skipToEnd();
75 75 return ret("comment", "comment");
76 76 }
77 77 else if (ch == "!") {
78 78 stream.match(/^\s*\w*/);
79 79 return ret("keyword", "important");
80 80 }
81 81 else if (/\d/.test(ch)) {
82 82 stream.eatWhile(/[\w.%]/);
83 83 return ret("number", "unit");
84 84 }
85 85 else if (/[,.+>*\/]/.test(ch)) {
86 86 return ret(null, "select-op");
87 87 }
88 88 else if (/[;{}:\[\]]/.test(ch)) {
89 89 return ret(null, ch);
90 90 }
91 91 else {
92 92 stream.eatWhile(/[\w\\\-]/);
93 93 return ret("variable", "variable");
94 94 }
95 95 }
96 96
97 97 function tokenCComment(stream, state) {
98 98 var maybeEnd = false, ch;
99 99 while ((ch = stream.next()) != null) {
100 100 if (maybeEnd && ch == "/") {
101 101 state.tokenize = tokenBase;
102 102 break;
103 103 }
104 104 maybeEnd = (ch == "*");
105 105 }
106 106 return ret("comment", "comment");
107 107 }
108 108
109 109 function tokenSGMLComment(stream, state) {
110 110 var dashes = 0, ch;
111 111 while ((ch = stream.next()) != null) {
112 112 if (dashes >= 2 && ch == ">") {
113 113 state.tokenize = tokenBase;
114 114 break;
115 115 }
116 116 dashes = (ch == "-") ? dashes + 1 : 0;
117 117 }
118 118 return ret("comment", "comment");
119 119 }
120 120
121 121 function tokenString(quote) {
122 122 return function(stream, state) {
123 123 var escaped = false, ch;
124 124 while ((ch = stream.next()) != null) {
125 125 if (ch == quote && !escaped)
126 126 break;
127 127 escaped = !escaped && ch == "\\";
128 128 }
129 129 if (!escaped) state.tokenize = tokenBase;
130 130 return ret("string", "string");
131 131 };
132 132 }
133 133
134 134 return {
135 135 startState: function(base) {
136 136 return {tokenize: tokenBase,
137 137 baseIndent: base || 0,
138 138 stack: []};
139 139 },
140 140
141 141 token: function(stream, state) {
142 142 if (stream.eatSpace()) return null;
143 143 type = null;
144 144 var style = state.tokenize(stream, state);
145 145
146 146 var context = state.stack[state.stack.length-1];
147 147 if (type == "hash" && context == "rule") style = "atom";
148 148 else if (style == "variable") {
149 149 if (context == "rule") style = "number";
150 150 else if (!context || context == "@media{") style = "tag";
151 151 }
152 152
153 153 if (context == "rule" && /^[\{\};]$/.test(type))
154 154 state.stack.pop();
155 155 if (type == "{") {
156 156 if (context == "@media") state.stack[state.stack.length-1] = "@media{";
157 157 else state.stack.push("{");
158 158 }
159 159 else if (type == "}") state.stack.pop();
160 160 else if (type == "@media") state.stack.push("@media");
161 161 else if (context == "{" && type != "comment") state.stack.push("rule");
162 162 return style;
163 163 },
164 164
165 165 indent: function(state, textAfter) {
166 166 var n = state.stack.length;
167 167 if (/^\}/.test(textAfter))
168 168 n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
169 169 return state.baseIndent + n * indentUnit;
170 170 },
171 171
172 172 electricChars: "}"
173 173 };
174 174 });
175 175
176 CodeMirror.defineMIME("text/nginx", "text/x-nginx-conf");
176 CodeMirror.defineMIME("text/x-nginx-conf", "nginx");
177 177
178 178 });
@@ -1,230 +1,234 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../clike/clike"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../clike/clike"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 function keywords(str) {
15 15 var obj = {}, words = str.split(" ");
16 16 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
17 17 return obj;
18 18 }
19 19
20 20 // Helper for phpString
21 21 function matchSequence(list, end, escapes) {
22 22 if (list.length == 0) return phpString(end);
23 23 return function (stream, state) {
24 24 var patterns = list[0];
25 25 for (var i = 0; i < patterns.length; i++) if (stream.match(patterns[i][0])) {
26 26 state.tokenize = matchSequence(list.slice(1), end);
27 27 return patterns[i][1];
28 28 }
29 29 state.tokenize = phpString(end, escapes);
30 30 return "string";
31 31 };
32 32 }
33 33 function phpString(closing, escapes) {
34 34 return function(stream, state) { return phpString_(stream, state, closing, escapes); };
35 35 }
36 36 function phpString_(stream, state, closing, escapes) {
37 37 // "Complex" syntax
38 38 if (escapes !== false && stream.match("${", false) || stream.match("{$", false)) {
39 39 state.tokenize = null;
40 40 return "string";
41 41 }
42 42
43 43 // Simple syntax
44 44 if (escapes !== false && stream.match(/^\$[a-zA-Z_][a-zA-Z0-9_]*/)) {
45 45 // After the variable name there may appear array or object operator.
46 46 if (stream.match("[", false)) {
47 47 // Match array operator
48 48 state.tokenize = matchSequence([
49 49 [["[", null]],
50 50 [[/\d[\w\.]*/, "number"],
51 51 [/\$[a-zA-Z_][a-zA-Z0-9_]*/, "variable-2"],
52 52 [/[\w\$]+/, "variable"]],
53 53 [["]", null]]
54 54 ], closing, escapes);
55 55 }
56 56 if (stream.match(/\-\>\w/, false)) {
57 57 // Match object operator
58 58 state.tokenize = matchSequence([
59 59 [["->", null]],
60 60 [[/[\w]+/, "variable"]]
61 61 ], closing, escapes);
62 62 }
63 63 return "variable-2";
64 64 }
65 65
66 66 var escaped = false;
67 67 // Normal string
68 68 while (!stream.eol() &&
69 69 (escaped || escapes === false ||
70 70 (!stream.match("{$", false) &&
71 71 !stream.match(/^(\$[a-zA-Z_][a-zA-Z0-9_]*|\$\{)/, false)))) {
72 72 if (!escaped && stream.match(closing)) {
73 73 state.tokenize = null;
74 74 state.tokStack.pop(); state.tokStack.pop();
75 75 break;
76 76 }
77 77 escaped = stream.next() == "\\" && !escaped;
78 78 }
79 79 return "string";
80 80 }
81 81
82 82 var phpKeywords = "abstract and array as break case catch class clone const continue declare default " +
83 83 "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
84 84 "for foreach function global goto if implements interface instanceof namespace " +
85 85 "new or private protected public static switch throw trait try use var while xor " +
86 86 "die echo empty exit eval include include_once isset list require require_once return " +
87 87 "print unset __halt_compiler self static parent yield insteadof finally";
88 88 var phpAtoms = "true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__";
89 var phpBuiltin = "func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once json_decode json_encode json_last_error json_last_error_msg curl_close curl_copy_handle curl_errno curl_error curl_escape curl_exec curl_file_create curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_multi_setopt curl_multi_strerror curl_pause curl_reset curl_setopt_array curl_setopt curl_share_close curl_share_init curl_share_setopt curl_strerror curl_unescape curl_version mysqli_affected_rows mysqli_autocommit mysqli_change_user mysqli_character_set_name mysqli_close mysqli_commit mysqli_connect_errno mysqli_connect_error mysqli_connect mysqli_data_seek mysqli_debug mysqli_dump_debug_info mysqli_errno mysqli_error_list mysqli_error mysqli_fetch_all mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field_direct mysqli_fetch_field mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_charset mysqli_get_client_info mysqli_get_client_stats mysqli_get_client_version mysqli_get_connection_stats mysqli_get_host_info mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_info mysqli_init mysqli_insert_id mysqli_kill mysqli_more_results mysqli_multi_query mysqli_next_result mysqli_num_fields mysqli_num_rows mysqli_options mysqli_ping mysqli_prepare mysqli_query mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_reap_async_query mysqli_refresh mysqli_rollback mysqli_select_db mysqli_set_charset mysqli_set_local_infile_default mysqli_set_local_infile_handler mysqli_sqlstate mysqli_ssl_set mysqli_stat mysqli_stmt_init mysqli_store_result mysqli_thread_id mysqli_thread_safe mysqli_use_result mysqli_warning_count";
89 var phpBuiltin = "func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents file_put_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once json_decode json_encode json_last_error json_last_error_msg curl_close curl_copy_handle curl_errno curl_error curl_escape curl_exec curl_file_create curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_multi_setopt curl_multi_strerror curl_pause curl_reset curl_setopt_array curl_setopt curl_share_close curl_share_init curl_share_setopt curl_strerror curl_unescape curl_version mysqli_affected_rows mysqli_autocommit mysqli_change_user mysqli_character_set_name mysqli_close mysqli_commit mysqli_connect_errno mysqli_connect_error mysqli_connect mysqli_data_seek mysqli_debug mysqli_dump_debug_info mysqli_errno mysqli_error_list mysqli_error mysqli_fetch_all mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field_direct mysqli_fetch_field mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_charset mysqli_get_client_info mysqli_get_client_stats mysqli_get_client_version mysqli_get_connection_stats mysqli_get_host_info mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_info mysqli_init mysqli_insert_id mysqli_kill mysqli_more_results mysqli_multi_query mysqli_next_result mysqli_num_fields mysqli_num_rows mysqli_options mysqli_ping mysqli_prepare mysqli_query mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_reap_async_query mysqli_refresh mysqli_rollback mysqli_select_db mysqli_set_charset mysqli_set_local_infile_default mysqli_set_local_infile_handler mysqli_sqlstate mysqli_ssl_set mysqli_stat mysqli_stmt_init mysqli_store_result mysqli_thread_id mysqli_thread_safe mysqli_use_result mysqli_warning_count";
90 90 CodeMirror.registerHelper("hintWords", "php", [phpKeywords, phpAtoms, phpBuiltin].join(" ").split(" "));
91 91 CodeMirror.registerHelper("wordChars", "php", /[\w$]/);
92 92
93 93 var phpConfig = {
94 94 name: "clike",
95 95 helperType: "php",
96 96 keywords: keywords(phpKeywords),
97 97 blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"),
98 98 defKeywords: keywords("class function interface namespace trait"),
99 99 atoms: keywords(phpAtoms),
100 100 builtin: keywords(phpBuiltin),
101 101 multiLineStrings: true,
102 102 hooks: {
103 103 "$": function(stream) {
104 104 stream.eatWhile(/[\w\$_]/);
105 105 return "variable-2";
106 106 },
107 107 "<": function(stream, state) {
108 if (stream.match(/<</)) {
109 var nowDoc = stream.eat("'");
108 var before;
109 if (before = stream.match(/<<\s*/)) {
110 var quoted = stream.eat(/['"]/);
110 111 stream.eatWhile(/[\w\.]/);
111 var delim = stream.current().slice(3 + (nowDoc ? 1 : 0));
112 if (nowDoc) stream.eat("'");
112 var delim = stream.current().slice(before[0].length + (quoted ? 2 : 1));
113 if (quoted) stream.eat(quoted);
113 114 if (delim) {
114 115 (state.tokStack || (state.tokStack = [])).push(delim, 0);
115 state.tokenize = phpString(delim, nowDoc ? false : true);
116 state.tokenize = phpString(delim, quoted != "'");
116 117 return "string";
117 118 }
118 119 }
119 120 return false;
120 121 },
121 122 "#": function(stream) {
122 123 while (!stream.eol() && !stream.match("?>", false)) stream.next();
123 124 return "comment";
124 125 },
125 126 "/": function(stream) {
126 127 if (stream.eat("/")) {
127 128 while (!stream.eol() && !stream.match("?>", false)) stream.next();
128 129 return "comment";
129 130 }
130 131 return false;
131 132 },
132 133 '"': function(_stream, state) {
133 134 (state.tokStack || (state.tokStack = [])).push('"', 0);
134 135 state.tokenize = phpString('"');
135 136 return "string";
136 137 },
137 138 "{": function(_stream, state) {
138 139 if (state.tokStack && state.tokStack.length)
139 140 state.tokStack[state.tokStack.length - 1]++;
140 141 return false;
141 142 },
142 143 "}": function(_stream, state) {
143 144 if (state.tokStack && state.tokStack.length > 0 &&
144 145 !--state.tokStack[state.tokStack.length - 1]) {
145 146 state.tokenize = phpString(state.tokStack[state.tokStack.length - 2]);
146 147 }
147 148 return false;
148 149 }
149 150 }
150 151 };
151 152
152 153 CodeMirror.defineMode("php", function(config, parserConfig) {
153 154 var htmlMode = CodeMirror.getMode(config, "text/html");
154 155 var phpMode = CodeMirror.getMode(config, phpConfig);
155 156
156 157 function dispatch(stream, state) {
157 158 var isPHP = state.curMode == phpMode;
158 159 if (stream.sol() && state.pending && state.pending != '"' && state.pending != "'") state.pending = null;
159 160 if (!isPHP) {
160 161 if (stream.match(/^<\?\w*/)) {
161 162 state.curMode = phpMode;
163 if (!state.php) state.php = CodeMirror.startState(phpMode, htmlMode.indent(state.html, ""))
162 164 state.curState = state.php;
163 165 return "meta";
164 166 }
165 167 if (state.pending == '"' || state.pending == "'") {
166 168 while (!stream.eol() && stream.next() != state.pending) {}
167 169 var style = "string";
168 170 } else if (state.pending && stream.pos < state.pending.end) {
169 171 stream.pos = state.pending.end;
170 172 var style = state.pending.style;
171 173 } else {
172 174 var style = htmlMode.token(stream, state.curState);
173 175 }
174 176 if (state.pending) state.pending = null;
175 177 var cur = stream.current(), openPHP = cur.search(/<\?/), m;
176 178 if (openPHP != -1) {
177 179 if (style == "string" && (m = cur.match(/[\'\"]$/)) && !/\?>/.test(cur)) state.pending = m[0];
178 180 else state.pending = {end: stream.pos, style: style};
179 181 stream.backUp(cur.length - openPHP);
180 182 }
181 183 return style;
182 184 } else if (isPHP && state.php.tokenize == null && stream.match("?>")) {
183 185 state.curMode = htmlMode;
184 186 state.curState = state.html;
187 if (!state.php.context.prev) state.php = null;
185 188 return "meta";
186 189 } else {
187 190 return phpMode.token(stream, state.curState);
188 191 }
189 192 }
190 193
191 194 return {
192 195 startState: function() {
193 var html = CodeMirror.startState(htmlMode), php = CodeMirror.startState(phpMode);
196 var html = CodeMirror.startState(htmlMode)
197 var php = parserConfig.startOpen ? CodeMirror.startState(phpMode) : null
194 198 return {html: html,
195 199 php: php,
196 200 curMode: parserConfig.startOpen ? phpMode : htmlMode,
197 201 curState: parserConfig.startOpen ? php : html,
198 202 pending: null};
199 203 },
200 204
201 205 copyState: function(state) {
202 206 var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
203 php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur;
207 php = state.php, phpNew = php && CodeMirror.copyState(phpMode, php), cur;
204 208 if (state.curMode == htmlMode) cur = htmlNew;
205 209 else cur = phpNew;
206 210 return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
207 211 pending: state.pending};
208 212 },
209 213
210 214 token: dispatch,
211 215
212 216 indent: function(state, textAfter) {
213 217 if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) ||
214 218 (state.curMode == phpMode && /^\?>/.test(textAfter)))
215 219 return htmlMode.indent(state.html, textAfter);
216 220 return state.curMode.indent(state.curState, textAfter);
217 221 },
218 222
219 223 blockCommentStart: "/*",
220 224 blockCommentEnd: "*/",
221 225 lineComment: "//",
222 226
223 227 innerMode: function(state) { return {state: state.curState, mode: state.curMode}; }
224 228 };
225 229 }, "htmlmixed", "clike");
226 230
227 231 CodeMirror.defineMIME("application/x-httpd-php", "php");
228 232 CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
229 233 CodeMirror.defineMIME("text/x-php", phpConfig);
230 234 });
@@ -1,358 +1,347 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 function wordRegexp(words) {
15 15 return new RegExp("^((" + words.join(")|(") + "))\\b");
16 16 }
17 17
18 18 var wordOperators = wordRegexp(["and", "or", "not", "is"]);
19 19 var commonKeywords = ["as", "assert", "break", "class", "continue",
20 20 "def", "del", "elif", "else", "except", "finally",
21 21 "for", "from", "global", "if", "import",
22 22 "lambda", "pass", "raise", "return",
23 23 "try", "while", "with", "yield", "in"];
24 24 var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr",
25 25 "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
26 26 "enumerate", "eval", "filter", "float", "format", "frozenset",
27 27 "getattr", "globals", "hasattr", "hash", "help", "hex", "id",
28 28 "input", "int", "isinstance", "issubclass", "iter", "len",
29 29 "list", "locals", "map", "max", "memoryview", "min", "next",
30 30 "object", "oct", "open", "ord", "pow", "property", "range",
31 31 "repr", "reversed", "round", "set", "setattr", "slice",
32 32 "sorted", "staticmethod", "str", "sum", "super", "tuple",
33 33 "type", "vars", "zip", "__import__", "NotImplemented",
34 34 "Ellipsis", "__debug__"];
35 35 var py2 = {builtins: ["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
36 36 "file", "intern", "long", "raw_input", "reduce", "reload",
37 37 "unichr", "unicode", "xrange", "False", "True", "None"],
38 38 keywords: ["exec", "print"]};
39 39 var py3 = {builtins: ["ascii", "bytes", "exec", "print"],
40 40 keywords: ["nonlocal", "False", "True", "None", "async", "await"]};
41 41
42 42 CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonBuiltins));
43 43
44 44 function top(state) {
45 45 return state.scopes[state.scopes.length - 1];
46 46 }
47 47
48 48 CodeMirror.defineMode("python", function(conf, parserConf) {
49 49 var ERRORCLASS = "error";
50 50
51 var singleDelimiters = parserConf.singleDelimiters || new RegExp("^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]");
52 var doubleOperators = parserConf.doubleOperators || new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
53 var doubleDelimiters = parserConf.doubleDelimiters || new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
54 var tripleDelimiters = parserConf.tripleDelimiters || new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
51 var singleDelimiters = parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/;
52 var doubleOperators = parserConf.doubleOperators || /^([!<>]==|<>|<<|>>|\/\/|\*\*)/;
53 var doubleDelimiters = parserConf.doubleDelimiters || /^(\+=|\-=|\*=|%=|\/=|&=|\|=|\^=)/;
54 var tripleDelimiters = parserConf.tripleDelimiters || /^(\/\/=|>>=|<<=|\*\*=)/;
55 55
56 56 if (parserConf.version && parseInt(parserConf.version, 10) == 3){
57 57 // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
58 var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!@]");
59 var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*");
58 var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!@]/;
59 var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
60 60 } else {
61 var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
62 var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
61 var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!]/;
62 var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
63 63 }
64 64
65 65 var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
66 66
67 67 var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
68 68 if(parserConf.extra_keywords != undefined){
69 69 myKeywords = myKeywords.concat(parserConf.extra_keywords);
70 70 }
71 71 if(parserConf.extra_builtins != undefined){
72 72 myBuiltins = myBuiltins.concat(parserConf.extra_builtins);
73 73 }
74 74 if (parserConf.version && parseInt(parserConf.version, 10) == 3) {
75 75 myKeywords = myKeywords.concat(py3.keywords);
76 76 myBuiltins = myBuiltins.concat(py3.builtins);
77 77 var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i");
78 78 } else {
79 79 myKeywords = myKeywords.concat(py2.keywords);
80 80 myBuiltins = myBuiltins.concat(py2.builtins);
81 81 var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
82 82 }
83 83 var keywords = wordRegexp(myKeywords);
84 84 var builtins = wordRegexp(myBuiltins);
85 85
86 86 // tokenizers
87 87 function tokenBase(stream, state) {
88 88 // Handle scope changes
89 89 if (stream.sol() && top(state).type == "py") {
90 90 var scopeOffset = top(state).offset;
91 91 if (stream.eatSpace()) {
92 92 var lineOffset = stream.indentation();
93 93 if (lineOffset > scopeOffset)
94 94 pushScope(stream, state, "py");
95 95 else if (lineOffset < scopeOffset && dedent(stream, state))
96 96 state.errorToken = true;
97 97 return null;
98 98 } else {
99 99 var style = tokenBaseInner(stream, state);
100 100 if (scopeOffset > 0 && dedent(stream, state))
101 101 style += " " + ERRORCLASS;
102 102 return style;
103 103 }
104 104 }
105 105 return tokenBaseInner(stream, state);
106 106 }
107 107
108 108 function tokenBaseInner(stream, state) {
109 109 if (stream.eatSpace()) return null;
110 110
111 111 var ch = stream.peek();
112 112
113 113 // Handle Comments
114 114 if (ch == "#") {
115 115 stream.skipToEnd();
116 116 return "comment";
117 117 }
118 118
119 119 // Handle Number Literals
120 120 if (stream.match(/^[0-9\.]/, false)) {
121 121 var floatLiteral = false;
122 122 // Floats
123 123 if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
124 124 if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
125 125 if (stream.match(/^\.\d+/)) { floatLiteral = true; }
126 126 if (floatLiteral) {
127 127 // Float literals may be "imaginary"
128 128 stream.eat(/J/i);
129 129 return "number";
130 130 }
131 131 // Integers
132 132 var intLiteral = false;
133 133 // Hex
134 134 if (stream.match(/^0x[0-9a-f]+/i)) intLiteral = true;
135 135 // Binary
136 136 if (stream.match(/^0b[01]+/i)) intLiteral = true;
137 137 // Octal
138 138 if (stream.match(/^0o[0-7]+/i)) intLiteral = true;
139 139 // Decimal
140 140 if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
141 141 // Decimal literals may be "imaginary"
142 142 stream.eat(/J/i);
143 143 // TODO - Can you have imaginary longs?
144 144 intLiteral = true;
145 145 }
146 146 // Zero by itself with no other piece of number.
147 147 if (stream.match(/^0(?![\dx])/i)) intLiteral = true;
148 148 if (intLiteral) {
149 149 // Integer literals may be "long"
150 150 stream.eat(/L/i);
151 151 return "number";
152 152 }
153 153 }
154 154
155 155 // Handle Strings
156 156 if (stream.match(stringPrefixes)) {
157 157 state.tokenize = tokenStringFactory(stream.current());
158 158 return state.tokenize(stream, state);
159 159 }
160 160
161 161 // Handle operators and Delimiters
162 162 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
163 return null;
163 return "punctuation";
164 164
165 165 if (stream.match(doubleOperators) || stream.match(singleOperators))
166 166 return "operator";
167 167
168 168 if (stream.match(singleDelimiters))
169 return null;
169 return "punctuation";
170
171 if (state.lastToken == "." && stream.match(identifiers))
172 return "property";
170 173
171 174 if (stream.match(keywords) || stream.match(wordOperators))
172 175 return "keyword";
173 176
174 177 if (stream.match(builtins))
175 178 return "builtin";
176 179
177 180 if (stream.match(/^(self|cls)\b/))
178 181 return "variable-2";
179 182
180 183 if (stream.match(identifiers)) {
181 184 if (state.lastToken == "def" || state.lastToken == "class")
182 185 return "def";
183 186 return "variable";
184 187 }
185 188
186 189 // Handle non-detected items
187 190 stream.next();
188 191 return ERRORCLASS;
189 192 }
190 193
191 194 function tokenStringFactory(delimiter) {
192 195 while ("rub".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
193 196 delimiter = delimiter.substr(1);
194 197
195 198 var singleline = delimiter.length == 1;
196 199 var OUTCLASS = "string";
197 200
198 201 function tokenString(stream, state) {
199 202 while (!stream.eol()) {
200 203 stream.eatWhile(/[^'"\\]/);
201 204 if (stream.eat("\\")) {
202 205 stream.next();
203 206 if (singleline && stream.eol())
204 207 return OUTCLASS;
205 208 } else if (stream.match(delimiter)) {
206 209 state.tokenize = tokenBase;
207 210 return OUTCLASS;
208 211 } else {
209 212 stream.eat(/['"]/);
210 213 }
211 214 }
212 215 if (singleline) {
213 216 if (parserConf.singleLineStringErrors)
214 217 return ERRORCLASS;
215 218 else
216 219 state.tokenize = tokenBase;
217 220 }
218 221 return OUTCLASS;
219 222 }
220 223 tokenString.isString = true;
221 224 return tokenString;
222 225 }
223 226
224 227 function pushScope(stream, state, type) {
225 228 var offset = 0, align = null;
226 229 if (type == "py") {
227 230 while (top(state).type != "py")
228 231 state.scopes.pop();
229 232 }
230 233 offset = top(state).offset + (type == "py" ? conf.indentUnit : hangingIndent);
231 234 if (type != "py" && !stream.match(/^(\s|#.*)*$/, false))
232 235 align = stream.column() + 1;
233 236 state.scopes.push({offset: offset, type: type, align: align});
234 237 }
235 238
236 239 function dedent(stream, state) {
237 240 var indented = stream.indentation();
238 241 while (top(state).offset > indented) {
239 242 if (top(state).type != "py") return true;
240 243 state.scopes.pop();
241 244 }
242 245 return top(state).offset != indented;
243 246 }
244 247
245 248 function tokenLexer(stream, state) {
246 249 var style = state.tokenize(stream, state);
247 250 var current = stream.current();
248 251
249 // Handle '.' connected identifiers
250 if (current == ".") {
251 style = stream.match(identifiers, false) ? null : ERRORCLASS;
252 if (style == null && state.lastStyle == "meta") {
253 // Apply 'meta' style to '.' connected identifiers when
254 // appropriate.
255 style = "meta";
256 }
257 return style;
258 }
259
260 252 // Handle decorators
261 253 if (current == "@"){
262 254 if(parserConf.version && parseInt(parserConf.version, 10) == 3){
263 255 return stream.match(identifiers, false) ? "meta" : "operator";
264 256 } else {
265 257 return stream.match(identifiers, false) ? "meta" : ERRORCLASS;
266 258 }
267 259 }
268 260
269 261 if ((style == "variable" || style == "builtin")
270 && state.lastStyle == "meta")
262 && state.lastToken == "meta")
271 263 style = "meta";
272 264
273 265 // Handle scope changes.
274 266 if (current == "pass" || current == "return")
275 267 state.dedent += 1;
276 268
277 269 if (current == "lambda") state.lambda = true;
278 270 if (current == ":" && !state.lambda && top(state).type == "py")
279 271 pushScope(stream, state, "py");
280 272
281 273 var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1;
282 274 if (delimiter_index != -1)
283 275 pushScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
284 276
285 277 delimiter_index = "])}".indexOf(current);
286 278 if (delimiter_index != -1) {
287 279 if (top(state).type == current) state.scopes.pop();
288 280 else return ERRORCLASS;
289 281 }
290 282 if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
291 283 if (state.scopes.length > 1) state.scopes.pop();
292 284 state.dedent -= 1;
293 285 }
294 286
295 287 return style;
296 288 }
297 289
298 290 var external = {
299 291 startState: function(basecolumn) {
300 292 return {
301 293 tokenize: tokenBase,
302 294 scopes: [{offset: basecolumn || 0, type: "py", align: null}],
303 lastStyle: null,
304 295 lastToken: null,
305 296 lambda: false,
306 297 dedent: 0
307 298 };
308 299 },
309 300
310 301 token: function(stream, state) {
311 302 var addErr = state.errorToken;
312 303 if (addErr) state.errorToken = false;
313 304 var style = tokenLexer(stream, state);
314 305
315 state.lastStyle = style;
316
317 var current = stream.current();
318 if (current && style)
319 state.lastToken = current;
306 if (style && style != "comment")
307 state.lastToken = (style == "keyword" || style == "punctuation") ? stream.current() : style;
308 if (style == "punctuation") style = null;
320 309
321 310 if (stream.eol() && state.lambda)
322 311 state.lambda = false;
323 312 return addErr ? style + " " + ERRORCLASS : style;
324 313 },
325 314
326 315 indent: function(state, textAfter) {
327 316 if (state.tokenize != tokenBase)
328 317 return state.tokenize.isString ? CodeMirror.Pass : 0;
329 318
330 319 var scope = top(state);
331 320 var closing = textAfter && textAfter.charAt(0) == scope.type;
332 321 if (scope.align != null)
333 322 return scope.align - (closing ? 1 : 0);
334 323 else if (closing && state.scopes.length > 1)
335 324 return state.scopes[state.scopes.length - 2].offset;
336 325 else
337 326 return scope.offset;
338 327 },
339 328
340 329 closeBrackets: {triples: "'\""},
341 330 lineComment: "#",
342 331 fold: "indent"
343 332 };
344 333 return external;
345 334 });
346 335
347 336 CodeMirror.defineMIME("text/x-python", "python");
348 337
349 338 var words = function(str) { return str.split(" "); };
350 339
351 340 CodeMirror.defineMIME("text/x-cython", {
352 341 name: "python",
353 342 extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
354 343 "extern gil include nogil property public"+
355 344 "readonly struct union DEF IF ELIF ELSE")
356 345 });
357 346
358 347 });
@@ -1,101 +1,109 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode("rpm-changes", function() {
15 15 var headerSeperator = /^-+$/;
16 16 var headerLine = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ?\d{1,2} \d{2}:\d{2}(:\d{2})? [A-Z]{3,4} \d{4} - /;
17 17 var simpleEmail = /^[\w+.-]+@[\w.-]+/;
18 18
19 19 return {
20 20 token: function(stream) {
21 21 if (stream.sol()) {
22 22 if (stream.match(headerSeperator)) { return 'tag'; }
23 23 if (stream.match(headerLine)) { return 'tag'; }
24 24 }
25 25 if (stream.match(simpleEmail)) { return 'string'; }
26 26 stream.next();
27 27 return null;
28 28 }
29 29 };
30 30 });
31 31
32 32 CodeMirror.defineMIME("text/x-rpm-changes", "rpm-changes");
33 33
34 34 // Quick and dirty spec file highlighting
35 35
36 36 CodeMirror.defineMode("rpm-spec", function() {
37 var arch = /^(i386|i586|i686|x86_64|ppc64|ppc|ia64|s390x|s390|sparc64|sparcv9|sparc|noarch|alphaev6|alpha|hppa|mipsel)/;
37 var arch = /^(i386|i586|i686|x86_64|ppc64le|ppc64|ppc|ia64|s390x|s390|sparc64|sparcv9|sparc|noarch|alphaev6|alpha|hppa|mipsel)/;
38 38
39 var preamble = /^(Name|Version|Release|License|Summary|Url|Group|Source|BuildArch|BuildRequires|BuildRoot|AutoReqProv|Provides|Requires(\(\w+\))?|Obsoletes|Conflicts|Recommends|Source\d*|Patch\d*|ExclusiveArch|NoSource|Supplements):/;
40 var section = /^%(debug_package|package|description|prep|build|install|files|clean|changelog|preinstall|preun|postinstall|postun|pre|post|triggerin|triggerun|pretrans|posttrans|verifyscript|check|triggerpostun|triggerprein|trigger)/;
39 var preamble = /^[a-zA-Z0-9()]+:/;
40 var section = /^%(debug_package|package|description|prep|build|install|files|clean|changelog|preinstall|preun|postinstall|postun|pretrans|posttrans|pre|post|triggerin|triggerun|verifyscript|check|triggerpostun|triggerprein|trigger)/;
41 41 var control_flow_complex = /^%(ifnarch|ifarch|if)/; // rpm control flow macros
42 42 var control_flow_simple = /^%(else|endif)/; // rpm control flow macros
43 43 var operators = /^(\!|\?|\<\=|\<|\>\=|\>|\=\=|\&\&|\|\|)/; // operators in control flow macros
44 44
45 45 return {
46 46 startState: function () {
47 47 return {
48 48 controlFlow: false,
49 49 macroParameters: false,
50 50 section: false
51 51 };
52 52 },
53 53 token: function (stream, state) {
54 54 var ch = stream.peek();
55 55 if (ch == "#") { stream.skipToEnd(); return "comment"; }
56 56
57 57 if (stream.sol()) {
58 if (stream.match(preamble)) { return "preamble"; }
59 if (stream.match(section)) { return "section"; }
58 if (stream.match(preamble)) { return "header"; }
59 if (stream.match(section)) { return "atom"; }
60 60 }
61 61
62 62 if (stream.match(/^\$\w+/)) { return "def"; } // Variables like '$RPM_BUILD_ROOT'
63 63 if (stream.match(/^\$\{\w+\}/)) { return "def"; } // Variables like '${RPM_BUILD_ROOT}'
64 64
65 65 if (stream.match(control_flow_simple)) { return "keyword"; }
66 66 if (stream.match(control_flow_complex)) {
67 67 state.controlFlow = true;
68 68 return "keyword";
69 69 }
70 70 if (state.controlFlow) {
71 71 if (stream.match(operators)) { return "operator"; }
72 72 if (stream.match(/^(\d+)/)) { return "number"; }
73 73 if (stream.eol()) { state.controlFlow = false; }
74 74 }
75 75
76 if (stream.match(arch)) { return "number"; }
76 if (stream.match(arch)) {
77 if (stream.eol()) { state.controlFlow = false; }
78 return "number";
79 }
77 80
78 81 // Macros like '%make_install' or '%attr(0775,root,root)'
79 82 if (stream.match(/^%[\w]+/)) {
80 83 if (stream.match(/^\(/)) { state.macroParameters = true; }
81 return "macro";
84 return "keyword";
82 85 }
83 86 if (state.macroParameters) {
84 87 if (stream.match(/^\d+/)) { return "number";}
85 88 if (stream.match(/^\)/)) {
86 89 state.macroParameters = false;
87 return "macro";
90 return "keyword";
88 91 }
89 92 }
90 if (stream.match(/^%\{\??[\w \-]+\}/)) { return "macro"; } // Macros like '%{defined fedora}'
93
94 // Macros like '%{defined fedora}'
95 if (stream.match(/^%\{\??[\w \-\:\!]+\}/)) {
96 if (stream.eol()) { state.controlFlow = false; }
97 return "def";
98 }
91 99
92 100 //TODO: Include bash script sub-parser (CodeMirror supports that)
93 101 stream.next();
94 102 return null;
95 103 }
96 104 };
97 105 });
98 106
99 107 CodeMirror.defineMIME("text/x-rpm-spec", "rpm-spec");
100 108
101 109 });
@@ -1,285 +1,285 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode("ruby", function(config) {
15 15 function wordObj(words) {
16 16 var o = {};
17 17 for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
18 18 return o;
19 19 }
20 20 var keywords = wordObj([
21 21 "alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else",
22 22 "elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or",
23 23 "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
24 24 "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
25 25 "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
26 26 "require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
27 27 ]);
28 var indentWords = wordObj(["def", "class", "case", "for", "while", "module", "then",
28 var indentWords = wordObj(["def", "class", "case", "for", "while", "until", "module", "then",
29 29 "catch", "loop", "proc", "begin"]);
30 30 var dedentWords = wordObj(["end", "until"]);
31 31 var matching = {"[": "]", "{": "}", "(": ")"};
32 32 var curPunc;
33 33
34 34 function chain(newtok, stream, state) {
35 35 state.tokenize.push(newtok);
36 36 return newtok(stream, state);
37 37 }
38 38
39 39 function tokenBase(stream, state) {
40 curPunc = null;
41 40 if (stream.sol() && stream.match("=begin") && stream.eol()) {
42 41 state.tokenize.push(readBlockComment);
43 42 return "comment";
44 43 }
45 44 if (stream.eatSpace()) return null;
46 45 var ch = stream.next(), m;
47 46 if (ch == "`" || ch == "'" || ch == '"') {
48 47 return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
49 48 } else if (ch == "/") {
50 49 var currentIndex = stream.current().length;
51 50 if (stream.skipTo("/")) {
52 51 var search_till = stream.current().length;
53 52 stream.backUp(stream.current().length - currentIndex);
54 53 var balance = 0; // balance brackets
55 54 while (stream.current().length < search_till) {
56 55 var chchr = stream.next();
57 56 if (chchr == "(") balance += 1;
58 57 else if (chchr == ")") balance -= 1;
59 58 if (balance < 0) break;
60 59 }
61 60 stream.backUp(stream.current().length - currentIndex);
62 61 if (balance == 0)
63 62 return chain(readQuoted(ch, "string-2", true), stream, state);
64 63 }
65 64 return "operator";
66 65 } else if (ch == "%") {
67 66 var style = "string", embed = true;
68 67 if (stream.eat("s")) style = "atom";
69 68 else if (stream.eat(/[WQ]/)) style = "string";
70 69 else if (stream.eat(/[r]/)) style = "string-2";
71 70 else if (stream.eat(/[wxq]/)) { style = "string"; embed = false; }
72 71 var delim = stream.eat(/[^\w\s=]/);
73 72 if (!delim) return "operator";
74 73 if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
75 74 return chain(readQuoted(delim, style, embed, true), stream, state);
76 75 } else if (ch == "#") {
77 76 stream.skipToEnd();
78 77 return "comment";
79 78 } else if (ch == "<" && (m = stream.match(/^<-?[\`\"\']?([a-zA-Z_?]\w*)[\`\"\']?(?:;|$)/))) {
80 79 return chain(readHereDoc(m[1]), stream, state);
81 80 } else if (ch == "0") {
82 81 if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/);
83 82 else if (stream.eat("b")) stream.eatWhile(/[01]/);
84 83 else stream.eatWhile(/[0-7]/);
85 84 return "number";
86 85 } else if (/\d/.test(ch)) {
87 86 stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/);
88 87 return "number";
89 88 } else if (ch == "?") {
90 89 while (stream.match(/^\\[CM]-/)) {}
91 90 if (stream.eat("\\")) stream.eatWhile(/\w/);
92 91 else stream.next();
93 92 return "string";
94 93 } else if (ch == ":") {
95 94 if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
96 95 if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
97 96
98 97 // :> :>> :< :<< are valid symbols
99 98 if (stream.eat(/[\<\>]/)) {
100 99 stream.eat(/[\<\>]/);
101 100 return "atom";
102 101 }
103 102
104 103 // :+ :- :/ :* :| :& :! are valid symbols
105 104 if (stream.eat(/[\+\-\*\/\&\|\:\!]/)) {
106 105 return "atom";
107 106 }
108 107
109 108 // Symbols can't start by a digit
110 109 if (stream.eat(/[a-zA-Z$@_\xa1-\uffff]/)) {
111 110 stream.eatWhile(/[\w$\xa1-\uffff]/);
112 111 // Only one ? ! = is allowed and only as the last character
113 112 stream.eat(/[\?\!\=]/);
114 113 return "atom";
115 114 }
116 115 return "operator";
117 116 } else if (ch == "@" && stream.match(/^@?[a-zA-Z_\xa1-\uffff]/)) {
118 117 stream.eat("@");
119 118 stream.eatWhile(/[\w\xa1-\uffff]/);
120 119 return "variable-2";
121 120 } else if (ch == "$") {
122 121 if (stream.eat(/[a-zA-Z_]/)) {
123 122 stream.eatWhile(/[\w]/);
124 123 } else if (stream.eat(/\d/)) {
125 124 stream.eat(/\d/);
126 125 } else {
127 126 stream.next(); // Must be a special global like $: or $!
128 127 }
129 128 return "variable-3";
130 129 } else if (/[a-zA-Z_\xa1-\uffff]/.test(ch)) {
131 130 stream.eatWhile(/[\w\xa1-\uffff]/);
132 131 stream.eat(/[\?\!]/);
133 132 if (stream.eat(":")) return "atom";
134 133 return "ident";
135 134 } else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
136 135 curPunc = "|";
137 136 return null;
138 137 } else if (/[\(\)\[\]{}\\;]/.test(ch)) {
139 138 curPunc = ch;
140 139 return null;
141 140 } else if (ch == "-" && stream.eat(">")) {
142 141 return "arrow";
143 142 } else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) {
144 143 var more = stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
145 144 if (ch == "." && !more) curPunc = ".";
146 145 return "operator";
147 146 } else {
148 147 return null;
149 148 }
150 149 }
151 150
152 151 function tokenBaseUntilBrace(depth) {
153 152 if (!depth) depth = 1;
154 153 return function(stream, state) {
155 154 if (stream.peek() == "}") {
156 155 if (depth == 1) {
157 156 state.tokenize.pop();
158 157 return state.tokenize[state.tokenize.length-1](stream, state);
159 158 } else {
160 159 state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth - 1);
161 160 }
162 161 } else if (stream.peek() == "{") {
163 162 state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth + 1);
164 163 }
165 164 return tokenBase(stream, state);
166 165 };
167 166 }
168 167 function tokenBaseOnce() {
169 168 var alreadyCalled = false;
170 169 return function(stream, state) {
171 170 if (alreadyCalled) {
172 171 state.tokenize.pop();
173 172 return state.tokenize[state.tokenize.length-1](stream, state);
174 173 }
175 174 alreadyCalled = true;
176 175 return tokenBase(stream, state);
177 176 };
178 177 }
179 178 function readQuoted(quote, style, embed, unescaped) {
180 179 return function(stream, state) {
181 180 var escaped = false, ch;
182 181
183 182 if (state.context.type === 'read-quoted-paused') {
184 183 state.context = state.context.prev;
185 184 stream.eat("}");
186 185 }
187 186
188 187 while ((ch = stream.next()) != null) {
189 188 if (ch == quote && (unescaped || !escaped)) {
190 189 state.tokenize.pop();
191 190 break;
192 191 }
193 192 if (embed && ch == "#" && !escaped) {
194 193 if (stream.eat("{")) {
195 194 if (quote == "}") {
196 195 state.context = {prev: state.context, type: 'read-quoted-paused'};
197 196 }
198 197 state.tokenize.push(tokenBaseUntilBrace());
199 198 break;
200 199 } else if (/[@\$]/.test(stream.peek())) {
201 200 state.tokenize.push(tokenBaseOnce());
202 201 break;
203 202 }
204 203 }
205 204 escaped = !escaped && ch == "\\";
206 205 }
207 206 return style;
208 207 };
209 208 }
210 209 function readHereDoc(phrase) {
211 210 return function(stream, state) {
212 211 if (stream.match(phrase)) state.tokenize.pop();
213 212 else stream.skipToEnd();
214 213 return "string";
215 214 };
216 215 }
217 216 function readBlockComment(stream, state) {
218 217 if (stream.sol() && stream.match("=end") && stream.eol())
219 218 state.tokenize.pop();
220 219 stream.skipToEnd();
221 220 return "comment";
222 221 }
223 222
224 223 return {
225 224 startState: function() {
226 225 return {tokenize: [tokenBase],
227 226 indented: 0,
228 227 context: {type: "top", indented: -config.indentUnit},
229 228 continuedLine: false,
230 229 lastTok: null,
231 230 varList: false};
232 231 },
233 232
234 233 token: function(stream, state) {
234 curPunc = null;
235 235 if (stream.sol()) state.indented = stream.indentation();
236 236 var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
237 237 var thisTok = curPunc;
238 238 if (style == "ident") {
239 239 var word = stream.current();
240 240 style = state.lastTok == "." ? "property"
241 241 : keywords.propertyIsEnumerable(stream.current()) ? "keyword"
242 242 : /^[A-Z]/.test(word) ? "tag"
243 243 : (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def"
244 244 : "variable";
245 245 if (style == "keyword") {
246 246 thisTok = word;
247 247 if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
248 248 else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
249 249 else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
250 250 kwtype = "indent";
251 251 else if (word == "do" && state.context.indented < state.indented)
252 252 kwtype = "indent";
253 253 }
254 254 }
255 255 if (curPunc || (style && style != "comment")) state.lastTok = thisTok;
256 256 if (curPunc == "|") state.varList = !state.varList;
257 257
258 258 if (kwtype == "indent" || /[\(\[\{]/.test(curPunc))
259 259 state.context = {prev: state.context, type: curPunc || style, indented: state.indented};
260 260 else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev)
261 261 state.context = state.context.prev;
262 262
263 263 if (stream.eol())
264 264 state.continuedLine = (curPunc == "\\" || style == "operator");
265 265 return style;
266 266 },
267 267
268 268 indent: function(state, textAfter) {
269 269 if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0;
270 270 var firstChar = textAfter && textAfter.charAt(0);
271 271 var ct = state.context;
272 272 var closing = ct.type == matching[firstChar] ||
273 273 ct.type == "keyword" && /^(?:end|until|else|elsif|when|rescue)\b/.test(textAfter);
274 274 return ct.indented + (closing ? 0 : config.indentUnit) +
275 275 (state.continuedLine ? config.indentUnit : 0);
276 276 },
277 277
278 electricChars: "}de", // enD and rescuE
278 electricInput: /^\s*(?:end|rescue|\})$/,
279 279 lineComment: "#"
280 280 };
281 281 });
282 282
283 283 CodeMirror.defineMIME("text/x-ruby", "ruby");
284 284
285 285 });
@@ -1,451 +1,71 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 CodeMirror.defineMode("rust", function() {
15 var indentUnit = 4, altIndentUnit = 2;
16 var valKeywords = {
17 "if": "if-style", "while": "if-style", "loop": "else-style", "else": "else-style",
18 "do": "else-style", "ret": "else-style", "fail": "else-style",
19 "break": "atom", "cont": "atom", "const": "let", "resource": "fn",
20 "let": "let", "fn": "fn", "for": "for", "alt": "alt", "iface": "iface",
21 "impl": "impl", "type": "type", "enum": "enum", "mod": "mod",
22 "as": "op", "true": "atom", "false": "atom", "assert": "op", "check": "op",
23 "claim": "op", "native": "ignore", "unsafe": "ignore", "import": "else-style",
24 "export": "else-style", "copy": "op", "log": "op", "log_err": "op",
25 "use": "op", "bind": "op", "self": "atom", "struct": "enum"
26 };
27 var typeKeywords = function() {
28 var keywords = {"fn": "fn", "block": "fn", "obj": "obj"};
29 var atoms = "bool uint int i8 i16 i32 i64 u8 u16 u32 u64 float f32 f64 str char".split(" ");
30 for (var i = 0, e = atoms.length; i < e; ++i) keywords[atoms[i]] = "atom";
31 return keywords;
32 }();
33 var operatorChar = /[+\-*&%=<>!?|\.@]/;
34
35 // Tokenizer
36
37 // Used as scratch variable to communicate multiple values without
38 // consing up tons of objects.
39 var tcat, content;
40 function r(tc, style) {
41 tcat = tc;
42 return style;
43 }
44
45 function tokenBase(stream, state) {
46 var ch = stream.next();
47 if (ch == '"') {
48 state.tokenize = tokenString;
49 return state.tokenize(stream, state);
50 }
51 if (ch == "'") {
52 tcat = "atom";
53 if (stream.eat("\\")) {
54 if (stream.skipTo("'")) { stream.next(); return "string"; }
55 else { return "error"; }
56 } else {
57 stream.next();
58 return stream.eat("'") ? "string" : "error";
59 }
60 }
61 if (ch == "/") {
62 if (stream.eat("/")) { stream.skipToEnd(); return "comment"; }
63 if (stream.eat("*")) {
64 state.tokenize = tokenComment(1);
65 return state.tokenize(stream, state);
66 }
67 }
68 if (ch == "#") {
69 if (stream.eat("[")) { tcat = "open-attr"; return null; }
70 stream.eatWhile(/\w/);
71 return r("macro", "meta");
72 }
73 if (ch == ":" && stream.match(":<")) {
74 return r("op", null);
75 }
76 if (ch.match(/\d/) || (ch == "." && stream.eat(/\d/))) {
77 var flp = false;
78 if (!stream.match(/^x[\da-f]+/i) && !stream.match(/^b[01]+/)) {
79 stream.eatWhile(/\d/);
80 if (stream.eat(".")) { flp = true; stream.eatWhile(/\d/); }
81 if (stream.match(/^e[+\-]?\d+/i)) { flp = true; }
82 }
83 if (flp) stream.match(/^f(?:32|64)/);
84 else stream.match(/^[ui](?:8|16|32|64)/);
85 return r("atom", "number");
86 }
87 if (ch.match(/[()\[\]{}:;,]/)) return r(ch, null);
88 if (ch == "-" && stream.eat(">")) return r("->", null);
89 if (ch.match(operatorChar)) {
90 stream.eatWhile(operatorChar);
91 return r("op", null);
92 }
93 stream.eatWhile(/\w/);
94 content = stream.current();
95 if (stream.match(/^::\w/)) {
96 stream.backUp(1);
97 return r("prefix", "variable-2");
98 }
99 if (state.keywords.propertyIsEnumerable(content))
100 return r(state.keywords[content], content.match(/true|false/) ? "atom" : "keyword");
101 return r("name", "variable");
102 }
103
104 function tokenString(stream, state) {
105 var ch, escaped = false;
106 while (ch = stream.next()) {
107 if (ch == '"' && !escaped) {
108 state.tokenize = tokenBase;
109 return r("atom", "string");
110 }
111 escaped = !escaped && ch == "\\";
112 }
113 // Hack to not confuse the parser when a string is split in
114 // pieces.
115 return r("op", "string");
116 }
117
118 function tokenComment(depth) {
119 return function(stream, state) {
120 var lastCh = null, ch;
121 while (ch = stream.next()) {
122 if (ch == "/" && lastCh == "*") {
123 if (depth == 1) {
124 state.tokenize = tokenBase;
125 break;
126 } else {
127 state.tokenize = tokenComment(depth - 1);
128 return state.tokenize(stream, state);
129 }
130 }
131 if (ch == "*" && lastCh == "/") {
132 state.tokenize = tokenComment(depth + 1);
133 return state.tokenize(stream, state);
134 }
135 lastCh = ch;
136 }
137 return "comment";
138 };
139 }
140
141 // Parser
142
143 var cx = {state: null, stream: null, marked: null, cc: null};
144 function pass() {
145 for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
146 }
147 function cont() {
148 pass.apply(null, arguments);
149 return true;
150 }
151
152 function pushlex(type, info) {
153 var result = function() {
154 var state = cx.state;
155 state.lexical = {indented: state.indented, column: cx.stream.column(),
156 type: type, prev: state.lexical, info: info};
157 };
158 result.lex = true;
159 return result;
160 }
161 function poplex() {
162 var state = cx.state;
163 if (state.lexical.prev) {
164 if (state.lexical.type == ")")
165 state.indented = state.lexical.indented;
166 state.lexical = state.lexical.prev;
167 }
168 }
169 function typecx() { cx.state.keywords = typeKeywords; }
170 function valcx() { cx.state.keywords = valKeywords; }
171 poplex.lex = typecx.lex = valcx.lex = true;
172
173 function commasep(comb, end) {
174 function more(type) {
175 if (type == ",") return cont(comb, more);
176 if (type == end) return cont();
177 return cont(more);
178 }
179 return function(type) {
180 if (type == end) return cont();
181 return pass(comb, more);
182 };
183 }
14 CodeMirror.defineSimpleMode("rust",{
15 start: [
16 // string and byte string
17 {regex: /b?"/, token: "string", next: "string"},
18 // raw string and raw byte string
19 {regex: /b?r"/, token: "string", next: "string_raw"},
20 {regex: /b?r#+"/, token: "string", next: "string_raw_hash"},
21 // character
22 {regex: /'(?:[^'\\]|\\(?:[nrt0'"]|x[\da-fA-F]{2}|u\{[\da-fA-F]{6}\}))'/, token: "string-2"},
23 // byte
24 {regex: /b'(?:[^']|\\(?:['\\nrt0]|x[\da-fA-F]{2}))'/, token: "string-2"},
184 25
185 function stat_of(comb, tag) {
186 return cont(pushlex("stat", tag), comb, poplex, block);
187 }
188 function block(type) {
189 if (type == "}") return cont();
190 if (type == "let") return stat_of(letdef1, "let");
191 if (type == "fn") return stat_of(fndef);
192 if (type == "type") return cont(pushlex("stat"), tydef, endstatement, poplex, block);
193 if (type == "enum") return stat_of(enumdef);
194 if (type == "mod") return stat_of(mod);
195 if (type == "iface") return stat_of(iface);
196 if (type == "impl") return stat_of(impl);
197 if (type == "open-attr") return cont(pushlex("]"), commasep(expression, "]"), poplex);
198 if (type == "ignore" || type.match(/[\]\);,]/)) return cont(block);
199 return pass(pushlex("stat"), expression, poplex, endstatement, block);
200 }
201 function endstatement(type) {
202 if (type == ";") return cont();
203 return pass();
204 }
205 function expression(type) {
206 if (type == "atom" || type == "name") return cont(maybeop);
207 if (type == "{") return cont(pushlex("}"), exprbrace, poplex);
208 if (type.match(/[\[\(]/)) return matchBrackets(type, expression);
209 if (type.match(/[\]\)\};,]/)) return pass();
210 if (type == "if-style") return cont(expression, expression);
211 if (type == "else-style" || type == "op") return cont(expression);
212 if (type == "for") return cont(pattern, maybetype, inop, expression, expression);
213 if (type == "alt") return cont(expression, altbody);
214 if (type == "fn") return cont(fndef);
215 if (type == "macro") return cont(macro);
216 return cont();
217 }
218 function maybeop(type) {
219 if (content == ".") return cont(maybeprop);
220 if (content == "::<"){return cont(typarams, maybeop);}
221 if (type == "op" || content == ":") return cont(expression);
222 if (type == "(" || type == "[") return matchBrackets(type, expression);
223 return pass();
224 }
225 function maybeprop() {
226 if (content.match(/^\w+$/)) {cx.marked = "variable"; return cont(maybeop);}
227 return pass(expression);
228 }
229 function exprbrace(type) {
230 if (type == "op") {
231 if (content == "|") return cont(blockvars, poplex, pushlex("}", "block"), block);
232 if (content == "||") return cont(poplex, pushlex("}", "block"), block);
233 }
234 if (content == "mutable" || (content.match(/^\w+$/) && cx.stream.peek() == ":"
235 && !cx.stream.match("::", false)))
236 return pass(record_of(expression));
237 return pass(block);
238 }
239 function record_of(comb) {
240 function ro(type) {
241 if (content == "mutable" || content == "with") {cx.marked = "keyword"; return cont(ro);}
242 if (content.match(/^\w*$/)) {cx.marked = "variable"; return cont(ro);}
243 if (type == ":") return cont(comb, ro);
244 if (type == "}") return cont();
245 return cont(ro);
246 }
247 return ro;
248 }
249 function blockvars(type) {
250 if (type == "name") {cx.marked = "def"; return cont(blockvars);}
251 if (type == "op" && content == "|") return cont();
252 return cont(blockvars);
253 }
254
255 function letdef1(type) {
256 if (type.match(/[\]\)\};]/)) return cont();
257 if (content == "=") return cont(expression, letdef2);
258 if (type == ",") return cont(letdef1);
259 return pass(pattern, maybetype, letdef1);
260 }
261 function letdef2(type) {
262 if (type.match(/[\]\)\};,]/)) return pass(letdef1);
263 else return pass(expression, letdef2);
264 }
265 function maybetype(type) {
266 if (type == ":") return cont(typecx, rtype, valcx);
267 return pass();
268 }
269 function inop(type) {
270 if (type == "name" && content == "in") {cx.marked = "keyword"; return cont();}
271 return pass();
272 }
273 function fndef(type) {
274 if (content == "@" || content == "~") {cx.marked = "keyword"; return cont(fndef);}
275 if (type == "name") {cx.marked = "def"; return cont(fndef);}
276 if (content == "<") return cont(typarams, fndef);
277 if (type == "{") return pass(expression);
278 if (type == "(") return cont(pushlex(")"), commasep(argdef, ")"), poplex, fndef);
279 if (type == "->") return cont(typecx, rtype, valcx, fndef);
280 if (type == ";") return cont();
281 return cont(fndef);
282 }
283 function tydef(type) {
284 if (type == "name") {cx.marked = "def"; return cont(tydef);}
285 if (content == "<") return cont(typarams, tydef);
286 if (content == "=") return cont(typecx, rtype, valcx);
287 return cont(tydef);
288 }
289 function enumdef(type) {
290 if (type == "name") {cx.marked = "def"; return cont(enumdef);}
291 if (content == "<") return cont(typarams, enumdef);
292 if (content == "=") return cont(typecx, rtype, valcx, endstatement);
293 if (type == "{") return cont(pushlex("}"), typecx, enumblock, valcx, poplex);
294 return cont(enumdef);
295 }
296 function enumblock(type) {
297 if (type == "}") return cont();
298 if (type == "(") return cont(pushlex(")"), commasep(rtype, ")"), poplex, enumblock);
299 if (content.match(/^\w+$/)) cx.marked = "def";
300 return cont(enumblock);
301 }
302 function mod(type) {
303 if (type == "name") {cx.marked = "def"; return cont(mod);}
304 if (type == "{") return cont(pushlex("}"), block, poplex);
305 return pass();
306 }
307 function iface(type) {
308 if (type == "name") {cx.marked = "def"; return cont(iface);}
309 if (content == "<") return cont(typarams, iface);
310 if (type == "{") return cont(pushlex("}"), block, poplex);
311 return pass();
312 }
313 function impl(type) {
314 if (content == "<") return cont(typarams, impl);
315 if (content == "of" || content == "for") {cx.marked = "keyword"; return cont(rtype, impl);}
316 if (type == "name") {cx.marked = "def"; return cont(impl);}
317 if (type == "{") return cont(pushlex("}"), block, poplex);
318 return pass();
319 }
320 function typarams() {
321 if (content == ">") return cont();
322 if (content == ",") return cont(typarams);
323 if (content == ":") return cont(rtype, typarams);
324 return pass(rtype, typarams);
325 }
326 function argdef(type) {
327 if (type == "name") {cx.marked = "def"; return cont(argdef);}
328 if (type == ":") return cont(typecx, rtype, valcx);
329 return pass();
330 }
331 function rtype(type) {
332 if (type == "name") {cx.marked = "variable-3"; return cont(rtypemaybeparam); }
333 if (content == "mutable") {cx.marked = "keyword"; return cont(rtype);}
334 if (type == "atom") return cont(rtypemaybeparam);
335 if (type == "op" || type == "obj") return cont(rtype);
336 if (type == "fn") return cont(fntype);
337 if (type == "{") return cont(pushlex("{"), record_of(rtype), poplex);
338 return matchBrackets(type, rtype);
339 }
340 function rtypemaybeparam() {
341 if (content == "<") return cont(typarams);
342 return pass();
343 }
344 function fntype(type) {
345 if (type == "(") return cont(pushlex("("), commasep(rtype, ")"), poplex, fntype);
346 if (type == "->") return cont(rtype);
347 return pass();
348 }
349 function pattern(type) {
350 if (type == "name") {cx.marked = "def"; return cont(patternmaybeop);}
351 if (type == "atom") return cont(patternmaybeop);
352 if (type == "op") return cont(pattern);
353 if (type.match(/[\]\)\};,]/)) return pass();
354 return matchBrackets(type, pattern);
355 }
356 function patternmaybeop(type) {
357 if (type == "op" && content == ".") return cont();
358 if (content == "to") {cx.marked = "keyword"; return cont(pattern);}
359 else return pass();
360 }
361 function altbody(type) {
362 if (type == "{") return cont(pushlex("}", "alt"), altblock1, poplex);
363 return pass();
364 }
365 function altblock1(type) {
366 if (type == "}") return cont();
367 if (type == "|") return cont(altblock1);
368 if (content == "when") {cx.marked = "keyword"; return cont(expression, altblock2);}
369 if (type.match(/[\]\);,]/)) return cont(altblock1);
370 return pass(pattern, altblock2);
371 }
372 function altblock2(type) {
373 if (type == "{") return cont(pushlex("}", "alt"), block, poplex, altblock1);
374 else return pass(altblock1);
375 }
376
377 function macro(type) {
378 if (type.match(/[\[\(\{]/)) return matchBrackets(type, expression);
379 return pass();
380 }
381 function matchBrackets(type, comb) {
382 if (type == "[") return cont(pushlex("]"), commasep(comb, "]"), poplex);
383 if (type == "(") return cont(pushlex(")"), commasep(comb, ")"), poplex);
384 if (type == "{") return cont(pushlex("}"), commasep(comb, "}"), poplex);
385 return cont();
386 }
387
388 function parse(state, stream, style) {
389 var cc = state.cc;
390 // Communicate our context to the combinators.
391 // (Less wasteful than consing up a hundred closures on every call.)
392 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
393
394 while (true) {
395 var combinator = cc.length ? cc.pop() : block;
396 if (combinator(tcat)) {
397 while(cc.length && cc[cc.length - 1].lex)
398 cc.pop()();
399 return cx.marked || style;
400 }
401 }
402 }
403
404 return {
405 startState: function() {
406 return {
407 tokenize: tokenBase,
408 cc: [],
409 lexical: {indented: -indentUnit, column: 0, type: "top", align: false},
410 keywords: valKeywords,
411 indented: 0
412 };
413 },
414
415 token: function(stream, state) {
416 if (stream.sol()) {
417 if (!state.lexical.hasOwnProperty("align"))
418 state.lexical.align = false;
419 state.indented = stream.indentation();
420 }
421 if (stream.eatSpace()) return null;
422 tcat = content = null;
423 var style = state.tokenize(stream, state);
424 if (style == "comment") return style;
425 if (!state.lexical.hasOwnProperty("align"))
426 state.lexical.align = true;
427 if (tcat == "prefix") return style;
428 if (!content) content = stream.current();
429 return parse(state, stream, style);
430 },
431
432 indent: function(state, textAfter) {
433 if (state.tokenize != tokenBase) return 0;
434 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
435 type = lexical.type, closing = firstChar == type;
436 if (type == "stat") return lexical.indented + indentUnit;
437 if (lexical.align) return lexical.column + (closing ? 0 : 1);
438 return lexical.indented + (closing ? 0 : (lexical.info == "alt" ? altIndentUnit : indentUnit));
439 },
440
441 electricChars: "{}",
26 {regex: /(?:(?:[0-9][0-9_]*)(?:(?:[Ee][+-]?[0-9_]+)|\.[0-9_]+(?:[Ee][+-]?[0-9_]+)?)(?:f32|f64)?)|(?:0(?:b[01_]+|(?:o[0-7_]+)|(?:x[0-9a-fA-F_]+))|(?:[0-9][0-9_]*))(?:u8|u16|u32|u64|i8|i16|i32|i64|isize|usize)?/,
27 token: "number"},
28 {regex: /(let(?:\s+mut)?|fn|enum|mod|struct|type)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/, token: ["keyword", null, "def"]},
29 {regex: /(?:abstract|alignof|as|box|break|continue|const|crate|do|else|enum|extern|fn|for|final|if|impl|in|loop|macro|match|mod|move|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\b/, token: "keyword"},
30 {regex: /\b(?:Self|isize|usize|char|bool|u8|u16|u32|u64|f16|f32|f64|i8|i16|i32|i64|str|Option)\b/, token: "atom"},
31 {regex: /\b(?:true|false|Some|None|Ok|Err)\b/, token: "builtin"},
32 {regex: /\b(fn)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/,
33 token: ["keyword", null ,"def"]},
34 {regex: /#!?\[.*\]/, token: "meta"},
35 {regex: /\/\/.*/, token: "comment"},
36 {regex: /\/\*/, token: "comment", next: "comment"},
37 {regex: /[-+\/*=<>!]+/, token: "operator"},
38 {regex: /[a-zA-Z_]\w*!/,token: "variable-3"},
39 {regex: /[a-zA-Z_]\w*/, token: "variable"},
40 {regex: /[\{\[\(]/, indent: true},
41 {regex: /[\}\]\)]/, dedent: true}
42 ],
43 string: [
44 {regex: /"/, token: "string", next: "start"},
45 {regex: /(?:[^\\"]|\\(?:.|$))*/, token: "string"}
46 ],
47 string_raw: [
48 {regex: /"/, token: "string", next: "start"},
49 {regex: /[^"]*/, token: "string"}
50 ],
51 string_raw_hash: [
52 {regex: /"#+/, token: "string", next: "start"},
53 {regex: /(?:[^"]|"(?!#))*/, token: "string"}
54 ],
55 comment: [
56 {regex: /.*?\*\//, token: "comment", next: "start"},
57 {regex: /.*/, token: "comment"}
58 ],
59 meta: {
60 dontIndentStates: ["comment"],
61 electricInput: /^\s*\}$/,
442 62 blockCommentStart: "/*",
443 63 blockCommentEnd: "*/",
444 64 lineComment: "//",
445 65 fold: "brace"
446 };
66 }
447 67 });
448 68
69
449 70 CodeMirror.defineMIME("text/x-rustsrc", "rust");
450
451 71 });
@@ -1,174 +1,176 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode("sparql", function(config) {
15 15 var indentUnit = config.indentUnit;
16 16 var curPunc;
17 17
18 18 function wordRegexp(words) {
19 19 return new RegExp("^(?:" + words.join("|") + ")$", "i");
20 20 }
21 21 var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
22 22 "iri", "uri", "bnode", "count", "sum", "min", "max", "avg", "sample",
23 23 "group_concat", "rand", "abs", "ceil", "floor", "round", "concat", "substr", "strlen",
24 24 "replace", "ucase", "lcase", "encode_for_uri", "contains", "strstarts", "strends",
25 25 "strbefore", "strafter", "year", "month", "day", "hours", "minutes", "seconds",
26 26 "timezone", "tz", "now", "uuid", "struuid", "md5", "sha1", "sha256", "sha384",
27 27 "sha512", "coalesce", "if", "strlang", "strdt", "isnumeric", "regex", "exists",
28 28 "isblank", "isliteral", "a"]);
29 29 var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
30 30 "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
31 31 "graph", "by", "asc", "desc", "as", "having", "undef", "values", "group",
32 32 "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union",
33 33 "true", "false", "with",
34 34 "data", "copy", "to", "move", "add", "create", "drop", "clear", "load"]);
35 35 var operatorChars = /[*+\-<>=&|\^\/!\?]/;
36 36
37 37 function tokenBase(stream, state) {
38 38 var ch = stream.next();
39 39 curPunc = null;
40 40 if (ch == "$" || ch == "?") {
41 41 if(ch == "?" && stream.match(/\s/, false)){
42 42 return "operator";
43 43 }
44 44 stream.match(/^[\w\d]*/);
45 45 return "variable-2";
46 46 }
47 47 else if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) {
48 48 stream.match(/^[^\s\u00a0>]*>?/);
49 49 return "atom";
50 50 }
51 51 else if (ch == "\"" || ch == "'") {
52 52 state.tokenize = tokenLiteral(ch);
53 53 return state.tokenize(stream, state);
54 54 }
55 55 else if (/[{}\(\),\.;\[\]]/.test(ch)) {
56 56 curPunc = ch;
57 57 return "bracket";
58 58 }
59 59 else if (ch == "#") {
60 60 stream.skipToEnd();
61 61 return "comment";
62 62 }
63 63 else if (operatorChars.test(ch)) {
64 64 stream.eatWhile(operatorChars);
65 65 return "operator";
66 66 }
67 67 else if (ch == ":") {
68 68 stream.eatWhile(/[\w\d\._\-]/);
69 69 return "atom";
70 70 }
71 71 else if (ch == "@") {
72 72 stream.eatWhile(/[a-z\d\-]/i);
73 73 return "meta";
74 74 }
75 75 else {
76 76 stream.eatWhile(/[_\w\d]/);
77 77 if (stream.eat(":")) {
78 78 stream.eatWhile(/[\w\d_\-]/);
79 79 return "atom";
80 80 }
81 81 var word = stream.current();
82 82 if (ops.test(word))
83 83 return "builtin";
84 84 else if (keywords.test(word))
85 85 return "keyword";
86 86 else
87 87 return "variable";
88 88 }
89 89 }
90 90
91 91 function tokenLiteral(quote) {
92 92 return function(stream, state) {
93 93 var escaped = false, ch;
94 94 while ((ch = stream.next()) != null) {
95 95 if (ch == quote && !escaped) {
96 96 state.tokenize = tokenBase;
97 97 break;
98 98 }
99 99 escaped = !escaped && ch == "\\";
100 100 }
101 101 return "string";
102 102 };
103 103 }
104 104
105 105 function pushContext(state, type, col) {
106 106 state.context = {prev: state.context, indent: state.indent, col: col, type: type};
107 107 }
108 108 function popContext(state) {
109 109 state.indent = state.context.indent;
110 110 state.context = state.context.prev;
111 111 }
112 112
113 113 return {
114 114 startState: function() {
115 115 return {tokenize: tokenBase,
116 116 context: null,
117 117 indent: 0,
118 118 col: 0};
119 119 },
120 120
121 121 token: function(stream, state) {
122 122 if (stream.sol()) {
123 123 if (state.context && state.context.align == null) state.context.align = false;
124 124 state.indent = stream.indentation();
125 125 }
126 126 if (stream.eatSpace()) return null;
127 127 var style = state.tokenize(stream, state);
128 128
129 129 if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") {
130 130 state.context.align = true;
131 131 }
132 132
133 133 if (curPunc == "(") pushContext(state, ")", stream.column());
134 134 else if (curPunc == "[") pushContext(state, "]", stream.column());
135 135 else if (curPunc == "{") pushContext(state, "}", stream.column());
136 136 else if (/[\]\}\)]/.test(curPunc)) {
137 137 while (state.context && state.context.type == "pattern") popContext(state);
138 138 if (state.context && curPunc == state.context.type) popContext(state);
139 139 }
140 140 else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state);
141 141 else if (/atom|string|variable/.test(style) && state.context) {
142 142 if (/[\}\]]/.test(state.context.type))
143 143 pushContext(state, "pattern", stream.column());
144 144 else if (state.context.type == "pattern" && !state.context.align) {
145 145 state.context.align = true;
146 146 state.context.col = stream.column();
147 147 }
148 148 }
149 149
150 150 return style;
151 151 },
152 152
153 153 indent: function(state, textAfter) {
154 154 var firstChar = textAfter && textAfter.charAt(0);
155 155 var context = state.context;
156 156 if (/[\]\}]/.test(firstChar))
157 157 while (context && context.type == "pattern") context = context.prev;
158 158
159 159 var closing = context && firstChar == context.type;
160 160 if (!context)
161 161 return 0;
162 162 else if (context.type == "pattern")
163 163 return context.col;
164 164 else if (context.align)
165 165 return context.col + (closing ? 0 : 1);
166 166 else
167 167 return context.indent + (closing ? 0 : indentUnit);
168 }
168 },
169
170 lineComment: "#"
169 171 };
170 172 });
171 173
172 174 CodeMirror.defineMIME("application/sparql-query", "sparql");
173 175
174 176 });
@@ -1,391 +1,391 b''
1 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 4 (function(mod) {
5 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 6 mod(require("../../lib/codemirror"));
7 7 else if (typeof define == "function" && define.amd) // AMD
8 8 define(["../../lib/codemirror"], mod);
9 9 else // Plain browser env
10 10 mod(CodeMirror);
11 11 })(function(CodeMirror) {
12 12 "use strict";
13 13
14 14 CodeMirror.defineMode("sql", function(config, parserConfig) {
15 15 "use strict";
16 16
17 17 var client = parserConfig.client || {},
18 18 atoms = parserConfig.atoms || {"false": true, "true": true, "null": true},
19 19 builtin = parserConfig.builtin || {},
20 20 keywords = parserConfig.keywords || {},
21 21 operatorChars = parserConfig.operatorChars || /^[*+\-%<>!=&|~^]/,
22 22 support = parserConfig.support || {},
23 23 hooks = parserConfig.hooks || {},
24 24 dateSQL = parserConfig.dateSQL || {"date" : true, "time" : true, "timestamp" : true};
25 25
26 26 function tokenBase(stream, state) {
27 27 var ch = stream.next();
28 28
29 29 // call hooks from the mime type
30 30 if (hooks[ch]) {
31 31 var result = hooks[ch](stream, state);
32 32 if (result !== false) return result;
33 33 }
34 34
35 35 if (support.hexNumber == true &&
36 36 ((ch == "0" && stream.match(/^[xX][0-9a-fA-F]+/))
37 37 || (ch == "x" || ch == "X") && stream.match(/^'[0-9a-fA-F]+'/))) {
38 38 // hex
39 39 // ref: http://dev.mysql.com/doc/refman/5.5/en/hexadecimal-literals.html
40 40 return "number";
41 41 } else if (support.binaryNumber == true &&
42 42 (((ch == "b" || ch == "B") && stream.match(/^'[01]+'/))
43 43 || (ch == "0" && stream.match(/^b[01]+/)))) {
44 44 // bitstring
45 45 // ref: http://dev.mysql.com/doc/refman/5.5/en/bit-field-literals.html
46 46 return "number";
47 47 } else if (ch.charCodeAt(0) > 47 && ch.charCodeAt(0) < 58) {
48 48 // numbers
49 49 // ref: http://dev.mysql.com/doc/refman/5.5/en/number-literals.html
50 50 stream.match(/^[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/);
51 51 support.decimallessFloat == true && stream.eat('.');
52 52 return "number";
53 53 } else if (ch == "?" && (stream.eatSpace() || stream.eol() || stream.eat(";"))) {
54 54 // placeholders
55 55 return "variable-3";
56 56 } else if (ch == "'" || (ch == '"' && support.doubleQuote)) {
57 57 // strings
58 58 // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
59 59 state.tokenize = tokenLiteral(ch);
60 60 return state.tokenize(stream, state);
61 61 } else if ((((support.nCharCast == true && (ch == "n" || ch == "N"))
62 62 || (support.charsetCast == true && ch == "_" && stream.match(/[a-z][a-z0-9]*/i)))
63 63 && (stream.peek() == "'" || stream.peek() == '"'))) {
64 64 // charset casting: _utf8'str', N'str', n'str'
65 65 // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
66 66 return "keyword";
67 67 } else if (/^[\(\),\;\[\]]/.test(ch)) {
68 68 // no highlightning
69 69 return null;
70 70 } else if (support.commentSlashSlash && ch == "/" && stream.eat("/")) {
71 71 // 1-line comment
72 72 stream.skipToEnd();
73 73 return "comment";
74 74 } else if ((support.commentHash && ch == "#")
75 75 || (ch == "-" && stream.eat("-") && (!support.commentSpaceRequired || stream.eat(" ")))) {
76 76 // 1-line comments
77 77 // ref: https://kb.askmonty.org/en/comment-syntax/
78 78 stream.skipToEnd();
79 79 return "comment";
80 80 } else if (ch == "/" && stream.eat("*")) {
81 81 // multi-line comments
82 82 // ref: https://kb.askmonty.org/en/comment-syntax/
83 83 state.tokenize = tokenComment;
84 84 return state.tokenize(stream, state);
85 85 } else if (ch == ".") {
86 86 // .1 for 0.1
87 87 if (support.zerolessFloat == true && stream.match(/^(?:\d+(?:e[+-]?\d+)?)/i)) {
88 88 return "number";
89 89 }
90 90 // .table_name (ODBC)
91 91 // // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
92 92 if (support.ODBCdotTable == true && stream.match(/^[a-zA-Z_]+/)) {
93 93 return "variable-2";
94 94 }
95 95 } else if (operatorChars.test(ch)) {
96 96 // operators
97 97 stream.eatWhile(operatorChars);
98 98 return null;
99 99 } else if (ch == '{' &&
100 100 (stream.match(/^( )*(d|D|t|T|ts|TS)( )*'[^']*'( )*}/) || stream.match(/^( )*(d|D|t|T|ts|TS)( )*"[^"]*"( )*}/))) {
101 101 // dates (weird ODBC syntax)
102 102 // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
103 103 return "number";
104 104 } else {
105 105 stream.eatWhile(/^[_\w\d]/);
106 106 var word = stream.current().toLowerCase();
107 107 // dates (standard SQL syntax)
108 108 // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
109 109 if (dateSQL.hasOwnProperty(word) && (stream.match(/^( )+'[^']*'/) || stream.match(/^( )+"[^"]*"/)))
110 110 return "number";
111 111 if (atoms.hasOwnProperty(word)) return "atom";
112 112 if (builtin.hasOwnProperty(word)) return "builtin";
113 113 if (keywords.hasOwnProperty(word)) return "keyword";
114 114 if (client.hasOwnProperty(word)) return "string-2";
115 115 return null;
116 116 }
117 117 }
118 118
119 119 // 'string', with char specified in quote escaped by '\'
120 120 function tokenLiteral(quote) {
121 121 return function(stream, state) {
122 122 var escaped = false, ch;
123 123 while ((ch = stream.next()) != null) {
124 124 if (ch == quote && !escaped) {
125 125 state.tokenize = tokenBase;
126 126 break;
127 127 }
128 128 escaped = !escaped && ch == "\\";
129 129 }
130 130 return "string";
131 131 };
132 132 }
133 133 function tokenComment(stream, state) {
134 134 while (true) {
135 135 if (stream.skipTo("*")) {
136 136 stream.next();
137 137 if (stream.eat("/")) {
138 138 state.tokenize = tokenBase;
139 139 break;
140 140 }
141 141 } else {
142 142 stream.skipToEnd();
143 143 break;
144 144 }
145 145 }
146 146 return "comment";
147 147 }
148 148
149 149 function pushContext(stream, state, type) {
150 150 state.context = {
151 151 prev: state.context,
152 152 indent: stream.indentation(),
153 153 col: stream.column(),
154 154 type: type
155 155 };
156 156 }
157 157
158 158 function popContext(state) {
159 159 state.indent = state.context.indent;
160 160 state.context = state.context.prev;
161 161 }
162 162
163 163 return {
164 164 startState: function() {
165 165 return {tokenize: tokenBase, context: null};
166 166 },
167 167
168 168 token: function(stream, state) {
169 169 if (stream.sol()) {
170 170 if (state.context && state.context.align == null)
171 171 state.context.align = false;
172 172 }
173 173 if (stream.eatSpace()) return null;
174 174
175 175 var style = state.tokenize(stream, state);
176 176 if (style == "comment") return style;
177 177
178 178 if (state.context && state.context.align == null)
179 179 state.context.align = true;
180 180
181 181 var tok = stream.current();
182 182 if (tok == "(")
183 183 pushContext(stream, state, ")");
184 184 else if (tok == "[")
185 185 pushContext(stream, state, "]");
186 186 else if (state.context && state.context.type == tok)
187 187 popContext(state);
188 188 return style;
189 189 },
190 190
191 191 indent: function(state, textAfter) {
192 192 var cx = state.context;
193 193 if (!cx) return CodeMirror.Pass;
194 194 var closing = textAfter.charAt(0) == cx.type;
195 195 if (cx.align) return cx.col + (closing ? 0 : 1);
196 196 else return cx.indent + (closing ? 0 : config.indentUnit);
197 197 },
198 198
199 199 blockCommentStart: "/*",
200 200 blockCommentEnd: "*/",
201 201 lineComment: support.commentSlashSlash ? "//" : support.commentHash ? "#" : null
202 202 };
203 203 });
204 204
205 205 (function() {
206 206 "use strict";
207 207
208 208 // `identifier`
209 209 function hookIdentifier(stream) {
210 210 // MySQL/MariaDB identifiers
211 211 // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
212 212 var ch;
213 213 while ((ch = stream.next()) != null) {
214 214 if (ch == "`" && !stream.eat("`")) return "variable-2";
215 215 }
216 216 stream.backUp(stream.current().length - 1);
217 217 return stream.eatWhile(/\w/) ? "variable-2" : null;
218 218 }
219 219
220 220 // variable token
221 221 function hookVar(stream) {
222 222 // variables
223 223 // @@prefix.varName @varName
224 224 // varName can be quoted with ` or ' or "
225 225 // ref: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
226 226 if (stream.eat("@")) {
227 227 stream.match(/^session\./);
228 228 stream.match(/^local\./);
229 229 stream.match(/^global\./);
230 230 }
231 231
232 232 if (stream.eat("'")) {
233 233 stream.match(/^.*'/);
234 234 return "variable-2";
235 235 } else if (stream.eat('"')) {
236 236 stream.match(/^.*"/);
237 237 return "variable-2";
238 238 } else if (stream.eat("`")) {
239 239 stream.match(/^.*`/);
240 240 return "variable-2";
241 241 } else if (stream.match(/^[0-9a-zA-Z$\.\_]+/)) {
242 242 return "variable-2";
243 243 }
244 244 return null;
245 245 };
246 246
247 247 // short client keyword token
248 248 function hookClient(stream) {
249 249 // \N means NULL
250 250 // ref: http://dev.mysql.com/doc/refman/5.5/en/null-values.html
251 251 if (stream.eat("N")) {
252 252 return "atom";
253 253 }
254 254 // \g, etc
255 255 // ref: http://dev.mysql.com/doc/refman/5.5/en/mysql-commands.html
256 256 return stream.match(/^[a-zA-Z.#!?]/) ? "variable-2" : null;
257 257 }
258 258
259 259 // these keywords are used by all SQL dialects (however, a mode can still overwrite it)
260 var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where ";
260 var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where limit";
261 261
262 262 // turn a space-separated list into an array
263 263 function set(str) {
264 264 var obj = {}, words = str.split(" ");
265 265 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
266 266 return obj;
267 267 }
268 268
269 269 // A generic SQL Mode. It's not a standard, it just try to support what is generally supported
270 270 CodeMirror.defineMIME("text/x-sql", {
271 271 name: "sql",
272 272 keywords: set(sqlKeywords + "begin"),
273 273 builtin: set("bool boolean bit blob enum long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision real date datetime year unsigned signed decimal numeric"),
274 274 atoms: set("false true null unknown"),
275 275 operatorChars: /^[*+\-%<>!=]/,
276 276 dateSQL: set("date time timestamp"),
277 277 support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
278 278 });
279 279
280 280 CodeMirror.defineMIME("text/x-mssql", {
281 281 name: "sql",
282 282 client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
283 283 keywords: set(sqlKeywords + "begin trigger proc view index for add constraint key primary foreign collate clustered nonclustered declare"),
284 284 builtin: set("bigint numeric bit smallint decimal smallmoney int tinyint money float real char varchar text nchar nvarchar ntext binary varbinary image cursor timestamp hierarchyid uniqueidentifier sql_variant xml table "),
285 285 atoms: set("false true null unknown"),
286 286 operatorChars: /^[*+\-%<>!=]/,
287 287 dateSQL: set("date datetimeoffset datetime2 smalldatetime datetime time"),
288 288 hooks: {
289 289 "@": hookVar
290 290 }
291 291 });
292 292
293 293 CodeMirror.defineMIME("text/x-mysql", {
294 294 name: "sql",
295 295 client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
296 296 keywords: set(sqlKeywords + "accessible action add after algorithm all analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general get global grant grants group group_concat handler hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show signal slave slow smallint snapshot soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),
297 297 builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"),
298 298 atoms: set("false true null unknown"),
299 299 operatorChars: /^[*+\-%<>!=&|^]/,
300 300 dateSQL: set("date time timestamp"),
301 301 support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
302 302 hooks: {
303 303 "@": hookVar,
304 304 "`": hookIdentifier,
305 305 "\\": hookClient
306 306 }
307 307 });
308 308
309 309 CodeMirror.defineMIME("text/x-mariadb", {
310 310 name: "sql",
311 311 client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
312 312 keywords: set(sqlKeywords + "accessible action add after algorithm all always analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general generated get global grant grants group groupby_concat handler hard hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password persistent phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show shutdown signal slave slow smallint snapshot soft soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views virtual warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),
313 313 builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"),
314 314 atoms: set("false true null unknown"),
315 315 operatorChars: /^[*+\-%<>!=&|^]/,
316 316 dateSQL: set("date time timestamp"),
317 317 support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
318 318 hooks: {
319 319 "@": hookVar,
320 320 "`": hookIdentifier,
321 321 "\\": hookClient
322 322 }
323 323 });
324 324
325 325 // the query language used by Apache Cassandra is called CQL, but this mime type
326 326 // is called Cassandra to avoid confusion with Contextual Query Language
327 327 CodeMirror.defineMIME("text/x-cassandra", {
328 328 name: "sql",
329 329 client: { },
330 330 keywords: set("add all allow alter and any apply as asc authorize batch begin by clustering columnfamily compact consistency count create custom delete desc distinct drop each_quorum exists filtering from grant if in index insert into key keyspace keyspaces level limit local_one local_quorum modify nan norecursive nosuperuser not of on one order password permission permissions primary quorum rename revoke schema select set storage superuser table three to token truncate ttl two type unlogged update use user users using values where with writetime"),
331 331 builtin: set("ascii bigint blob boolean counter decimal double float frozen inet int list map static text timestamp timeuuid tuple uuid varchar varint"),
332 332 atoms: set("false true infinity NaN"),
333 333 operatorChars: /^[<>=]/,
334 334 dateSQL: { },
335 335 support: set("commentSlashSlash decimallessFloat"),
336 336 hooks: { }
337 337 });
338 338
339 339 // this is based on Peter Raganitsch's 'plsql' mode
340 340 CodeMirror.defineMIME("text/x-plsql", {
341 341 name: "sql",
342 342 client: set("appinfo arraysize autocommit autoprint autorecovery autotrace blockterminator break btitle cmdsep colsep compatibility compute concat copycommit copytypecheck define describe echo editfile embedded escape exec execute feedback flagger flush heading headsep instance linesize lno loboffset logsource long longchunksize markup native newpage numformat numwidth pagesize pause pno recsep recsepchar release repfooter repheader serveroutput shiftinout show showmode size spool sqlblanklines sqlcase sqlcode sqlcontinue sqlnumber sqlpluscompatibility sqlprefix sqlprompt sqlterminator suffix tab term termout time timing trimout trimspool ttitle underline verify version wrap"),
343 343 keywords: set("abort accept access add all alter and any array arraylen as asc assert assign at attributes audit authorization avg base_table begin between binary_integer body boolean by case cast char char_base check close cluster clusters colauth column comment commit compress connect connected constant constraint crash create current currval cursor data_base database date dba deallocate debugoff debugon decimal declare default definition delay delete desc digits dispose distinct do drop else elseif elsif enable end entry escape exception exception_init exchange exclusive exists exit external fast fetch file for force form from function generic goto grant group having identified if immediate in increment index indexes indicator initial initrans insert interface intersect into is key level library like limited local lock log logging long loop master maxextents maxtrans member minextents minus mislabel mode modify multiset new next no noaudit nocompress nologging noparallel not nowait number_base object of off offline on online only open option or order out package parallel partition pctfree pctincrease pctused pls_integer positive positiven pragma primary prior private privileges procedure public raise range raw read rebuild record ref references refresh release rename replace resource restrict return returning returns reverse revoke rollback row rowid rowlabel rownum rows run savepoint schema segment select separate session set share snapshot some space split sql start statement storage subtype successful synonym tabauth table tables tablespace task terminate then to trigger truncate type union unique unlimited unrecoverable unusable update use using validate value values variable view views when whenever where while with work"),
344 344 builtin: set("abs acos add_months ascii asin atan atan2 average bfile bfilename bigserial bit blob ceil character chartorowid chr clob concat convert cos cosh count dec decode deref dual dump dup_val_on_index empty error exp false float floor found glb greatest hextoraw initcap instr instrb int integer isopen last_day least lenght lenghtb ln lower lpad ltrim lub make_ref max min mlslabel mod months_between natural naturaln nchar nclob new_time next_day nextval nls_charset_decl_len nls_charset_id nls_charset_name nls_initcap nls_lower nls_sort nls_upper nlssort no_data_found notfound null number numeric nvarchar2 nvl others power rawtohex real reftohex round rowcount rowidtochar rowtype rpad rtrim serial sign signtype sin sinh smallint soundex sqlcode sqlerrm sqrt stddev string substr substrb sum sysdate tan tanh to_char text to_date to_label to_multi_byte to_number to_single_byte translate true trunc uid unlogged upper user userenv varchar varchar2 variance varying vsize xml"),
345 345 operatorChars: /^[*+\-%<>!=~]/,
346 346 dateSQL: set("date time timestamp"),
347 347 support: set("doubleQuote nCharCast zerolessFloat binaryNumber hexNumber")
348 348 });
349 349
350 350 // Created to support specific hive keywords
351 351 CodeMirror.defineMIME("text/x-hive", {
352 352 name: "sql",
353 353 keywords: set("select alter $elem$ $key$ $value$ add after all analyze and archive as asc before between binary both bucket buckets by cascade case cast change cluster clustered clusterstatus collection column columns comment compute concatenate continue create cross cursor data database databases dbproperties deferred delete delimited desc describe directory disable distinct distribute drop else enable end escaped exclusive exists explain export extended external false fetch fields fileformat first format formatted from full function functions grant group having hold_ddltime idxproperties if import in index indexes inpath inputdriver inputformat insert intersect into is items join keys lateral left like limit lines load local location lock locks mapjoin materialized minus msck no_drop nocompress not of offline on option or order out outer outputdriver outputformat overwrite partition partitioned partitions percent plus preserve procedure purge range rcfile read readonly reads rebuild recordreader recordwriter recover reduce regexp rename repair replace restrict revoke right rlike row schema schemas semi sequencefile serde serdeproperties set shared show show_database sort sorted ssl statistics stored streamtable table tables tablesample tblproperties temporary terminated textfile then tmp to touch transform trigger true unarchive undo union uniquejoin unlock update use using utc utc_tmestamp view when where while with"),
354 354 builtin: set("bool boolean long timestamp tinyint smallint bigint int float double date datetime unsigned string array struct map uniontype"),
355 355 atoms: set("false true null unknown"),
356 356 operatorChars: /^[*+\-%<>!=]/,
357 357 dateSQL: set("date timestamp"),
358 358 support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
359 359 });
360 360 }());
361 361
362 362 });
363 363
364 364 /*
365 365 How Properties of Mime Types are used by SQL Mode
366 366 =================================================
367 367
368 368 keywords:
369 369 A list of keywords you want to be highlighted.
370 370 builtin:
371 371 A list of builtin types you want to be highlighted (if you want types to be of class "builtin" instead of "keyword").
372 372 operatorChars:
373 373 All characters that must be handled as operators.
374 374 client:
375 375 Commands parsed and executed by the client (not the server).
376 376 support:
377 377 A list of supported syntaxes which are not common, but are supported by more than 1 DBMS.
378 378 * ODBCdotTable: .tableName
379 379 * zerolessFloat: .1
380 380 * doubleQuote
381 381 * nCharCast: N'string'
382 382 * charsetCast: _utf8'string'
383 383 * commentHash: use # char for comments
384 384 * commentSlashSlash: use // for comments
385 385 * commentSpaceRequired: require a space after -- for comments
386 386 atoms:
387 387 Keywords that must be highlighted as atoms,. Some DBMS's support more atoms than others:
388 388 UNKNOWN, INFINITY, UNDERFLOW, NaN...
389 389 dateSQL:
390 390 Used for date/time SQL standard syntax, because not all DBMS's support same temporal types.
391 391 */
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now