##// 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 /* BASICS */
1 /* BASICS */
2
2
3 .CodeMirror {
3 .CodeMirror {
4 /* Set height, width, borders, and global font properties here */
4 /* Set height, width, borders, and global font properties here */
5 font-family: monospace;
5 font-family: monospace;
6 height: 300px;
6 height: 300px;
7 color: black;
7 color: black;
8 border-radius: @border-radius;
8 border-radius: @border-radius;
9 border: @border-thickness solid @grey6;
9 border: @border-thickness solid @grey6;
10 margin: 0 0 @padding;
10 margin: 0 0 @padding;
11 }
11 }
12
12
13 /* PADDING */
13 /* PADDING */
14
14
15 .CodeMirror-lines {
15 .CodeMirror-lines {
16 padding: 4px 0; /* Vertical padding around content */
16 padding: 4px 0; /* Vertical padding around content */
17 }
17 }
18 .CodeMirror pre {
18 .CodeMirror pre {
19 padding: 0 4px; /* Horizontal padding of content */
19 padding: 0 4px; /* Horizontal padding of content */
20 }
20 }
21
21
22 .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
22 .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
23 background-color: white; /* The little square between H and V scrollbars */
23 background-color: white; /* The little square between H and V scrollbars */
24 }
24 }
25
25
26 /* GUTTER */
26 /* GUTTER */
27
27
28 .CodeMirror-gutters {
28 .CodeMirror-gutters {
29 border-right: 1px solid #ddd;
29 border-right: 1px solid #ddd;
30 background-color: @grey6;
30 background-color: @grey6;
31 white-space: nowrap;
31 white-space: nowrap;
32 }
32 }
33 .CodeMirror-linenumbers {}
33 .CodeMirror-linenumbers {}
34 .CodeMirror-linenumber {
34 .CodeMirror-linenumber {
35 padding: 0 3px 0 5px;
35 padding: 0 3px 0 5px;
36 min-width: 20px;
36 min-width: 20px;
37 text-align: right;
37 text-align: right;
38 color: @grey4;
38 color: @grey4;
39 white-space: nowrap;
39 white-space: nowrap;
40 }
40 }
41
41
42 .CodeMirror-guttermarker { color: black; }
42 .CodeMirror-guttermarker { color: black; }
43 .CodeMirror-guttermarker-subtle { color: #999; }
43 .CodeMirror-guttermarker-subtle { color: #999; }
44
44
45 /* CURSOR */
45 /* CURSOR */
46
46
47 .CodeMirror div.CodeMirror-cursor {
47 .CodeMirror div.CodeMirror-cursor {
48 border-left: 1px solid black;
48 border-left: 1px solid black;
49 }
49 }
50 /* Shown when moving in bi-directional text */
50 /* Shown when moving in bi-directional text */
51 .CodeMirror div.CodeMirror-secondarycursor {
51 .CodeMirror div.CodeMirror-secondarycursor {
52 border-left: 1px solid silver;
52 border-left: 1px solid silver;
53 }
53 }
54 .CodeMirror.cm-fat-cursor div.CodeMirror-cursor {
54 .CodeMirror.cm-fat-cursor div.CodeMirror-cursor {
55 width: auto;
55 width: auto;
56 border: 0;
56 border: 0;
57 background: @grey6;
57 background: @grey6;
58 }
58 }
59 .CodeMirror.cm-fat-cursor div.CodeMirror-cursors {
59 .CodeMirror.cm-fat-cursor div.CodeMirror-cursors {
60 z-index: 1;
60 z-index: 1;
61 }
61 }
62
62
63 .cm-animate-fat-cursor {
63 .cm-animate-fat-cursor {
64 width: auto;
64 width: auto;
65 border: 0;
65 border: 0;
66 -webkit-animation: blink 1.06s steps(1) infinite;
66 -webkit-animation: blink 1.06s steps(1) infinite;
67 -moz-animation: blink 1.06s steps(1) infinite;
67 -moz-animation: blink 1.06s steps(1) infinite;
68 animation: blink 1.06s steps(1) infinite;
68 animation: blink 1.06s steps(1) infinite;
69 }
69 }
70 @-moz-keyframes blink {
70 @-moz-keyframes blink {
71 0% { background: #7e7; }
71 0% { background: #7e7; }
72 50% { background: none; }
72 50% { background: none; }
73 100% { background: #7e7; }
73 100% { background: #7e7; }
74 }
74 }
75 @-webkit-keyframes blink {
75 @-webkit-keyframes blink {
76 0% { background: #7e7; }
76 0% { background: #7e7; }
77 50% { background: none; }
77 50% { background: none; }
78 100% { background: #7e7; }
78 100% { background: #7e7; }
79 }
79 }
80 @keyframes blink {
80 @keyframes blink {
81 0% { background: #7e7; }
81 0% { background: #7e7; }
82 50% { background: none; }
82 50% { background: none; }
83 100% { background: #7e7; }
83 100% { background: #7e7; }
84 }
84 }
85
85
86 /* Can style cursor different in overwrite (non-insert) mode */
86 /* Can style cursor different in overwrite (non-insert) mode */
87 div.CodeMirror-overwrite div.CodeMirror-cursor {}
87 div.CodeMirror-overwrite div.CodeMirror-cursor {}
88
88
89 .cm-tab { display: inline-block; text-decoration: inherit; }
89 .cm-tab { display: inline-block; text-decoration: inherit; }
90
90
91 .CodeMirror-ruler {
91 .CodeMirror-ruler {
92 border-left: 1px solid #ccc;
92 border-left: 1px solid #ccc;
93 position: absolute;
93 position: absolute;
94 }
94 }
95
95
96 /* DEFAULT THEME */
96 /* DEFAULT THEME */
97
97
98 .cm-s-default .cm-header {color: blue;}
98 .cm-s-default .cm-header {color: blue;}
99 .cm-s-default .cm-quote {color: #090;}
99 .cm-s-default .cm-quote {color: #090;}
100 .cm-negative {color: #d44;}
100 .cm-negative {color: #d44;}
101 .cm-positive {color: #292;}
101 .cm-positive {color: #292;}
102 .cm-header, .cm-strong {font-weight: bold;}
102 .cm-header, .cm-strong {font-weight: bold;}
103 .cm-em {font-style: italic;}
103 .cm-em {font-style: italic;}
104 .cm-link {text-decoration: underline;}
104 .cm-link {text-decoration: underline;}
105 .cm-strikethrough {text-decoration: line-through;}
105 .cm-strikethrough {text-decoration: line-through;}
106
106
107 .cm-s-default .cm-keyword {color: #708;}
107 .cm-s-default .cm-keyword {color: #708;}
108 .cm-s-default .cm-atom {color: #219;}
108 .cm-s-default .cm-atom {color: #219;}
109 .cm-s-default .cm-number {color: #164;}
109 .cm-s-default .cm-number {color: #164;}
110 .cm-s-default .cm-def {color: #00f;}
110 .cm-s-default .cm-def {color: #00f;}
111 .cm-s-default .cm-variable,
111 .cm-s-default .cm-variable,
112 .cm-s-default .cm-punctuation,
112 .cm-s-default .cm-punctuation,
113 .cm-s-default .cm-property,
113 .cm-s-default .cm-property,
114 .cm-s-default .cm-operator {}
114 .cm-s-default .cm-operator {}
115 .cm-s-default .cm-variable-2 {color: #05a;}
115 .cm-s-default .cm-variable-2 {color: #05a;}
116 .cm-s-default .cm-variable-3 {color: #085;}
116 .cm-s-default .cm-variable-3 {color: #085;}
117 .cm-s-default .cm-comment {color: #a50;}
117 .cm-s-default .cm-comment {color: #a50;}
118 .cm-s-default .cm-string {color: #a11;}
118 .cm-s-default .cm-string {color: #a11;}
119 .cm-s-default .cm-string-2 {color: #f50;}
119 .cm-s-default .cm-string-2 {color: #f50;}
120 .cm-s-default .cm-meta {color: #555;}
120 .cm-s-default .cm-meta {color: #555;}
121 .cm-s-default .cm-qualifier {color: #555;}
121 .cm-s-default .cm-qualifier {color: #555;}
122 .cm-s-default .cm-builtin {color: #30a;}
122 .cm-s-default .cm-builtin {color: #30a;}
123 .cm-s-default .cm-bracket {color: #997;}
123 .cm-s-default .cm-bracket {color: #997;}
124 .cm-s-default .cm-tag {color: #170;}
124 .cm-s-default .cm-tag {color: #170;}
125 .cm-s-default .cm-attribute {color: #00c;}
125 .cm-s-default .cm-attribute {color: #00c;}
126 .cm-s-default .cm-hr {color: #999;}
126 .cm-s-default .cm-hr {color: #999;}
127 .cm-s-default .cm-link {color: #00c;}
127 .cm-s-default .cm-link {color: #00c;}
128
128
129 .cm-s-default .cm-error {color: #f00;}
129 .cm-s-default .cm-error {color: #f00;}
130 .cm-invalidchar {color: #f00;}
130 .cm-invalidchar {color: #f00;}
131
131
132 .CodeMirror-composing { border-bottom: 2px solid; }
132 .CodeMirror-composing { border-bottom: 2px solid; }
133
133
134 /* Default styles for common addons */
134 /* Default styles for common addons */
135
135
136 div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
136 div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
137 div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
137 div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
138 .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
138 .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
139 .CodeMirror-activeline-background {background: #e8f2ff;}
139 .CodeMirror-activeline-background {background: #e8f2ff;}
140
140
141 /* STOP */
141 /* STOP */
142
142
143 /* The rest of this file contains styles related to the mechanics of
143 /* The rest of this file contains styles related to the mechanics of
144 the editor. You probably shouldn't touch them. */
144 the editor. You probably shouldn't touch them. */
145
145
146 .CodeMirror {
146 .CodeMirror {
147 position: relative;
147 position: relative;
148 overflow: hidden;
148 overflow: hidden;
149 background: white;
149 background: white;
150 }
150 }
151
151
152 .CodeMirror-scroll {
152 .CodeMirror-scroll {
153 overflow: scroll !important; /* Things will break if this is overridden */
153 overflow: scroll !important; /* Things will break if this is overridden */
154 /* 30px is the magic margin used to hide the element's real scrollbars */
154 /* 30px is the magic margin used to hide the element's real scrollbars */
155 /* See overflow: hidden in .CodeMirror */
155 /* See overflow: hidden in .CodeMirror */
156 margin-bottom: -30px; margin-right: -30px;
156 margin-bottom: -30px; margin-right: -30px;
157 padding-bottom: 30px;
157 padding-bottom: 30px;
158 height: 100%;
158 height: 100%;
159 outline: none; /* Prevent dragging from highlighting the element */
159 outline: none; /* Prevent dragging from highlighting the element */
160 position: relative;
160 position: relative;
161 }
161 }
162 .CodeMirror-sizer {
162 .CodeMirror-sizer {
163 position: relative;
163 position: relative;
164 border-right: 30px solid transparent;
164 border-right: 30px solid transparent;
165 }
165 }
166
166
167 /* The fake, visible scrollbars. Used to force redraw during scrolling
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 flickering artifacts. */
169 flickering artifacts. */
170 .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
170 .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
171 position: absolute;
171 position: absolute;
172 z-index: 6;
172 z-index: 6;
173 display: none;
173 display: none;
174 }
174 }
175 .CodeMirror-vscrollbar {
175 .CodeMirror-vscrollbar {
176 right: 0; top: 0;
176 right: 0; top: 0;
177 overflow-x: hidden;
177 overflow-x: hidden;
178 overflow-y: scroll;
178 overflow-y: scroll;
179 }
179 }
180 .CodeMirror-hscrollbar {
180 .CodeMirror-hscrollbar {
181 bottom: 0; left: 0;
181 bottom: 0; left: 0;
182 overflow-y: hidden;
182 overflow-y: hidden;
183 overflow-x: scroll;
183 overflow-x: scroll;
184 }
184 }
185 .CodeMirror-scrollbar-filler {
185 .CodeMirror-scrollbar-filler {
186 right: 0; bottom: 0;
186 right: 0; bottom: 0;
187 }
187 }
188 .CodeMirror-gutter-filler {
188 .CodeMirror-gutter-filler {
189 left: 0; bottom: 0;
189 left: 0; bottom: 0;
190 }
190 }
191
191
192 .CodeMirror-gutters {
192 .CodeMirror-gutters {
193 position: absolute; left: 0; top: 0;
193 position: absolute; left: 0; top: 0;
194 z-index: 3;
194 z-index: 3;
195 }
195 }
196 .CodeMirror-gutter {
196 .CodeMirror-gutter {
197 white-space: normal;
197 white-space: normal;
198 height: 100%;
198 height: 100%;
199 display: inline-block;
199 display: inline-block;
200 margin-bottom: -30px;
200 margin-bottom: -30px;
201 /* Hack to make IE7 behave */
201 /* Hack to make IE7 behave */
202 *zoom:1;
202 *zoom:1;
203 *display:inline;
203 *display:inline;
204 }
204 }
205 .CodeMirror-gutter-wrapper {
205 .CodeMirror-gutter-wrapper {
206 position: absolute;
206 position: absolute;
207 z-index: 4;
207 z-index: 4;
208 height: 100%;
208 height: 100%;
209 }
209 }
210 .CodeMirror-gutter-background {
211 position: absolute;
212 top: 0; bottom: 0;
213 z-index: 4;
214 }
210 .CodeMirror-gutter-elt {
215 .CodeMirror-gutter-elt {
211 position: absolute;
216 position: absolute;
212 cursor: default;
217 cursor: default;
213 z-index: 4;
218 z-index: 4;
214 }
219 }
215 .CodeMirror-gutter-wrapper {
220 .CodeMirror-gutter-wrapper {
216 -webkit-user-select: none;
221 -webkit-user-select: none;
217 -moz-user-select: none;
222 -moz-user-select: none;
218 user-select: none;
223 user-select: none;
219 }
224 }
220
225
221 .CodeMirror-lines {
226 .CodeMirror-lines {
222 cursor: text;
227 cursor: text;
223 min-height: 1px; /* prevents collapsing before first draw */
228 min-height: 1px; /* prevents collapsing before first draw */
224 }
229 }
225 .CodeMirror pre {
230 .CodeMirror pre {
226 /* Reset some styles that the rest of the page might have set */
231 /* Reset some styles that the rest of the page might have set */
227 -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
232 -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
228 border-width: 0;
233 border-width: 0;
229 background: transparent;
234 background: transparent;
230 font-family: inherit;
235 font-family: inherit;
231 font-size: inherit;
236 font-size: inherit;
232 margin: 0;
237 margin: 0;
233 white-space: pre;
238 white-space: pre;
234 word-wrap: normal;
239 word-wrap: normal;
235 line-height: inherit;
240 line-height: inherit;
236 color: inherit;
241 color: inherit;
237 z-index: 2;
242 z-index: 2;
238 position: relative;
243 position: relative;
239 overflow: visible;
244 overflow: visible;
240 -webkit-tap-highlight-color: transparent;
245 -webkit-tap-highlight-color: transparent;
241 }
246 }
242 .CodeMirror-wrap pre {
247 .CodeMirror-wrap pre {
243 word-wrap: break-word;
248 word-wrap: break-word;
244 white-space: pre-wrap;
249 white-space: pre-wrap;
245 word-break: normal;
250 word-break: normal;
246 }
251 }
247
252
248 .CodeMirror-linebackground {
253 .CodeMirror-linebackground {
249 position: absolute;
254 position: absolute;
250 left: 0; right: 0; top: 0; bottom: 0;
255 left: 0; right: 0; top: 0; bottom: 0;
251 z-index: 0;
256 z-index: 0;
252 }
257 }
253
258
254 .CodeMirror-linewidget {
259 .CodeMirror-linewidget {
255 position: relative;
260 position: relative;
256 z-index: 2;
261 z-index: 2;
257 overflow: auto;
262 overflow: auto;
258 }
263 }
259
264
260 .CodeMirror-widget {}
265 .CodeMirror-widget {}
261
266
262 .CodeMirror-code {
267 .CodeMirror-code {
263 outline: none;
268 outline: none;
264 }
269 }
265
270
266 /* Force content-box sizing for the elements where we expect it */
271 /* Force content-box sizing for the elements where we expect it */
267 .CodeMirror-scroll,
272 .CodeMirror-scroll,
268 .CodeMirror-sizer,
273 .CodeMirror-sizer,
269 .CodeMirror-gutter,
274 .CodeMirror-gutter,
270 .CodeMirror-gutters,
275 .CodeMirror-gutters,
271 .CodeMirror-linenumber {
276 .CodeMirror-linenumber {
272 -moz-box-sizing: content-box;
277 -moz-box-sizing: content-box;
273 box-sizing: content-box;
278 box-sizing: content-box;
274 }
279 }
275
280
276 .CodeMirror-measure {
281 .CodeMirror-measure {
277 position: absolute;
282 position: absolute;
278 width: 100%;
283 width: 100%;
279 height: 0;
284 height: 0;
280 overflow: hidden;
285 overflow: hidden;
281 visibility: hidden;
286 visibility: hidden;
282 }
287 }
283 .CodeMirror-measure pre { position: static; }
288
284
289
285 .CodeMirror div.CodeMirror-cursor {
290 .CodeMirror div.CodeMirror-cursor {
286 position: absolute;
291 position: absolute;
287 border-right: none;
292 border-right: none;
288 width: 0;
293 width: 0;
289 }
294 }
290
295
296 .CodeMirror-measure pre { position: static; }
297
291 div.CodeMirror-cursors {
298 div.CodeMirror-cursors {
292 visibility: hidden;
299 visibility: hidden;
293 position: relative;
300 position: relative;
294 z-index: 3;
301 z-index: 3;
295 }
302 }
303 div.CodeMirror-dragcursors {
304 visibility: visible;
305 }
306
296 .CodeMirror-focused div.CodeMirror-cursors {
307 .CodeMirror-focused div.CodeMirror-cursors {
297 visibility: visible;
308 visibility: visible;
298 }
309 }
299
310
300 .CodeMirror-selected { background: #d9d9d9; }
311 .CodeMirror-selected { background: #d9d9d9; }
301 .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
312 .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
302 .CodeMirror-crosshair { cursor: crosshair; }
313 .CodeMirror-crosshair { cursor: crosshair; }
303 .CodeMirror ::selection { background: #d7d4f0; }
314 .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
304 .CodeMirror ::-moz-selection { background: #d7d4f0; }
315 .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
305
316
306 .cm-searching {
317 .cm-searching {
307 background: #ffa;
318 background: #ffa;
308 background: rgba(255, 255, 0, .4);
319 background: rgba(255, 255, 0, .4);
309 }
320 }
310
321
311 /* IE7 hack to prevent it from returning funny offsetTops on the spans */
322 /* IE7 hack to prevent it from returning funny offsetTops on the spans */
312 .CodeMirror span { *vertical-align: text-bottom; }
323 .CodeMirror span { *vertical-align: text-bottom; }
313
324
314 /* Used to force a border model for a node */
325 /* Used to force a border model for a node */
315 .cm-force-border { padding-right: .1px; }
326 .cm-force-border { padding-right: .1px; }
316
327
317 @media print {
328 @media print {
318 /* Hide the cursor when printing */
329 /* Hide the cursor when printing */
319 .CodeMirror div.CodeMirror-cursors {
330 .CodeMirror div.CodeMirror-cursors {
320 visibility: hidden;
331 visibility: hidden;
321 }
332 }
322 }
333 }
323
334
324 /* See issue #2901 */
335 /* See issue #2901 */
325 .cm-tab-wrap-hack:after { content: ''; }
336 .cm-tab-wrap-hack:after { content: ''; }
326
337
327 /* Help users use markselection to safely style text background */
338 /* Help users use markselection to safely style text background */
328 span.CodeMirror-selectedtext { background: none; }
339 span.CodeMirror-selectedtext { background: none; }
329
340
330 /* codemirror autocomplete widget */
341 /* codemirror autocomplete widget */
331 .CodeMirror-hints {
342 .CodeMirror-hints {
332 position: absolute;
343 position: absolute;
333 z-index: 10;
344 z-index: 10;
334 overflow: hidden;
345 overflow: hidden;
335 list-style: none;
346 list-style: none;
336
347
337 margin: 0;
348 margin: 0;
338 padding: 0;
349 padding: 0;
339
350
340 border-radius: @border-radius;
351 border-radius: @border-radius;
341 border: @border-thickness solid @rcblue;
352 border: @border-thickness solid @rcblue;
342
353
343 color: @rcblue;
354 color: @rcblue;
344 background-color: white;
355 background-color: white;
345 font-size: 95%;
356 font-size: 95%;
346
357
347 max-height: 20em;
358 max-height: 20em;
348 overflow-y: auto;
359 overflow-y: auto;
349 }
360 }
350
361
351 .CodeMirror-hint {
362 .CodeMirror-hint {
352 margin: 0;
363 margin: 0;
353 padding: 4px 8px;
364 padding: 4px 8px;
354 max-width: 40em;
365 max-width: 40em;
355 white-space: pre;
366 white-space: pre;
356 color: @rcblue;
367 color: @rcblue;
357 cursor: pointer;
368 cursor: pointer;
358 }
369 }
359
370
360 .CodeMirror-hint-active {
371 .CodeMirror-hint-active {
361 background: @rclightblue;
372 background: @rclightblue;
362 color: @rcblue;
373 color: @rcblue;
363 }
374 }
364
375
365 .CodeMirror-hint-entry {
376 .CodeMirror-hint-entry {
366 width: 38em;
377 width: 38em;
367 color: @rcblue;
378 color: @rcblue;
368 }
379 }
369
380
370 .CodeMirror-hint-entry .gravatar {
381 .CodeMirror-hint-entry .gravatar {
371 margin-right: 4px;
382 margin-right: 4px;
372 }
383 }
373
384
374 .CodeMirror-empty {
385 .CodeMirror-empty {
375 border: @border-thickness solid @grey5;
386 border: @border-thickness solid @grey5;
376 }
387 }
377
388
378 .CodeMirror-focused {
389 .CodeMirror-focused {
379 border: @border-thickness solid @grey5;
390 border: @border-thickness solid @grey5;
380 }
391 }
381
392
382 .CodeMirror-empty.CodeMirror-focused {
393 .CodeMirror-empty.CodeMirror-focused {
383 border: @border-thickness solid @grey5;
394 border: @border-thickness solid @grey5;
384 }
395 }
385
396
386 .CodeMirror pre.CodeMirror-placeholder {
397 .CodeMirror pre.CodeMirror-placeholder {
387 color: @grey4;
398 color: @grey4;
388 }
399 }
389
400
390 /** RhodeCode Customizations **/
401 /** RhodeCode Customizations **/
391
402
392 .CodeMirror.cm-s-rc-input {
403 .CodeMirror.cm-s-rc-input {
393 border: @border-thickness solid @grey4;
404 border: @border-thickness solid @grey4;
394 }
405 }
395
406
396 .CodeMirror-code pre {
407 .CodeMirror-code pre {
397 border-right: 30px solid transparent;
408 border-right: 30px solid transparent;
398 width: -webkit-fit-content;
409 width: -webkit-fit-content;
399 width: -moz-fit-content;
410 width: -moz-fit-content;
400 width: fit-content;
411 width: fit-content;
401 }
412 }
402 .CodeMirror-wrap .CodeMirror-code pre {
413 .CodeMirror-wrap .CodeMirror-code pre {
403 border-right: none;
414 border-right: none;
404 width: auto;
415 width: auto;
405 }
416 }
@@ -1,591 +1,772 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("clike", function(config, parserConfig) {
14 CodeMirror.defineMode("clike", function(config, parserConfig) {
15 var indentUnit = config.indentUnit,
15 var indentUnit = config.indentUnit,
16 statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
16 statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
17 dontAlignCalls = parserConfig.dontAlignCalls,
17 dontAlignCalls = parserConfig.dontAlignCalls,
18 keywords = parserConfig.keywords || {},
18 keywords = parserConfig.keywords || {},
19 types = parserConfig.types || {},
19 types = parserConfig.types || {},
20 builtin = parserConfig.builtin || {},
20 builtin = parserConfig.builtin || {},
21 blockKeywords = parserConfig.blockKeywords || {},
21 blockKeywords = parserConfig.blockKeywords || {},
22 defKeywords = parserConfig.defKeywords || {},
22 defKeywords = parserConfig.defKeywords || {},
23 atoms = parserConfig.atoms || {},
23 atoms = parserConfig.atoms || {},
24 hooks = parserConfig.hooks || {},
24 hooks = parserConfig.hooks || {},
25 multiLineStrings = parserConfig.multiLineStrings,
25 multiLineStrings = parserConfig.multiLineStrings,
26 indentStatements = parserConfig.indentStatements !== false,
26 indentStatements = parserConfig.indentStatements !== false,
27 indentSwitch = parserConfig.indentSwitch !== false,
27 indentSwitch = parserConfig.indentSwitch !== false,
28 namespaceSeparator = parserConfig.namespaceSeparator;
28 namespaceSeparator = parserConfig.namespaceSeparator,
29 var isOperatorChar = /[+\-*&%=<>!?|\/]/;
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 var curPunc, isDefKeyword;
35 var curPunc, isDefKeyword;
32
36
33 function tokenBase(stream, state) {
37 function tokenBase(stream, state) {
34 var ch = stream.next();
38 var ch = stream.next();
35 if (hooks[ch]) {
39 if (hooks[ch]) {
36 var result = hooks[ch](stream, state);
40 var result = hooks[ch](stream, state);
37 if (result !== false) return result;
41 if (result !== false) return result;
38 }
42 }
39 if (ch == '"' || ch == "'") {
43 if (ch == '"' || ch == "'") {
40 state.tokenize = tokenString(ch);
44 state.tokenize = tokenString(ch);
41 return state.tokenize(stream, state);
45 return state.tokenize(stream, state);
42 }
46 }
43 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
47 if (isPunctuationChar.test(ch)) {
44 curPunc = ch;
48 curPunc = ch;
45 return null;
49 return null;
46 }
50 }
47 if (/\d/.test(ch)) {
51 if (numberStart.test(ch)) {
48 stream.eatWhile(/[\w\.]/);
52 stream.backUp(1)
49 return "number";
53 if (stream.match(number)) return "number"
54 stream.next()
50 }
55 }
51 if (ch == "/") {
56 if (ch == "/") {
52 if (stream.eat("*")) {
57 if (stream.eat("*")) {
53 state.tokenize = tokenComment;
58 state.tokenize = tokenComment;
54 return tokenComment(stream, state);
59 return tokenComment(stream, state);
55 }
60 }
56 if (stream.eat("/")) {
61 if (stream.eat("/")) {
57 stream.skipToEnd();
62 stream.skipToEnd();
58 return "comment";
63 return "comment";
59 }
64 }
60 }
65 }
61 if (isOperatorChar.test(ch)) {
66 if (isOperatorChar.test(ch)) {
62 stream.eatWhile(isOperatorChar);
67 stream.eatWhile(isOperatorChar);
63 return "operator";
68 return "operator";
64 }
69 }
65 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
70 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
66 if (namespaceSeparator) while (stream.match(namespaceSeparator))
71 if (namespaceSeparator) while (stream.match(namespaceSeparator))
67 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
72 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
68
73
69 var cur = stream.current();
74 var cur = stream.current();
70 if (keywords.propertyIsEnumerable(cur)) {
75 if (contains(keywords, cur)) {
71 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
76 if (contains(blockKeywords, cur)) curPunc = "newstatement";
72 if (defKeywords.propertyIsEnumerable(cur)) isDefKeyword = true;
77 if (contains(defKeywords, cur)) isDefKeyword = true;
73 return "keyword";
78 return "keyword";
74 }
79 }
75 if (types.propertyIsEnumerable(cur)) return "variable-3";
80 if (contains(types, cur)) return "variable-3";
76 if (builtin.propertyIsEnumerable(cur)) {
81 if (contains(builtin, cur)) {
77 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
82 if (contains(blockKeywords, cur)) curPunc = "newstatement";
78 return "builtin";
83 return "builtin";
79 }
84 }
80 if (atoms.propertyIsEnumerable(cur)) return "atom";
85 if (contains(atoms, cur)) return "atom";
81 return "variable";
86 return "variable";
82 }
87 }
83
88
84 function tokenString(quote) {
89 function tokenString(quote) {
85 return function(stream, state) {
90 return function(stream, state) {
86 var escaped = false, next, end = false;
91 var escaped = false, next, end = false;
87 while ((next = stream.next()) != null) {
92 while ((next = stream.next()) != null) {
88 if (next == quote && !escaped) {end = true; break;}
93 if (next == quote && !escaped) {end = true; break;}
89 escaped = !escaped && next == "\\";
94 escaped = !escaped && next == "\\";
90 }
95 }
91 if (end || !(escaped || multiLineStrings))
96 if (end || !(escaped || multiLineStrings))
92 state.tokenize = null;
97 state.tokenize = null;
93 return "string";
98 return "string";
94 };
99 };
95 }
100 }
96
101
97 function tokenComment(stream, state) {
102 function tokenComment(stream, state) {
98 var maybeEnd = false, ch;
103 var maybeEnd = false, ch;
99 while (ch = stream.next()) {
104 while (ch = stream.next()) {
100 if (ch == "/" && maybeEnd) {
105 if (ch == "/" && maybeEnd) {
101 state.tokenize = null;
106 state.tokenize = null;
102 break;
107 break;
103 }
108 }
104 maybeEnd = (ch == "*");
109 maybeEnd = (ch == "*");
105 }
110 }
106 return "comment";
111 return "comment";
107 }
112 }
108
113
109 function Context(indented, column, type, align, prev) {
114 function Context(indented, column, type, align, prev) {
110 this.indented = indented;
115 this.indented = indented;
111 this.column = column;
116 this.column = column;
112 this.type = type;
117 this.type = type;
113 this.align = align;
118 this.align = align;
114 this.prev = prev;
119 this.prev = prev;
115 }
120 }
116 function isStatement(type) {
121 function isStatement(type) {
117 return type == "statement" || type == "switchstatement" || type == "namespace";
122 return type == "statement" || type == "switchstatement" || type == "namespace";
118 }
123 }
119 function pushContext(state, col, type) {
124 function pushContext(state, col, type) {
120 var indent = state.indented;
125 var indent = state.indented;
121 if (state.context && isStatement(state.context.type) && !isStatement(type))
126 if (state.context && isStatement(state.context.type) && !isStatement(type))
122 indent = state.context.indented;
127 indent = state.context.indented;
123 return state.context = new Context(indent, col, type, null, state.context);
128 return state.context = new Context(indent, col, type, null, state.context);
124 }
129 }
125 function popContext(state) {
130 function popContext(state) {
126 var t = state.context.type;
131 var t = state.context.type;
127 if (t == ")" || t == "]" || t == "}")
132 if (t == ")" || t == "]" || t == "}")
128 state.indented = state.context.indented;
133 state.indented = state.context.indented;
129 return state.context = state.context.prev;
134 return state.context = state.context.prev;
130 }
135 }
131
136
132 function typeBefore(stream, state) {
137 function typeBefore(stream, state) {
133 if (state.prevToken == "variable" || state.prevToken == "variable-3") return true;
138 if (state.prevToken == "variable" || state.prevToken == "variable-3") return true;
134 if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, stream.start))) return true;
139 if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, stream.start))) return true;
135 }
140 }
136
141
137 function isTopScope(context) {
142 function isTopScope(context) {
138 for (;;) {
143 for (;;) {
139 if (!context || context.type == "top") return true;
144 if (!context || context.type == "top") return true;
140 if (context.type == "}" && context.prev.type != "namespace") return false;
145 if (context.type == "}" && context.prev.type != "namespace") return false;
141 context = context.prev;
146 context = context.prev;
142 }
147 }
143 }
148 }
144
149
145 // Interface
150 // Interface
146
151
147 return {
152 return {
148 startState: function(basecolumn) {
153 startState: function(basecolumn) {
149 return {
154 return {
150 tokenize: null,
155 tokenize: null,
151 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
156 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
152 indented: 0,
157 indented: 0,
153 startOfLine: true,
158 startOfLine: true,
154 prevToken: null
159 prevToken: null
155 };
160 };
156 },
161 },
157
162
158 token: function(stream, state) {
163 token: function(stream, state) {
159 var ctx = state.context;
164 var ctx = state.context;
160 if (stream.sol()) {
165 if (stream.sol()) {
161 if (ctx.align == null) ctx.align = false;
166 if (ctx.align == null) ctx.align = false;
162 state.indented = stream.indentation();
167 state.indented = stream.indentation();
163 state.startOfLine = true;
168 state.startOfLine = true;
164 }
169 }
165 if (stream.eatSpace()) return null;
170 if (stream.eatSpace()) return null;
166 curPunc = isDefKeyword = null;
171 curPunc = isDefKeyword = null;
167 var style = (state.tokenize || tokenBase)(stream, state);
172 var style = (state.tokenize || tokenBase)(stream, state);
168 if (style == "comment" || style == "meta") return style;
173 if (style == "comment" || style == "meta") return style;
169 if (ctx.align == null) ctx.align = true;
174 if (ctx.align == null) ctx.align = true;
170
175
171 if ((curPunc == ";" || curPunc == ":" || curPunc == ","))
176 if (endStatement.test(curPunc)) while (isStatement(state.context.type)) popContext(state);
172 while (isStatement(state.context.type)) popContext(state);
173 else if (curPunc == "{") pushContext(state, stream.column(), "}");
177 else if (curPunc == "{") pushContext(state, stream.column(), "}");
174 else if (curPunc == "[") pushContext(state, stream.column(), "]");
178 else if (curPunc == "[") pushContext(state, stream.column(), "]");
175 else if (curPunc == "(") pushContext(state, stream.column(), ")");
179 else if (curPunc == "(") pushContext(state, stream.column(), ")");
176 else if (curPunc == "}") {
180 else if (curPunc == "}") {
177 while (isStatement(ctx.type)) ctx = popContext(state);
181 while (isStatement(ctx.type)) ctx = popContext(state);
178 if (ctx.type == "}") ctx = popContext(state);
182 if (ctx.type == "}") ctx = popContext(state);
179 while (isStatement(ctx.type)) ctx = popContext(state);
183 while (isStatement(ctx.type)) ctx = popContext(state);
180 }
184 }
181 else if (curPunc == ctx.type) popContext(state);
185 else if (curPunc == ctx.type) popContext(state);
182 else if (indentStatements &&
186 else if (indentStatements &&
183 (((ctx.type == "}" || ctx.type == "top") && curPunc != ";") ||
187 (((ctx.type == "}" || ctx.type == "top") && curPunc != ";") ||
184 (isStatement(ctx.type) && curPunc == "newstatement"))) {
188 (isStatement(ctx.type) && curPunc == "newstatement"))) {
185 var type = "statement";
189 var type = "statement";
186 if (curPunc == "newstatement" && indentSwitch && stream.current() == "switch")
190 if (curPunc == "newstatement" && indentSwitch && stream.current() == "switch")
187 type = "switchstatement";
191 type = "switchstatement";
188 else if (style == "keyword" && stream.current() == "namespace")
192 else if (style == "keyword" && stream.current() == "namespace")
189 type = "namespace";
193 type = "namespace";
190 pushContext(state, stream.column(), type);
194 pushContext(state, stream.column(), type);
191 }
195 }
192
196
193 if (style == "variable" &&
197 if (style == "variable" &&
194 ((state.prevToken == "def" ||
198 ((state.prevToken == "def" ||
195 (parserConfig.typeFirstDefinitions && typeBefore(stream, state) &&
199 (parserConfig.typeFirstDefinitions && typeBefore(stream, state) &&
196 isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
200 isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
197 style = "def";
201 style = "def";
198
202
199 if (hooks.token) {
203 if (hooks.token) {
200 var result = hooks.token(stream, state, style);
204 var result = hooks.token(stream, state, style);
201 if (result !== undefined) style = result;
205 if (result !== undefined) style = result;
202 }
206 }
203
207
204 if (style == "def" && parserConfig.styleDefs === false) style = "variable";
208 if (style == "def" && parserConfig.styleDefs === false) style = "variable";
205
209
206 state.startOfLine = false;
210 state.startOfLine = false;
207 state.prevToken = isDefKeyword ? "def" : style || curPunc;
211 state.prevToken = isDefKeyword ? "def" : style || curPunc;
208 return style;
212 return style;
209 },
213 },
210
214
211 indent: function(state, textAfter) {
215 indent: function(state, textAfter) {
212 if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
216 if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
213 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
217 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
214 if (isStatement(ctx.type) && firstChar == "}") ctx = ctx.prev;
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 var closing = firstChar == ctx.type;
223 var closing = firstChar == ctx.type;
216 var switchBlock = ctx.prev && ctx.prev.type == "switchstatement";
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 if (isStatement(ctx.type))
229 if (isStatement(ctx.type))
218 return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
230 return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
219 if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
231 if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
220 return ctx.column + (closing ? 0 : 1);
232 return ctx.column + (closing ? 0 : 1);
221 if (ctx.type == ")" && !closing)
233 if (ctx.type == ")" && !closing)
222 return ctx.indented + statementIndentUnit;
234 return ctx.indented + statementIndentUnit;
223
235
224 return ctx.indented + (closing ? 0 : indentUnit) +
236 return ctx.indented + (closing ? 0 : indentUnit) +
225 (!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0);
237 (!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0);
226 },
238 },
227
239
228 electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
240 electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
229 blockCommentStart: "/*",
241 blockCommentStart: "/*",
230 blockCommentEnd: "*/",
242 blockCommentEnd: "*/",
231 lineComment: "//",
243 lineComment: "//",
232 fold: "brace"
244 fold: "brace"
233 };
245 };
234 });
246 });
235
247
236 function words(str) {
248 function words(str) {
237 var obj = {}, words = str.split(" ");
249 var obj = {}, words = str.split(" ");
238 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
250 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
239 return obj;
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 var cKeywords = "auto if break case register continue return default do sizeof " +
260 var cKeywords = "auto if break case register continue return default do sizeof " +
242 "static else struct switch extern typedef float union for " +
261 "static else struct switch extern typedef union for goto while enum const volatile";
243 "goto while enum const volatile";
244 var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
262 var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
245
263
246 function cppHook(stream, state) {
264 function cppHook(stream, state) {
247 if (!state.startOfLine) return false;
265 if (!state.startOfLine) return false
248 for (;;) {
266 for (var ch, next = null; ch = stream.peek();) {
249 if (stream.skipTo("\\")) {
267 if (ch == "\\" && stream.match(/^.$/)) {
250 stream.next();
268 next = cppHook
251 if (stream.eol()) {
269 break
252 state.tokenize = cppHook;
270 } else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) {
253 break;
271 break
254 }
255 } else {
256 stream.skipToEnd();
257 state.tokenize = null;
258 break;
259 }
272 }
273 stream.next()
260 }
274 }
261 return "meta";
275 state.tokenize = next
276 return "meta"
262 }
277 }
263
278
264 function pointerHook(_stream, state) {
279 function pointerHook(_stream, state) {
265 if (state.prevToken == "variable-3") return "variable-3";
280 if (state.prevToken == "variable-3") return "variable-3";
266 return false;
281 return false;
267 }
282 }
268
283
284 function cpp14Literal(stream) {
285 stream.eatWhile(/[\w\.']/);
286 return "number";
287 }
288
269 function cpp11StringHook(stream, state) {
289 function cpp11StringHook(stream, state) {
270 stream.backUp(1);
290 stream.backUp(1);
271 // Raw strings.
291 // Raw strings.
272 if (stream.match(/(R|u8R|uR|UR|LR)/)) {
292 if (stream.match(/(R|u8R|uR|UR|LR)/)) {
273 var match = stream.match(/"([^\s\\()]{0,16})\(/);
293 var match = stream.match(/"([^\s\\()]{0,16})\(/);
274 if (!match) {
294 if (!match) {
275 return false;
295 return false;
276 }
296 }
277 state.cpp11RawStringDelim = match[1];
297 state.cpp11RawStringDelim = match[1];
278 state.tokenize = tokenRawString;
298 state.tokenize = tokenRawString;
279 return tokenRawString(stream, state);
299 return tokenRawString(stream, state);
280 }
300 }
281 // Unicode strings/chars.
301 // Unicode strings/chars.
282 if (stream.match(/(u8|u|U|L)/)) {
302 if (stream.match(/(u8|u|U|L)/)) {
283 if (stream.match(/["']/, /* eat */ false)) {
303 if (stream.match(/["']/, /* eat */ false)) {
284 return "string";
304 return "string";
285 }
305 }
286 return false;
306 return false;
287 }
307 }
288 // Ignore this hook.
308 // Ignore this hook.
289 stream.next();
309 stream.next();
290 return false;
310 return false;
291 }
311 }
292
312
293 function cppLooksLikeConstructor(word) {
313 function cppLooksLikeConstructor(word) {
294 var lastTwo = /(\w+)::(\w+)$/.exec(word);
314 var lastTwo = /(\w+)::(\w+)$/.exec(word);
295 return lastTwo && lastTwo[1] == lastTwo[2];
315 return lastTwo && lastTwo[1] == lastTwo[2];
296 }
316 }
297
317
298 // C#-style strings where "" escapes a quote.
318 // C#-style strings where "" escapes a quote.
299 function tokenAtString(stream, state) {
319 function tokenAtString(stream, state) {
300 var next;
320 var next;
301 while ((next = stream.next()) != null) {
321 while ((next = stream.next()) != null) {
302 if (next == '"' && !stream.eat('"')) {
322 if (next == '"' && !stream.eat('"')) {
303 state.tokenize = null;
323 state.tokenize = null;
304 break;
324 break;
305 }
325 }
306 }
326 }
307 return "string";
327 return "string";
308 }
328 }
309
329
310 // C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
330 // C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
311 // <delim> can be a string up to 16 characters long.
331 // <delim> can be a string up to 16 characters long.
312 function tokenRawString(stream, state) {
332 function tokenRawString(stream, state) {
313 // Escape characters that have special regex meanings.
333 // Escape characters that have special regex meanings.
314 var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&');
334 var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&');
315 var match = stream.match(new RegExp(".*?\\)" + delim + '"'));
335 var match = stream.match(new RegExp(".*?\\)" + delim + '"'));
316 if (match)
336 if (match)
317 state.tokenize = null;
337 state.tokenize = null;
318 else
338 else
319 stream.skipToEnd();
339 stream.skipToEnd();
320 return "string";
340 return "string";
321 }
341 }
322
342
323 function def(mimes, mode) {
343 function def(mimes, mode) {
324 if (typeof mimes == "string") mimes = [mimes];
344 if (typeof mimes == "string") mimes = [mimes];
325 var words = [];
345 var words = [];
326 function add(obj) {
346 function add(obj) {
327 if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
347 if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
328 words.push(prop);
348 words.push(prop);
329 }
349 }
330 add(mode.keywords);
350 add(mode.keywords);
331 add(mode.types);
351 add(mode.types);
332 add(mode.builtin);
352 add(mode.builtin);
333 add(mode.atoms);
353 add(mode.atoms);
334 if (words.length) {
354 if (words.length) {
335 mode.helperType = mimes[0];
355 mode.helperType = mimes[0];
336 CodeMirror.registerHelper("hintWords", mimes[0], words);
356 CodeMirror.registerHelper("hintWords", mimes[0], words);
337 }
357 }
338
358
339 for (var i = 0; i < mimes.length; ++i)
359 for (var i = 0; i < mimes.length; ++i)
340 CodeMirror.defineMIME(mimes[i], mode);
360 CodeMirror.defineMIME(mimes[i], mode);
341 }
361 }
342
362
343 def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
363 def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
344 name: "clike",
364 name: "clike",
345 keywords: words(cKeywords),
365 keywords: words(cKeywords),
346 types: words(cTypes + " bool _Complex _Bool float_t double_t intptr_t intmax_t " +
366 types: words(cTypes + " bool _Complex _Bool float_t double_t intptr_t intmax_t " +
347 "int8_t int16_t int32_t int64_t uintptr_t uintmax_t uint8_t uint16_t " +
367 "int8_t int16_t int32_t int64_t uintptr_t uintmax_t uint8_t uint16_t " +
348 "uint32_t uint64_t"),
368 "uint32_t uint64_t"),
349 blockKeywords: words("case do else for if switch while struct"),
369 blockKeywords: words("case do else for if switch while struct"),
350 defKeywords: words("struct"),
370 defKeywords: words("struct"),
351 typeFirstDefinitions: true,
371 typeFirstDefinitions: true,
352 atoms: words("null true false"),
372 atoms: words("null true false"),
353 hooks: {"#": cppHook, "*": pointerHook},
373 hooks: {"#": cppHook, "*": pointerHook},
354 modeProps: {fold: ["brace", "include"]}
374 modeProps: {fold: ["brace", "include"]}
355 });
375 });
356
376
357 def(["text/x-c++src", "text/x-c++hdr"], {
377 def(["text/x-c++src", "text/x-c++hdr"], {
358 name: "clike",
378 name: "clike",
359 keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try explicit new " +
379 keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try explicit new " +
360 "static_cast typeid catch operator template typename class friend private " +
380 "static_cast typeid catch operator template typename class friend private " +
361 "this using const_cast inline public throw virtual delete mutable protected " +
381 "this using const_cast inline public throw virtual delete mutable protected " +
362 "alignas alignof constexpr decltype nullptr noexcept thread_local final " +
382 "alignas alignof constexpr decltype nullptr noexcept thread_local final " +
363 "static_assert override"),
383 "static_assert override"),
364 types: words(cTypes + " bool wchar_t"),
384 types: words(cTypes + " bool wchar_t"),
365 blockKeywords: words("catch class do else finally for if struct switch try while"),
385 blockKeywords: words("catch class do else finally for if struct switch try while"),
366 defKeywords: words("class namespace struct enum union"),
386 defKeywords: words("class namespace struct enum union"),
367 typeFirstDefinitions: true,
387 typeFirstDefinitions: true,
368 atoms: words("true false null"),
388 atoms: words("true false null"),
369 hooks: {
389 hooks: {
370 "#": cppHook,
390 "#": cppHook,
371 "*": pointerHook,
391 "*": pointerHook,
372 "u": cpp11StringHook,
392 "u": cpp11StringHook,
373 "U": cpp11StringHook,
393 "U": cpp11StringHook,
374 "L": cpp11StringHook,
394 "L": cpp11StringHook,
375 "R": cpp11StringHook,
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 token: function(stream, state, style) {
406 token: function(stream, state, style) {
377 if (style == "variable" && stream.peek() == "(" &&
407 if (style == "variable" && stream.peek() == "(" &&
378 (state.prevToken == ";" || state.prevToken == null ||
408 (state.prevToken == ";" || state.prevToken == null ||
379 state.prevToken == "}") &&
409 state.prevToken == "}") &&
380 cppLooksLikeConstructor(stream.current()))
410 cppLooksLikeConstructor(stream.current()))
381 return "def";
411 return "def";
382 }
412 }
383 },
413 },
384 namespaceSeparator: "::",
414 namespaceSeparator: "::",
385 modeProps: {fold: ["brace", "include"]}
415 modeProps: {fold: ["brace", "include"]}
386 });
416 });
387
417
388 def("text/x-java", {
418 def("text/x-java", {
389 name: "clike",
419 name: "clike",
390 keywords: words("abstract assert break case catch class const continue default " +
420 keywords: words("abstract assert break case catch class const continue default " +
391 "do else enum extends final finally float for goto if implements import " +
421 "do else enum extends final finally float for goto if implements import " +
392 "instanceof interface native new package private protected public " +
422 "instanceof interface native new package private protected public " +
393 "return static strictfp super switch synchronized this throw throws transient " +
423 "return static strictfp super switch synchronized this throw throws transient " +
394 "try volatile while"),
424 "try volatile while"),
395 types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
425 types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
396 "Integer Long Number Object Short String StringBuffer StringBuilder Void"),
426 "Integer Long Number Object Short String StringBuffer StringBuilder Void"),
397 blockKeywords: words("catch class do else finally for if switch try while"),
427 blockKeywords: words("catch class do else finally for if switch try while"),
398 defKeywords: words("class interface package enum"),
428 defKeywords: words("class interface package enum"),
399 typeFirstDefinitions: true,
429 typeFirstDefinitions: true,
400 atoms: words("true false null"),
430 atoms: words("true false null"),
431 endStatement: /^[;:]$/,
401 hooks: {
432 hooks: {
402 "@": function(stream) {
433 "@": function(stream) {
403 stream.eatWhile(/[\w\$_]/);
434 stream.eatWhile(/[\w\$_]/);
404 return "meta";
435 return "meta";
405 }
436 }
406 },
437 },
407 modeProps: {fold: ["brace", "import"]}
438 modeProps: {fold: ["brace", "import"]}
408 });
439 });
409
440
410 def("text/x-csharp", {
441 def("text/x-csharp", {
411 name: "clike",
442 name: "clike",
412 keywords: words("abstract as async await base break case catch checked class const continue" +
443 keywords: words("abstract as async await base break case catch checked class const continue" +
413 " default delegate do else enum event explicit extern finally fixed for" +
444 " default delegate do else enum event explicit extern finally fixed for" +
414 " foreach goto if implicit in interface internal is lock namespace new" +
445 " foreach goto if implicit in interface internal is lock namespace new" +
415 " operator out override params private protected public readonly ref return sealed" +
446 " operator out override params private protected public readonly ref return sealed" +
416 " sizeof stackalloc static struct switch this throw try typeof unchecked" +
447 " sizeof stackalloc static struct switch this throw try typeof unchecked" +
417 " unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
448 " unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
418 " global group into join let orderby partial remove select set value var yield"),
449 " global group into join let orderby partial remove select set value var yield"),
419 types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" +
450 types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" +
420 " Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" +
451 " Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" +
421 " UInt64 bool byte char decimal double short int long object" +
452 " UInt64 bool byte char decimal double short int long object" +
422 " sbyte float string ushort uint ulong"),
453 " sbyte float string ushort uint ulong"),
423 blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
454 blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
424 defKeywords: words("class interface namespace struct var"),
455 defKeywords: words("class interface namespace struct var"),
425 typeFirstDefinitions: true,
456 typeFirstDefinitions: true,
426 atoms: words("true false null"),
457 atoms: words("true false null"),
427 hooks: {
458 hooks: {
428 "@": function(stream, state) {
459 "@": function(stream, state) {
429 if (stream.eat('"')) {
460 if (stream.eat('"')) {
430 state.tokenize = tokenAtString;
461 state.tokenize = tokenAtString;
431 return tokenAtString(stream, state);
462 return tokenAtString(stream, state);
432 }
463 }
433 stream.eatWhile(/[\w\$_]/);
464 stream.eatWhile(/[\w\$_]/);
434 return "meta";
465 return "meta";
435 }
466 }
436 }
467 }
437 });
468 });
438
469
439 function tokenTripleString(stream, state) {
470 function tokenTripleString(stream, state) {
440 var escaped = false;
471 var escaped = false;
441 while (!stream.eol()) {
472 while (!stream.eol()) {
442 if (!escaped && stream.match('"""')) {
473 if (!escaped && stream.match('"""')) {
443 state.tokenize = null;
474 state.tokenize = null;
444 break;
475 break;
445 }
476 }
446 escaped = stream.next() == "\\" && !escaped;
477 escaped = stream.next() == "\\" && !escaped;
447 }
478 }
448 return "string";
479 return "string";
449 }
480 }
450
481
451 def("text/x-scala", {
482 def("text/x-scala", {
452 name: "clike",
483 name: "clike",
453 keywords: words(
484 keywords: words(
454
485
455 /* scala */
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 "implicit import lazy match new null object override package private protected return " +
488 "implicit import lazy match new null object override package private protected return " +
458 "sealed super this throw trait try type val var while with yield _ : = => <- <: " +
489 "sealed super this throw trait try type val var while with yield _ : = => <- <: " +
459 "<% >: # @ " +
490 "<% >: # @ " +
460
491
461 /* package scala */
492 /* package scala */
462 "assert assume require print println printf readLine readBoolean readByte readShort " +
493 "assert assume require print println printf readLine readBoolean readByte readShort " +
463 "readChar readInt readLong readFloat readDouble " +
494 "readChar readInt readLong readFloat readDouble " +
464
495
465 ":: #:: "
496 ":: #:: "
466 ),
497 ),
467 types: words(
498 types: words(
468 "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
499 "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
469 "Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " +
500 "Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " +
470 "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
501 "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
471 "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
502 "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
472 "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " +
503 "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " +
473
504
474 /* package java.lang */
505 /* package java.lang */
475 "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
506 "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
476 "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
507 "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
477 "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
508 "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
478 "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
509 "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
479 ),
510 ),
480 multiLineStrings: true,
511 multiLineStrings: true,
481 blockKeywords: words("catch class do else finally for forSome if match switch try while"),
512 blockKeywords: words("catch class do else finally for forSome if match switch try while"),
482 defKeywords: words("class def object package trait type val var"),
513 defKeywords: words("class def object package trait type val var"),
483 atoms: words("true false null"),
514 atoms: words("true false null"),
484 indentStatements: false,
515 indentStatements: false,
485 indentSwitch: false,
516 indentSwitch: false,
486 hooks: {
517 hooks: {
487 "@": function(stream) {
518 "@": function(stream) {
488 stream.eatWhile(/[\w\$_]/);
519 stream.eatWhile(/[\w\$_]/);
489 return "meta";
520 return "meta";
490 },
521 },
491 '"': function(stream, state) {
522 '"': function(stream, state) {
492 if (!stream.match('""')) return false;
523 if (!stream.match('""')) return false;
493 state.tokenize = tokenTripleString;
524 state.tokenize = tokenTripleString;
494 return state.tokenize(stream, state);
525 return state.tokenize(stream, state);
495 },
526 },
496 "'": function(stream) {
527 "'": function(stream) {
497 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
528 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
498 return "atom";
529 return "atom";
499 }
530 }
500 },
531 },
501 modeProps: {closeBrackets: {triples: '"'}}
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 def(["x-shader/x-vertex", "x-shader/x-fragment"], {
588 def(["x-shader/x-vertex", "x-shader/x-fragment"], {
505 name: "clike",
589 name: "clike",
506 keywords: words("sampler1D sampler2D sampler3D samplerCube " +
590 keywords: words("sampler1D sampler2D sampler3D samplerCube " +
507 "sampler1DShadow sampler2DShadow " +
591 "sampler1DShadow sampler2DShadow " +
508 "const attribute uniform varying " +
592 "const attribute uniform varying " +
509 "break continue discard return " +
593 "break continue discard return " +
510 "for while do if else struct " +
594 "for while do if else struct " +
511 "in out inout"),
595 "in out inout"),
512 types: words("float int bool void " +
596 types: words("float int bool void " +
513 "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
597 "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
514 "mat2 mat3 mat4"),
598 "mat2 mat3 mat4"),
515 blockKeywords: words("for while do if else struct"),
599 blockKeywords: words("for while do if else struct"),
516 builtin: words("radians degrees sin cos tan asin acos atan " +
600 builtin: words("radians degrees sin cos tan asin acos atan " +
517 "pow exp log exp2 sqrt inversesqrt " +
601 "pow exp log exp2 sqrt inversesqrt " +
518 "abs sign floor ceil fract mod min max clamp mix step smoothstep " +
602 "abs sign floor ceil fract mod min max clamp mix step smoothstep " +
519 "length distance dot cross normalize ftransform faceforward " +
603 "length distance dot cross normalize ftransform faceforward " +
520 "reflect refract matrixCompMult " +
604 "reflect refract matrixCompMult " +
521 "lessThan lessThanEqual greaterThan greaterThanEqual " +
605 "lessThan lessThanEqual greaterThan greaterThanEqual " +
522 "equal notEqual any all not " +
606 "equal notEqual any all not " +
523 "texture1D texture1DProj texture1DLod texture1DProjLod " +
607 "texture1D texture1DProj texture1DLod texture1DProjLod " +
524 "texture2D texture2DProj texture2DLod texture2DProjLod " +
608 "texture2D texture2DProj texture2DLod texture2DProjLod " +
525 "texture3D texture3DProj texture3DLod texture3DProjLod " +
609 "texture3D texture3DProj texture3DLod texture3DProjLod " +
526 "textureCube textureCubeLod " +
610 "textureCube textureCubeLod " +
527 "shadow1D shadow2D shadow1DProj shadow2DProj " +
611 "shadow1D shadow2D shadow1DProj shadow2DProj " +
528 "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
612 "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
529 "dFdx dFdy fwidth " +
613 "dFdx dFdy fwidth " +
530 "noise1 noise2 noise3 noise4"),
614 "noise1 noise2 noise3 noise4"),
531 atoms: words("true false " +
615 atoms: words("true false " +
532 "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
616 "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
533 "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
617 "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
534 "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
618 "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
535 "gl_FogCoord gl_PointCoord " +
619 "gl_FogCoord gl_PointCoord " +
536 "gl_Position gl_PointSize gl_ClipVertex " +
620 "gl_Position gl_PointSize gl_ClipVertex " +
537 "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
621 "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
538 "gl_TexCoord gl_FogFragCoord " +
622 "gl_TexCoord gl_FogFragCoord " +
539 "gl_FragCoord gl_FrontFacing " +
623 "gl_FragCoord gl_FrontFacing " +
540 "gl_FragData gl_FragDepth " +
624 "gl_FragData gl_FragDepth " +
541 "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
625 "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
542 "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
626 "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
543 "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
627 "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
544 "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
628 "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
545 "gl_ProjectionMatrixInverseTranspose " +
629 "gl_ProjectionMatrixInverseTranspose " +
546 "gl_ModelViewProjectionMatrixInverseTranspose " +
630 "gl_ModelViewProjectionMatrixInverseTranspose " +
547 "gl_TextureMatrixInverseTranspose " +
631 "gl_TextureMatrixInverseTranspose " +
548 "gl_NormalScale gl_DepthRange gl_ClipPlane " +
632 "gl_NormalScale gl_DepthRange gl_ClipPlane " +
549 "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
633 "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
550 "gl_FrontLightModelProduct gl_BackLightModelProduct " +
634 "gl_FrontLightModelProduct gl_BackLightModelProduct " +
551 "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
635 "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
552 "gl_FogParameters " +
636 "gl_FogParameters " +
553 "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
637 "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
554 "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
638 "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
555 "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
639 "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
556 "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
640 "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
557 "gl_MaxDrawBuffers"),
641 "gl_MaxDrawBuffers"),
558 indentSwitch: false,
642 indentSwitch: false,
559 hooks: {"#": cppHook},
643 hooks: {"#": cppHook},
560 modeProps: {fold: ["brace", "include"]}
644 modeProps: {fold: ["brace", "include"]}
561 });
645 });
562
646
563 def("text/x-nesc", {
647 def("text/x-nesc", {
564 name: "clike",
648 name: "clike",
565 keywords: words(cKeywords + "as atomic async call command component components configuration event generic " +
649 keywords: words(cKeywords + "as atomic async call command component components configuration event generic " +
566 "implementation includes interface module new norace nx_struct nx_union post provides " +
650 "implementation includes interface module new norace nx_struct nx_union post provides " +
567 "signal task uses abstract extends"),
651 "signal task uses abstract extends"),
568 types: words(cTypes),
652 types: words(cTypes),
569 blockKeywords: words("case do else for if switch while struct"),
653 blockKeywords: words("case do else for if switch while struct"),
570 atoms: words("null true false"),
654 atoms: words("null true false"),
571 hooks: {"#": cppHook},
655 hooks: {"#": cppHook},
572 modeProps: {fold: ["brace", "include"]}
656 modeProps: {fold: ["brace", "include"]}
573 });
657 });
574
658
575 def("text/x-objectivec", {
659 def("text/x-objectivec", {
576 name: "clike",
660 name: "clike",
577 keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginery BOOL Class bycopy byref id IMP in " +
661 keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginery BOOL Class bycopy byref id IMP in " +
578 "inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),
662 "inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),
579 types: words(cTypes),
663 types: words(cTypes),
580 atoms: words("YES NO NULL NILL ON OFF true false"),
664 atoms: words("YES NO NULL NILL ON OFF true false"),
581 hooks: {
665 hooks: {
582 "@": function(stream) {
666 "@": function(stream) {
583 stream.eatWhile(/[\w\$]/);
667 stream.eatWhile(/[\w\$]/);
584 return "keyword";
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 modeProps: {fold: "brace"}
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"]}
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
591 });
772 });
@@ -1,244 +1,249 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 /**
4 /**
5 * Author: Hans Engel
5 * Author: Hans Engel
6 * Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun)
6 * Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun)
7 */
7 */
8
8
9 (function(mod) {
9 (function(mod) {
10 if (typeof exports == "object" && typeof module == "object") // CommonJS
10 if (typeof exports == "object" && typeof module == "object") // CommonJS
11 mod(require("../../lib/codemirror"));
11 mod(require("../../lib/codemirror"));
12 else if (typeof define == "function" && define.amd) // AMD
12 else if (typeof define == "function" && define.amd) // AMD
13 define(["../../lib/codemirror"], mod);
13 define(["../../lib/codemirror"], mod);
14 else // Plain browser env
14 else // Plain browser env
15 mod(CodeMirror);
15 mod(CodeMirror);
16 })(function(CodeMirror) {
16 })(function(CodeMirror) {
17 "use strict";
17 "use strict";
18
18
19 CodeMirror.defineMode("clojure", function (options) {
19 CodeMirror.defineMode("clojure", function (options) {
20 var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", CHARACTER = "string-2",
20 var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", CHARACTER = "string-2",
21 ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD = "keyword", VAR = "variable";
21 ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD = "keyword", VAR = "variable";
22 var INDENT_WORD_SKIP = options.indentUnit || 2;
22 var INDENT_WORD_SKIP = options.indentUnit || 2;
23 var NORMAL_INDENT_UNIT = options.indentUnit || 2;
23 var NORMAL_INDENT_UNIT = options.indentUnit || 2;
24
24
25 function makeKeywords(str) {
25 function makeKeywords(str) {
26 var obj = {}, words = str.split(" ");
26 var obj = {}, words = str.split(" ");
27 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
27 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
28 return obj;
28 return obj;
29 }
29 }
30
30
31 var atoms = makeKeywords("true false nil");
31 var atoms = makeKeywords("true false nil");
32
32
33 var keywords = makeKeywords(
33 var keywords = makeKeywords(
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");
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 var builtins = makeKeywords(
36 var builtins = makeKeywords(
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->>");
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 var indentKeys = makeKeywords(
39 var indentKeys = makeKeywords(
40 // Built-ins
40 // Built-ins
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 " +
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 // Binding forms
43 // Binding forms
44 "let letfn binding loop for doseq dotimes when-let if-let " +
44 "let letfn binding loop for doseq dotimes when-let if-let " +
45
45
46 // Data structures
46 // Data structures
47 "defstruct struct-map assoc " +
47 "defstruct struct-map assoc " +
48
48
49 // clojure.test
49 // clojure.test
50 "testing deftest " +
50 "testing deftest " +
51
51
52 // contrib
52 // contrib
53 "handler-case handle dotrace deftrace");
53 "handler-case handle dotrace deftrace");
54
54
55 var tests = {
55 var tests = {
56 digit: /\d/,
56 digit: /\d/,
57 digit_or_colon: /[\d:]/,
57 digit_or_colon: /[\d:]/,
58 hex: /[0-9a-f]/i,
58 hex: /[0-9a-f]/i,
59 sign: /[+-]/,
59 sign: /[+-]/,
60 exponent: /e/i,
60 exponent: /e/i,
61 keyword_char: /[^\s\(\[\;\)\]]/,
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 function stateStack(indent, type, prev) { // represents a state stack object
66 function stateStack(indent, type, prev) { // represents a state stack object
66 this.indent = indent;
67 this.indent = indent;
67 this.type = type;
68 this.type = type;
68 this.prev = prev;
69 this.prev = prev;
69 }
70 }
70
71
71 function pushStack(state, indent, type) {
72 function pushStack(state, indent, type) {
72 state.indentStack = new stateStack(indent, type, state.indentStack);
73 state.indentStack = new stateStack(indent, type, state.indentStack);
73 }
74 }
74
75
75 function popStack(state) {
76 function popStack(state) {
76 state.indentStack = state.indentStack.prev;
77 state.indentStack = state.indentStack.prev;
77 }
78 }
78
79
79 function isNumber(ch, stream){
80 function isNumber(ch, stream){
80 // hex
81 // hex
81 if ( ch === '0' && stream.eat(/x/i) ) {
82 if ( ch === '0' && stream.eat(/x/i) ) {
82 stream.eatWhile(tests.hex);
83 stream.eatWhile(tests.hex);
83 return true;
84 return true;
84 }
85 }
85
86
86 // leading sign
87 // leading sign
87 if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
88 if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
88 stream.eat(tests.sign);
89 stream.eat(tests.sign);
89 ch = stream.next();
90 ch = stream.next();
90 }
91 }
91
92
92 if ( tests.digit.test(ch) ) {
93 if ( tests.digit.test(ch) ) {
93 stream.eat(ch);
94 stream.eat(ch);
94 stream.eatWhile(tests.digit);
95 stream.eatWhile(tests.digit);
95
96
96 if ( '.' == stream.peek() ) {
97 if ( '.' == stream.peek() ) {
97 stream.eat('.');
98 stream.eat('.');
98 stream.eatWhile(tests.digit);
99 stream.eatWhile(tests.digit);
100 } else if ('/' == stream.peek() ) {
101 stream.eat('/');
102 stream.eatWhile(tests.digit);
99 }
103 }
100
104
101 if ( stream.eat(tests.exponent) ) {
105 if ( stream.eat(tests.exponent) ) {
102 stream.eat(tests.sign);
106 stream.eat(tests.sign);
103 stream.eatWhile(tests.digit);
107 stream.eatWhile(tests.digit);
104 }
108 }
105
109
106 return true;
110 return true;
107 }
111 }
108
112
109 return false;
113 return false;
110 }
114 }
111
115
112 // Eat character that starts after backslash \
116 // Eat character that starts after backslash \
113 function eatCharacter(stream) {
117 function eatCharacter(stream) {
114 var first = stream.next();
118 var first = stream.next();
115 // Read special literals: backspace, newline, space, return.
119 // Read special literals: backspace, newline, space, return.
116 // Just read all lowercase letters.
120 // Just read all lowercase letters.
117 if (first && first.match(/[a-z]/) && stream.match(/[a-z]+/, true)) {
121 if (first && first.match(/[a-z]/) && stream.match(/[a-z]+/, true)) {
118 return;
122 return;
119 }
123 }
120 // Read unicode character: \u1000 \uA0a1
124 // Read unicode character: \u1000 \uA0a1
121 if (first === "u") {
125 if (first === "u") {
122 stream.match(/[0-9a-z]{4}/i, true);
126 stream.match(/[0-9a-z]{4}/i, true);
123 }
127 }
124 }
128 }
125
129
126 return {
130 return {
127 startState: function () {
131 startState: function () {
128 return {
132 return {
129 indentStack: null,
133 indentStack: null,
130 indentation: 0,
134 indentation: 0,
131 mode: false
135 mode: false
132 };
136 };
133 },
137 },
134
138
135 token: function (stream, state) {
139 token: function (stream, state) {
136 if (state.indentStack == null && stream.sol()) {
140 if (state.indentStack == null && stream.sol()) {
137 // update indentation, but only if indentStack is empty
141 // update indentation, but only if indentStack is empty
138 state.indentation = stream.indentation();
142 state.indentation = stream.indentation();
139 }
143 }
140
144
141 // skip spaces
145 // skip spaces
142 if (stream.eatSpace()) {
146 if (state.mode != "string" && stream.eatSpace()) {
143 return null;
147 return null;
144 }
148 }
145 var returnType = null;
149 var returnType = null;
146
150
147 switch(state.mode){
151 switch(state.mode){
148 case "string": // multi-line string parsing mode
152 case "string": // multi-line string parsing mode
149 var next, escaped = false;
153 var next, escaped = false;
150 while ((next = stream.next()) != null) {
154 while ((next = stream.next()) != null) {
151 if (next == "\"" && !escaped) {
155 if (next == "\"" && !escaped) {
152
156
153 state.mode = false;
157 state.mode = false;
154 break;
158 break;
155 }
159 }
156 escaped = !escaped && next == "\\";
160 escaped = !escaped && next == "\\";
157 }
161 }
158 returnType = STRING; // continue on in string mode
162 returnType = STRING; // continue on in string mode
159 break;
163 break;
160 default: // default parsing mode
164 default: // default parsing mode
161 var ch = stream.next();
165 var ch = stream.next();
162
166
163 if (ch == "\"") {
167 if (ch == "\"") {
164 state.mode = "string";
168 state.mode = "string";
165 returnType = STRING;
169 returnType = STRING;
166 } else if (ch == "\\") {
170 } else if (ch == "\\") {
167 eatCharacter(stream);
171 eatCharacter(stream);
168 returnType = CHARACTER;
172 returnType = CHARACTER;
169 } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
173 } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
170 returnType = ATOM;
174 returnType = ATOM;
171 } else if (ch == ";") { // comment
175 } else if (ch == ";") { // comment
172 stream.skipToEnd(); // rest of the line is a comment
176 stream.skipToEnd(); // rest of the line is a comment
173 returnType = COMMENT;
177 returnType = COMMENT;
174 } else if (isNumber(ch,stream)){
178 } else if (isNumber(ch,stream)){
175 returnType = NUMBER;
179 returnType = NUMBER;
176 } else if (ch == "(" || ch == "[" || ch == "{" ) {
180 } else if (ch == "(" || ch == "[" || ch == "{" ) {
177 var keyWord = '', indentTemp = stream.column(), letter;
181 var keyWord = '', indentTemp = stream.column(), letter;
178 /**
182 /**
179 Either
183 Either
180 (indent-word ..
184 (indent-word ..
181 (non-indent-word ..
185 (non-indent-word ..
182 (;something else, bracket, etc.
186 (;something else, bracket, etc.
183 */
187 */
184
188
185 if (ch == "(") while ((letter = stream.eat(tests.keyword_char)) != null) {
189 if (ch == "(") while ((letter = stream.eat(tests.keyword_char)) != null) {
186 keyWord += letter;
190 keyWord += letter;
187 }
191 }
188
192
189 if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) ||
193 if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) ||
190 /^(?:def|with)/.test(keyWord))) { // indent-word
194 tests.block_indent.test(keyWord))) { // indent-word
191 pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
195 pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
192 } else { // non-indent word
196 } else { // non-indent word
193 // we continue eating the spaces
197 // we continue eating the spaces
194 stream.eatSpace();
198 stream.eatSpace();
195 if (stream.eol() || stream.peek() == ";") {
199 if (stream.eol() || stream.peek() == ";") {
196 // nothing significant after
200 // nothing significant after
197 // we restart indentation the user defined spaces after
201 // we restart indentation the user defined spaces after
198 pushStack(state, indentTemp + NORMAL_INDENT_UNIT, ch);
202 pushStack(state, indentTemp + NORMAL_INDENT_UNIT, ch);
199 } else {
203 } else {
200 pushStack(state, indentTemp + stream.current().length, ch); // else we match
204 pushStack(state, indentTemp + stream.current().length, ch); // else we match
201 }
205 }
202 }
206 }
203 stream.backUp(stream.current().length - 1); // undo all the eating
207 stream.backUp(stream.current().length - 1); // undo all the eating
204
208
205 returnType = BRACKET;
209 returnType = BRACKET;
206 } else if (ch == ")" || ch == "]" || ch == "}") {
210 } else if (ch == ")" || ch == "]" || ch == "}") {
207 returnType = BRACKET;
211 returnType = BRACKET;
208 if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : (ch == "]" ? "[" :"{"))) {
212 if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : (ch == "]" ? "[" :"{"))) {
209 popStack(state);
213 popStack(state);
210 }
214 }
211 } else if ( ch == ":" ) {
215 } else if ( ch == ":" ) {
212 stream.eatWhile(tests.symbol);
216 stream.eatWhile(tests.symbol);
213 return ATOM;
217 return ATOM;
214 } else {
218 } else {
215 stream.eatWhile(tests.symbol);
219 stream.eatWhile(tests.symbol);
216
220
217 if (keywords && keywords.propertyIsEnumerable(stream.current())) {
221 if (keywords && keywords.propertyIsEnumerable(stream.current())) {
218 returnType = KEYWORD;
222 returnType = KEYWORD;
219 } else if (builtins && builtins.propertyIsEnumerable(stream.current())) {
223 } else if (builtins && builtins.propertyIsEnumerable(stream.current())) {
220 returnType = BUILTIN;
224 returnType = BUILTIN;
221 } else if (atoms && atoms.propertyIsEnumerable(stream.current())) {
225 } else if (atoms && atoms.propertyIsEnumerable(stream.current())) {
222 returnType = ATOM;
226 returnType = ATOM;
223 } else {
227 } else {
224 returnType = VAR;
228 returnType = VAR;
225 }
229 }
226 }
230 }
227 }
231 }
228
232
229 return returnType;
233 return returnType;
230 },
234 },
231
235
232 indent: function (state) {
236 indent: function (state) {
233 if (state.indentStack == null) return state.indentation;
237 if (state.indentStack == null) return state.indentation;
234 return state.indentStack.indent;
238 return state.indentStack.indent;
235 },
239 },
236
240
237 closeBrackets: {pairs: "()[]{}\"\""},
241 closeBrackets: {pairs: "()[]{}\"\""},
238 lineComment: ";;"
242 lineComment: ";;"
239 };
243 };
240 });
244 });
241
245
242 CodeMirror.defineMIME("text/x-clojure", "clojure");
246 CodeMirror.defineMIME("text/x-clojure", "clojure");
247 CodeMirror.defineMIME("text/x-clojurescript", "clojure");
243
248
244 });
249 });
@@ -1,369 +1,355 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 /**
4 /**
5 * Link to the project's GitHub page:
5 * Link to the project's GitHub page:
6 * https://github.com/pickhardt/coffeescript-codemirror-mode
6 * https://github.com/pickhardt/coffeescript-codemirror-mode
7 */
7 */
8 (function(mod) {
8 (function(mod) {
9 if (typeof exports == "object" && typeof module == "object") // CommonJS
9 if (typeof exports == "object" && typeof module == "object") // CommonJS
10 mod(require("../../lib/codemirror"));
10 mod(require("../../lib/codemirror"));
11 else if (typeof define == "function" && define.amd) // AMD
11 else if (typeof define == "function" && define.amd) // AMD
12 define(["../../lib/codemirror"], mod);
12 define(["../../lib/codemirror"], mod);
13 else // Plain browser env
13 else // Plain browser env
14 mod(CodeMirror);
14 mod(CodeMirror);
15 })(function(CodeMirror) {
15 })(function(CodeMirror) {
16 "use strict";
16 "use strict";
17
17
18 CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
18 CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
19 var ERRORCLASS = "error";
19 var ERRORCLASS = "error";
20
20
21 function wordRegexp(words) {
21 function wordRegexp(words) {
22 return new RegExp("^((" + words.join(")|(") + "))\\b");
22 return new RegExp("^((" + words.join(")|(") + "))\\b");
23 }
23 }
24
24
25 var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;
25 var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;
26 var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
26 var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
27 var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
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 var wordOperators = wordRegexp(["and", "or", "not",
30 var wordOperators = wordRegexp(["and", "or", "not",
31 "is", "isnt", "in",
31 "is", "isnt", "in",
32 "instanceof", "typeof"]);
32 "instanceof", "typeof"]);
33 var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
33 var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
34 "switch", "try", "catch", "finally", "class"];
34 "switch", "try", "catch", "finally", "class"];
35 var commonKeywords = ["break", "by", "continue", "debugger", "delete",
35 var commonKeywords = ["break", "by", "continue", "debugger", "delete",
36 "do", "in", "of", "new", "return", "then",
36 "do", "in", "of", "new", "return", "then",
37 "this", "@", "throw", "when", "until", "extends"];
37 "this", "@", "throw", "when", "until", "extends"];
38
38
39 var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
39 var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
40
40
41 indentKeywords = wordRegexp(indentKeywords);
41 indentKeywords = wordRegexp(indentKeywords);
42
42
43
43
44 var stringPrefixes = /^('{3}|\"{3}|['\"])/;
44 var stringPrefixes = /^('{3}|\"{3}|['\"])/;
45 var regexPrefixes = /^(\/{3}|\/)/;
45 var regexPrefixes = /^(\/{3}|\/)/;
46 var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
46 var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
47 var constants = wordRegexp(commonConstants);
47 var constants = wordRegexp(commonConstants);
48
48
49 // Tokenizers
49 // Tokenizers
50 function tokenBase(stream, state) {
50 function tokenBase(stream, state) {
51 // Handle scope changes
51 // Handle scope changes
52 if (stream.sol()) {
52 if (stream.sol()) {
53 if (state.scope.align === null) state.scope.align = false;
53 if (state.scope.align === null) state.scope.align = false;
54 var scopeOffset = state.scope.offset;
54 var scopeOffset = state.scope.offset;
55 if (stream.eatSpace()) {
55 if (stream.eatSpace()) {
56 var lineOffset = stream.indentation();
56 var lineOffset = stream.indentation();
57 if (lineOffset > scopeOffset && state.scope.type == "coffee") {
57 if (lineOffset > scopeOffset && state.scope.type == "coffee") {
58 return "indent";
58 return "indent";
59 } else if (lineOffset < scopeOffset) {
59 } else if (lineOffset < scopeOffset) {
60 return "dedent";
60 return "dedent";
61 }
61 }
62 return null;
62 return null;
63 } else {
63 } else {
64 if (scopeOffset > 0) {
64 if (scopeOffset > 0) {
65 dedent(stream, state);
65 dedent(stream, state);
66 }
66 }
67 }
67 }
68 }
68 }
69 if (stream.eatSpace()) {
69 if (stream.eatSpace()) {
70 return null;
70 return null;
71 }
71 }
72
72
73 var ch = stream.peek();
73 var ch = stream.peek();
74
74
75 // Handle docco title comment (single line)
75 // Handle docco title comment (single line)
76 if (stream.match("####")) {
76 if (stream.match("####")) {
77 stream.skipToEnd();
77 stream.skipToEnd();
78 return "comment";
78 return "comment";
79 }
79 }
80
80
81 // Handle multi line comments
81 // Handle multi line comments
82 if (stream.match("###")) {
82 if (stream.match("###")) {
83 state.tokenize = longComment;
83 state.tokenize = longComment;
84 return state.tokenize(stream, state);
84 return state.tokenize(stream, state);
85 }
85 }
86
86
87 // Single line comment
87 // Single line comment
88 if (ch === "#") {
88 if (ch === "#") {
89 stream.skipToEnd();
89 stream.skipToEnd();
90 return "comment";
90 return "comment";
91 }
91 }
92
92
93 // Handle number literals
93 // Handle number literals
94 if (stream.match(/^-?[0-9\.]/, false)) {
94 if (stream.match(/^-?[0-9\.]/, false)) {
95 var floatLiteral = false;
95 var floatLiteral = false;
96 // Floats
96 // Floats
97 if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
97 if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
98 floatLiteral = true;
98 floatLiteral = true;
99 }
99 }
100 if (stream.match(/^-?\d+\.\d*/)) {
100 if (stream.match(/^-?\d+\.\d*/)) {
101 floatLiteral = true;
101 floatLiteral = true;
102 }
102 }
103 if (stream.match(/^-?\.\d+/)) {
103 if (stream.match(/^-?\.\d+/)) {
104 floatLiteral = true;
104 floatLiteral = true;
105 }
105 }
106
106
107 if (floatLiteral) {
107 if (floatLiteral) {
108 // prevent from getting extra . on 1..
108 // prevent from getting extra . on 1..
109 if (stream.peek() == "."){
109 if (stream.peek() == "."){
110 stream.backUp(1);
110 stream.backUp(1);
111 }
111 }
112 return "number";
112 return "number";
113 }
113 }
114 // Integers
114 // Integers
115 var intLiteral = false;
115 var intLiteral = false;
116 // Hex
116 // Hex
117 if (stream.match(/^-?0x[0-9a-f]+/i)) {
117 if (stream.match(/^-?0x[0-9a-f]+/i)) {
118 intLiteral = true;
118 intLiteral = true;
119 }
119 }
120 // Decimal
120 // Decimal
121 if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
121 if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
122 intLiteral = true;
122 intLiteral = true;
123 }
123 }
124 // Zero by itself with no other piece of number.
124 // Zero by itself with no other piece of number.
125 if (stream.match(/^-?0(?![\dx])/i)) {
125 if (stream.match(/^-?0(?![\dx])/i)) {
126 intLiteral = true;
126 intLiteral = true;
127 }
127 }
128 if (intLiteral) {
128 if (intLiteral) {
129 return "number";
129 return "number";
130 }
130 }
131 }
131 }
132
132
133 // Handle strings
133 // Handle strings
134 if (stream.match(stringPrefixes)) {
134 if (stream.match(stringPrefixes)) {
135 state.tokenize = tokenFactory(stream.current(), false, "string");
135 state.tokenize = tokenFactory(stream.current(), false, "string");
136 return state.tokenize(stream, state);
136 return state.tokenize(stream, state);
137 }
137 }
138 // Handle regex literals
138 // Handle regex literals
139 if (stream.match(regexPrefixes)) {
139 if (stream.match(regexPrefixes)) {
140 if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
140 if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
141 state.tokenize = tokenFactory(stream.current(), true, "string-2");
141 state.tokenize = tokenFactory(stream.current(), true, "string-2");
142 return state.tokenize(stream, state);
142 return state.tokenize(stream, state);
143 } else {
143 } else {
144 stream.backUp(1);
144 stream.backUp(1);
145 }
145 }
146 }
146 }
147
147
148
149
148 // Handle operators and delimiters
150 // Handle operators and delimiters
149 if (stream.match(operators) || stream.match(wordOperators)) {
151 if (stream.match(operators) || stream.match(wordOperators)) {
150 return "operator";
152 return "operator";
151 }
153 }
152 if (stream.match(delimiters)) {
154 if (stream.match(delimiters)) {
153 return "punctuation";
155 return "punctuation";
154 }
156 }
155
157
156 if (stream.match(constants)) {
158 if (stream.match(constants)) {
157 return "atom";
159 return "atom";
158 }
160 }
159
161
162 if (stream.match(atProp) || state.prop && stream.match(identifiers)) {
163 return "property";
164 }
165
160 if (stream.match(keywords)) {
166 if (stream.match(keywords)) {
161 return "keyword";
167 return "keyword";
162 }
168 }
163
169
164 if (stream.match(identifiers)) {
170 if (stream.match(identifiers)) {
165 return "variable";
171 return "variable";
166 }
172 }
167
173
168 if (stream.match(properties)) {
169 return "property";
170 }
171
172 // Handle non-detected items
174 // Handle non-detected items
173 stream.next();
175 stream.next();
174 return ERRORCLASS;
176 return ERRORCLASS;
175 }
177 }
176
178
177 function tokenFactory(delimiter, singleline, outclass) {
179 function tokenFactory(delimiter, singleline, outclass) {
178 return function(stream, state) {
180 return function(stream, state) {
179 while (!stream.eol()) {
181 while (!stream.eol()) {
180 stream.eatWhile(/[^'"\/\\]/);
182 stream.eatWhile(/[^'"\/\\]/);
181 if (stream.eat("\\")) {
183 if (stream.eat("\\")) {
182 stream.next();
184 stream.next();
183 if (singleline && stream.eol()) {
185 if (singleline && stream.eol()) {
184 return outclass;
186 return outclass;
185 }
187 }
186 } else if (stream.match(delimiter)) {
188 } else if (stream.match(delimiter)) {
187 state.tokenize = tokenBase;
189 state.tokenize = tokenBase;
188 return outclass;
190 return outclass;
189 } else {
191 } else {
190 stream.eat(/['"\/]/);
192 stream.eat(/['"\/]/);
191 }
193 }
192 }
194 }
193 if (singleline) {
195 if (singleline) {
194 if (parserConf.singleLineStringErrors) {
196 if (parserConf.singleLineStringErrors) {
195 outclass = ERRORCLASS;
197 outclass = ERRORCLASS;
196 } else {
198 } else {
197 state.tokenize = tokenBase;
199 state.tokenize = tokenBase;
198 }
200 }
199 }
201 }
200 return outclass;
202 return outclass;
201 };
203 };
202 }
204 }
203
205
204 function longComment(stream, state) {
206 function longComment(stream, state) {
205 while (!stream.eol()) {
207 while (!stream.eol()) {
206 stream.eatWhile(/[^#]/);
208 stream.eatWhile(/[^#]/);
207 if (stream.match("###")) {
209 if (stream.match("###")) {
208 state.tokenize = tokenBase;
210 state.tokenize = tokenBase;
209 break;
211 break;
210 }
212 }
211 stream.eatWhile("#");
213 stream.eatWhile("#");
212 }
214 }
213 return "comment";
215 return "comment";
214 }
216 }
215
217
216 function indent(stream, state, type) {
218 function indent(stream, state, type) {
217 type = type || "coffee";
219 type = type || "coffee";
218 var offset = 0, align = false, alignOffset = null;
220 var offset = 0, align = false, alignOffset = null;
219 for (var scope = state.scope; scope; scope = scope.prev) {
221 for (var scope = state.scope; scope; scope = scope.prev) {
220 if (scope.type === "coffee" || scope.type == "}") {
222 if (scope.type === "coffee" || scope.type == "}") {
221 offset = scope.offset + conf.indentUnit;
223 offset = scope.offset + conf.indentUnit;
222 break;
224 break;
223 }
225 }
224 }
226 }
225 if (type !== "coffee") {
227 if (type !== "coffee") {
226 align = null;
228 align = null;
227 alignOffset = stream.column() + stream.current().length;
229 alignOffset = stream.column() + stream.current().length;
228 } else if (state.scope.align) {
230 } else if (state.scope.align) {
229 state.scope.align = false;
231 state.scope.align = false;
230 }
232 }
231 state.scope = {
233 state.scope = {
232 offset: offset,
234 offset: offset,
233 type: type,
235 type: type,
234 prev: state.scope,
236 prev: state.scope,
235 align: align,
237 align: align,
236 alignOffset: alignOffset
238 alignOffset: alignOffset
237 };
239 };
238 }
240 }
239
241
240 function dedent(stream, state) {
242 function dedent(stream, state) {
241 if (!state.scope.prev) return;
243 if (!state.scope.prev) return;
242 if (state.scope.type === "coffee") {
244 if (state.scope.type === "coffee") {
243 var _indent = stream.indentation();
245 var _indent = stream.indentation();
244 var matched = false;
246 var matched = false;
245 for (var scope = state.scope; scope; scope = scope.prev) {
247 for (var scope = state.scope; scope; scope = scope.prev) {
246 if (_indent === scope.offset) {
248 if (_indent === scope.offset) {
247 matched = true;
249 matched = true;
248 break;
250 break;
249 }
251 }
250 }
252 }
251 if (!matched) {
253 if (!matched) {
252 return true;
254 return true;
253 }
255 }
254 while (state.scope.prev && state.scope.offset !== _indent) {
256 while (state.scope.prev && state.scope.offset !== _indent) {
255 state.scope = state.scope.prev;
257 state.scope = state.scope.prev;
256 }
258 }
257 return false;
259 return false;
258 } else {
260 } else {
259 state.scope = state.scope.prev;
261 state.scope = state.scope.prev;
260 return false;
262 return false;
261 }
263 }
262 }
264 }
263
265
264 function tokenLexer(stream, state) {
266 function tokenLexer(stream, state) {
265 var style = state.tokenize(stream, state);
267 var style = state.tokenize(stream, state);
266 var current = stream.current();
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 // Handle scope changes.
270 // Handle scope changes.
280 if (current === "return") {
271 if (current === "return") {
281 state.dedent = true;
272 state.dedent = true;
282 }
273 }
283 if (((current === "->" || current === "=>") &&
274 if (((current === "->" || current === "=>") && stream.eol())
284 !state.lambda &&
285 !stream.peek())
286 || style === "indent") {
275 || style === "indent") {
287 indent(stream, state);
276 indent(stream, state);
288 }
277 }
289 var delimiter_index = "[({".indexOf(current);
278 var delimiter_index = "[({".indexOf(current);
290 if (delimiter_index !== -1) {
279 if (delimiter_index !== -1) {
291 indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
280 indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
292 }
281 }
293 if (indentKeywords.exec(current)){
282 if (indentKeywords.exec(current)){
294 indent(stream, state);
283 indent(stream, state);
295 }
284 }
296 if (current == "then"){
285 if (current == "then"){
297 dedent(stream, state);
286 dedent(stream, state);
298 }
287 }
299
288
300
289
301 if (style === "dedent") {
290 if (style === "dedent") {
302 if (dedent(stream, state)) {
291 if (dedent(stream, state)) {
303 return ERRORCLASS;
292 return ERRORCLASS;
304 }
293 }
305 }
294 }
306 delimiter_index = "])}".indexOf(current);
295 delimiter_index = "])}".indexOf(current);
307 if (delimiter_index !== -1) {
296 if (delimiter_index !== -1) {
308 while (state.scope.type == "coffee" && state.scope.prev)
297 while (state.scope.type == "coffee" && state.scope.prev)
309 state.scope = state.scope.prev;
298 state.scope = state.scope.prev;
310 if (state.scope.type == current)
299 if (state.scope.type == current)
311 state.scope = state.scope.prev;
300 state.scope = state.scope.prev;
312 }
301 }
313 if (state.dedent && stream.eol()) {
302 if (state.dedent && stream.eol()) {
314 if (state.scope.type == "coffee" && state.scope.prev)
303 if (state.scope.type == "coffee" && state.scope.prev)
315 state.scope = state.scope.prev;
304 state.scope = state.scope.prev;
316 state.dedent = false;
305 state.dedent = false;
317 }
306 }
318
307
319 return style;
308 return style;
320 }
309 }
321
310
322 var external = {
311 var external = {
323 startState: function(basecolumn) {
312 startState: function(basecolumn) {
324 return {
313 return {
325 tokenize: tokenBase,
314 tokenize: tokenBase,
326 scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
315 scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
327 lastToken: null,
316 prop: false,
328 lambda: false,
329 dedent: 0
317 dedent: 0
330 };
318 };
331 },
319 },
332
320
333 token: function(stream, state) {
321 token: function(stream, state) {
334 var fillAlign = state.scope.align === null && state.scope;
322 var fillAlign = state.scope.align === null && state.scope;
335 if (fillAlign && stream.sol()) fillAlign.align = false;
323 if (fillAlign && stream.sol()) fillAlign.align = false;
336
324
337 var style = tokenLexer(stream, state);
325 var style = tokenLexer(stream, state);
338 if (fillAlign && style && style != "comment") fillAlign.align = true;
326 if (style && style != "comment") {
339
327 if (fillAlign) fillAlign.align = true;
340 state.lastToken = {style:style, content: stream.current()};
328 state.prop = style == "punctuation" && stream.current() == "."
341
342 if (stream.eol() && stream.lambda) {
343 state.lambda = false;
344 }
329 }
345
330
346 return style;
331 return style;
347 },
332 },
348
333
349 indent: function(state, text) {
334 indent: function(state, text) {
350 if (state.tokenize != tokenBase) return 0;
335 if (state.tokenize != tokenBase) return 0;
351 var scope = state.scope;
336 var scope = state.scope;
352 var closer = text && "])}".indexOf(text.charAt(0)) > -1;
337 var closer = text && "])}".indexOf(text.charAt(0)) > -1;
353 if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
338 if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
354 var closes = closer && scope.type === text.charAt(0);
339 var closes = closer && scope.type === text.charAt(0);
355 if (scope.align)
340 if (scope.align)
356 return scope.alignOffset - (closes ? 1 : 0);
341 return scope.alignOffset - (closes ? 1 : 0);
357 else
342 else
358 return (closes ? scope.prev : scope).offset;
343 return (closes ? scope.prev : scope).offset;
359 },
344 },
360
345
361 lineComment: "#",
346 lineComment: "#",
362 fold: "indent"
347 fold: "indent"
363 };
348 };
364 return external;
349 return external;
365 });
350 });
366
351
367 CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
352 CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
353 CodeMirror.defineMIME("text/coffeescript", "coffeescript");
368
354
369 });
355 });
@@ -1,754 +1,825 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("css", function(config, parserConfig) {
14 CodeMirror.defineMode("css", function(config, parserConfig) {
15 var inline = parserConfig.inline
15 if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
16 if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
16
17
17 var indentUnit = config.indentUnit,
18 var indentUnit = config.indentUnit,
18 tokenHooks = parserConfig.tokenHooks,
19 tokenHooks = parserConfig.tokenHooks,
19 documentTypes = parserConfig.documentTypes || {},
20 documentTypes = parserConfig.documentTypes || {},
20 mediaTypes = parserConfig.mediaTypes || {},
21 mediaTypes = parserConfig.mediaTypes || {},
21 mediaFeatures = parserConfig.mediaFeatures || {},
22 mediaFeatures = parserConfig.mediaFeatures || {},
23 mediaValueKeywords = parserConfig.mediaValueKeywords || {},
22 propertyKeywords = parserConfig.propertyKeywords || {},
24 propertyKeywords = parserConfig.propertyKeywords || {},
23 nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
25 nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
24 fontProperties = parserConfig.fontProperties || {},
26 fontProperties = parserConfig.fontProperties || {},
25 counterDescriptors = parserConfig.counterDescriptors || {},
27 counterDescriptors = parserConfig.counterDescriptors || {},
26 colorKeywords = parserConfig.colorKeywords || {},
28 colorKeywords = parserConfig.colorKeywords || {},
27 valueKeywords = parserConfig.valueKeywords || {},
29 valueKeywords = parserConfig.valueKeywords || {},
28 allowNested = parserConfig.allowNested;
30 allowNested = parserConfig.allowNested,
31 supportsAtComponent = parserConfig.supportsAtComponent === true;
29
32
30 var type, override;
33 var type, override;
31 function ret(style, tp) { type = tp; return style; }
34 function ret(style, tp) { type = tp; return style; }
32
35
33 // Tokenizers
36 // Tokenizers
34
37
35 function tokenBase(stream, state) {
38 function tokenBase(stream, state) {
36 var ch = stream.next();
39 var ch = stream.next();
37 if (tokenHooks[ch]) {
40 if (tokenHooks[ch]) {
38 var result = tokenHooks[ch](stream, state);
41 var result = tokenHooks[ch](stream, state);
39 if (result !== false) return result;
42 if (result !== false) return result;
40 }
43 }
41 if (ch == "@") {
44 if (ch == "@") {
42 stream.eatWhile(/[\w\\\-]/);
45 stream.eatWhile(/[\w\\\-]/);
43 return ret("def", stream.current());
46 return ret("def", stream.current());
44 } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
47 } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
45 return ret(null, "compare");
48 return ret(null, "compare");
46 } else if (ch == "\"" || ch == "'") {
49 } else if (ch == "\"" || ch == "'") {
47 state.tokenize = tokenString(ch);
50 state.tokenize = tokenString(ch);
48 return state.tokenize(stream, state);
51 return state.tokenize(stream, state);
49 } else if (ch == "#") {
52 } else if (ch == "#") {
50 stream.eatWhile(/[\w\\\-]/);
53 stream.eatWhile(/[\w\\\-]/);
51 return ret("atom", "hash");
54 return ret("atom", "hash");
52 } else if (ch == "!") {
55 } else if (ch == "!") {
53 stream.match(/^\s*\w*/);
56 stream.match(/^\s*\w*/);
54 return ret("keyword", "important");
57 return ret("keyword", "important");
55 } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
58 } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
56 stream.eatWhile(/[\w.%]/);
59 stream.eatWhile(/[\w.%]/);
57 return ret("number", "unit");
60 return ret("number", "unit");
58 } else if (ch === "-") {
61 } else if (ch === "-") {
59 if (/[\d.]/.test(stream.peek())) {
62 if (/[\d.]/.test(stream.peek())) {
60 stream.eatWhile(/[\w.%]/);
63 stream.eatWhile(/[\w.%]/);
61 return ret("number", "unit");
64 return ret("number", "unit");
62 } else if (stream.match(/^-[\w\\\-]+/)) {
65 } else if (stream.match(/^-[\w\\\-]+/)) {
63 stream.eatWhile(/[\w\\\-]/);
66 stream.eatWhile(/[\w\\\-]/);
64 if (stream.match(/^\s*:/, false))
67 if (stream.match(/^\s*:/, false))
65 return ret("variable-2", "variable-definition");
68 return ret("variable-2", "variable-definition");
66 return ret("variable-2", "variable");
69 return ret("variable-2", "variable");
67 } else if (stream.match(/^\w+-/)) {
70 } else if (stream.match(/^\w+-/)) {
68 return ret("meta", "meta");
71 return ret("meta", "meta");
69 }
72 }
70 } else if (/[,+>*\/]/.test(ch)) {
73 } else if (/[,+>*\/]/.test(ch)) {
71 return ret(null, "select-op");
74 return ret(null, "select-op");
72 } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
75 } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
73 return ret("qualifier", "qualifier");
76 return ret("qualifier", "qualifier");
74 } else if (/[:;{}\[\]\(\)]/.test(ch)) {
77 } else if (/[:;{}\[\]\(\)]/.test(ch)) {
75 return ret(null, ch);
78 return ret(null, ch);
76 } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
79 } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
77 (ch == "d" && stream.match("omain(")) ||
80 (ch == "d" && stream.match("omain(")) ||
78 (ch == "r" && stream.match("egexp("))) {
81 (ch == "r" && stream.match("egexp("))) {
79 stream.backUp(1);
82 stream.backUp(1);
80 state.tokenize = tokenParenthesized;
83 state.tokenize = tokenParenthesized;
81 return ret("property", "word");
84 return ret("property", "word");
82 } else if (/[\w\\\-]/.test(ch)) {
85 } else if (/[\w\\\-]/.test(ch)) {
83 stream.eatWhile(/[\w\\\-]/);
86 stream.eatWhile(/[\w\\\-]/);
84 return ret("property", "word");
87 return ret("property", "word");
85 } else {
88 } else {
86 return ret(null, null);
89 return ret(null, null);
87 }
90 }
88 }
91 }
89
92
90 function tokenString(quote) {
93 function tokenString(quote) {
91 return function(stream, state) {
94 return function(stream, state) {
92 var escaped = false, ch;
95 var escaped = false, ch;
93 while ((ch = stream.next()) != null) {
96 while ((ch = stream.next()) != null) {
94 if (ch == quote && !escaped) {
97 if (ch == quote && !escaped) {
95 if (quote == ")") stream.backUp(1);
98 if (quote == ")") stream.backUp(1);
96 break;
99 break;
97 }
100 }
98 escaped = !escaped && ch == "\\";
101 escaped = !escaped && ch == "\\";
99 }
102 }
100 if (ch == quote || !escaped && quote != ")") state.tokenize = null;
103 if (ch == quote || !escaped && quote != ")") state.tokenize = null;
101 return ret("string", "string");
104 return ret("string", "string");
102 };
105 };
103 }
106 }
104
107
105 function tokenParenthesized(stream, state) {
108 function tokenParenthesized(stream, state) {
106 stream.next(); // Must be '('
109 stream.next(); // Must be '('
107 if (!stream.match(/\s*[\"\')]/, false))
110 if (!stream.match(/\s*[\"\')]/, false))
108 state.tokenize = tokenString(")");
111 state.tokenize = tokenString(")");
109 else
112 else
110 state.tokenize = null;
113 state.tokenize = null;
111 return ret(null, "(");
114 return ret(null, "(");
112 }
115 }
113
116
114 // Context management
117 // Context management
115
118
116 function Context(type, indent, prev) {
119 function Context(type, indent, prev) {
117 this.type = type;
120 this.type = type;
118 this.indent = indent;
121 this.indent = indent;
119 this.prev = prev;
122 this.prev = prev;
120 }
123 }
121
124
122 function pushContext(state, stream, type) {
125 function pushContext(state, stream, type, indent) {
123 state.context = new Context(type, stream.indentation() + indentUnit, state.context);
126 state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
124 return type;
127 return type;
125 }
128 }
126
129
127 function popContext(state) {
130 function popContext(state) {
128 state.context = state.context.prev;
131 if (state.context.prev)
132 state.context = state.context.prev;
129 return state.context.type;
133 return state.context.type;
130 }
134 }
131
135
132 function pass(type, stream, state) {
136 function pass(type, stream, state) {
133 return states[state.context.type](type, stream, state);
137 return states[state.context.type](type, stream, state);
134 }
138 }
135 function popAndPass(type, stream, state, n) {
139 function popAndPass(type, stream, state, n) {
136 for (var i = n || 1; i > 0; i--)
140 for (var i = n || 1; i > 0; i--)
137 state.context = state.context.prev;
141 state.context = state.context.prev;
138 return pass(type, stream, state);
142 return pass(type, stream, state);
139 }
143 }
140
144
141 // Parser
145 // Parser
142
146
143 function wordAsValue(stream) {
147 function wordAsValue(stream) {
144 var word = stream.current().toLowerCase();
148 var word = stream.current().toLowerCase();
145 if (valueKeywords.hasOwnProperty(word))
149 if (valueKeywords.hasOwnProperty(word))
146 override = "atom";
150 override = "atom";
147 else if (colorKeywords.hasOwnProperty(word))
151 else if (colorKeywords.hasOwnProperty(word))
148 override = "keyword";
152 override = "keyword";
149 else
153 else
150 override = "variable";
154 override = "variable";
151 }
155 }
152
156
153 var states = {};
157 var states = {};
154
158
155 states.top = function(type, stream, state) {
159 states.top = function(type, stream, state) {
156 if (type == "{") {
160 if (type == "{") {
157 return pushContext(state, stream, "block");
161 return pushContext(state, stream, "block");
158 } else if (type == "}" && state.context.prev) {
162 } else if (type == "}" && state.context.prev) {
159 return popContext(state);
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 return pushContext(state, stream, "atBlock");
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 state.stateArg = type;
171 state.stateArg = type;
164 return "restricted_atBlock_before";
172 return "restricted_atBlock_before";
165 } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
173 } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
166 return "keyframes";
174 return "keyframes";
167 } else if (type && type.charAt(0) == "@") {
175 } else if (type && type.charAt(0) == "@") {
168 return pushContext(state, stream, "at");
176 return pushContext(state, stream, "at");
169 } else if (type == "hash") {
177 } else if (type == "hash") {
170 override = "builtin";
178 override = "builtin";
171 } else if (type == "word") {
179 } else if (type == "word") {
172 override = "tag";
180 override = "tag";
173 } else if (type == "variable-definition") {
181 } else if (type == "variable-definition") {
174 return "maybeprop";
182 return "maybeprop";
175 } else if (type == "interpolation") {
183 } else if (type == "interpolation") {
176 return pushContext(state, stream, "interpolation");
184 return pushContext(state, stream, "interpolation");
177 } else if (type == ":") {
185 } else if (type == ":") {
178 return "pseudo";
186 return "pseudo";
179 } else if (allowNested && type == "(") {
187 } else if (allowNested && type == "(") {
180 return pushContext(state, stream, "parens");
188 return pushContext(state, stream, "parens");
181 }
189 }
182 return state.context.type;
190 return state.context.type;
183 };
191 };
184
192
185 states.block = function(type, stream, state) {
193 states.block = function(type, stream, state) {
186 if (type == "word") {
194 if (type == "word") {
187 var word = stream.current().toLowerCase();
195 var word = stream.current().toLowerCase();
188 if (propertyKeywords.hasOwnProperty(word)) {
196 if (propertyKeywords.hasOwnProperty(word)) {
189 override = "property";
197 override = "property";
190 return "maybeprop";
198 return "maybeprop";
191 } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
199 } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
192 override = "string-2";
200 override = "string-2";
193 return "maybeprop";
201 return "maybeprop";
194 } else if (allowNested) {
202 } else if (allowNested) {
195 override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
203 override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
196 return "block";
204 return "block";
197 } else {
205 } else {
198 override += " error";
206 override += " error";
199 return "maybeprop";
207 return "maybeprop";
200 }
208 }
201 } else if (type == "meta") {
209 } else if (type == "meta") {
202 return "block";
210 return "block";
203 } else if (!allowNested && (type == "hash" || type == "qualifier")) {
211 } else if (!allowNested && (type == "hash" || type == "qualifier")) {
204 override = "error";
212 override = "error";
205 return "block";
213 return "block";
206 } else {
214 } else {
207 return states.top(type, stream, state);
215 return states.top(type, stream, state);
208 }
216 }
209 };
217 };
210
218
211 states.maybeprop = function(type, stream, state) {
219 states.maybeprop = function(type, stream, state) {
212 if (type == ":") return pushContext(state, stream, "prop");
220 if (type == ":") return pushContext(state, stream, "prop");
213 return pass(type, stream, state);
221 return pass(type, stream, state);
214 };
222 };
215
223
216 states.prop = function(type, stream, state) {
224 states.prop = function(type, stream, state) {
217 if (type == ";") return popContext(state);
225 if (type == ";") return popContext(state);
218 if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
226 if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
219 if (type == "}" || type == "{") return popAndPass(type, stream, state);
227 if (type == "}" || type == "{") return popAndPass(type, stream, state);
220 if (type == "(") return pushContext(state, stream, "parens");
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 override += " error";
231 override += " error";
224 } else if (type == "word") {
232 } else if (type == "word") {
225 wordAsValue(stream);
233 wordAsValue(stream);
226 } else if (type == "interpolation") {
234 } else if (type == "interpolation") {
227 return pushContext(state, stream, "interpolation");
235 return pushContext(state, stream, "interpolation");
228 }
236 }
229 return "prop";
237 return "prop";
230 };
238 };
231
239
232 states.propBlock = function(type, _stream, state) {
240 states.propBlock = function(type, _stream, state) {
233 if (type == "}") return popContext(state);
241 if (type == "}") return popContext(state);
234 if (type == "word") { override = "property"; return "maybeprop"; }
242 if (type == "word") { override = "property"; return "maybeprop"; }
235 return state.context.type;
243 return state.context.type;
236 };
244 };
237
245
238 states.parens = function(type, stream, state) {
246 states.parens = function(type, stream, state) {
239 if (type == "{" || type == "}") return popAndPass(type, stream, state);
247 if (type == "{" || type == "}") return popAndPass(type, stream, state);
240 if (type == ")") return popContext(state);
248 if (type == ")") return popContext(state);
241 if (type == "(") return pushContext(state, stream, "parens");
249 if (type == "(") return pushContext(state, stream, "parens");
242 if (type == "interpolation") return pushContext(state, stream, "interpolation");
250 if (type == "interpolation") return pushContext(state, stream, "interpolation");
243 if (type == "word") wordAsValue(stream);
251 if (type == "word") wordAsValue(stream);
244 return "parens";
252 return "parens";
245 };
253 };
246
254
247 states.pseudo = function(type, stream, state) {
255 states.pseudo = function(type, stream, state) {
248 if (type == "word") {
256 if (type == "word") {
249 override = "variable-3";
257 override = "variable-3";
250 return state.context.type;
258 return state.context.type;
251 }
259 }
252 return pass(type, stream, state);
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 states.atBlock = function(type, stream, state) {
272 states.atBlock = function(type, stream, state) {
256 if (type == "(") return pushContext(state, stream, "atBlock_parens");
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 if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
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 if (type == "word") {
279 if (type == "word") {
261 var word = stream.current().toLowerCase();
280 var word = stream.current().toLowerCase();
262 if (word == "only" || word == "not" || word == "and" || word == "or")
281 if (word == "only" || word == "not" || word == "and" || word == "or")
263 override = "keyword";
282 override = "keyword";
264 else if (documentTypes.hasOwnProperty(word))
265 override = "tag";
266 else if (mediaTypes.hasOwnProperty(word))
283 else if (mediaTypes.hasOwnProperty(word))
267 override = "attribute";
284 override = "attribute";
268 else if (mediaFeatures.hasOwnProperty(word))
285 else if (mediaFeatures.hasOwnProperty(word))
269 override = "property";
286 override = "property";
287 else if (mediaValueKeywords.hasOwnProperty(word))
288 override = "keyword";
270 else if (propertyKeywords.hasOwnProperty(word))
289 else if (propertyKeywords.hasOwnProperty(word))
271 override = "property";
290 override = "property";
272 else if (nonStandardPropertyKeywords.hasOwnProperty(word))
291 else if (nonStandardPropertyKeywords.hasOwnProperty(word))
273 override = "string-2";
292 override = "string-2";
274 else if (valueKeywords.hasOwnProperty(word))
293 else if (valueKeywords.hasOwnProperty(word))
275 override = "atom";
294 override = "atom";
295 else if (colorKeywords.hasOwnProperty(word))
296 override = "keyword";
276 else
297 else
277 override = "error";
298 override = "error";
278 }
299 }
279 return state.context.type;
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 states.atBlock_parens = function(type, stream, state) {
313 states.atBlock_parens = function(type, stream, state) {
283 if (type == ")") return popContext(state);
314 if (type == ")") return popContext(state);
284 if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
315 if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
285 return states.atBlock(type, stream, state);
316 return states.atBlock(type, stream, state);
286 };
317 };
287
318
288 states.restricted_atBlock_before = function(type, stream, state) {
319 states.restricted_atBlock_before = function(type, stream, state) {
289 if (type == "{")
320 if (type == "{")
290 return pushContext(state, stream, "restricted_atBlock");
321 return pushContext(state, stream, "restricted_atBlock");
291 if (type == "word" && state.stateArg == "@counter-style") {
322 if (type == "word" && state.stateArg == "@counter-style") {
292 override = "variable";
323 override = "variable";
293 return "restricted_atBlock_before";
324 return "restricted_atBlock_before";
294 }
325 }
295 return pass(type, stream, state);
326 return pass(type, stream, state);
296 };
327 };
297
328
298 states.restricted_atBlock = function(type, stream, state) {
329 states.restricted_atBlock = function(type, stream, state) {
299 if (type == "}") {
330 if (type == "}") {
300 state.stateArg = null;
331 state.stateArg = null;
301 return popContext(state);
332 return popContext(state);
302 }
333 }
303 if (type == "word") {
334 if (type == "word") {
304 if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
335 if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
305 (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
336 (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
306 override = "error";
337 override = "error";
307 else
338 else
308 override = "property";
339 override = "property";
309 return "maybeprop";
340 return "maybeprop";
310 }
341 }
311 return "restricted_atBlock";
342 return "restricted_atBlock";
312 };
343 };
313
344
314 states.keyframes = function(type, stream, state) {
345 states.keyframes = function(type, stream, state) {
315 if (type == "word") { override = "variable"; return "keyframes"; }
346 if (type == "word") { override = "variable"; return "keyframes"; }
316 if (type == "{") return pushContext(state, stream, "top");
347 if (type == "{") return pushContext(state, stream, "top");
317 return pass(type, stream, state);
348 return pass(type, stream, state);
318 };
349 };
319
350
320 states.at = function(type, stream, state) {
351 states.at = function(type, stream, state) {
321 if (type == ";") return popContext(state);
352 if (type == ";") return popContext(state);
322 if (type == "{" || type == "}") return popAndPass(type, stream, state);
353 if (type == "{" || type == "}") return popAndPass(type, stream, state);
323 if (type == "word") override = "tag";
354 if (type == "word") override = "tag";
324 else if (type == "hash") override = "builtin";
355 else if (type == "hash") override = "builtin";
325 return "at";
356 return "at";
326 };
357 };
327
358
328 states.interpolation = function(type, stream, state) {
359 states.interpolation = function(type, stream, state) {
329 if (type == "}") return popContext(state);
360 if (type == "}") return popContext(state);
330 if (type == "{" || type == ";") return popAndPass(type, stream, state);
361 if (type == "{" || type == ";") return popAndPass(type, stream, state);
331 if (type == "word") override = "variable";
362 if (type == "word") override = "variable";
332 else if (type != "variable" && type != "(" && type != ")") override = "error";
363 else if (type != "variable" && type != "(" && type != ")") override = "error";
333 return "interpolation";
364 return "interpolation";
334 };
365 };
335
366
336 return {
367 return {
337 startState: function(base) {
368 startState: function(base) {
338 return {tokenize: null,
369 return {tokenize: null,
339 state: "top",
370 state: inline ? "block" : "top",
340 stateArg: null,
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 token: function(stream, state) {
375 token: function(stream, state) {
345 if (!state.tokenize && stream.eatSpace()) return null;
376 if (!state.tokenize && stream.eatSpace()) return null;
346 var style = (state.tokenize || tokenBase)(stream, state);
377 var style = (state.tokenize || tokenBase)(stream, state);
347 if (style && typeof style == "object") {
378 if (style && typeof style == "object") {
348 type = style[1];
379 type = style[1];
349 style = style[0];
380 style = style[0];
350 }
381 }
351 override = style;
382 override = style;
352 state.state = states[state.state](type, stream, state);
383 state.state = states[state.state](type, stream, state);
353 return override;
384 return override;
354 },
385 },
355
386
356 indent: function(state, textAfter) {
387 indent: function(state, textAfter) {
357 var cx = state.context, ch = textAfter && textAfter.charAt(0);
388 var cx = state.context, ch = textAfter && textAfter.charAt(0);
358 var indent = cx.indent;
389 var indent = cx.indent;
359 if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
390 if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
360 if (cx.prev &&
391 if (cx.prev) {
361 (ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "restricted_atBlock") ||
392 if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
362 ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
393 cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
363 ch == "{" && (cx.type == "at" || cx.type == "atBlock"))) {
394 // Resume indentation from parent context.
364 indent = cx.indent - indentUnit;
395 cx = cx.prev;
365 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 return indent;
404 return indent;
368 },
405 },
369
406
370 electricChars: "}",
407 electricChars: "}",
371 blockCommentStart: "/*",
408 blockCommentStart: "/*",
372 blockCommentEnd: "*/",
409 blockCommentEnd: "*/",
373 fold: "brace"
410 fold: "brace"
374 };
411 };
375 });
412 });
376
413
377 function keySet(array) {
414 function keySet(array) {
378 var keys = {};
415 var keys = {};
379 for (var i = 0; i < array.length; ++i) {
416 for (var i = 0; i < array.length; ++i) {
380 keys[array[i]] = true;
417 keys[array[i]] = true;
381 }
418 }
382 return keys;
419 return keys;
383 }
420 }
384
421
385 var documentTypes_ = [
422 var documentTypes_ = [
386 "domain", "regexp", "url", "url-prefix"
423 "domain", "regexp", "url", "url-prefix"
387 ], documentTypes = keySet(documentTypes_);
424 ], documentTypes = keySet(documentTypes_);
388
425
389 var mediaTypes_ = [
426 var mediaTypes_ = [
390 "all", "aural", "braille", "handheld", "print", "projection", "screen",
427 "all", "aural", "braille", "handheld", "print", "projection", "screen",
391 "tty", "tv", "embossed"
428 "tty", "tv", "embossed"
392 ], mediaTypes = keySet(mediaTypes_);
429 ], mediaTypes = keySet(mediaTypes_);
393
430
394 var mediaFeatures_ = [
431 var mediaFeatures_ = [
395 "width", "min-width", "max-width", "height", "min-height", "max-height",
432 "width", "min-width", "max-width", "height", "min-height", "max-height",
396 "device-width", "min-device-width", "max-device-width", "device-height",
433 "device-width", "min-device-width", "max-device-width", "device-height",
397 "min-device-height", "max-device-height", "aspect-ratio",
434 "min-device-height", "max-device-height", "aspect-ratio",
398 "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
435 "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
399 "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
436 "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
400 "max-color", "color-index", "min-color-index", "max-color-index",
437 "max-color", "color-index", "min-color-index", "max-color-index",
401 "monochrome", "min-monochrome", "max-monochrome", "resolution",
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 ], mediaFeatures = keySet(mediaFeatures_);
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 var propertyKeywords_ = [
449 var propertyKeywords_ = [
406 "align-content", "align-items", "align-self", "alignment-adjust",
450 "align-content", "align-items", "align-self", "alignment-adjust",
407 "alignment-baseline", "anchor-point", "animation", "animation-delay",
451 "alignment-baseline", "anchor-point", "animation", "animation-delay",
408 "animation-direction", "animation-duration", "animation-fill-mode",
452 "animation-direction", "animation-duration", "animation-fill-mode",
409 "animation-iteration-count", "animation-name", "animation-play-state",
453 "animation-iteration-count", "animation-name", "animation-play-state",
410 "animation-timing-function", "appearance", "azimuth", "backface-visibility",
454 "animation-timing-function", "appearance", "azimuth", "backface-visibility",
411 "background", "background-attachment", "background-clip", "background-color",
455 "background", "background-attachment", "background-blend-mode", "background-clip",
412 "background-image", "background-origin", "background-position",
456 "background-color", "background-image", "background-origin", "background-position",
413 "background-repeat", "background-size", "baseline-shift", "binding",
457 "background-repeat", "background-size", "baseline-shift", "binding",
414 "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
458 "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
415 "bookmark-target", "border", "border-bottom", "border-bottom-color",
459 "bookmark-target", "border", "border-bottom", "border-bottom-color",
416 "border-bottom-left-radius", "border-bottom-right-radius",
460 "border-bottom-left-radius", "border-bottom-right-radius",
417 "border-bottom-style", "border-bottom-width", "border-collapse",
461 "border-bottom-style", "border-bottom-width", "border-collapse",
418 "border-color", "border-image", "border-image-outset",
462 "border-color", "border-image", "border-image-outset",
419 "border-image-repeat", "border-image-slice", "border-image-source",
463 "border-image-repeat", "border-image-slice", "border-image-source",
420 "border-image-width", "border-left", "border-left-color",
464 "border-image-width", "border-left", "border-left-color",
421 "border-left-style", "border-left-width", "border-radius", "border-right",
465 "border-left-style", "border-left-width", "border-radius", "border-right",
422 "border-right-color", "border-right-style", "border-right-width",
466 "border-right-color", "border-right-style", "border-right-width",
423 "border-spacing", "border-style", "border-top", "border-top-color",
467 "border-spacing", "border-style", "border-top", "border-top-color",
424 "border-top-left-radius", "border-top-right-radius", "border-top-style",
468 "border-top-left-radius", "border-top-right-radius", "border-top-style",
425 "border-top-width", "border-width", "bottom", "box-decoration-break",
469 "border-top-width", "border-width", "bottom", "box-decoration-break",
426 "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
470 "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
427 "caption-side", "clear", "clip", "color", "color-profile", "column-count",
471 "caption-side", "clear", "clip", "color", "color-profile", "column-count",
428 "column-fill", "column-gap", "column-rule", "column-rule-color",
472 "column-fill", "column-gap", "column-rule", "column-rule-color",
429 "column-rule-style", "column-rule-width", "column-span", "column-width",
473 "column-rule-style", "column-rule-width", "column-span", "column-width",
430 "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
474 "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
431 "cue-after", "cue-before", "cursor", "direction", "display",
475 "cue-after", "cue-before", "cursor", "direction", "display",
432 "dominant-baseline", "drop-initial-after-adjust",
476 "dominant-baseline", "drop-initial-after-adjust",
433 "drop-initial-after-align", "drop-initial-before-adjust",
477 "drop-initial-after-align", "drop-initial-before-adjust",
434 "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
478 "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
435 "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
479 "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
436 "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
480 "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
437 "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
481 "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
438 "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
482 "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
439 "font-stretch", "font-style", "font-synthesis", "font-variant",
483 "font-stretch", "font-style", "font-synthesis", "font-variant",
440 "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
484 "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
441 "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
485 "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
442 "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
486 "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
443 "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
487 "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
444 "grid-column-start", "grid-row", "grid-row-end", "grid-row-start",
488 "grid-column-start", "grid-row", "grid-row-end", "grid-row-start",
445 "grid-template", "grid-template-areas", "grid-template-columns",
489 "grid-template", "grid-template-areas", "grid-template-columns",
446 "grid-template-rows", "hanging-punctuation", "height", "hyphens",
490 "grid-template-rows", "hanging-punctuation", "height", "hyphens",
447 "icon", "image-orientation", "image-rendering", "image-resolution",
491 "icon", "image-orientation", "image-rendering", "image-resolution",
448 "inline-box-align", "justify-content", "left", "letter-spacing",
492 "inline-box-align", "justify-content", "left", "letter-spacing",
449 "line-break", "line-height", "line-stacking", "line-stacking-ruby",
493 "line-break", "line-height", "line-stacking", "line-stacking-ruby",
450 "line-stacking-shift", "line-stacking-strategy", "list-style",
494 "line-stacking-shift", "line-stacking-strategy", "list-style",
451 "list-style-image", "list-style-position", "list-style-type", "margin",
495 "list-style-image", "list-style-position", "list-style-type", "margin",
452 "margin-bottom", "margin-left", "margin-right", "margin-top",
496 "margin-bottom", "margin-left", "margin-right", "margin-top",
453 "marker-offset", "marks", "marquee-direction", "marquee-loop",
497 "marker-offset", "marks", "marquee-direction", "marquee-loop",
454 "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
498 "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
455 "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
499 "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
456 "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
500 "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
457 "opacity", "order", "orphans", "outline",
501 "opacity", "order", "orphans", "outline",
458 "outline-color", "outline-offset", "outline-style", "outline-width",
502 "outline-color", "outline-offset", "outline-style", "outline-width",
459 "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
503 "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
460 "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
504 "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
461 "page", "page-break-after", "page-break-before", "page-break-inside",
505 "page", "page-break-after", "page-break-before", "page-break-inside",
462 "page-policy", "pause", "pause-after", "pause-before", "perspective",
506 "page-policy", "pause", "pause-after", "pause-before", "perspective",
463 "perspective-origin", "pitch", "pitch-range", "play-during", "position",
507 "perspective-origin", "pitch", "pitch-range", "play-during", "position",
464 "presentation-level", "punctuation-trim", "quotes", "region-break-after",
508 "presentation-level", "punctuation-trim", "quotes", "region-break-after",
465 "region-break-before", "region-break-inside", "region-fragment",
509 "region-break-before", "region-break-inside", "region-fragment",
466 "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
510 "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
467 "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
511 "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
468 "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
512 "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
469 "shape-outside", "size", "speak", "speak-as", "speak-header",
513 "shape-outside", "size", "speak", "speak-as", "speak-header",
470 "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
514 "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
471 "tab-size", "table-layout", "target", "target-name", "target-new",
515 "tab-size", "table-layout", "target", "target-name", "target-new",
472 "target-position", "text-align", "text-align-last", "text-decoration",
516 "target-position", "text-align", "text-align-last", "text-decoration",
473 "text-decoration-color", "text-decoration-line", "text-decoration-skip",
517 "text-decoration-color", "text-decoration-line", "text-decoration-skip",
474 "text-decoration-style", "text-emphasis", "text-emphasis-color",
518 "text-decoration-style", "text-emphasis", "text-emphasis-color",
475 "text-emphasis-position", "text-emphasis-style", "text-height",
519 "text-emphasis-position", "text-emphasis-style", "text-height",
476 "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
520 "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
477 "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
521 "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
478 "text-wrap", "top", "transform", "transform-origin", "transform-style",
522 "text-wrap", "top", "transform", "transform-origin", "transform-style",
479 "transition", "transition-delay", "transition-duration",
523 "transition", "transition-delay", "transition-duration",
480 "transition-property", "transition-timing-function", "unicode-bidi",
524 "transition-property", "transition-timing-function", "unicode-bidi",
481 "vertical-align", "visibility", "voice-balance", "voice-duration",
525 "vertical-align", "visibility", "voice-balance", "voice-duration",
482 "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
526 "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
483 "voice-volume", "volume", "white-space", "widows", "width", "word-break",
527 "voice-volume", "volume", "white-space", "widows", "width", "word-break",
484 "word-spacing", "word-wrap", "z-index",
528 "word-spacing", "word-wrap", "z-index",
485 // SVG-specific
529 // SVG-specific
486 "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
530 "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
487 "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
531 "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
488 "color-interpolation", "color-interpolation-filters",
532 "color-interpolation", "color-interpolation-filters",
489 "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
533 "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
490 "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
534 "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
491 "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
535 "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
492 "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
536 "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
493 "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
537 "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
494 "glyph-orientation-vertical", "text-anchor", "writing-mode"
538 "glyph-orientation-vertical", "text-anchor", "writing-mode"
495 ], propertyKeywords = keySet(propertyKeywords_);
539 ], propertyKeywords = keySet(propertyKeywords_);
496
540
497 var nonStandardPropertyKeywords_ = [
541 var nonStandardPropertyKeywords_ = [
498 "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
542 "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
499 "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
543 "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
500 "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
544 "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
501 "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
545 "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
502 "searchfield-results-decoration", "zoom"
546 "searchfield-results-decoration", "zoom"
503 ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
547 ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
504
548
505 var fontProperties_ = [
549 var fontProperties_ = [
506 "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
550 "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
507 "font-stretch", "font-weight", "font-style"
551 "font-stretch", "font-weight", "font-style"
508 ], fontProperties = keySet(fontProperties_);
552 ], fontProperties = keySet(fontProperties_);
509
553
510 var counterDescriptors_ = [
554 var counterDescriptors_ = [
511 "additive-symbols", "fallback", "negative", "pad", "prefix", "range",
555 "additive-symbols", "fallback", "negative", "pad", "prefix", "range",
512 "speak-as", "suffix", "symbols", "system"
556 "speak-as", "suffix", "symbols", "system"
513 ], counterDescriptors = keySet(counterDescriptors_);
557 ], counterDescriptors = keySet(counterDescriptors_);
514
558
515 var colorKeywords_ = [
559 var colorKeywords_ = [
516 "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
560 "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
517 "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
561 "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
518 "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
562 "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
519 "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
563 "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
520 "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
564 "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
521 "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
565 "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
522 "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
566 "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
523 "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
567 "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
524 "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
568 "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
525 "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
569 "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
526 "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
570 "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
527 "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
571 "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
528 "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
572 "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
529 "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
573 "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
530 "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
574 "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
531 "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
575 "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
532 "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
576 "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
533 "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
577 "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
534 "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
578 "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
535 "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
579 "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
536 "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
580 "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
537 "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
581 "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
538 "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
582 "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
539 "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
583 "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
540 "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
584 "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
541 "whitesmoke", "yellow", "yellowgreen"
585 "whitesmoke", "yellow", "yellowgreen"
542 ], colorKeywords = keySet(colorKeywords_);
586 ], colorKeywords = keySet(colorKeywords_);
543
587
544 var valueKeywords_ = [
588 var valueKeywords_ = [
545 "above", "absolute", "activeborder", "additive", "activecaption", "afar",
589 "above", "absolute", "activeborder", "additive", "activecaption", "afar",
546 "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
590 "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
547 "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
591 "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
548 "arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page",
592 "arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page",
549 "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
593 "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
550 "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
594 "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
551 "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
595 "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
552 "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
596 "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
553 "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
597 "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
554 "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
598 "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
555 "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
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 "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
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 "decimal-leading-zero", "default", "default-button", "destination-atop",
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 "disc", "discard", "disclosure-closed", "disclosure-open", "document",
606 "disc", "discard", "disclosure-closed", "disclosure-open", "document",
562 "dot-dash", "dot-dot-dash",
607 "dot-dash", "dot-dot-dash",
563 "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
608 "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
564 "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
609 "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
565 "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
610 "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
566 "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
611 "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
567 "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
612 "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
568 "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
613 "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
569 "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
614 "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
570 "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
615 "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
571 "ethiopic-numeric", "ew-resize", "expanded", "extends", "extra-condensed",
616 "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
572 "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "footnotes",
617 "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
573 "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
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 "help", "hidden", "hide", "higher", "highlight", "highlighttext",
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 "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
622 "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
578 "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
623 "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
579 "inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
624 "inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
580 "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
625 "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
581 "katakana", "katakana-iroha", "keep-all", "khmer",
626 "katakana", "katakana-iroha", "keep-all", "khmer",
582 "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
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 "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
629 "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
585 "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
630 "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
586 "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
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 "media-controls-background", "media-current-time-display",
633 "media-controls-background", "media-current-time-display",
589 "media-fullscreen-button", "media-mute-button", "media-play-button",
634 "media-fullscreen-button", "media-mute-button", "media-play-button",
590 "media-return-to-realtime-button", "media-rewind-button",
635 "media-return-to-realtime-button", "media-rewind-button",
591 "media-seek-back-button", "media-seek-forward-button", "media-slider",
636 "media-seek-back-button", "media-seek-forward-button", "media-slider",
592 "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
637 "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
593 "media-volume-slider-container", "media-volume-sliderthumb", "medium",
638 "media-volume-slider-container", "media-volume-sliderthumb", "medium",
594 "menu", "menulist", "menulist-button", "menulist-text",
639 "menu", "menulist", "menulist-button", "menulist-text",
595 "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
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 "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
642 "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
598 "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
643 "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
599 "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
644 "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
600 "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
645 "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
601 "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
646 "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
602 "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
647 "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
603 "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
648 "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
604 "progress", "push-button", "radial-gradient", "radio", "read-only",
649 "progress", "push-button", "radial-gradient", "radio", "read-only",
605 "read-write", "read-write-plaintext-only", "rectangle", "region",
650 "read-write", "read-write-plaintext-only", "rectangle", "region",
606 "relative", "repeat", "repeating-linear-gradient",
651 "relative", "repeat", "repeating-linear-gradient",
607 "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
652 "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
608 "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
653 "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
609 "rotateZ", "round", "row-resize", "rtl", "run-in", "running",
654 "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
610 "s-resize", "sans-serif", "scale", "scale3d", "scaleX", "scaleY", "scaleZ",
655 "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
611 "scroll", "scrollbar", "se-resize", "searchfield",
656 "scroll", "scrollbar", "se-resize", "searchfield",
612 "searchfield-cancel-button", "searchfield-decoration",
657 "searchfield-cancel-button", "searchfield-decoration",
613 "searchfield-results-button", "searchfield-results-decoration",
658 "searchfield-results-button", "searchfield-results-decoration",
614 "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
659 "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
615 "simp-chinese-formal", "simp-chinese-informal", "single",
660 "simp-chinese-formal", "simp-chinese-informal", "single",
616 "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
661 "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
617 "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
662 "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
618 "small", "small-caps", "small-caption", "smaller", "solid", "somali",
663 "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
619 "source-atop", "source-in", "source-out", "source-over", "space", "spell-out", "square",
664 "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square",
620 "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
665 "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
621 "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
666 "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
622 "table-caption", "table-cell", "table-column", "table-column-group",
667 "table-caption", "table-cell", "table-column", "table-column-group",
623 "table-footer-group", "table-header-group", "table-row", "table-row-group",
668 "table-footer-group", "table-header-group", "table-row", "table-row-group",
624 "tamil",
669 "tamil",
625 "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
670 "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
626 "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
671 "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
627 "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
672 "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
628 "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
673 "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
629 "trad-chinese-formal", "trad-chinese-informal",
674 "trad-chinese-formal", "trad-chinese-informal",
630 "translate", "translate3d", "translateX", "translateY", "translateZ",
675 "translate", "translate3d", "translateX", "translateY", "translateZ",
631 "transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
676 "transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
632 "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
677 "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
633 "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
678 "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
634 "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
679 "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
635 "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
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 "xx-large", "xx-small"
682 "xx-large", "xx-small"
638 ], valueKeywords = keySet(valueKeywords_);
683 ], valueKeywords = keySet(valueKeywords_);
639
684
640 var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(propertyKeywords_)
685 var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
641 .concat(nonStandardPropertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
686 .concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
687 .concat(valueKeywords_);
642 CodeMirror.registerHelper("hintWords", "css", allWords);
688 CodeMirror.registerHelper("hintWords", "css", allWords);
643
689
644 function tokenCComment(stream, state) {
690 function tokenCComment(stream, state) {
645 var maybeEnd = false, ch;
691 var maybeEnd = false, ch;
646 while ((ch = stream.next()) != null) {
692 while ((ch = stream.next()) != null) {
647 if (maybeEnd && ch == "/") {
693 if (maybeEnd && ch == "/") {
648 state.tokenize = null;
694 state.tokenize = null;
649 break;
695 break;
650 }
696 }
651 maybeEnd = (ch == "*");
697 maybeEnd = (ch == "*");
652 }
698 }
653 return ["comment", "comment"];
699 return ["comment", "comment"];
654 }
700 }
655
701
656 CodeMirror.defineMIME("text/css", {
702 CodeMirror.defineMIME("text/css", {
657 documentTypes: documentTypes,
703 documentTypes: documentTypes,
658 mediaTypes: mediaTypes,
704 mediaTypes: mediaTypes,
659 mediaFeatures: mediaFeatures,
705 mediaFeatures: mediaFeatures,
706 mediaValueKeywords: mediaValueKeywords,
660 propertyKeywords: propertyKeywords,
707 propertyKeywords: propertyKeywords,
661 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
708 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
662 fontProperties: fontProperties,
709 fontProperties: fontProperties,
663 counterDescriptors: counterDescriptors,
710 counterDescriptors: counterDescriptors,
664 colorKeywords: colorKeywords,
711 colorKeywords: colorKeywords,
665 valueKeywords: valueKeywords,
712 valueKeywords: valueKeywords,
666 tokenHooks: {
713 tokenHooks: {
667 "/": function(stream, state) {
714 "/": function(stream, state) {
668 if (!stream.eat("*")) return false;
715 if (!stream.eat("*")) return false;
669 state.tokenize = tokenCComment;
716 state.tokenize = tokenCComment;
670 return tokenCComment(stream, state);
717 return tokenCComment(stream, state);
671 }
718 }
672 },
719 },
673 name: "css"
720 name: "css"
674 });
721 });
675
722
676 CodeMirror.defineMIME("text/x-scss", {
723 CodeMirror.defineMIME("text/x-scss", {
677 mediaTypes: mediaTypes,
724 mediaTypes: mediaTypes,
678 mediaFeatures: mediaFeatures,
725 mediaFeatures: mediaFeatures,
726 mediaValueKeywords: mediaValueKeywords,
679 propertyKeywords: propertyKeywords,
727 propertyKeywords: propertyKeywords,
680 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
728 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
681 colorKeywords: colorKeywords,
729 colorKeywords: colorKeywords,
682 valueKeywords: valueKeywords,
730 valueKeywords: valueKeywords,
683 fontProperties: fontProperties,
731 fontProperties: fontProperties,
684 allowNested: true,
732 allowNested: true,
685 tokenHooks: {
733 tokenHooks: {
686 "/": function(stream, state) {
734 "/": function(stream, state) {
687 if (stream.eat("/")) {
735 if (stream.eat("/")) {
688 stream.skipToEnd();
736 stream.skipToEnd();
689 return ["comment", "comment"];
737 return ["comment", "comment"];
690 } else if (stream.eat("*")) {
738 } else if (stream.eat("*")) {
691 state.tokenize = tokenCComment;
739 state.tokenize = tokenCComment;
692 return tokenCComment(stream, state);
740 return tokenCComment(stream, state);
693 } else {
741 } else {
694 return ["operator", "operator"];
742 return ["operator", "operator"];
695 }
743 }
696 },
744 },
697 ":": function(stream) {
745 ":": function(stream) {
698 if (stream.match(/\s*\{/))
746 if (stream.match(/\s*\{/))
699 return [null, "{"];
747 return [null, "{"];
700 return false;
748 return false;
701 },
749 },
702 "$": function(stream) {
750 "$": function(stream) {
703 stream.match(/^[\w-]+/);
751 stream.match(/^[\w-]+/);
704 if (stream.match(/^\s*:/, false))
752 if (stream.match(/^\s*:/, false))
705 return ["variable-2", "variable-definition"];
753 return ["variable-2", "variable-definition"];
706 return ["variable-2", "variable"];
754 return ["variable-2", "variable"];
707 },
755 },
708 "#": function(stream) {
756 "#": function(stream) {
709 if (!stream.eat("{")) return false;
757 if (!stream.eat("{")) return false;
710 return [null, "interpolation"];
758 return [null, "interpolation"];
711 }
759 }
712 },
760 },
713 name: "css",
761 name: "css",
714 helperType: "scss"
762 helperType: "scss"
715 });
763 });
716
764
717 CodeMirror.defineMIME("text/x-less", {
765 CodeMirror.defineMIME("text/x-less", {
718 mediaTypes: mediaTypes,
766 mediaTypes: mediaTypes,
719 mediaFeatures: mediaFeatures,
767 mediaFeatures: mediaFeatures,
768 mediaValueKeywords: mediaValueKeywords,
720 propertyKeywords: propertyKeywords,
769 propertyKeywords: propertyKeywords,
721 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
770 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
722 colorKeywords: colorKeywords,
771 colorKeywords: colorKeywords,
723 valueKeywords: valueKeywords,
772 valueKeywords: valueKeywords,
724 fontProperties: fontProperties,
773 fontProperties: fontProperties,
725 allowNested: true,
774 allowNested: true,
726 tokenHooks: {
775 tokenHooks: {
727 "/": function(stream, state) {
776 "/": function(stream, state) {
728 if (stream.eat("/")) {
777 if (stream.eat("/")) {
729 stream.skipToEnd();
778 stream.skipToEnd();
730 return ["comment", "comment"];
779 return ["comment", "comment"];
731 } else if (stream.eat("*")) {
780 } else if (stream.eat("*")) {
732 state.tokenize = tokenCComment;
781 state.tokenize = tokenCComment;
733 return tokenCComment(stream, state);
782 return tokenCComment(stream, state);
734 } else {
783 } else {
735 return ["operator", "operator"];
784 return ["operator", "operator"];
736 }
785 }
737 },
786 },
738 "@": function(stream) {
787 "@": function(stream) {
739 if (stream.eat("{")) return [null, "interpolation"];
788 if (stream.eat("{")) return [null, "interpolation"];
740 if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
789 if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
741 stream.eatWhile(/[\w\\\-]/);
790 stream.eatWhile(/[\w\\\-]/);
742 if (stream.match(/^\s*:/, false))
791 if (stream.match(/^\s*:/, false))
743 return ["variable-2", "variable-definition"];
792 return ["variable-2", "variable-definition"];
744 return ["variable-2", "variable"];
793 return ["variable-2", "variable"];
745 },
794 },
746 "&": function() {
795 "&": function() {
747 return ["atom", "atom"];
796 return ["atom", "atom"];
748 }
797 }
749 },
798 },
750 name: "css",
799 name: "css",
751 helperType: "less"
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"
823 });
824
754 });
825 });
@@ -1,146 +1,146 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 // By the Neo4j Team and contributors.
4 // By the Neo4j Team and contributors.
5 // https://github.com/neo4j-contrib/CodeMirror
5 // https://github.com/neo4j-contrib/CodeMirror
6
6
7 (function(mod) {
7 (function(mod) {
8 if (typeof exports == "object" && typeof module == "object") // CommonJS
8 if (typeof exports == "object" && typeof module == "object") // CommonJS
9 mod(require("../../lib/codemirror"));
9 mod(require("../../lib/codemirror"));
10 else if (typeof define == "function" && define.amd) // AMD
10 else if (typeof define == "function" && define.amd) // AMD
11 define(["../../lib/codemirror"], mod);
11 define(["../../lib/codemirror"], mod);
12 else // Plain browser env
12 else // Plain browser env
13 mod(CodeMirror);
13 mod(CodeMirror);
14 })(function(CodeMirror) {
14 })(function(CodeMirror) {
15 "use strict";
15 "use strict";
16 var wordRegexp = function(words) {
16 var wordRegexp = function(words) {
17 return new RegExp("^(?:" + words.join("|") + ")$", "i");
17 return new RegExp("^(?:" + words.join("|") + ")$", "i");
18 };
18 };
19
19
20 CodeMirror.defineMode("cypher", function(config) {
20 CodeMirror.defineMode("cypher", function(config) {
21 var tokenBase = function(stream/*, state*/) {
21 var tokenBase = function(stream/*, state*/) {
22 var ch = stream.next();
22 var ch = stream.next();
23 if (ch === "\"" || ch === "'") {
23 if (ch === "\"" || ch === "'") {
24 stream.match(/.+?["']/);
24 stream.match(/.+?["']/);
25 return "string";
25 return "string";
26 }
26 }
27 if (/[{}\(\),\.;\[\]]/.test(ch)) {
27 if (/[{}\(\),\.;\[\]]/.test(ch)) {
28 curPunc = ch;
28 curPunc = ch;
29 return "node";
29 return "node";
30 } else if (ch === "/" && stream.eat("/")) {
30 } else if (ch === "/" && stream.eat("/")) {
31 stream.skipToEnd();
31 stream.skipToEnd();
32 return "comment";
32 return "comment";
33 } else if (operatorChars.test(ch)) {
33 } else if (operatorChars.test(ch)) {
34 stream.eatWhile(operatorChars);
34 stream.eatWhile(operatorChars);
35 return null;
35 return null;
36 } else {
36 } else {
37 stream.eatWhile(/[_\w\d]/);
37 stream.eatWhile(/[_\w\d]/);
38 if (stream.eat(":")) {
38 if (stream.eat(":")) {
39 stream.eatWhile(/[\w\d_\-]/);
39 stream.eatWhile(/[\w\d_\-]/);
40 return "atom";
40 return "atom";
41 }
41 }
42 var word = stream.current();
42 var word = stream.current();
43 if (funcs.test(word)) return "builtin";
43 if (funcs.test(word)) return "builtin";
44 if (preds.test(word)) return "def";
44 if (preds.test(word)) return "def";
45 if (keywords.test(word)) return "keyword";
45 if (keywords.test(word)) return "keyword";
46 return "variable";
46 return "variable";
47 }
47 }
48 };
48 };
49 var pushContext = function(state, type, col) {
49 var pushContext = function(state, type, col) {
50 return state.context = {
50 return state.context = {
51 prev: state.context,
51 prev: state.context,
52 indent: state.indent,
52 indent: state.indent,
53 col: col,
53 col: col,
54 type: type
54 type: type
55 };
55 };
56 };
56 };
57 var popContext = function(state) {
57 var popContext = function(state) {
58 state.indent = state.context.indent;
58 state.indent = state.context.indent;
59 return state.context = state.context.prev;
59 return state.context = state.context.prev;
60 };
60 };
61 var indentUnit = config.indentUnit;
61 var indentUnit = config.indentUnit;
62 var curPunc;
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"]);
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", "has", "in", "none", "not", "or", "single", "xor"]);
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", "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"]);
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 var operatorChars = /[*+\-<>=&|~%^]/;
66 var operatorChars = /[*+\-<>=&|~%^]/;
67
67
68 return {
68 return {
69 startState: function(/*base*/) {
69 startState: function(/*base*/) {
70 return {
70 return {
71 tokenize: tokenBase,
71 tokenize: tokenBase,
72 context: null,
72 context: null,
73 indent: 0,
73 indent: 0,
74 col: 0
74 col: 0
75 };
75 };
76 },
76 },
77 token: function(stream, state) {
77 token: function(stream, state) {
78 if (stream.sol()) {
78 if (stream.sol()) {
79 if (state.context && (state.context.align == null)) {
79 if (state.context && (state.context.align == null)) {
80 state.context.align = false;
80 state.context.align = false;
81 }
81 }
82 state.indent = stream.indentation();
82 state.indent = stream.indentation();
83 }
83 }
84 if (stream.eatSpace()) {
84 if (stream.eatSpace()) {
85 return null;
85 return null;
86 }
86 }
87 var style = state.tokenize(stream, state);
87 var style = state.tokenize(stream, state);
88 if (style !== "comment" && state.context && (state.context.align == null) && state.context.type !== "pattern") {
88 if (style !== "comment" && state.context && (state.context.align == null) && state.context.type !== "pattern") {
89 state.context.align = true;
89 state.context.align = true;
90 }
90 }
91 if (curPunc === "(") {
91 if (curPunc === "(") {
92 pushContext(state, ")", stream.column());
92 pushContext(state, ")", stream.column());
93 } else if (curPunc === "[") {
93 } else if (curPunc === "[") {
94 pushContext(state, "]", stream.column());
94 pushContext(state, "]", stream.column());
95 } else if (curPunc === "{") {
95 } else if (curPunc === "{") {
96 pushContext(state, "}", stream.column());
96 pushContext(state, "}", stream.column());
97 } else if (/[\]\}\)]/.test(curPunc)) {
97 } else if (/[\]\}\)]/.test(curPunc)) {
98 while (state.context && state.context.type === "pattern") {
98 while (state.context && state.context.type === "pattern") {
99 popContext(state);
99 popContext(state);
100 }
100 }
101 if (state.context && curPunc === state.context.type) {
101 if (state.context && curPunc === state.context.type) {
102 popContext(state);
102 popContext(state);
103 }
103 }
104 } else if (curPunc === "." && state.context && state.context.type === "pattern") {
104 } else if (curPunc === "." && state.context && state.context.type === "pattern") {
105 popContext(state);
105 popContext(state);
106 } else if (/atom|string|variable/.test(style) && state.context) {
106 } else if (/atom|string|variable/.test(style) && state.context) {
107 if (/[\}\]]/.test(state.context.type)) {
107 if (/[\}\]]/.test(state.context.type)) {
108 pushContext(state, "pattern", stream.column());
108 pushContext(state, "pattern", stream.column());
109 } else if (state.context.type === "pattern" && !state.context.align) {
109 } else if (state.context.type === "pattern" && !state.context.align) {
110 state.context.align = true;
110 state.context.align = true;
111 state.context.col = stream.column();
111 state.context.col = stream.column();
112 }
112 }
113 }
113 }
114 return style;
114 return style;
115 },
115 },
116 indent: function(state, textAfter) {
116 indent: function(state, textAfter) {
117 var firstChar = textAfter && textAfter.charAt(0);
117 var firstChar = textAfter && textAfter.charAt(0);
118 var context = state.context;
118 var context = state.context;
119 if (/[\]\}]/.test(firstChar)) {
119 if (/[\]\}]/.test(firstChar)) {
120 while (context && context.type === "pattern") {
120 while (context && context.type === "pattern") {
121 context = context.prev;
121 context = context.prev;
122 }
122 }
123 }
123 }
124 var closing = context && firstChar === context.type;
124 var closing = context && firstChar === context.type;
125 if (!context) return 0;
125 if (!context) return 0;
126 if (context.type === "keywords") return CodeMirror.commands.newlineAndIndent;
126 if (context.type === "keywords") return CodeMirror.commands.newlineAndIndent;
127 if (context.align) return context.col + (closing ? 0 : 1);
127 if (context.align) return context.col + (closing ? 0 : 1);
128 return context.indent + (closing ? 0 : indentUnit);
128 return context.indent + (closing ? 0 : indentUnit);
129 }
129 }
130 };
130 };
131 });
131 });
132
132
133 CodeMirror.modeExtensions["cypher"] = {
133 CodeMirror.modeExtensions["cypher"] = {
134 autoFormatLineBreaks: function(text) {
134 autoFormatLineBreaks: function(text) {
135 var i, lines, reProcessedPortion;
135 var i, lines, reProcessedPortion;
136 var lines = text.split("\n");
136 var lines = text.split("\n");
137 var reProcessedPortion = /\s+\b(return|where|order by|match|with|skip|limit|create|delete|set)\b\s/g;
137 var reProcessedPortion = /\s+\b(return|where|order by|match|with|skip|limit|create|delete|set)\b\s/g;
138 for (var i = 0; i < lines.length; i++)
138 for (var i = 0; i < lines.length; i++)
139 lines[i] = lines[i].replace(reProcessedPortion, " \n$1 ").trim();
139 lines[i] = lines[i].replace(reProcessedPortion, " \n$1 ").trim();
140 return lines.join("\n");
140 return lines.join("\n");
141 }
141 }
142 };
142 };
143
143
144 CodeMirror.defineMIME("application/x-cypher-query", "cypher");
144 CodeMirror.defineMIME("application/x-cypher-query", "cypher");
145
145
146 });
146 });
@@ -1,50 +1,130 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../clike/clike"));
6 mod(require("../../lib/codemirror"), require("../clike/clike"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../clike/clike"], mod);
8 define(["../../lib/codemirror", "../clike/clike"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 var keywords = ("this super static final const abstract class extends external factory " +
14 var keywords = ("this super static final const abstract class extends external factory " +
15 "implements get native operator set typedef with enum throw rethrow " +
15 "implements get native operator set typedef with enum throw rethrow " +
16 "assert break case continue default in return new deferred async await " +
16 "assert break case continue default in return new deferred async await " +
17 "try catch finally do else for if switch while import library export " +
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 var blockKeywords = "try catch finally do else for if switch while".split(" ");
19 var blockKeywords = "try catch finally do else for if switch while".split(" ");
20 var atoms = "true false null".split(" ");
20 var atoms = "true false null".split(" ");
21 var builtins = "void bool num int double dynamic var String".split(" ");
21 var builtins = "void bool num int double dynamic var String".split(" ");
22
22
23 function set(words) {
23 function set(words) {
24 var obj = {};
24 var obj = {};
25 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
25 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
26 return obj;
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 CodeMirror.defineMIME("application/dart", {
41 CodeMirror.defineMIME("application/dart", {
30 name: "clike",
42 name: "clike",
31 keywords: set(keywords),
43 keywords: set(keywords),
32 multiLineStrings: true,
33 blockKeywords: set(blockKeywords),
44 blockKeywords: set(blockKeywords),
34 builtin: set(builtins),
45 builtin: set(builtins),
35 atoms: set(atoms),
46 atoms: set(atoms),
36 hooks: {
47 hooks: {
37 "@": function(stream) {
48 "@": function(stream) {
38 stream.eatWhile(/[\w\$_]/);
49 stream.eatWhile(/[\w\$_\.]/);
39 return "meta";
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 CodeMirror.registerHelper("hintWords", "application/dart", keywords.concat(atoms).concat(builtins));
124 CodeMirror.registerHelper("hintWords", "application/dart", keywords.concat(atoms).concat(builtins));
45
125
46 // This is needed to make loading through meta.js work.
126 // This is needed to make loading through meta.js work.
47 CodeMirror.defineMode("dart", function(conf) {
127 CodeMirror.defineMode("dart", function(conf) {
48 return CodeMirror.getMode(conf, "application/dart");
128 return CodeMirror.getMode(conf, "application/dart");
49 }, "clike");
129 }, "clike");
50 });
130 });
@@ -1,350 +1,356 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
7 require("../../addon/mode/overlay"));
7 require("../../addon/mode/overlay"));
8 else if (typeof define == "function" && define.amd) // AMD
8 else if (typeof define == "function" && define.amd) // AMD
9 define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
9 define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
10 "../../addon/mode/overlay"], mod);
10 "../../addon/mode/overlay"], mod);
11 else // Plain browser env
11 else // Plain browser env
12 mod(CodeMirror);
12 mod(CodeMirror);
13 })(function(CodeMirror) {
13 })(function(CodeMirror) {
14 "use strict";
14 "use strict";
15
15
16 CodeMirror.defineMode("django:inner", function() {
16 CodeMirror.defineMode("django:inner", function() {
17 var keywords = ["block", "endblock", "for", "endfor", "true", "false",
17 var keywords = ["block", "endblock", "for", "endfor", "true", "false", "filter", "endfilter",
18 "loop", "none", "self", "super", "if", "endif", "as",
18 "loop", "none", "self", "super", "if", "elif", "endif", "as", "else", "import",
19 "else", "import", "with", "endwith", "without", "context", "ifequal", "endifequal",
19 "with", "endwith", "without", "context", "ifequal", "endifequal", "ifnotequal",
20 "ifnotequal", "endifnotequal", "extends", "include", "load", "comment",
20 "endifnotequal", "extends", "include", "load", "comment", "endcomment",
21 "endcomment", "empty", "url", "static", "trans", "blocktrans", "now", "regroup",
21 "empty", "url", "static", "trans", "blocktrans", "endblocktrans", "now",
22 "lorem", "ifchanged", "endifchanged", "firstof", "debug", "cycle", "csrf_token",
22 "regroup", "lorem", "ifchanged", "endifchanged", "firstof", "debug", "cycle",
23 "autoescape", "endautoescape", "spaceless", "ssi", "templatetag",
23 "csrf_token", "autoescape", "endautoescape", "spaceless", "endspaceless",
24 "verbatim", "endverbatim", "widthratio"],
24 "ssi", "templatetag", "verbatim", "endverbatim", "widthratio"],
25 filters = ["add", "addslashes", "capfirst", "center", "cut", "date",
25 filters = ["add", "addslashes", "capfirst", "center", "cut", "date",
26 "default", "default_if_none", "dictsort",
26 "default", "default_if_none", "dictsort",
27 "dictsortreversed", "divisibleby", "escape", "escapejs",
27 "dictsortreversed", "divisibleby", "escape", "escapejs",
28 "filesizeformat", "first", "floatformat", "force_escape",
28 "filesizeformat", "first", "floatformat", "force_escape",
29 "get_digit", "iriencode", "join", "last", "length",
29 "get_digit", "iriencode", "join", "last", "length",
30 "length_is", "linebreaks", "linebreaksbr", "linenumbers",
30 "length_is", "linebreaks", "linebreaksbr", "linenumbers",
31 "ljust", "lower", "make_list", "phone2numeric", "pluralize",
31 "ljust", "lower", "make_list", "phone2numeric", "pluralize",
32 "pprint", "random", "removetags", "rjust", "safe",
32 "pprint", "random", "removetags", "rjust", "safe",
33 "safeseq", "slice", "slugify", "stringformat", "striptags",
33 "safeseq", "slice", "slugify", "stringformat", "striptags",
34 "time", "timesince", "timeuntil", "title", "truncatechars",
34 "time", "timesince", "timeuntil", "title", "truncatechars",
35 "truncatechars_html", "truncatewords", "truncatewords_html",
35 "truncatechars_html", "truncatewords", "truncatewords_html",
36 "unordered_list", "upper", "urlencode", "urlize",
36 "unordered_list", "upper", "urlencode", "urlize",
37 "urlizetrunc", "wordcount", "wordwrap", "yesno"],
37 "urlizetrunc", "wordcount", "wordwrap", "yesno"],
38 operators = ["==", "!=", "<", ">", "<=", ">=", "in", "not", "or", "and"];
38 operators = ["==", "!=", "<", ">", "<=", ">="],
39 wordOperators = ["in", "not", "or", "and"];
39
40
40 keywords = new RegExp("^\\b(" + keywords.join("|") + ")\\b");
41 keywords = new RegExp("^\\b(" + keywords.join("|") + ")\\b");
41 filters = new RegExp("^\\b(" + filters.join("|") + ")\\b");
42 filters = new RegExp("^\\b(" + filters.join("|") + ")\\b");
42 operators = new RegExp("^\\b(" + operators.join("|") + ")\\b");
43 operators = new RegExp("^\\b(" + operators.join("|") + ")\\b");
44 wordOperators = new RegExp("^\\b(" + wordOperators.join("|") + ")\\b");
43
45
44 // We have to return "null" instead of null, in order to avoid string
46 // We have to return "null" instead of null, in order to avoid string
45 // styling as the default, when using Django templates inside HTML
47 // styling as the default, when using Django templates inside HTML
46 // element attributes
48 // element attributes
47 function tokenBase (stream, state) {
49 function tokenBase (stream, state) {
48 // Attempt to identify a variable, template or comment tag respectively
50 // Attempt to identify a variable, template or comment tag respectively
49 if (stream.match("{{")) {
51 if (stream.match("{{")) {
50 state.tokenize = inVariable;
52 state.tokenize = inVariable;
51 return "tag";
53 return "tag";
52 } else if (stream.match("{%")) {
54 } else if (stream.match("{%")) {
53 state.tokenize = inTag;
55 state.tokenize = inTag;
54 return "tag";
56 return "tag";
55 } else if (stream.match("{#")) {
57 } else if (stream.match("{#")) {
56 state.tokenize = inComment;
58 state.tokenize = inComment;
57 return "comment";
59 return "comment";
58 }
60 }
59
61
60 // Ignore completely any stream series that do not match the
62 // Ignore completely any stream series that do not match the
61 // Django template opening tags.
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 return null;
65 return null;
64 }
66 }
65
67
66 // A string can be included in either single or double quotes (this is
68 // A string can be included in either single or double quotes (this is
67 // the delimeter). Mark everything as a string until the start delimeter
69 // the delimeter). Mark everything as a string until the start delimeter
68 // occurs again.
70 // occurs again.
69 function inString (delimeter, previousTokenizer) {
71 function inString (delimeter, previousTokenizer) {
70 return function (stream, state) {
72 return function (stream, state) {
71 if (!state.escapeNext && stream.eat(delimeter)) {
73 if (!state.escapeNext && stream.eat(delimeter)) {
72 state.tokenize = previousTokenizer;
74 state.tokenize = previousTokenizer;
73 } else {
75 } else {
74 if (state.escapeNext) {
76 if (state.escapeNext) {
75 state.escapeNext = false;
77 state.escapeNext = false;
76 }
78 }
77
79
78 var ch = stream.next();
80 var ch = stream.next();
79
81
80 // Take into account the backslash for escaping characters, such as
82 // Take into account the backslash for escaping characters, such as
81 // the string delimeter.
83 // the string delimeter.
82 if (ch == "\\") {
84 if (ch == "\\") {
83 state.escapeNext = true;
85 state.escapeNext = true;
84 }
86 }
85 }
87 }
86
88
87 return "string";
89 return "string";
88 };
90 };
89 }
91 }
90
92
91 // Apply Django template variable syntax highlighting
93 // Apply Django template variable syntax highlighting
92 function inVariable (stream, state) {
94 function inVariable (stream, state) {
93 // Attempt to match a dot that precedes a property
95 // Attempt to match a dot that precedes a property
94 if (state.waitDot) {
96 if (state.waitDot) {
95 state.waitDot = false;
97 state.waitDot = false;
96
98
97 if (stream.peek() != ".") {
99 if (stream.peek() != ".") {
98 return "null";
100 return "null";
99 }
101 }
100
102
101 // Dot folowed by a non-word character should be considered an error.
103 // Dot folowed by a non-word character should be considered an error.
102 if (stream.match(/\.\W+/)) {
104 if (stream.match(/\.\W+/)) {
103 return "error";
105 return "error";
104 } else if (stream.eat(".")) {
106 } else if (stream.eat(".")) {
105 state.waitProperty = true;
107 state.waitProperty = true;
106 return "null";
108 return "null";
107 } else {
109 } else {
108 throw Error ("Unexpected error while waiting for property.");
110 throw Error ("Unexpected error while waiting for property.");
109 }
111 }
110 }
112 }
111
113
112 // Attempt to match a pipe that precedes a filter
114 // Attempt to match a pipe that precedes a filter
113 if (state.waitPipe) {
115 if (state.waitPipe) {
114 state.waitPipe = false;
116 state.waitPipe = false;
115
117
116 if (stream.peek() != "|") {
118 if (stream.peek() != "|") {
117 return "null";
119 return "null";
118 }
120 }
119
121
120 // Pipe folowed by a non-word character should be considered an error.
122 // Pipe folowed by a non-word character should be considered an error.
121 if (stream.match(/\.\W+/)) {
123 if (stream.match(/\.\W+/)) {
122 return "error";
124 return "error";
123 } else if (stream.eat("|")) {
125 } else if (stream.eat("|")) {
124 state.waitFilter = true;
126 state.waitFilter = true;
125 return "null";
127 return "null";
126 } else {
128 } else {
127 throw Error ("Unexpected error while waiting for filter.");
129 throw Error ("Unexpected error while waiting for filter.");
128 }
130 }
129 }
131 }
130
132
131 // Highlight properties
133 // Highlight properties
132 if (state.waitProperty) {
134 if (state.waitProperty) {
133 state.waitProperty = false;
135 state.waitProperty = false;
134 if (stream.match(/\b(\w+)\b/)) {
136 if (stream.match(/\b(\w+)\b/)) {
135 state.waitDot = true; // A property can be followed by another property
137 state.waitDot = true; // A property can be followed by another property
136 state.waitPipe = true; // A property can be followed by a filter
138 state.waitPipe = true; // A property can be followed by a filter
137 return "property";
139 return "property";
138 }
140 }
139 }
141 }
140
142
141 // Highlight filters
143 // Highlight filters
142 if (state.waitFilter) {
144 if (state.waitFilter) {
143 state.waitFilter = false;
145 state.waitFilter = false;
144 if (stream.match(filters)) {
146 if (stream.match(filters)) {
145 return "variable-2";
147 return "variable-2";
146 }
148 }
147 }
149 }
148
150
149 // Ignore all white spaces
151 // Ignore all white spaces
150 if (stream.eatSpace()) {
152 if (stream.eatSpace()) {
151 state.waitProperty = false;
153 state.waitProperty = false;
152 return "null";
154 return "null";
153 }
155 }
154
156
155 // Identify numbers
157 // Identify numbers
156 if (stream.match(/\b\d+(\.\d+)?\b/)) {
158 if (stream.match(/\b\d+(\.\d+)?\b/)) {
157 return "number";
159 return "number";
158 }
160 }
159
161
160 // Identify strings
162 // Identify strings
161 if (stream.match("'")) {
163 if (stream.match("'")) {
162 state.tokenize = inString("'", state.tokenize);
164 state.tokenize = inString("'", state.tokenize);
163 return "string";
165 return "string";
164 } else if (stream.match('"')) {
166 } else if (stream.match('"')) {
165 state.tokenize = inString('"', state.tokenize);
167 state.tokenize = inString('"', state.tokenize);
166 return "string";
168 return "string";
167 }
169 }
168
170
169 // Attempt to find the variable
171 // Attempt to find the variable
170 if (stream.match(/\b(\w+)\b/) && !state.foundVariable) {
172 if (stream.match(/\b(\w+)\b/) && !state.foundVariable) {
171 state.waitDot = true;
173 state.waitDot = true;
172 state.waitPipe = true; // A property can be followed by a filter
174 state.waitPipe = true; // A property can be followed by a filter
173 return "variable";
175 return "variable";
174 }
176 }
175
177
176 // If found closing tag reset
178 // If found closing tag reset
177 if (stream.match("}}")) {
179 if (stream.match("}}")) {
178 state.waitProperty = null;
180 state.waitProperty = null;
179 state.waitFilter = null;
181 state.waitFilter = null;
180 state.waitDot = null;
182 state.waitDot = null;
181 state.waitPipe = null;
183 state.waitPipe = null;
182 state.tokenize = tokenBase;
184 state.tokenize = tokenBase;
183 return "tag";
185 return "tag";
184 }
186 }
185
187
186 // If nothing was found, advance to the next character
188 // If nothing was found, advance to the next character
187 stream.next();
189 stream.next();
188 return "null";
190 return "null";
189 }
191 }
190
192
191 function inTag (stream, state) {
193 function inTag (stream, state) {
192 // Attempt to match a dot that precedes a property
194 // Attempt to match a dot that precedes a property
193 if (state.waitDot) {
195 if (state.waitDot) {
194 state.waitDot = false;
196 state.waitDot = false;
195
197
196 if (stream.peek() != ".") {
198 if (stream.peek() != ".") {
197 return "null";
199 return "null";
198 }
200 }
199
201
200 // Dot folowed by a non-word character should be considered an error.
202 // Dot folowed by a non-word character should be considered an error.
201 if (stream.match(/\.\W+/)) {
203 if (stream.match(/\.\W+/)) {
202 return "error";
204 return "error";
203 } else if (stream.eat(".")) {
205 } else if (stream.eat(".")) {
204 state.waitProperty = true;
206 state.waitProperty = true;
205 return "null";
207 return "null";
206 } else {
208 } else {
207 throw Error ("Unexpected error while waiting for property.");
209 throw Error ("Unexpected error while waiting for property.");
208 }
210 }
209 }
211 }
210
212
211 // Attempt to match a pipe that precedes a filter
213 // Attempt to match a pipe that precedes a filter
212 if (state.waitPipe) {
214 if (state.waitPipe) {
213 state.waitPipe = false;
215 state.waitPipe = false;
214
216
215 if (stream.peek() != "|") {
217 if (stream.peek() != "|") {
216 return "null";
218 return "null";
217 }
219 }
218
220
219 // Pipe folowed by a non-word character should be considered an error.
221 // Pipe folowed by a non-word character should be considered an error.
220 if (stream.match(/\.\W+/)) {
222 if (stream.match(/\.\W+/)) {
221 return "error";
223 return "error";
222 } else if (stream.eat("|")) {
224 } else if (stream.eat("|")) {
223 state.waitFilter = true;
225 state.waitFilter = true;
224 return "null";
226 return "null";
225 } else {
227 } else {
226 throw Error ("Unexpected error while waiting for filter.");
228 throw Error ("Unexpected error while waiting for filter.");
227 }
229 }
228 }
230 }
229
231
230 // Highlight properties
232 // Highlight properties
231 if (state.waitProperty) {
233 if (state.waitProperty) {
232 state.waitProperty = false;
234 state.waitProperty = false;
233 if (stream.match(/\b(\w+)\b/)) {
235 if (stream.match(/\b(\w+)\b/)) {
234 state.waitDot = true; // A property can be followed by another property
236 state.waitDot = true; // A property can be followed by another property
235 state.waitPipe = true; // A property can be followed by a filter
237 state.waitPipe = true; // A property can be followed by a filter
236 return "property";
238 return "property";
237 }
239 }
238 }
240 }
239
241
240 // Highlight filters
242 // Highlight filters
241 if (state.waitFilter) {
243 if (state.waitFilter) {
242 state.waitFilter = false;
244 state.waitFilter = false;
243 if (stream.match(filters)) {
245 if (stream.match(filters)) {
244 return "variable-2";
246 return "variable-2";
245 }
247 }
246 }
248 }
247
249
248 // Ignore all white spaces
250 // Ignore all white spaces
249 if (stream.eatSpace()) {
251 if (stream.eatSpace()) {
250 state.waitProperty = false;
252 state.waitProperty = false;
251 return "null";
253 return "null";
252 }
254 }
253
255
254 // Identify numbers
256 // Identify numbers
255 if (stream.match(/\b\d+(\.\d+)?\b/)) {
257 if (stream.match(/\b\d+(\.\d+)?\b/)) {
256 return "number";
258 return "number";
257 }
259 }
258
260
259 // Identify strings
261 // Identify strings
260 if (stream.match("'")) {
262 if (stream.match("'")) {
261 state.tokenize = inString("'", state.tokenize);
263 state.tokenize = inString("'", state.tokenize);
262 return "string";
264 return "string";
263 } else if (stream.match('"')) {
265 } else if (stream.match('"')) {
264 state.tokenize = inString('"', state.tokenize);
266 state.tokenize = inString('"', state.tokenize);
265 return "string";
267 return "string";
266 }
268 }
267
269
268 // Attempt to match an operator
270 // Attempt to match an operator
269 if (stream.match(operators)) {
271 if (stream.match(operators)) {
270 return "operator";
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 // Attempt to match a keyword
280 // Attempt to match a keyword
274 var keywordMatch = stream.match(keywords);
281 var keywordMatch = stream.match(keywords);
275 if (keywordMatch) {
282 if (keywordMatch) {
276 if (keywordMatch[0] == "comment") {
283 if (keywordMatch[0] == "comment") {
277 state.blockCommentTag = true;
284 state.blockCommentTag = true;
278 }
285 }
279 return "keyword";
286 return "keyword";
280 }
287 }
281
288
282 // Attempt to match a variable
289 // Attempt to match a variable
283 if (stream.match(/\b(\w+)\b/)) {
290 if (stream.match(/\b(\w+)\b/)) {
284 state.waitDot = true;
291 state.waitDot = true;
285 state.waitPipe = true; // A property can be followed by a filter
292 state.waitPipe = true; // A property can be followed by a filter
286 return "variable";
293 return "variable";
287 }
294 }
288
295
289 // If found closing tag reset
296 // If found closing tag reset
290 if (stream.match("%}")) {
297 if (stream.match("%}")) {
291 state.waitProperty = null;
298 state.waitProperty = null;
292 state.waitFilter = null;
299 state.waitFilter = null;
293 state.waitDot = null;
300 state.waitDot = null;
294 state.waitPipe = null;
301 state.waitPipe = null;
295 // If the tag that closes is a block comment tag, we want to mark the
302 // If the tag that closes is a block comment tag, we want to mark the
296 // following code as comment, until the tag closes.
303 // following code as comment, until the tag closes.
297 if (state.blockCommentTag) {
304 if (state.blockCommentTag) {
298 state.blockCommentTag = false; // Release the "lock"
305 state.blockCommentTag = false; // Release the "lock"
299 state.tokenize = inBlockComment;
306 state.tokenize = inBlockComment;
300 } else {
307 } else {
301 state.tokenize = tokenBase;
308 state.tokenize = tokenBase;
302 }
309 }
303 return "tag";
310 return "tag";
304 }
311 }
305
312
306 // If nothing was found, advance to the next character
313 // If nothing was found, advance to the next character
307 stream.next();
314 stream.next();
308 return "null";
315 return "null";
309 }
316 }
310
317
311 // Mark everything as comment inside the tag and the tag itself.
318 // Mark everything as comment inside the tag and the tag itself.
312 function inComment (stream, state) {
319 function inComment (stream, state) {
313 if (stream.match("#}")) {
320 if (stream.match(/^.*?#\}/)) state.tokenize = tokenBase
314 state.tokenize = tokenBase;
321 else stream.skipToEnd()
315 }
316 return "comment";
322 return "comment";
317 }
323 }
318
324
319 // Mark everything as a comment until the `blockcomment` tag closes.
325 // Mark everything as a comment until the `blockcomment` tag closes.
320 function inBlockComment (stream, state) {
326 function inBlockComment (stream, state) {
321 if (stream.match(/\{%\s*endcomment\s*%\}/, false)) {
327 if (stream.match(/\{%\s*endcomment\s*%\}/, false)) {
322 state.tokenize = inTag;
328 state.tokenize = inTag;
323 stream.match("{%");
329 stream.match("{%");
324 return "tag";
330 return "tag";
325 } else {
331 } else {
326 stream.next();
332 stream.next();
327 return "comment";
333 return "comment";
328 }
334 }
329 }
335 }
330
336
331 return {
337 return {
332 startState: function () {
338 startState: function () {
333 return {tokenize: tokenBase};
339 return {tokenize: tokenBase};
334 },
340 },
335 token: function (stream, state) {
341 token: function (stream, state) {
336 return state.tokenize(stream, state);
342 return state.tokenize(stream, state);
337 },
343 },
338 blockCommentStart: "{% comment %}",
344 blockCommentStart: "{% comment %}",
339 blockCommentEnd: "{% endcomment %}"
345 blockCommentEnd: "{% endcomment %}"
340 };
346 };
341 });
347 });
342
348
343 CodeMirror.defineMode("django", function(config) {
349 CodeMirror.defineMode("django", function(config) {
344 var htmlBase = CodeMirror.getMode(config, "text/html");
350 var htmlBase = CodeMirror.getMode(config, "text/html");
345 var djangoInner = CodeMirror.getMode(config, "django:inner");
351 var djangoInner = CodeMirror.getMode(config, "django:inner");
346 return CodeMirror.overlayMode(htmlBase, djangoInner);
352 return CodeMirror.overlayMode(htmlBase, djangoInner);
347 });
353 });
348
354
349 CodeMirror.defineMIME("text/x-django", "django");
355 CodeMirror.defineMIME("text/x-django", "django");
350 });
356 });
@@ -1,76 +1,79 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
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"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
8 define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 // Collect all Dockerfile directives
14 // Collect all Dockerfile directives
15 var instructions = ["from", "maintainer", "run", "cmd", "expose", "env",
15 var instructions = ["from", "maintainer", "run", "cmd", "expose", "env",
16 "add", "copy", "entrypoint", "volume", "user",
16 "add", "copy", "entrypoint", "volume", "user",
17 "workdir", "onbuild"],
17 "workdir", "onbuild"],
18 instructionRegex = "(" + instructions.join('|') + ")",
18 instructionRegex = "(" + instructions.join('|') + ")",
19 instructionOnlyLine = new RegExp(instructionRegex + "\\s*$", "i"),
19 instructionOnlyLine = new RegExp(instructionRegex + "\\s*$", "i"),
20 instructionWithArguments = new RegExp(instructionRegex + "(\\s+)", "i");
20 instructionWithArguments = new RegExp(instructionRegex + "(\\s+)", "i");
21
21
22 CodeMirror.defineSimpleMode("dockerfile", {
22 CodeMirror.defineSimpleMode("dockerfile", {
23 start: [
23 start: [
24 // Block comment: This is a line starting with a comment
24 // Block comment: This is a line starting with a comment
25 {
25 {
26 regex: /#.*$/,
26 regex: /#.*$/,
27 token: "comment"
27 token: "comment"
28 },
28 },
29 // Highlight an instruction without any arguments (for convenience)
29 // Highlight an instruction without any arguments (for convenience)
30 {
30 {
31 regex: instructionOnlyLine,
31 regex: instructionOnlyLine,
32 token: "variable-2"
32 token: "variable-2"
33 },
33 },
34 // Highlight an instruction followed by arguments
34 // Highlight an instruction followed by arguments
35 {
35 {
36 regex: instructionWithArguments,
36 regex: instructionWithArguments,
37 token: ["variable-2", null],
37 token: ["variable-2", null],
38 next: "arguments"
38 next: "arguments"
39 },
39 },
40 {
40 {
41 regex: /./,
41 regex: /./,
42 token: null
42 token: null
43 }
43 }
44 ],
44 ],
45 arguments: [
45 arguments: [
46 {
46 {
47 // Line comment without instruction arguments is an error
47 // Line comment without instruction arguments is an error
48 regex: /#.*$/,
48 regex: /#.*$/,
49 token: "error",
49 token: "error",
50 next: "start"
50 next: "start"
51 },
51 },
52 {
52 {
53 regex: /[^#]+\\$/,
53 regex: /[^#]+\\$/,
54 token: null
54 token: null
55 },
55 },
56 {
56 {
57 // Match everything except for the inline comment
57 // Match everything except for the inline comment
58 regex: /[^#]+/,
58 regex: /[^#]+/,
59 token: null,
59 token: null,
60 next: "start"
60 next: "start"
61 },
61 },
62 {
62 {
63 regex: /$/,
63 regex: /$/,
64 token: null,
64 token: null,
65 next: "start"
65 next: "start"
66 },
66 },
67 // Fail safe return to start
67 // Fail safe return to start
68 {
68 {
69 token: null,
69 token: null,
70 next: "start"
70 next: "start"
71 }
71 }
72 ]
72 ],
73 meta: {
74 lineComment: "#"
75 }
73 });
76 });
74
77
75 CodeMirror.defineMIME("text/x-dockerfile", "dockerfile");
78 CodeMirror.defineMIME("text/x-dockerfile", "dockerfile");
76 });
79 });
@@ -1,205 +1,205 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("elm", function() {
14 CodeMirror.defineMode("elm", function() {
15
15
16 function switchState(source, setState, f) {
16 function switchState(source, setState, f) {
17 setState(f);
17 setState(f);
18 return f(source, setState);
18 return f(source, setState);
19 }
19 }
20
20
21 // These should all be Unicode extended, as per the Haskell 2010 report
21 // These should all be Unicode extended, as per the Haskell 2010 report
22 var smallRE = /[a-z_]/;
22 var smallRE = /[a-z_]/;
23 var largeRE = /[A-Z]/;
23 var largeRE = /[A-Z]/;
24 var digitRE = /[0-9]/;
24 var digitRE = /[0-9]/;
25 var hexitRE = /[0-9A-Fa-f]/;
25 var hexitRE = /[0-9A-Fa-f]/;
26 var octitRE = /[0-7]/;
26 var octitRE = /[0-7]/;
27 var idRE = /[a-z_A-Z0-9\']/;
27 var idRE = /[a-z_A-Z0-9\']/;
28 var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/;
28 var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/;
29 var specialRE = /[(),;[\]`{}]/;
29 var specialRE = /[(),;[\]`{}]/;
30 var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer
30 var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer
31
31
32 function normal() {
32 function normal() {
33 return function (source, setState) {
33 return function (source, setState) {
34 if (source.eatWhile(whiteCharRE)) {
34 if (source.eatWhile(whiteCharRE)) {
35 return null;
35 return null;
36 }
36 }
37
37
38 var ch = source.next();
38 var ch = source.next();
39 if (specialRE.test(ch)) {
39 if (specialRE.test(ch)) {
40 if (ch == '{' && source.eat('-')) {
40 if (ch == '{' && source.eat('-')) {
41 var t = "comment";
41 var t = "comment";
42 if (source.eat('#')) t = "meta";
42 if (source.eat('#')) t = "meta";
43 return switchState(source, setState, ncomment(t, 1));
43 return switchState(source, setState, ncomment(t, 1));
44 }
44 }
45 return null;
45 return null;
46 }
46 }
47
47
48 if (ch == '\'') {
48 if (ch == '\'') {
49 if (source.eat('\\'))
49 if (source.eat('\\'))
50 source.next(); // should handle other escapes here
50 source.next(); // should handle other escapes here
51 else
51 else
52 source.next();
52 source.next();
53
53
54 if (source.eat('\''))
54 if (source.eat('\''))
55 return "string";
55 return "string";
56 return "error";
56 return "error";
57 }
57 }
58
58
59 if (ch == '"') {
59 if (ch == '"') {
60 return switchState(source, setState, stringLiteral);
60 return switchState(source, setState, stringLiteral);
61 }
61 }
62
62
63 if (largeRE.test(ch)) {
63 if (largeRE.test(ch)) {
64 source.eatWhile(idRE);
64 source.eatWhile(idRE);
65 if (source.eat('.'))
65 if (source.eat('.'))
66 return "qualifier";
66 return "qualifier";
67 return "variable-2";
67 return "variable-2";
68 }
68 }
69
69
70 if (smallRE.test(ch)) {
70 if (smallRE.test(ch)) {
71 var isDef = source.pos === 1;
71 var isDef = source.pos === 1;
72 source.eatWhile(idRE);
72 source.eatWhile(idRE);
73 return isDef ? "variable-3" : "variable";
73 return isDef ? "variable-3" : "variable";
74 }
74 }
75
75
76 if (digitRE.test(ch)) {
76 if (digitRE.test(ch)) {
77 if (ch == '0') {
77 if (ch == '0') {
78 if (source.eat(/[xX]/)) {
78 if (source.eat(/[xX]/)) {
79 source.eatWhile(hexitRE); // should require at least 1
79 source.eatWhile(hexitRE); // should require at least 1
80 return "integer";
80 return "integer";
81 }
81 }
82 if (source.eat(/[oO]/)) {
82 if (source.eat(/[oO]/)) {
83 source.eatWhile(octitRE); // should require at least 1
83 source.eatWhile(octitRE); // should require at least 1
84 return "number";
84 return "number";
85 }
85 }
86 }
86 }
87 source.eatWhile(digitRE);
87 source.eatWhile(digitRE);
88 var t = "number";
88 var t = "number";
89 if (source.eat('.')) {
89 if (source.eat('.')) {
90 t = "number";
90 t = "number";
91 source.eatWhile(digitRE); // should require at least 1
91 source.eatWhile(digitRE); // should require at least 1
92 }
92 }
93 if (source.eat(/[eE]/)) {
93 if (source.eat(/[eE]/)) {
94 t = "number";
94 t = "number";
95 source.eat(/[-+]/);
95 source.eat(/[-+]/);
96 source.eatWhile(digitRE); // should require at least 1
96 source.eatWhile(digitRE); // should require at least 1
97 }
97 }
98 return t;
98 return t;
99 }
99 }
100
100
101 if (symbolRE.test(ch)) {
101 if (symbolRE.test(ch)) {
102 if (ch == '-' && source.eat(/-/)) {
102 if (ch == '-' && source.eat(/-/)) {
103 source.eatWhile(/-/);
103 source.eatWhile(/-/);
104 if (!source.eat(symbolRE)) {
104 if (!source.eat(symbolRE)) {
105 source.skipToEnd();
105 source.skipToEnd();
106 return "comment";
106 return "comment";
107 }
107 }
108 }
108 }
109 source.eatWhile(symbolRE);
109 source.eatWhile(symbolRE);
110 return "builtin";
110 return "builtin";
111 }
111 }
112
112
113 return "error";
113 return "error";
114 }
114 }
115 }
115 }
116
116
117 function ncomment(type, nest) {
117 function ncomment(type, nest) {
118 if (nest == 0) {
118 if (nest == 0) {
119 return normal();
119 return normal();
120 }
120 }
121 return function(source, setState) {
121 return function(source, setState) {
122 var currNest = nest;
122 var currNest = nest;
123 while (!source.eol()) {
123 while (!source.eol()) {
124 var ch = source.next();
124 var ch = source.next();
125 if (ch == '{' && source.eat('-')) {
125 if (ch == '{' && source.eat('-')) {
126 ++currNest;
126 ++currNest;
127 } else if (ch == '-' && source.eat('}')) {
127 } else if (ch == '-' && source.eat('}')) {
128 --currNest;
128 --currNest;
129 if (currNest == 0) {
129 if (currNest == 0) {
130 setState(normal());
130 setState(normal());
131 return type;
131 return type;
132 }
132 }
133 }
133 }
134 }
134 }
135 setState(ncomment(type, currNest));
135 setState(ncomment(type, currNest));
136 return type;
136 return type;
137 }
137 }
138 }
138 }
139
139
140 function stringLiteral(source, setState) {
140 function stringLiteral(source, setState) {
141 while (!source.eol()) {
141 while (!source.eol()) {
142 var ch = source.next();
142 var ch = source.next();
143 if (ch == '"') {
143 if (ch == '"') {
144 setState(normal());
144 setState(normal());
145 return "string";
145 return "string";
146 }
146 }
147 if (ch == '\\') {
147 if (ch == '\\') {
148 if (source.eol() || source.eat(whiteCharRE)) {
148 if (source.eol() || source.eat(whiteCharRE)) {
149 setState(stringGap);
149 setState(stringGap);
150 return "string";
150 return "string";
151 }
151 }
152 if (!source.eat('&')) source.next(); // should handle other escapes here
152 if (!source.eat('&')) source.next(); // should handle other escapes here
153 }
153 }
154 }
154 }
155 setState(normal());
155 setState(normal());
156 return "error";
156 return "error";
157 }
157 }
158
158
159 function stringGap(source, setState) {
159 function stringGap(source, setState) {
160 if (source.eat('\\')) {
160 if (source.eat('\\')) {
161 return switchState(source, setState, stringLiteral);
161 return switchState(source, setState, stringLiteral);
162 }
162 }
163 source.next();
163 source.next();
164 setState(normal());
164 setState(normal());
165 return "error";
165 return "error";
166 }
166 }
167
167
168
168
169 var wellKnownWords = (function() {
169 var wellKnownWords = (function() {
170 var wkw = {};
170 var wkw = {};
171
171
172 var keywords = [
172 var keywords = [
173 "case", "of", "as",
173 "case", "of", "as",
174 "if", "then", "else",
174 "if", "then", "else",
175 "let", "in",
175 "let", "in",
176 "infix", "infixl", "infixr",
176 "infix", "infixl", "infixr",
177 "type", "alias",
177 "type", "alias",
178 "input", "output", "foreign", "loopback",
178 "input", "output", "foreign", "loopback",
179 "module", "where", "import", "exposing",
179 "module", "where", "import", "exposing",
180 "_", "..", "|", ":", "=", "\\", "\"", "->", "<-"
180 "_", "..", "|", ":", "=", "\\", "\"", "->", "<-"
181 ];
181 ];
182
182
183 for (var i = keywords.length; i--;)
183 for (var i = keywords.length; i--;)
184 wkw[keywords[i]] = "keyword";
184 wkw[keywords[i]] = "keyword";
185
185
186 return wkw;
186 return wkw;
187 })();
187 })();
188
188
189
189
190
190
191 return {
191 return {
192 startState: function () { return { f: normal() }; },
192 startState: function () { return { f: normal() }; },
193 copyState: function (s) { return { f: s.f }; },
193 copyState: function (s) { return { f: s.f }; },
194
194
195 token: function(stream, state) {
195 token: function(stream, state) {
196 var t = state.f(stream, function(s) { state.f = s; });
196 var t = state.f(stream, function(s) { state.f = s; });
197 var w = stream.current();
197 var w = stream.current();
198 return (wellKnownWords.hasOwnProperty(w)) ? wellKnownWords[w] : t;
198 return (wellKnownWords.hasOwnProperty(w)) ? wellKnownWords[w] : t;
199 }
199 }
200 };
200 };
201
201
202 });
202 });
203
203
204 CodeMirror.defineMIME("text/x-elm", "elm");
204 CodeMirror.defineMIME("text/x-elm", "elm");
205 })();
205 });
@@ -1,622 +1,618 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 /*jshint unused:true, eqnull:true, curly:true, bitwise:true */
4 /*jshint unused:true, eqnull:true, curly:true, bitwise:true */
5 /*jshint undef:true, latedef:true, trailing:true */
5 /*jshint undef:true, latedef:true, trailing:true */
6 /*global CodeMirror:true */
6 /*global CodeMirror:true */
7
7
8 // erlang mode.
8 // erlang mode.
9 // tokenizer -> token types -> CodeMirror styles
9 // tokenizer -> token types -> CodeMirror styles
10 // tokenizer maintains a parse stack
10 // tokenizer maintains a parse stack
11 // indenter uses the parse stack
11 // indenter uses the parse stack
12
12
13 // TODO indenter:
13 // TODO indenter:
14 // bit syntax
14 // bit syntax
15 // old guard/bif/conversion clashes (e.g. "float/1")
15 // old guard/bif/conversion clashes (e.g. "float/1")
16 // type/spec/opaque
16 // type/spec/opaque
17
17
18 (function(mod) {
18 (function(mod) {
19 if (typeof exports == "object" && typeof module == "object") // CommonJS
19 if (typeof exports == "object" && typeof module == "object") // CommonJS
20 mod(require("../../lib/codemirror"));
20 mod(require("../../lib/codemirror"));
21 else if (typeof define == "function" && define.amd) // AMD
21 else if (typeof define == "function" && define.amd) // AMD
22 define(["../../lib/codemirror"], mod);
22 define(["../../lib/codemirror"], mod);
23 else // Plain browser env
23 else // Plain browser env
24 mod(CodeMirror);
24 mod(CodeMirror);
25 })(function(CodeMirror) {
25 })(function(CodeMirror) {
26 "use strict";
26 "use strict";
27
27
28 CodeMirror.defineMIME("text/x-erlang", "erlang");
28 CodeMirror.defineMIME("text/x-erlang", "erlang");
29
29
30 CodeMirror.defineMode("erlang", function(cmCfg) {
30 CodeMirror.defineMode("erlang", function(cmCfg) {
31 "use strict";
31 "use strict";
32
32
33 /////////////////////////////////////////////////////////////////////////////
33 /////////////////////////////////////////////////////////////////////////////
34 // constants
34 // constants
35
35
36 var typeWords = [
36 var typeWords = [
37 "-type", "-spec", "-export_type", "-opaque"];
37 "-type", "-spec", "-export_type", "-opaque"];
38
38
39 var keywordWords = [
39 var keywordWords = [
40 "after","begin","catch","case","cond","end","fun","if",
40 "after","begin","catch","case","cond","end","fun","if",
41 "let","of","query","receive","try","when"];
41 "let","of","query","receive","try","when"];
42
42
43 var separatorRE = /[\->,;]/;
43 var separatorRE = /[\->,;]/;
44 var separatorWords = [
44 var separatorWords = [
45 "->",";",","];
45 "->",";",","];
46
46
47 var operatorAtomWords = [
47 var operatorAtomWords = [
48 "and","andalso","band","bnot","bor","bsl","bsr","bxor",
48 "and","andalso","band","bnot","bor","bsl","bsr","bxor",
49 "div","not","or","orelse","rem","xor"];
49 "div","not","or","orelse","rem","xor"];
50
50
51 var operatorSymbolRE = /[\+\-\*\/<>=\|:!]/;
51 var operatorSymbolRE = /[\+\-\*\/<>=\|:!]/;
52 var operatorSymbolWords = [
52 var operatorSymbolWords = [
53 "=","+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-","!"];
53 "=","+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-","!"];
54
54
55 var openParenRE = /[<\(\[\{]/;
55 var openParenRE = /[<\(\[\{]/;
56 var openParenWords = [
56 var openParenWords = [
57 "<<","(","[","{"];
57 "<<","(","[","{"];
58
58
59 var closeParenRE = /[>\)\]\}]/;
59 var closeParenRE = /[>\)\]\}]/;
60 var closeParenWords = [
60 var closeParenWords = [
61 "}","]",")",">>"];
61 "}","]",")",">>"];
62
62
63 var guardWords = [
63 var guardWords = [
64 "is_atom","is_binary","is_bitstring","is_boolean","is_float",
64 "is_atom","is_binary","is_bitstring","is_boolean","is_float",
65 "is_function","is_integer","is_list","is_number","is_pid",
65 "is_function","is_integer","is_list","is_number","is_pid",
66 "is_port","is_record","is_reference","is_tuple",
66 "is_port","is_record","is_reference","is_tuple",
67 "atom","binary","bitstring","boolean","function","integer","list",
67 "atom","binary","bitstring","boolean","function","integer","list",
68 "number","pid","port","record","reference","tuple"];
68 "number","pid","port","record","reference","tuple"];
69
69
70 var bifWords = [
70 var bifWords = [
71 "abs","adler32","adler32_combine","alive","apply","atom_to_binary",
71 "abs","adler32","adler32_combine","alive","apply","atom_to_binary",
72 "atom_to_list","binary_to_atom","binary_to_existing_atom",
72 "atom_to_list","binary_to_atom","binary_to_existing_atom",
73 "binary_to_list","binary_to_term","bit_size","bitstring_to_list",
73 "binary_to_list","binary_to_term","bit_size","bitstring_to_list",
74 "byte_size","check_process_code","contact_binary","crc32",
74 "byte_size","check_process_code","contact_binary","crc32",
75 "crc32_combine","date","decode_packet","delete_module",
75 "crc32_combine","date","decode_packet","delete_module",
76 "disconnect_node","element","erase","exit","float","float_to_list",
76 "disconnect_node","element","erase","exit","float","float_to_list",
77 "garbage_collect","get","get_keys","group_leader","halt","hd",
77 "garbage_collect","get","get_keys","group_leader","halt","hd",
78 "integer_to_list","internal_bif","iolist_size","iolist_to_binary",
78 "integer_to_list","internal_bif","iolist_size","iolist_to_binary",
79 "is_alive","is_atom","is_binary","is_bitstring","is_boolean",
79 "is_alive","is_atom","is_binary","is_bitstring","is_boolean",
80 "is_float","is_function","is_integer","is_list","is_number","is_pid",
80 "is_float","is_function","is_integer","is_list","is_number","is_pid",
81 "is_port","is_process_alive","is_record","is_reference","is_tuple",
81 "is_port","is_process_alive","is_record","is_reference","is_tuple",
82 "length","link","list_to_atom","list_to_binary","list_to_bitstring",
82 "length","link","list_to_atom","list_to_binary","list_to_bitstring",
83 "list_to_existing_atom","list_to_float","list_to_integer",
83 "list_to_existing_atom","list_to_float","list_to_integer",
84 "list_to_pid","list_to_tuple","load_module","make_ref","module_loaded",
84 "list_to_pid","list_to_tuple","load_module","make_ref","module_loaded",
85 "monitor_node","node","node_link","node_unlink","nodes","notalive",
85 "monitor_node","node","node_link","node_unlink","nodes","notalive",
86 "now","open_port","pid_to_list","port_close","port_command",
86 "now","open_port","pid_to_list","port_close","port_command",
87 "port_connect","port_control","pre_loaded","process_flag",
87 "port_connect","port_control","pre_loaded","process_flag",
88 "process_info","processes","purge_module","put","register",
88 "process_info","processes","purge_module","put","register",
89 "registered","round","self","setelement","size","spawn","spawn_link",
89 "registered","round","self","setelement","size","spawn","spawn_link",
90 "spawn_monitor","spawn_opt","split_binary","statistics",
90 "spawn_monitor","spawn_opt","split_binary","statistics",
91 "term_to_binary","time","throw","tl","trunc","tuple_size",
91 "term_to_binary","time","throw","tl","trunc","tuple_size",
92 "tuple_to_list","unlink","unregister","whereis"];
92 "tuple_to_list","unlink","unregister","whereis"];
93
93
94 // upper case: [A-Z] [Ø-Þ] [À-Ö]
94 // upper case: [A-Z] [Ø-Þ] [À-Ö]
95 // lower case: [a-z] [ß-ö] [ø-ÿ]
95 // lower case: [a-z] [ß-ö] [ø-ÿ]
96 var anumRE = /[\w@Ø-ÞÀ-Öß-öø-ÿ]/;
96 var anumRE = /[\w@Ø-ÞÀ-Öß-öø-ÿ]/;
97 var escapesRE =
97 var escapesRE =
98 /[0-7]{1,3}|[bdefnrstv\\"']|\^[a-zA-Z]|x[0-9a-zA-Z]{2}|x{[0-9a-zA-Z]+}/;
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 // tokenizer
101 // tokenizer
102
102
103 function tokenizer(stream,state) {
103 function tokenizer(stream,state) {
104 // in multi-line string
104 // in multi-line string
105 if (state.in_string) {
105 if (state.in_string) {
106 state.in_string = (!doubleQuote(stream));
106 state.in_string = (!doubleQuote(stream));
107 return rval(state,stream,"string");
107 return rval(state,stream,"string");
108 }
108 }
109
109
110 // in multi-line atom
110 // in multi-line atom
111 if (state.in_atom) {
111 if (state.in_atom) {
112 state.in_atom = (!singleQuote(stream));
112 state.in_atom = (!singleQuote(stream));
113 return rval(state,stream,"atom");
113 return rval(state,stream,"atom");
114 }
114 }
115
115
116 // whitespace
116 // whitespace
117 if (stream.eatSpace()) {
117 if (stream.eatSpace()) {
118 return rval(state,stream,"whitespace");
118 return rval(state,stream,"whitespace");
119 }
119 }
120
120
121 // attributes and type specs
121 // attributes and type specs
122 if (!peekToken(state) &&
122 if (!peekToken(state) &&
123 stream.match(/-\s*[a-zß-öø-ÿ][\wØ-ÞÀ-Öß-öø-ÿ]*/)) {
123 stream.match(/-\s*[a-zß-öø-ÿ][\wØ-ÞÀ-Öß-öø-ÿ]*/)) {
124 if (is_member(stream.current(),typeWords)) {
124 if (is_member(stream.current(),typeWords)) {
125 return rval(state,stream,"type");
125 return rval(state,stream,"type");
126 }else{
126 }else{
127 return rval(state,stream,"attribute");
127 return rval(state,stream,"attribute");
128 }
128 }
129 }
129 }
130
130
131 var ch = stream.next();
131 var ch = stream.next();
132
132
133 // comment
133 // comment
134 if (ch == '%') {
134 if (ch == '%') {
135 stream.skipToEnd();
135 stream.skipToEnd();
136 return rval(state,stream,"comment");
136 return rval(state,stream,"comment");
137 }
137 }
138
138
139 // colon
139 // colon
140 if (ch == ":") {
140 if (ch == ":") {
141 return rval(state,stream,"colon");
141 return rval(state,stream,"colon");
142 }
142 }
143
143
144 // macro
144 // macro
145 if (ch == '?') {
145 if (ch == '?') {
146 stream.eatSpace();
146 stream.eatSpace();
147 stream.eatWhile(anumRE);
147 stream.eatWhile(anumRE);
148 return rval(state,stream,"macro");
148 return rval(state,stream,"macro");
149 }
149 }
150
150
151 // record
151 // record
152 if (ch == "#") {
152 if (ch == "#") {
153 stream.eatSpace();
153 stream.eatSpace();
154 stream.eatWhile(anumRE);
154 stream.eatWhile(anumRE);
155 return rval(state,stream,"record");
155 return rval(state,stream,"record");
156 }
156 }
157
157
158 // dollar escape
158 // dollar escape
159 if (ch == "$") {
159 if (ch == "$") {
160 if (stream.next() == "\\" && !stream.match(escapesRE)) {
160 if (stream.next() == "\\" && !stream.match(escapesRE)) {
161 return rval(state,stream,"error");
161 return rval(state,stream,"error");
162 }
162 }
163 return rval(state,stream,"number");
163 return rval(state,stream,"number");
164 }
164 }
165
165
166 // dot
166 // dot
167 if (ch == ".") {
167 if (ch == ".") {
168 return rval(state,stream,"dot");
168 return rval(state,stream,"dot");
169 }
169 }
170
170
171 // quoted atom
171 // quoted atom
172 if (ch == '\'') {
172 if (ch == '\'') {
173 if (!(state.in_atom = (!singleQuote(stream)))) {
173 if (!(state.in_atom = (!singleQuote(stream)))) {
174 if (stream.match(/\s*\/\s*[0-9]/,false)) {
174 if (stream.match(/\s*\/\s*[0-9]/,false)) {
175 stream.match(/\s*\/\s*[0-9]/,true);
175 stream.match(/\s*\/\s*[0-9]/,true);
176 return rval(state,stream,"fun"); // 'f'/0 style fun
176 return rval(state,stream,"fun"); // 'f'/0 style fun
177 }
177 }
178 if (stream.match(/\s*\(/,false) || stream.match(/\s*:/,false)) {
178 if (stream.match(/\s*\(/,false) || stream.match(/\s*:/,false)) {
179 return rval(state,stream,"function");
179 return rval(state,stream,"function");
180 }
180 }
181 }
181 }
182 return rval(state,stream,"atom");
182 return rval(state,stream,"atom");
183 }
183 }
184
184
185 // string
185 // string
186 if (ch == '"') {
186 if (ch == '"') {
187 state.in_string = (!doubleQuote(stream));
187 state.in_string = (!doubleQuote(stream));
188 return rval(state,stream,"string");
188 return rval(state,stream,"string");
189 }
189 }
190
190
191 // variable
191 // variable
192 if (/[A-Z_Ø-ÞÀ-Ö]/.test(ch)) {
192 if (/[A-Z_Ø-ÞÀ-Ö]/.test(ch)) {
193 stream.eatWhile(anumRE);
193 stream.eatWhile(anumRE);
194 return rval(state,stream,"variable");
194 return rval(state,stream,"variable");
195 }
195 }
196
196
197 // atom/keyword/BIF/function
197 // atom/keyword/BIF/function
198 if (/[a-z_ß-öø-ÿ]/.test(ch)) {
198 if (/[a-z_ß-öø-ÿ]/.test(ch)) {
199 stream.eatWhile(anumRE);
199 stream.eatWhile(anumRE);
200
200
201 if (stream.match(/\s*\/\s*[0-9]/,false)) {
201 if (stream.match(/\s*\/\s*[0-9]/,false)) {
202 stream.match(/\s*\/\s*[0-9]/,true);
202 stream.match(/\s*\/\s*[0-9]/,true);
203 return rval(state,stream,"fun"); // f/0 style fun
203 return rval(state,stream,"fun"); // f/0 style fun
204 }
204 }
205
205
206 var w = stream.current();
206 var w = stream.current();
207
207
208 if (is_member(w,keywordWords)) {
208 if (is_member(w,keywordWords)) {
209 return rval(state,stream,"keyword");
209 return rval(state,stream,"keyword");
210 }else if (is_member(w,operatorAtomWords)) {
210 }else if (is_member(w,operatorAtomWords)) {
211 return rval(state,stream,"operator");
211 return rval(state,stream,"operator");
212 }else if (stream.match(/\s*\(/,false)) {
212 }else if (stream.match(/\s*\(/,false)) {
213 // 'put' and 'erlang:put' are bifs, 'foo:put' is not
213 // 'put' and 'erlang:put' are bifs, 'foo:put' is not
214 if (is_member(w,bifWords) &&
214 if (is_member(w,bifWords) &&
215 ((peekToken(state).token != ":") ||
215 ((peekToken(state).token != ":") ||
216 (peekToken(state,2).token == "erlang"))) {
216 (peekToken(state,2).token == "erlang"))) {
217 return rval(state,stream,"builtin");
217 return rval(state,stream,"builtin");
218 }else if (is_member(w,guardWords)) {
218 }else if (is_member(w,guardWords)) {
219 return rval(state,stream,"guard");
219 return rval(state,stream,"guard");
220 }else{
220 }else{
221 return rval(state,stream,"function");
221 return rval(state,stream,"function");
222 }
222 }
223 }else if (is_member(w,operatorAtomWords)) {
224 return rval(state,stream,"operator");
225 }else if (lookahead(stream) == ":") {
223 }else if (lookahead(stream) == ":") {
226 if (w == "erlang") {
224 if (w == "erlang") {
227 return rval(state,stream,"builtin");
225 return rval(state,stream,"builtin");
228 } else {
226 } else {
229 return rval(state,stream,"function");
227 return rval(state,stream,"function");
230 }
228 }
231 }else if (is_member(w,["true","false"])) {
229 }else if (is_member(w,["true","false"])) {
232 return rval(state,stream,"boolean");
230 return rval(state,stream,"boolean");
233 }else if (is_member(w,["true","false"])) {
234 return rval(state,stream,"boolean");
235 }else{
231 }else{
236 return rval(state,stream,"atom");
232 return rval(state,stream,"atom");
237 }
233 }
238 }
234 }
239
235
240 // number
236 // number
241 var digitRE = /[0-9]/;
237 var digitRE = /[0-9]/;
242 var radixRE = /[0-9a-zA-Z]/; // 36#zZ style int
238 var radixRE = /[0-9a-zA-Z]/; // 36#zZ style int
243 if (digitRE.test(ch)) {
239 if (digitRE.test(ch)) {
244 stream.eatWhile(digitRE);
240 stream.eatWhile(digitRE);
245 if (stream.eat('#')) { // 36#aZ style integer
241 if (stream.eat('#')) { // 36#aZ style integer
246 if (!stream.eatWhile(radixRE)) {
242 if (!stream.eatWhile(radixRE)) {
247 stream.backUp(1); //"36#" - syntax error
243 stream.backUp(1); //"36#" - syntax error
248 }
244 }
249 } else if (stream.eat('.')) { // float
245 } else if (stream.eat('.')) { // float
250 if (!stream.eatWhile(digitRE)) {
246 if (!stream.eatWhile(digitRE)) {
251 stream.backUp(1); // "3." - probably end of function
247 stream.backUp(1); // "3." - probably end of function
252 } else {
248 } else {
253 if (stream.eat(/[eE]/)) { // float with exponent
249 if (stream.eat(/[eE]/)) { // float with exponent
254 if (stream.eat(/[-+]/)) {
250 if (stream.eat(/[-+]/)) {
255 if (!stream.eatWhile(digitRE)) {
251 if (!stream.eatWhile(digitRE)) {
256 stream.backUp(2); // "2e-" - syntax error
252 stream.backUp(2); // "2e-" - syntax error
257 }
253 }
258 } else {
254 } else {
259 if (!stream.eatWhile(digitRE)) {
255 if (!stream.eatWhile(digitRE)) {
260 stream.backUp(1); // "2e" - syntax error
256 stream.backUp(1); // "2e" - syntax error
261 }
257 }
262 }
258 }
263 }
259 }
264 }
260 }
265 }
261 }
266 return rval(state,stream,"number"); // normal integer
262 return rval(state,stream,"number"); // normal integer
267 }
263 }
268
264
269 // open parens
265 // open parens
270 if (nongreedy(stream,openParenRE,openParenWords)) {
266 if (nongreedy(stream,openParenRE,openParenWords)) {
271 return rval(state,stream,"open_paren");
267 return rval(state,stream,"open_paren");
272 }
268 }
273
269
274 // close parens
270 // close parens
275 if (nongreedy(stream,closeParenRE,closeParenWords)) {
271 if (nongreedy(stream,closeParenRE,closeParenWords)) {
276 return rval(state,stream,"close_paren");
272 return rval(state,stream,"close_paren");
277 }
273 }
278
274
279 // separators
275 // separators
280 if (greedy(stream,separatorRE,separatorWords)) {
276 if (greedy(stream,separatorRE,separatorWords)) {
281 return rval(state,stream,"separator");
277 return rval(state,stream,"separator");
282 }
278 }
283
279
284 // operators
280 // operators
285 if (greedy(stream,operatorSymbolRE,operatorSymbolWords)) {
281 if (greedy(stream,operatorSymbolRE,operatorSymbolWords)) {
286 return rval(state,stream,"operator");
282 return rval(state,stream,"operator");
287 }
283 }
288
284
289 return rval(state,stream,null);
285 return rval(state,stream,null);
290 }
286 }
291
287
292 /////////////////////////////////////////////////////////////////////////////
288 /////////////////////////////////////////////////////////////////////////////
293 // utilities
289 // utilities
294 function nongreedy(stream,re,words) {
290 function nongreedy(stream,re,words) {
295 if (stream.current().length == 1 && re.test(stream.current())) {
291 if (stream.current().length == 1 && re.test(stream.current())) {
296 stream.backUp(1);
292 stream.backUp(1);
297 while (re.test(stream.peek())) {
293 while (re.test(stream.peek())) {
298 stream.next();
294 stream.next();
299 if (is_member(stream.current(),words)) {
295 if (is_member(stream.current(),words)) {
300 return true;
296 return true;
301 }
297 }
302 }
298 }
303 stream.backUp(stream.current().length-1);
299 stream.backUp(stream.current().length-1);
304 }
300 }
305 return false;
301 return false;
306 }
302 }
307
303
308 function greedy(stream,re,words) {
304 function greedy(stream,re,words) {
309 if (stream.current().length == 1 && re.test(stream.current())) {
305 if (stream.current().length == 1 && re.test(stream.current())) {
310 while (re.test(stream.peek())) {
306 while (re.test(stream.peek())) {
311 stream.next();
307 stream.next();
312 }
308 }
313 while (0 < stream.current().length) {
309 while (0 < stream.current().length) {
314 if (is_member(stream.current(),words)) {
310 if (is_member(stream.current(),words)) {
315 return true;
311 return true;
316 }else{
312 }else{
317 stream.backUp(1);
313 stream.backUp(1);
318 }
314 }
319 }
315 }
320 stream.next();
316 stream.next();
321 }
317 }
322 return false;
318 return false;
323 }
319 }
324
320
325 function doubleQuote(stream) {
321 function doubleQuote(stream) {
326 return quote(stream, '"', '\\');
322 return quote(stream, '"', '\\');
327 }
323 }
328
324
329 function singleQuote(stream) {
325 function singleQuote(stream) {
330 return quote(stream,'\'','\\');
326 return quote(stream,'\'','\\');
331 }
327 }
332
328
333 function quote(stream,quoteChar,escapeChar) {
329 function quote(stream,quoteChar,escapeChar) {
334 while (!stream.eol()) {
330 while (!stream.eol()) {
335 var ch = stream.next();
331 var ch = stream.next();
336 if (ch == quoteChar) {
332 if (ch == quoteChar) {
337 return true;
333 return true;
338 }else if (ch == escapeChar) {
334 }else if (ch == escapeChar) {
339 stream.next();
335 stream.next();
340 }
336 }
341 }
337 }
342 return false;
338 return false;
343 }
339 }
344
340
345 function lookahead(stream) {
341 function lookahead(stream) {
346 var m = stream.match(/([\n\s]+|%[^\n]*\n)*(.)/,false);
342 var m = stream.match(/([\n\s]+|%[^\n]*\n)*(.)/,false);
347 return m ? m.pop() : "";
343 return m ? m.pop() : "";
348 }
344 }
349
345
350 function is_member(element,list) {
346 function is_member(element,list) {
351 return (-1 < list.indexOf(element));
347 return (-1 < list.indexOf(element));
352 }
348 }
353
349
354 function rval(state,stream,type) {
350 function rval(state,stream,type) {
355
351
356 // parse stack
352 // parse stack
357 pushToken(state,realToken(type,stream));
353 pushToken(state,realToken(type,stream));
358
354
359 // map erlang token type to CodeMirror style class
355 // map erlang token type to CodeMirror style class
360 // erlang -> CodeMirror tag
356 // erlang -> CodeMirror tag
361 switch (type) {
357 switch (type) {
362 case "atom": return "atom";
358 case "atom": return "atom";
363 case "attribute": return "attribute";
359 case "attribute": return "attribute";
364 case "boolean": return "atom";
360 case "boolean": return "atom";
365 case "builtin": return "builtin";
361 case "builtin": return "builtin";
366 case "close_paren": return null;
362 case "close_paren": return null;
367 case "colon": return null;
363 case "colon": return null;
368 case "comment": return "comment";
364 case "comment": return "comment";
369 case "dot": return null;
365 case "dot": return null;
370 case "error": return "error";
366 case "error": return "error";
371 case "fun": return "meta";
367 case "fun": return "meta";
372 case "function": return "tag";
368 case "function": return "tag";
373 case "guard": return "property";
369 case "guard": return "property";
374 case "keyword": return "keyword";
370 case "keyword": return "keyword";
375 case "macro": return "variable-2";
371 case "macro": return "variable-2";
376 case "number": return "number";
372 case "number": return "number";
377 case "open_paren": return null;
373 case "open_paren": return null;
378 case "operator": return "operator";
374 case "operator": return "operator";
379 case "record": return "bracket";
375 case "record": return "bracket";
380 case "separator": return null;
376 case "separator": return null;
381 case "string": return "string";
377 case "string": return "string";
382 case "type": return "def";
378 case "type": return "def";
383 case "variable": return "variable";
379 case "variable": return "variable";
384 default: return null;
380 default: return null;
385 }
381 }
386 }
382 }
387
383
388 function aToken(tok,col,ind,typ) {
384 function aToken(tok,col,ind,typ) {
389 return {token: tok,
385 return {token: tok,
390 column: col,
386 column: col,
391 indent: ind,
387 indent: ind,
392 type: typ};
388 type: typ};
393 }
389 }
394
390
395 function realToken(type,stream) {
391 function realToken(type,stream) {
396 return aToken(stream.current(),
392 return aToken(stream.current(),
397 stream.column(),
393 stream.column(),
398 stream.indentation(),
394 stream.indentation(),
399 type);
395 type);
400 }
396 }
401
397
402 function fakeToken(type) {
398 function fakeToken(type) {
403 return aToken(type,0,0,type);
399 return aToken(type,0,0,type);
404 }
400 }
405
401
406 function peekToken(state,depth) {
402 function peekToken(state,depth) {
407 var len = state.tokenStack.length;
403 var len = state.tokenStack.length;
408 var dep = (depth ? depth : 1);
404 var dep = (depth ? depth : 1);
409
405
410 if (len < dep) {
406 if (len < dep) {
411 return false;
407 return false;
412 }else{
408 }else{
413 return state.tokenStack[len-dep];
409 return state.tokenStack[len-dep];
414 }
410 }
415 }
411 }
416
412
417 function pushToken(state,token) {
413 function pushToken(state,token) {
418
414
419 if (!(token.type == "comment" || token.type == "whitespace")) {
415 if (!(token.type == "comment" || token.type == "whitespace")) {
420 state.tokenStack = maybe_drop_pre(state.tokenStack,token);
416 state.tokenStack = maybe_drop_pre(state.tokenStack,token);
421 state.tokenStack = maybe_drop_post(state.tokenStack);
417 state.tokenStack = maybe_drop_post(state.tokenStack);
422 }
418 }
423 }
419 }
424
420
425 function maybe_drop_pre(s,token) {
421 function maybe_drop_pre(s,token) {
426 var last = s.length-1;
422 var last = s.length-1;
427
423
428 if (0 < last && s[last].type === "record" && token.type === "dot") {
424 if (0 < last && s[last].type === "record" && token.type === "dot") {
429 s.pop();
425 s.pop();
430 }else if (0 < last && s[last].type === "group") {
426 }else if (0 < last && s[last].type === "group") {
431 s.pop();
427 s.pop();
432 s.push(token);
428 s.push(token);
433 }else{
429 }else{
434 s.push(token);
430 s.push(token);
435 }
431 }
436 return s;
432 return s;
437 }
433 }
438
434
439 function maybe_drop_post(s) {
435 function maybe_drop_post(s) {
440 var last = s.length-1;
436 var last = s.length-1;
441
437
442 if (s[last].type === "dot") {
438 if (s[last].type === "dot") {
443 return [];
439 return [];
444 }
440 }
445 if (s[last].type === "fun" && s[last-1].token === "fun") {
441 if (s[last].type === "fun" && s[last-1].token === "fun") {
446 return s.slice(0,last-1);
442 return s.slice(0,last-1);
447 }
443 }
448 switch (s[s.length-1].token) {
444 switch (s[s.length-1].token) {
449 case "}": return d(s,{g:["{"]});
445 case "}": return d(s,{g:["{"]});
450 case "]": return d(s,{i:["["]});
446 case "]": return d(s,{i:["["]});
451 case ")": return d(s,{i:["("]});
447 case ")": return d(s,{i:["("]});
452 case ">>": return d(s,{i:["<<"]});
448 case ">>": return d(s,{i:["<<"]});
453 case "end": return d(s,{i:["begin","case","fun","if","receive","try"]});
449 case "end": return d(s,{i:["begin","case","fun","if","receive","try"]});
454 case ",": return d(s,{e:["begin","try","when","->",
450 case ",": return d(s,{e:["begin","try","when","->",
455 ",","(","[","{","<<"]});
451 ",","(","[","{","<<"]});
456 case "->": return d(s,{r:["when"],
452 case "->": return d(s,{r:["when"],
457 m:["try","if","case","receive"]});
453 m:["try","if","case","receive"]});
458 case ";": return d(s,{E:["case","fun","if","receive","try","when"]});
454 case ";": return d(s,{E:["case","fun","if","receive","try","when"]});
459 case "catch":return d(s,{e:["try"]});
455 case "catch":return d(s,{e:["try"]});
460 case "of": return d(s,{e:["case"]});
456 case "of": return d(s,{e:["case"]});
461 case "after":return d(s,{e:["receive","try"]});
457 case "after":return d(s,{e:["receive","try"]});
462 default: return s;
458 default: return s;
463 }
459 }
464 }
460 }
465
461
466 function d(stack,tt) {
462 function d(stack,tt) {
467 // stack is a stack of Token objects.
463 // stack is a stack of Token objects.
468 // tt is an object; {type:tokens}
464 // tt is an object; {type:tokens}
469 // type is a char, tokens is a list of token strings.
465 // type is a char, tokens is a list of token strings.
470 // The function returns (possibly truncated) stack.
466 // The function returns (possibly truncated) stack.
471 // It will descend the stack, looking for a Token such that Token.token
467 // It will descend the stack, looking for a Token such that Token.token
472 // is a member of tokens. If it does not find that, it will normally (but
468 // is a member of tokens. If it does not find that, it will normally (but
473 // see "E" below) return stack. If it does find a match, it will remove
469 // see "E" below) return stack. If it does find a match, it will remove
474 // all the Tokens between the top and the matched Token.
470 // all the Tokens between the top and the matched Token.
475 // If type is "m", that is all it does.
471 // If type is "m", that is all it does.
476 // If type is "i", it will also remove the matched Token and the top Token.
472 // If type is "i", it will also remove the matched Token and the top Token.
477 // If type is "g", like "i", but add a fake "group" token at the top.
473 // If type is "g", like "i", but add a fake "group" token at the top.
478 // If type is "r", it will remove the matched Token, but not the top Token.
474 // If type is "r", it will remove the matched Token, but not the top Token.
479 // If type is "e", it will keep the matched Token but not the top Token.
475 // If type is "e", it will keep the matched Token but not the top Token.
480 // If type is "E", it behaves as for type "e", except if there is no match,
476 // If type is "E", it behaves as for type "e", except if there is no match,
481 // in which case it will return an empty stack.
477 // in which case it will return an empty stack.
482
478
483 for (var type in tt) {
479 for (var type in tt) {
484 var len = stack.length-1;
480 var len = stack.length-1;
485 var tokens = tt[type];
481 var tokens = tt[type];
486 for (var i = len-1; -1 < i ; i--) {
482 for (var i = len-1; -1 < i ; i--) {
487 if (is_member(stack[i].token,tokens)) {
483 if (is_member(stack[i].token,tokens)) {
488 var ss = stack.slice(0,i);
484 var ss = stack.slice(0,i);
489 switch (type) {
485 switch (type) {
490 case "m": return ss.concat(stack[i]).concat(stack[len]);
486 case "m": return ss.concat(stack[i]).concat(stack[len]);
491 case "r": return ss.concat(stack[len]);
487 case "r": return ss.concat(stack[len]);
492 case "i": return ss;
488 case "i": return ss;
493 case "g": return ss.concat(fakeToken("group"));
489 case "g": return ss.concat(fakeToken("group"));
494 case "E": return ss.concat(stack[i]);
490 case "E": return ss.concat(stack[i]);
495 case "e": return ss.concat(stack[i]);
491 case "e": return ss.concat(stack[i]);
496 }
492 }
497 }
493 }
498 }
494 }
499 }
495 }
500 return (type == "E" ? [] : stack);
496 return (type == "E" ? [] : stack);
501 }
497 }
502
498
503 /////////////////////////////////////////////////////////////////////////////
499 /////////////////////////////////////////////////////////////////////////////
504 // indenter
500 // indenter
505
501
506 function indenter(state,textAfter) {
502 function indenter(state,textAfter) {
507 var t;
503 var t;
508 var unit = cmCfg.indentUnit;
504 var unit = cmCfg.indentUnit;
509 var wordAfter = wordafter(textAfter);
505 var wordAfter = wordafter(textAfter);
510 var currT = peekToken(state,1);
506 var currT = peekToken(state,1);
511 var prevT = peekToken(state,2);
507 var prevT = peekToken(state,2);
512
508
513 if (state.in_string || state.in_atom) {
509 if (state.in_string || state.in_atom) {
514 return CodeMirror.Pass;
510 return CodeMirror.Pass;
515 }else if (!prevT) {
511 }else if (!prevT) {
516 return 0;
512 return 0;
517 }else if (currT.token == "when") {
513 }else if (currT.token == "when") {
518 return currT.column+unit;
514 return currT.column+unit;
519 }else if (wordAfter === "when" && prevT.type === "function") {
515 }else if (wordAfter === "when" && prevT.type === "function") {
520 return prevT.indent+unit;
516 return prevT.indent+unit;
521 }else if (wordAfter === "(" && currT.token === "fun") {
517 }else if (wordAfter === "(" && currT.token === "fun") {
522 return currT.column+3;
518 return currT.column+3;
523 }else if (wordAfter === "catch" && (t = getToken(state,["try"]))) {
519 }else if (wordAfter === "catch" && (t = getToken(state,["try"]))) {
524 return t.column;
520 return t.column;
525 }else if (is_member(wordAfter,["end","after","of"])) {
521 }else if (is_member(wordAfter,["end","after","of"])) {
526 t = getToken(state,["begin","case","fun","if","receive","try"]);
522 t = getToken(state,["begin","case","fun","if","receive","try"]);
527 return t ? t.column : CodeMirror.Pass;
523 return t ? t.column : CodeMirror.Pass;
528 }else if (is_member(wordAfter,closeParenWords)) {
524 }else if (is_member(wordAfter,closeParenWords)) {
529 t = getToken(state,openParenWords);
525 t = getToken(state,openParenWords);
530 return t ? t.column : CodeMirror.Pass;
526 return t ? t.column : CodeMirror.Pass;
531 }else if (is_member(currT.token,[",","|","||"]) ||
527 }else if (is_member(currT.token,[",","|","||"]) ||
532 is_member(wordAfter,[",","|","||"])) {
528 is_member(wordAfter,[",","|","||"])) {
533 t = postcommaToken(state);
529 t = postcommaToken(state);
534 return t ? t.column+t.token.length : unit;
530 return t ? t.column+t.token.length : unit;
535 }else if (currT.token == "->") {
531 }else if (currT.token == "->") {
536 if (is_member(prevT.token, ["receive","case","if","try"])) {
532 if (is_member(prevT.token, ["receive","case","if","try"])) {
537 return prevT.column+unit+unit;
533 return prevT.column+unit+unit;
538 }else{
534 }else{
539 return prevT.column+unit;
535 return prevT.column+unit;
540 }
536 }
541 }else if (is_member(currT.token,openParenWords)) {
537 }else if (is_member(currT.token,openParenWords)) {
542 return currT.column+currT.token.length;
538 return currT.column+currT.token.length;
543 }else{
539 }else{
544 t = defaultToken(state);
540 t = defaultToken(state);
545 return truthy(t) ? t.column+unit : 0;
541 return truthy(t) ? t.column+unit : 0;
546 }
542 }
547 }
543 }
548
544
549 function wordafter(str) {
545 function wordafter(str) {
550 var m = str.match(/,|[a-z]+|\}|\]|\)|>>|\|+|\(/);
546 var m = str.match(/,|[a-z]+|\}|\]|\)|>>|\|+|\(/);
551
547
552 return truthy(m) && (m.index === 0) ? m[0] : "";
548 return truthy(m) && (m.index === 0) ? m[0] : "";
553 }
549 }
554
550
555 function postcommaToken(state) {
551 function postcommaToken(state) {
556 var objs = state.tokenStack.slice(0,-1);
552 var objs = state.tokenStack.slice(0,-1);
557 var i = getTokenIndex(objs,"type",["open_paren"]);
553 var i = getTokenIndex(objs,"type",["open_paren"]);
558
554
559 return truthy(objs[i]) ? objs[i] : false;
555 return truthy(objs[i]) ? objs[i] : false;
560 }
556 }
561
557
562 function defaultToken(state) {
558 function defaultToken(state) {
563 var objs = state.tokenStack;
559 var objs = state.tokenStack;
564 var stop = getTokenIndex(objs,"type",["open_paren","separator","keyword"]);
560 var stop = getTokenIndex(objs,"type",["open_paren","separator","keyword"]);
565 var oper = getTokenIndex(objs,"type",["operator"]);
561 var oper = getTokenIndex(objs,"type",["operator"]);
566
562
567 if (truthy(stop) && truthy(oper) && stop < oper) {
563 if (truthy(stop) && truthy(oper) && stop < oper) {
568 return objs[stop+1];
564 return objs[stop+1];
569 } else if (truthy(stop)) {
565 } else if (truthy(stop)) {
570 return objs[stop];
566 return objs[stop];
571 } else {
567 } else {
572 return false;
568 return false;
573 }
569 }
574 }
570 }
575
571
576 function getToken(state,tokens) {
572 function getToken(state,tokens) {
577 var objs = state.tokenStack;
573 var objs = state.tokenStack;
578 var i = getTokenIndex(objs,"token",tokens);
574 var i = getTokenIndex(objs,"token",tokens);
579
575
580 return truthy(objs[i]) ? objs[i] : false;
576 return truthy(objs[i]) ? objs[i] : false;
581 }
577 }
582
578
583 function getTokenIndex(objs,propname,propvals) {
579 function getTokenIndex(objs,propname,propvals) {
584
580
585 for (var i = objs.length-1; -1 < i ; i--) {
581 for (var i = objs.length-1; -1 < i ; i--) {
586 if (is_member(objs[i][propname],propvals)) {
582 if (is_member(objs[i][propname],propvals)) {
587 return i;
583 return i;
588 }
584 }
589 }
585 }
590 return false;
586 return false;
591 }
587 }
592
588
593 function truthy(x) {
589 function truthy(x) {
594 return (x !== false) && (x != null);
590 return (x !== false) && (x != null);
595 }
591 }
596
592
597 /////////////////////////////////////////////////////////////////////////////
593 /////////////////////////////////////////////////////////////////////////////
598 // this object defines the mode
594 // this object defines the mode
599
595
600 return {
596 return {
601 startState:
597 startState:
602 function() {
598 function() {
603 return {tokenStack: [],
599 return {tokenStack: [],
604 in_string: false,
600 in_string: false,
605 in_atom: false};
601 in_atom: false};
606 },
602 },
607
603
608 token:
604 token:
609 function(stream, state) {
605 function(stream, state) {
610 return tokenizer(stream, state);
606 return tokenizer(stream, state);
611 },
607 },
612
608
613 indent:
609 indent:
614 function(state, textAfter) {
610 function(state, textAfter) {
615 return indenter(state,textAfter);
611 return indenter(state,textAfter);
616 },
612 },
617
613
618 lineComment: "%"
614 lineComment: "%"
619 };
615 };
620 });
616 });
621
617
622 });
618 });
@@ -1,123 +1,130 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../markdown/markdown"), require("../../addon/mode/overlay"));
6 mod(require("../../lib/codemirror"), require("../markdown/markdown"), require("../../addon/mode/overlay"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../markdown/markdown", "../../addon/mode/overlay"], mod);
8 define(["../../lib/codemirror", "../markdown/markdown", "../../addon/mode/overlay"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
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 CodeMirror.defineMode("gfm", function(config, modeConfig) {
16 CodeMirror.defineMode("gfm", function(config, modeConfig) {
15 var codeDepth = 0;
17 var codeDepth = 0;
16 function blankLine(state) {
18 function blankLine(state) {
17 state.code = false;
19 state.code = false;
18 return null;
20 return null;
19 }
21 }
20 var gfmOverlay = {
22 var gfmOverlay = {
21 startState: function() {
23 startState: function() {
22 return {
24 return {
23 code: false,
25 code: false,
24 codeBlock: false,
26 codeBlock: false,
25 ateSpace: false
27 ateSpace: false
26 };
28 };
27 },
29 },
28 copyState: function(s) {
30 copyState: function(s) {
29 return {
31 return {
30 code: s.code,
32 code: s.code,
31 codeBlock: s.codeBlock,
33 codeBlock: s.codeBlock,
32 ateSpace: s.ateSpace
34 ateSpace: s.ateSpace
33 };
35 };
34 },
36 },
35 token: function(stream, state) {
37 token: function(stream, state) {
36 state.combineTokens = null;
38 state.combineTokens = null;
37
39
38 // Hack to prevent formatting override inside code blocks (block and inline)
40 // Hack to prevent formatting override inside code blocks (block and inline)
39 if (state.codeBlock) {
41 if (state.codeBlock) {
40 if (stream.match(/^```/)) {
42 if (stream.match(/^```+/)) {
41 state.codeBlock = false;
43 state.codeBlock = false;
42 return null;
44 return null;
43 }
45 }
44 stream.skipToEnd();
46 stream.skipToEnd();
45 return null;
47 return null;
46 }
48 }
47 if (stream.sol()) {
49 if (stream.sol()) {
48 state.code = false;
50 state.code = false;
49 }
51 }
50 if (stream.sol() && stream.match(/^```/)) {
52 if (stream.sol() && stream.match(/^```+/)) {
51 stream.skipToEnd();
53 stream.skipToEnd();
52 state.codeBlock = true;
54 state.codeBlock = true;
53 return null;
55 return null;
54 }
56 }
55 // If this block is changed, it may need to be updated in Markdown mode
57 // If this block is changed, it may need to be updated in Markdown mode
56 if (stream.peek() === '`') {
58 if (stream.peek() === '`') {
57 stream.next();
59 stream.next();
58 var before = stream.pos;
60 var before = stream.pos;
59 stream.eatWhile('`');
61 stream.eatWhile('`');
60 var difference = 1 + stream.pos - before;
62 var difference = 1 + stream.pos - before;
61 if (!state.code) {
63 if (!state.code) {
62 codeDepth = difference;
64 codeDepth = difference;
63 state.code = true;
65 state.code = true;
64 } else {
66 } else {
65 if (difference === codeDepth) { // Must be exact
67 if (difference === codeDepth) { // Must be exact
66 state.code = false;
68 state.code = false;
67 }
69 }
68 }
70 }
69 return null;
71 return null;
70 } else if (state.code) {
72 } else if (state.code) {
71 stream.next();
73 stream.next();
72 return null;
74 return null;
73 }
75 }
74 // Check if space. If so, links can be formatted later on
76 // Check if space. If so, links can be formatted later on
75 if (stream.eatSpace()) {
77 if (stream.eatSpace()) {
76 state.ateSpace = true;
78 state.ateSpace = true;
77 return null;
79 return null;
78 }
80 }
79 if (stream.sol() || state.ateSpace) {
81 if (stream.sol() || state.ateSpace) {
80 state.ateSpace = false;
82 state.ateSpace = false;
81 if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) {
83 if (modeConfig.gitHubSpice !== false) {
82 // User/Project@SHA
84 if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) {
83 // User@SHA
85 // User/Project@SHA
84 // SHA
86 // User@SHA
85 state.combineTokens = true;
87 // SHA
86 return "link";
88 state.combineTokens = true;
87 } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) {
89 return "link";
88 // User/Project#Num
90 } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) {
89 // User#Num
91 // User/Project#Num
90 // #Num
92 // User#Num
91 state.combineTokens = true;
93 // #Num
92 return "link";
94 state.combineTokens = true;
95 return "link";
96 }
93 }
97 }
94 }
98 }
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) &&
99 if (stream.match(urlRE) &&
96 stream.string.slice(stream.start - 2, stream.start) != "](") {
100 stream.string.slice(stream.start - 2, stream.start) != "](" &&
101 (stream.start == 0 || /\W/.test(stream.string.charAt(stream.start - 1)))) {
97 // URLs
102 // URLs
98 // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
103 // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
99 // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine
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 state.combineTokens = true;
106 state.combineTokens = true;
101 return "link";
107 return "link";
102 }
108 }
103 stream.next();
109 stream.next();
104 return null;
110 return null;
105 },
111 },
106 blankLine: blankLine
112 blankLine: blankLine
107 };
113 };
108
114
109 var markdownConfig = {
115 var markdownConfig = {
110 underscoresBreakWords: false,
116 underscoresBreakWords: false,
111 taskLists: true,
117 taskLists: true,
112 fencedCodeBlocks: true,
118 fencedCodeBlocks: '```',
113 strikethrough: true
119 strikethrough: true
114 };
120 };
115 for (var attr in modeConfig) {
121 for (var attr in modeConfig) {
116 markdownConfig[attr] = modeConfig[attr];
122 markdownConfig[attr] = modeConfig[attr];
117 }
123 }
118 markdownConfig.name = "markdown";
124 markdownConfig.name = "markdown";
119 CodeMirror.defineMIME("gfmBase", markdownConfig);
125 return CodeMirror.overlayMode(CodeMirror.getMode(config, markdownConfig), gfmOverlay);
120 return CodeMirror.overlayMode(CodeMirror.getMode(config, "gfmBase"), gfmOverlay);
126
121 }, "markdown");
127 }, "markdown");
122
128
129 CodeMirror.defineMIME("text/x-gfm", "gfm");
123 });
130 });
@@ -1,185 +1,185 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("go", function(config) {
14 CodeMirror.defineMode("go", function(config) {
15 var indentUnit = config.indentUnit;
15 var indentUnit = config.indentUnit;
16
16
17 var keywords = {
17 var keywords = {
18 "break":true, "case":true, "chan":true, "const":true, "continue":true,
18 "break":true, "case":true, "chan":true, "const":true, "continue":true,
19 "default":true, "defer":true, "else":true, "fallthrough":true, "for":true,
19 "default":true, "defer":true, "else":true, "fallthrough":true, "for":true,
20 "func":true, "go":true, "goto":true, "if":true, "import":true,
20 "func":true, "go":true, "goto":true, "if":true, "import":true,
21 "interface":true, "map":true, "package":true, "range":true, "return":true,
21 "interface":true, "map":true, "package":true, "range":true, "return":true,
22 "select":true, "struct":true, "switch":true, "type":true, "var":true,
22 "select":true, "struct":true, "switch":true, "type":true, "var":true,
23 "bool":true, "byte":true, "complex64":true, "complex128":true,
23 "bool":true, "byte":true, "complex64":true, "complex128":true,
24 "float32":true, "float64":true, "int8":true, "int16":true, "int32":true,
24 "float32":true, "float64":true, "int8":true, "int16":true, "int32":true,
25 "int64":true, "string":true, "uint8":true, "uint16":true, "uint32":true,
25 "int64":true, "string":true, "uint8":true, "uint16":true, "uint32":true,
26 "uint64":true, "int":true, "uint":true, "uintptr":true
26 "uint64":true, "int":true, "uint":true, "uintptr":true
27 };
27 };
28
28
29 var atoms = {
29 var atoms = {
30 "true":true, "false":true, "iota":true, "nil":true, "append":true,
30 "true":true, "false":true, "iota":true, "nil":true, "append":true,
31 "cap":true, "close":true, "complex":true, "copy":true, "imag":true,
31 "cap":true, "close":true, "complex":true, "copy":true, "imag":true,
32 "len":true, "make":true, "new":true, "panic":true, "print":true,
32 "len":true, "make":true, "new":true, "panic":true, "print":true,
33 "println":true, "real":true, "recover":true
33 "println":true, "real":true, "recover":true
34 };
34 };
35
35
36 var isOperatorChar = /[+\-*&^%:=<>!|\/]/;
36 var isOperatorChar = /[+\-*&^%:=<>!|\/]/;
37
37
38 var curPunc;
38 var curPunc;
39
39
40 function tokenBase(stream, state) {
40 function tokenBase(stream, state) {
41 var ch = stream.next();
41 var ch = stream.next();
42 if (ch == '"' || ch == "'" || ch == "`") {
42 if (ch == '"' || ch == "'" || ch == "`") {
43 state.tokenize = tokenString(ch);
43 state.tokenize = tokenString(ch);
44 return state.tokenize(stream, state);
44 return state.tokenize(stream, state);
45 }
45 }
46 if (/[\d\.]/.test(ch)) {
46 if (/[\d\.]/.test(ch)) {
47 if (ch == ".") {
47 if (ch == ".") {
48 stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/);
48 stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/);
49 } else if (ch == "0") {
49 } else if (ch == "0") {
50 stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/);
50 stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/);
51 } else {
51 } else {
52 stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/);
52 stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/);
53 }
53 }
54 return "number";
54 return "number";
55 }
55 }
56 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
56 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
57 curPunc = ch;
57 curPunc = ch;
58 return null;
58 return null;
59 }
59 }
60 if (ch == "/") {
60 if (ch == "/") {
61 if (stream.eat("*")) {
61 if (stream.eat("*")) {
62 state.tokenize = tokenComment;
62 state.tokenize = tokenComment;
63 return tokenComment(stream, state);
63 return tokenComment(stream, state);
64 }
64 }
65 if (stream.eat("/")) {
65 if (stream.eat("/")) {
66 stream.skipToEnd();
66 stream.skipToEnd();
67 return "comment";
67 return "comment";
68 }
68 }
69 }
69 }
70 if (isOperatorChar.test(ch)) {
70 if (isOperatorChar.test(ch)) {
71 stream.eatWhile(isOperatorChar);
71 stream.eatWhile(isOperatorChar);
72 return "operator";
72 return "operator";
73 }
73 }
74 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
74 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
75 var cur = stream.current();
75 var cur = stream.current();
76 if (keywords.propertyIsEnumerable(cur)) {
76 if (keywords.propertyIsEnumerable(cur)) {
77 if (cur == "case" || cur == "default") curPunc = "case";
77 if (cur == "case" || cur == "default") curPunc = "case";
78 return "keyword";
78 return "keyword";
79 }
79 }
80 if (atoms.propertyIsEnumerable(cur)) return "atom";
80 if (atoms.propertyIsEnumerable(cur)) return "atom";
81 return "variable";
81 return "variable";
82 }
82 }
83
83
84 function tokenString(quote) {
84 function tokenString(quote) {
85 return function(stream, state) {
85 return function(stream, state) {
86 var escaped = false, next, end = false;
86 var escaped = false, next, end = false;
87 while ((next = stream.next()) != null) {
87 while ((next = stream.next()) != null) {
88 if (next == quote && !escaped) {end = true; break;}
88 if (next == quote && !escaped) {end = true; break;}
89 escaped = !escaped && next == "\\";
89 escaped = !escaped && quote != "`" && next == "\\";
90 }
90 }
91 if (end || !(escaped || quote == "`"))
91 if (end || !(escaped || quote == "`"))
92 state.tokenize = tokenBase;
92 state.tokenize = tokenBase;
93 return "string";
93 return "string";
94 };
94 };
95 }
95 }
96
96
97 function tokenComment(stream, state) {
97 function tokenComment(stream, state) {
98 var maybeEnd = false, ch;
98 var maybeEnd = false, ch;
99 while (ch = stream.next()) {
99 while (ch = stream.next()) {
100 if (ch == "/" && maybeEnd) {
100 if (ch == "/" && maybeEnd) {
101 state.tokenize = tokenBase;
101 state.tokenize = tokenBase;
102 break;
102 break;
103 }
103 }
104 maybeEnd = (ch == "*");
104 maybeEnd = (ch == "*");
105 }
105 }
106 return "comment";
106 return "comment";
107 }
107 }
108
108
109 function Context(indented, column, type, align, prev) {
109 function Context(indented, column, type, align, prev) {
110 this.indented = indented;
110 this.indented = indented;
111 this.column = column;
111 this.column = column;
112 this.type = type;
112 this.type = type;
113 this.align = align;
113 this.align = align;
114 this.prev = prev;
114 this.prev = prev;
115 }
115 }
116 function pushContext(state, col, type) {
116 function pushContext(state, col, type) {
117 return state.context = new Context(state.indented, col, type, null, state.context);
117 return state.context = new Context(state.indented, col, type, null, state.context);
118 }
118 }
119 function popContext(state) {
119 function popContext(state) {
120 if (!state.context.prev) return;
120 if (!state.context.prev) return;
121 var t = state.context.type;
121 var t = state.context.type;
122 if (t == ")" || t == "]" || t == "}")
122 if (t == ")" || t == "]" || t == "}")
123 state.indented = state.context.indented;
123 state.indented = state.context.indented;
124 return state.context = state.context.prev;
124 return state.context = state.context.prev;
125 }
125 }
126
126
127 // Interface
127 // Interface
128
128
129 return {
129 return {
130 startState: function(basecolumn) {
130 startState: function(basecolumn) {
131 return {
131 return {
132 tokenize: null,
132 tokenize: null,
133 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
133 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
134 indented: 0,
134 indented: 0,
135 startOfLine: true
135 startOfLine: true
136 };
136 };
137 },
137 },
138
138
139 token: function(stream, state) {
139 token: function(stream, state) {
140 var ctx = state.context;
140 var ctx = state.context;
141 if (stream.sol()) {
141 if (stream.sol()) {
142 if (ctx.align == null) ctx.align = false;
142 if (ctx.align == null) ctx.align = false;
143 state.indented = stream.indentation();
143 state.indented = stream.indentation();
144 state.startOfLine = true;
144 state.startOfLine = true;
145 if (ctx.type == "case") ctx.type = "}";
145 if (ctx.type == "case") ctx.type = "}";
146 }
146 }
147 if (stream.eatSpace()) return null;
147 if (stream.eatSpace()) return null;
148 curPunc = null;
148 curPunc = null;
149 var style = (state.tokenize || tokenBase)(stream, state);
149 var style = (state.tokenize || tokenBase)(stream, state);
150 if (style == "comment") return style;
150 if (style == "comment") return style;
151 if (ctx.align == null) ctx.align = true;
151 if (ctx.align == null) ctx.align = true;
152
152
153 if (curPunc == "{") pushContext(state, stream.column(), "}");
153 if (curPunc == "{") pushContext(state, stream.column(), "}");
154 else if (curPunc == "[") pushContext(state, stream.column(), "]");
154 else if (curPunc == "[") pushContext(state, stream.column(), "]");
155 else if (curPunc == "(") pushContext(state, stream.column(), ")");
155 else if (curPunc == "(") pushContext(state, stream.column(), ")");
156 else if (curPunc == "case") ctx.type = "case";
156 else if (curPunc == "case") ctx.type = "case";
157 else if (curPunc == "}" && ctx.type == "}") ctx = popContext(state);
157 else if (curPunc == "}" && ctx.type == "}") ctx = popContext(state);
158 else if (curPunc == ctx.type) popContext(state);
158 else if (curPunc == ctx.type) popContext(state);
159 state.startOfLine = false;
159 state.startOfLine = false;
160 return style;
160 return style;
161 },
161 },
162
162
163 indent: function(state, textAfter) {
163 indent: function(state, textAfter) {
164 if (state.tokenize != tokenBase && state.tokenize != null) return 0;
164 if (state.tokenize != tokenBase && state.tokenize != null) return 0;
165 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
165 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
166 if (ctx.type == "case" && /^(?:case|default)\b/.test(textAfter)) {
166 if (ctx.type == "case" && /^(?:case|default)\b/.test(textAfter)) {
167 state.context.type = "}";
167 state.context.type = "}";
168 return ctx.indented;
168 return ctx.indented;
169 }
169 }
170 var closing = firstChar == ctx.type;
170 var closing = firstChar == ctx.type;
171 if (ctx.align) return ctx.column + (closing ? 0 : 1);
171 if (ctx.align) return ctx.column + (closing ? 0 : 1);
172 else return ctx.indented + (closing ? 0 : indentUnit);
172 else return ctx.indented + (closing ? 0 : indentUnit);
173 },
173 },
174
174
175 electricChars: "{}):",
175 electricChars: "{}):",
176 fold: "brace",
176 fold: "brace",
177 blockCommentStart: "/*",
177 blockCommentStart: "/*",
178 blockCommentEnd: "*/",
178 blockCommentEnd: "*/",
179 lineComment: "//"
179 lineComment: "//"
180 };
180 };
181 });
181 });
182
182
183 CodeMirror.defineMIME("text/x-go", "go");
183 CodeMirror.defineMIME("text/x-go", "go");
184
184
185 });
185 });
@@ -1,159 +1,161 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../ruby/ruby"));
6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../ruby/ruby"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../ruby/ruby"], mod);
8 define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../ruby/ruby"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 // full haml mode. This handled embeded ruby and html fragments too
14 // full haml mode. This handled embeded ruby and html fragments too
15 CodeMirror.defineMode("haml", function(config) {
15 CodeMirror.defineMode("haml", function(config) {
16 var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"});
16 var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"});
17 var rubyMode = CodeMirror.getMode(config, "ruby");
17 var rubyMode = CodeMirror.getMode(config, "ruby");
18
18
19 function rubyInQuote(endQuote) {
19 function rubyInQuote(endQuote) {
20 return function(stream, state) {
20 return function(stream, state) {
21 var ch = stream.peek();
21 var ch = stream.peek();
22 if (ch == endQuote && state.rubyState.tokenize.length == 1) {
22 if (ch == endQuote && state.rubyState.tokenize.length == 1) {
23 // step out of ruby context as it seems to complete processing all the braces
23 // step out of ruby context as it seems to complete processing all the braces
24 stream.next();
24 stream.next();
25 state.tokenize = html;
25 state.tokenize = html;
26 return "closeAttributeTag";
26 return "closeAttributeTag";
27 } else {
27 } else {
28 return ruby(stream, state);
28 return ruby(stream, state);
29 }
29 }
30 };
30 };
31 }
31 }
32
32
33 function ruby(stream, state) {
33 function ruby(stream, state) {
34 if (stream.match("-#")) {
34 if (stream.match("-#")) {
35 stream.skipToEnd();
35 stream.skipToEnd();
36 return "comment";
36 return "comment";
37 }
37 }
38 return rubyMode.token(stream, state.rubyState);
38 return rubyMode.token(stream, state.rubyState);
39 }
39 }
40
40
41 function html(stream, state) {
41 function html(stream, state) {
42 var ch = stream.peek();
42 var ch = stream.peek();
43
43
44 // handle haml declarations. All declarations that cant be handled here
44 // handle haml declarations. All declarations that cant be handled here
45 // will be passed to html mode
45 // will be passed to html mode
46 if (state.previousToken.style == "comment" ) {
46 if (state.previousToken.style == "comment" ) {
47 if (state.indented > state.previousToken.indented) {
47 if (state.indented > state.previousToken.indented) {
48 stream.skipToEnd();
48 stream.skipToEnd();
49 return "commentLine";
49 return "commentLine";
50 }
50 }
51 }
51 }
52
52
53 if (state.startOfLine) {
53 if (state.startOfLine) {
54 if (ch == "!" && stream.match("!!")) {
54 if (ch == "!" && stream.match("!!")) {
55 stream.skipToEnd();
55 stream.skipToEnd();
56 return "tag";
56 return "tag";
57 } else if (stream.match(/^%[\w:#\.]+=/)) {
57 } else if (stream.match(/^%[\w:#\.]+=/)) {
58 state.tokenize = ruby;
58 state.tokenize = ruby;
59 return "hamlTag";
59 return "hamlTag";
60 } else if (stream.match(/^%[\w:]+/)) {
60 } else if (stream.match(/^%[\w:]+/)) {
61 return "hamlTag";
61 return "hamlTag";
62 } else if (ch == "/" ) {
62 } else if (ch == "/" ) {
63 stream.skipToEnd();
63 stream.skipToEnd();
64 return "comment";
64 return "comment";
65 }
65 }
66 }
66 }
67
67
68 if (state.startOfLine || state.previousToken.style == "hamlTag") {
68 if (state.startOfLine || state.previousToken.style == "hamlTag") {
69 if ( ch == "#" || ch == ".") {
69 if ( ch == "#" || ch == ".") {
70 stream.match(/[\w-#\.]*/);
70 stream.match(/[\w-#\.]*/);
71 return "hamlAttribute";
71 return "hamlAttribute";
72 }
72 }
73 }
73 }
74
74
75 // donot handle --> as valid ruby, make it HTML close comment instead
75 // donot handle --> as valid ruby, make it HTML close comment instead
76 if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) {
76 if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) {
77 state.tokenize = ruby;
77 state.tokenize = ruby;
78 return state.tokenize(stream, state);
78 return state.tokenize(stream, state);
79 }
79 }
80
80
81 if (state.previousToken.style == "hamlTag" ||
81 if (state.previousToken.style == "hamlTag" ||
82 state.previousToken.style == "closeAttributeTag" ||
82 state.previousToken.style == "closeAttributeTag" ||
83 state.previousToken.style == "hamlAttribute") {
83 state.previousToken.style == "hamlAttribute") {
84 if (ch == "(") {
84 if (ch == "(") {
85 state.tokenize = rubyInQuote(")");
85 state.tokenize = rubyInQuote(")");
86 return state.tokenize(stream, state);
86 return state.tokenize(stream, state);
87 } else if (ch == "{") {
87 } else if (ch == "{") {
88 state.tokenize = rubyInQuote("}");
88 if (!stream.match(/^\{%.*/)) {
89 return state.tokenize(stream, state);
89 state.tokenize = rubyInQuote("}");
90 return state.tokenize(stream, state);
91 }
90 }
92 }
91 }
93 }
92
94
93 return htmlMode.token(stream, state.htmlState);
95 return htmlMode.token(stream, state.htmlState);
94 }
96 }
95
97
96 return {
98 return {
97 // default to html mode
99 // default to html mode
98 startState: function() {
100 startState: function() {
99 var htmlState = htmlMode.startState();
101 var htmlState = htmlMode.startState();
100 var rubyState = rubyMode.startState();
102 var rubyState = rubyMode.startState();
101 return {
103 return {
102 htmlState: htmlState,
104 htmlState: htmlState,
103 rubyState: rubyState,
105 rubyState: rubyState,
104 indented: 0,
106 indented: 0,
105 previousToken: { style: null, indented: 0},
107 previousToken: { style: null, indented: 0},
106 tokenize: html
108 tokenize: html
107 };
109 };
108 },
110 },
109
111
110 copyState: function(state) {
112 copyState: function(state) {
111 return {
113 return {
112 htmlState : CodeMirror.copyState(htmlMode, state.htmlState),
114 htmlState : CodeMirror.copyState(htmlMode, state.htmlState),
113 rubyState: CodeMirror.copyState(rubyMode, state.rubyState),
115 rubyState: CodeMirror.copyState(rubyMode, state.rubyState),
114 indented: state.indented,
116 indented: state.indented,
115 previousToken: state.previousToken,
117 previousToken: state.previousToken,
116 tokenize: state.tokenize
118 tokenize: state.tokenize
117 };
119 };
118 },
120 },
119
121
120 token: function(stream, state) {
122 token: function(stream, state) {
121 if (stream.sol()) {
123 if (stream.sol()) {
122 state.indented = stream.indentation();
124 state.indented = stream.indentation();
123 state.startOfLine = true;
125 state.startOfLine = true;
124 }
126 }
125 if (stream.eatSpace()) return null;
127 if (stream.eatSpace()) return null;
126 var style = state.tokenize(stream, state);
128 var style = state.tokenize(stream, state);
127 state.startOfLine = false;
129 state.startOfLine = false;
128 // dont record comment line as we only want to measure comment line with
130 // dont record comment line as we only want to measure comment line with
129 // the opening comment block
131 // the opening comment block
130 if (style && style != "commentLine") {
132 if (style && style != "commentLine") {
131 state.previousToken = { style: style, indented: state.indented };
133 state.previousToken = { style: style, indented: state.indented };
132 }
134 }
133 // if current state is ruby and the previous token is not `,` reset the
135 // if current state is ruby and the previous token is not `,` reset the
134 // tokenize to html
136 // tokenize to html
135 if (stream.eol() && state.tokenize == ruby) {
137 if (stream.eol() && state.tokenize == ruby) {
136 stream.backUp(1);
138 stream.backUp(1);
137 var ch = stream.peek();
139 var ch = stream.peek();
138 stream.next();
140 stream.next();
139 if (ch && ch != ",") {
141 if (ch && ch != ",") {
140 state.tokenize = html;
142 state.tokenize = html;
141 }
143 }
142 }
144 }
143 // reprocess some of the specific style tag when finish setting previousToken
145 // reprocess some of the specific style tag when finish setting previousToken
144 if (style == "hamlTag") {
146 if (style == "hamlTag") {
145 style = "tag";
147 style = "tag";
146 } else if (style == "commentLine") {
148 } else if (style == "commentLine") {
147 style = "comment";
149 style = "comment";
148 } else if (style == "hamlAttribute") {
150 } else if (style == "hamlAttribute") {
149 style = "attribute";
151 style = "attribute";
150 } else if (style == "closeAttributeTag") {
152 } else if (style == "closeAttributeTag") {
151 style = null;
153 style = null;
152 }
154 }
153 return style;
155 return style;
154 }
156 }
155 };
157 };
156 }, "htmlmixed", "ruby");
158 }, "htmlmixed", "ruby");
157
159
158 CodeMirror.defineMIME("text/x-haml", "haml");
160 CodeMirror.defineMIME("text/x-haml", "haml");
159 });
161 });
@@ -1,53 +1,62 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
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 else if (typeof define == "function" && define.amd) // AMD
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 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineSimpleMode("handlebars", {
14 CodeMirror.defineSimpleMode("handlebars-tags", {
15 start: [
15 start: [
16 { regex: /\{\{!--/, push: "dash_comment", token: "comment" },
16 { regex: /\{\{!--/, push: "dash_comment", token: "comment" },
17 { regex: /\{\{!/, push: "comment", token: "comment" },
17 { regex: /\{\{!/, push: "comment", token: "comment" },
18 { regex: /\{\{/, push: "handlebars", token: "tag" }
18 { regex: /\{\{/, push: "handlebars", token: "tag" }
19 ],
19 ],
20 handlebars: [
20 handlebars: [
21 { regex: /\}\}/, pop: true, token: "tag" },
21 { regex: /\}\}/, pop: true, token: "tag" },
22
22
23 // Double and single quotes
23 // Double and single quotes
24 { regex: /"(?:[^\\]|\\.)*?"/, token: "string" },
24 { regex: /"(?:[^\\"]|\\.)*"?/, token: "string" },
25 { regex: /'(?:[^\\]|\\.)*?'/, token: "string" },
25 { regex: /'(?:[^\\']|\\.)*'?/, token: "string" },
26
26
27 // Handlebars keywords
27 // Handlebars keywords
28 { regex: />|[#\/]([A-Za-z_]\w*)/, token: "keyword" },
28 { regex: />|[#\/]([A-Za-z_]\w*)/, token: "keyword" },
29 { regex: /(?:else|this)\b/, token: "keyword" },
29 { regex: /(?:else|this)\b/, token: "keyword" },
30
30
31 // Numeral
31 // Numeral
32 { regex: /\d+/i, token: "number" },
32 { regex: /\d+/i, token: "number" },
33
33
34 // Atoms like = and .
34 // Atoms like = and .
35 { regex: /=|~|@|true|false/, token: "atom" },
35 { regex: /=|~|@|true|false/, token: "atom" },
36
36
37 // Paths
37 // Paths
38 { regex: /(?:\.\.\/)*(?:[A-Za-z_][\w\.]*)+/, token: "variable-2" }
38 { regex: /(?:\.\.\/)*(?:[A-Za-z_][\w\.]*)+/, token: "variable-2" }
39 ],
39 ],
40 dash_comment: [
40 dash_comment: [
41 { regex: /--\}\}/, pop: true, token: "comment" },
41 { regex: /--\}\}/, pop: true, token: "comment" },
42
42
43 // Commented code
43 // Commented code
44 { regex: /./, token: "comment"}
44 { regex: /./, token: "comment"}
45 ],
45 ],
46 comment: [
46 comment: [
47 { regex: /\}\}/, pop: true, token: "comment" },
47 { regex: /\}\}/, pop: true, token: "comment" },
48 { regex: /./, token: "comment" }
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 CodeMirror.defineMIME("text/x-handlebars-template", "handlebars");
61 CodeMirror.defineMIME("text/x-handlebars-template", "handlebars");
53 });
62 });
@@ -1,518 +1,515 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("haxe", function(config, parserConfig) {
14 CodeMirror.defineMode("haxe", function(config, parserConfig) {
15 var indentUnit = config.indentUnit;
15 var indentUnit = config.indentUnit;
16
16
17 // Tokenizer
17 // Tokenizer
18
18
19 var keywords = function(){
19 function kw(type) {return {type: type, style: "keyword"};}
20 function kw(type) {return {type: type, style: "keyword"};}
20 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
21 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
21 var operator = kw("operator"), atom = {type: "atom", style: "atom"}, attribute = {type:"attribute", style: "attribute"};
22 var operator = kw("operator"), atom = {type: "atom", style: "atom"}, attribute = {type:"attribute", style: "attribute"};
23 var type = kw("typedef");
22 var type = kw("typedef");
24 return {
23 var keywords = {
25 "if": A, "while": A, "else": B, "do": B, "try": B,
24 "if": A, "while": A, "else": B, "do": B, "try": B,
26 "return": C, "break": C, "continue": C, "new": C, "throw": C,
25 "return": C, "break": C, "continue": C, "new": C, "throw": C,
27 "var": kw("var"), "inline":attribute, "static": attribute, "using":kw("import"),
26 "var": kw("var"), "inline":attribute, "static": attribute, "using":kw("import"),
28 "public": attribute, "private": attribute, "cast": kw("cast"), "import": kw("import"), "macro": kw("macro"),
27 "public": attribute, "private": attribute, "cast": kw("cast"), "import": kw("import"), "macro": kw("macro"),
29 "function": kw("function"), "catch": kw("catch"), "untyped": kw("untyped"), "callback": kw("cb"),
28 "function": kw("function"), "catch": kw("catch"), "untyped": kw("untyped"), "callback": kw("cb"),
30 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
29 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
31 "in": operator, "never": kw("property_access"), "trace":kw("trace"),
30 "in": operator, "never": kw("property_access"), "trace":kw("trace"),
32 "class": type, "abstract":type, "enum":type, "interface":type, "typedef":type, "extends":type, "implements":type, "dynamic":type,
31 "class": type, "abstract":type, "enum":type, "interface":type, "typedef":type, "extends":type, "implements":type, "dynamic":type,
33 "true": atom, "false": atom, "null": atom
32 "true": atom, "false": atom, "null": atom
34 };
33 };
35 }();
36
34
37 var isOperatorChar = /[+\-*&%=<>!?|]/;
35 var isOperatorChar = /[+\-*&%=<>!?|]/;
38
36
39 function chain(stream, state, f) {
37 function chain(stream, state, f) {
40 state.tokenize = f;
38 state.tokenize = f;
41 return f(stream, state);
39 return f(stream, state);
42 }
40 }
43
41
44 function nextUntilUnescaped(stream, end) {
42 function toUnescaped(stream, end) {
45 var escaped = false, next;
43 var escaped = false, next;
46 while ((next = stream.next()) != null) {
44 while ((next = stream.next()) != null) {
47 if (next == end && !escaped)
45 if (next == end && !escaped)
48 return false;
46 return true;
49 escaped = !escaped && next == "\\";
47 escaped = !escaped && next == "\\";
50 }
48 }
51 return escaped;
52 }
49 }
53
50
54 // Used as scratch variables to communicate multiple values without
51 // Used as scratch variables to communicate multiple values without
55 // consing up tons of objects.
52 // consing up tons of objects.
56 var type, content;
53 var type, content;
57 function ret(tp, style, cont) {
54 function ret(tp, style, cont) {
58 type = tp; content = cont;
55 type = tp; content = cont;
59 return style;
56 return style;
60 }
57 }
61
58
62 function haxeTokenBase(stream, state) {
59 function haxeTokenBase(stream, state) {
63 var ch = stream.next();
60 var ch = stream.next();
64 if (ch == '"' || ch == "'")
61 if (ch == '"' || ch == "'") {
65 return chain(stream, state, haxeTokenString(ch));
62 return chain(stream, state, haxeTokenString(ch));
66 else if (/[\[\]{}\(\),;\:\.]/.test(ch))
63 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
67 return ret(ch);
64 return ret(ch);
68 else if (ch == "0" && stream.eat(/x/i)) {
65 } else if (ch == "0" && stream.eat(/x/i)) {
69 stream.eatWhile(/[\da-f]/i);
66 stream.eatWhile(/[\da-f]/i);
70 return ret("number", "number");
67 return ret("number", "number");
71 }
68 } else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
72 else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
69 stream.match(/^\d*(?:\.\d*(?!\.))?(?:[eE][+\-]?\d+)?/);
73 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
74 return ret("number", "number");
70 return ret("number", "number");
75 }
71 } else if (state.reAllowed && (ch == "~" && stream.eat(/\//))) {
76 else if (state.reAllowed && (ch == "~" && stream.eat(/\//))) {
72 toUnescaped(stream, "/");
77 nextUntilUnescaped(stream, "/");
78 stream.eatWhile(/[gimsu]/);
73 stream.eatWhile(/[gimsu]/);
79 return ret("regexp", "string-2");
74 return ret("regexp", "string-2");
80 }
75 } else if (ch == "/") {
81 else if (ch == "/") {
82 if (stream.eat("*")) {
76 if (stream.eat("*")) {
83 return chain(stream, state, haxeTokenComment);
77 return chain(stream, state, haxeTokenComment);
84 }
78 } else if (stream.eat("/")) {
85 else if (stream.eat("/")) {
86 stream.skipToEnd();
79 stream.skipToEnd();
87 return ret("comment", "comment");
80 return ret("comment", "comment");
88 }
81 } else {
89 else {
90 stream.eatWhile(isOperatorChar);
82 stream.eatWhile(isOperatorChar);
91 return ret("operator", null, stream.current());
83 return ret("operator", null, stream.current());
92 }
84 }
93 }
85 } else if (ch == "#") {
94 else if (ch == "#") {
95 stream.skipToEnd();
86 stream.skipToEnd();
96 return ret("conditional", "meta");
87 return ret("conditional", "meta");
97 }
88 } else if (ch == "@") {
98 else if (ch == "@") {
99 stream.eat(/:/);
89 stream.eat(/:/);
100 stream.eatWhile(/[\w_]/);
90 stream.eatWhile(/[\w_]/);
101 return ret ("metadata", "meta");
91 return ret ("metadata", "meta");
102 }
92 } else if (isOperatorChar.test(ch)) {
103 else if (isOperatorChar.test(ch)) {
104 stream.eatWhile(isOperatorChar);
93 stream.eatWhile(isOperatorChar);
105 return ret("operator", null, stream.current());
94 return ret("operator", null, stream.current());
106 }
95 } else {
107 else {
96 var word;
108 var word;
97 if(/[A-Z]/.test(ch)) {
109 if(/[A-Z]/.test(ch))
98 stream.eatWhile(/[\w_<>]/);
110 {
99 word = stream.current();
111 stream.eatWhile(/[\w_<>]/);
100 return ret("type", "variable-3", word);
112 word = stream.current();
101 } else {
113 return ret("type", "variable-3", word);
114 }
115 else
116 {
117 stream.eatWhile(/[\w_]/);
102 stream.eatWhile(/[\w_]/);
118 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
103 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
119 return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
104 return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
120 ret("variable", "variable", word);
105 ret("variable", "variable", word);
121 }
106 }
122 }
107 }
123 }
108 }
124
109
125 function haxeTokenString(quote) {
110 function haxeTokenString(quote) {
126 return function(stream, state) {
111 return function(stream, state) {
127 if (!nextUntilUnescaped(stream, quote))
112 if (toUnescaped(stream, quote))
128 state.tokenize = haxeTokenBase;
113 state.tokenize = haxeTokenBase;
129 return ret("string", "string");
114 return ret("string", "string");
130 };
115 };
131 }
116 }
132
117
133 function haxeTokenComment(stream, state) {
118 function haxeTokenComment(stream, state) {
134 var maybeEnd = false, ch;
119 var maybeEnd = false, ch;
135 while (ch = stream.next()) {
120 while (ch = stream.next()) {
136 if (ch == "/" && maybeEnd) {
121 if (ch == "/" && maybeEnd) {
137 state.tokenize = haxeTokenBase;
122 state.tokenize = haxeTokenBase;
138 break;
123 break;
139 }
124 }
140 maybeEnd = (ch == "*");
125 maybeEnd = (ch == "*");
141 }
126 }
142 return ret("comment", "comment");
127 return ret("comment", "comment");
143 }
128 }
144
129
145 // Parser
130 // Parser
146
131
147 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
132 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
148
133
149 function HaxeLexical(indented, column, type, align, prev, info) {
134 function HaxeLexical(indented, column, type, align, prev, info) {
150 this.indented = indented;
135 this.indented = indented;
151 this.column = column;
136 this.column = column;
152 this.type = type;
137 this.type = type;
153 this.prev = prev;
138 this.prev = prev;
154 this.info = info;
139 this.info = info;
155 if (align != null) this.align = align;
140 if (align != null) this.align = align;
156 }
141 }
157
142
158 function inScope(state, varname) {
143 function inScope(state, varname) {
159 for (var v = state.localVars; v; v = v.next)
144 for (var v = state.localVars; v; v = v.next)
160 if (v.name == varname) return true;
145 if (v.name == varname) return true;
161 }
146 }
162
147
163 function parseHaxe(state, style, type, content, stream) {
148 function parseHaxe(state, style, type, content, stream) {
164 var cc = state.cc;
149 var cc = state.cc;
165 // Communicate our context to the combinators.
150 // Communicate our context to the combinators.
166 // (Less wasteful than consing up a hundred closures on every call.)
151 // (Less wasteful than consing up a hundred closures on every call.)
167 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
152 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
168
153
169 if (!state.lexical.hasOwnProperty("align"))
154 if (!state.lexical.hasOwnProperty("align"))
170 state.lexical.align = true;
155 state.lexical.align = true;
171
156
172 while(true) {
157 while(true) {
173 var combinator = cc.length ? cc.pop() : statement;
158 var combinator = cc.length ? cc.pop() : statement;
174 if (combinator(type, content)) {
159 if (combinator(type, content)) {
175 while(cc.length && cc[cc.length - 1].lex)
160 while(cc.length && cc[cc.length - 1].lex)
176 cc.pop()();
161 cc.pop()();
177 if (cx.marked) return cx.marked;
162 if (cx.marked) return cx.marked;
178 if (type == "variable" && inScope(state, content)) return "variable-2";
163 if (type == "variable" && inScope(state, content)) return "variable-2";
179 if (type == "variable" && imported(state, content)) return "variable-3";
164 if (type == "variable" && imported(state, content)) return "variable-3";
180 return style;
165 return style;
181 }
166 }
182 }
167 }
183 }
168 }
184
169
185 function imported(state, typename)
170 function imported(state, typename) {
186 {
171 if (/[a-z]/.test(typename.charAt(0)))
187 if (/[a-z]/.test(typename.charAt(0)))
172 return false;
188 return false;
173 var len = state.importedtypes.length;
189 var len = state.importedtypes.length;
174 for (var i = 0; i<len; i++)
190 for (var i = 0; i<len; i++)
175 if(state.importedtypes[i]==typename) return true;
191 if(state.importedtypes[i]==typename) return true;
192 }
176 }
193
177
194
195 function registerimport(importname) {
178 function registerimport(importname) {
196 var state = cx.state;
179 var state = cx.state;
197 for (var t = state.importedtypes; t; t = t.next)
180 for (var t = state.importedtypes; t; t = t.next)
198 if(t.name == importname) return;
181 if(t.name == importname) return;
199 state.importedtypes = { name: importname, next: state.importedtypes };
182 state.importedtypes = { name: importname, next: state.importedtypes };
200 }
183 }
201 // Combinator utils
184 // Combinator utils
202
185
203 var cx = {state: null, column: null, marked: null, cc: null};
186 var cx = {state: null, column: null, marked: null, cc: null};
204 function pass() {
187 function pass() {
205 for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
188 for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
206 }
189 }
207 function cont() {
190 function cont() {
208 pass.apply(null, arguments);
191 pass.apply(null, arguments);
209 return true;
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 function register(varname) {
199 function register(varname) {
212 var state = cx.state;
200 var state = cx.state;
213 if (state.context) {
201 if (state.context) {
214 cx.marked = "def";
202 cx.marked = "def";
215 for (var v = state.localVars; v; v = v.next)
203 if (inList(varname, state.localVars)) return;
216 if (v.name == varname) return;
217 state.localVars = {name: varname, next: state.localVars};
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 // Combinators
211 // Combinators
222
212
223 var defaultVars = {name: "this", next: null};
213 var defaultVars = {name: "this", next: null};
224 function pushcontext() {
214 function pushcontext() {
225 if (!cx.state.context) cx.state.localVars = defaultVars;
215 if (!cx.state.context) cx.state.localVars = defaultVars;
226 cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
216 cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
227 }
217 }
228 function popcontext() {
218 function popcontext() {
229 cx.state.localVars = cx.state.context.vars;
219 cx.state.localVars = cx.state.context.vars;
230 cx.state.context = cx.state.context.prev;
220 cx.state.context = cx.state.context.prev;
231 }
221 }
222 popcontext.lex = true;
232 function pushlex(type, info) {
223 function pushlex(type, info) {
233 var result = function() {
224 var result = function() {
234 var state = cx.state;
225 var state = cx.state;
235 state.lexical = new HaxeLexical(state.indented, cx.stream.column(), type, null, state.lexical, info);
226 state.lexical = new HaxeLexical(state.indented, cx.stream.column(), type, null, state.lexical, info);
236 };
227 };
237 result.lex = true;
228 result.lex = true;
238 return result;
229 return result;
239 }
230 }
240 function poplex() {
231 function poplex() {
241 var state = cx.state;
232 var state = cx.state;
242 if (state.lexical.prev) {
233 if (state.lexical.prev) {
243 if (state.lexical.type == ")")
234 if (state.lexical.type == ")")
244 state.indented = state.lexical.indented;
235 state.indented = state.lexical.indented;
245 state.lexical = state.lexical.prev;
236 state.lexical = state.lexical.prev;
246 }
237 }
247 }
238 }
248 poplex.lex = true;
239 poplex.lex = true;
249
240
250 function expect(wanted) {
241 function expect(wanted) {
251 function f(type) {
242 function f(type) {
252 if (type == wanted) return cont();
243 if (type == wanted) return cont();
253 else if (wanted == ";") return pass();
244 else if (wanted == ";") return pass();
254 else return cont(f);
245 else return cont(f);
255 };
246 }
256 return f;
247 return f;
257 }
248 }
258
249
259 function statement(type) {
250 function statement(type) {
260 if (type == "@") return cont(metadef);
251 if (type == "@") return cont(metadef);
261 if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
252 if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
262 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
253 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
263 if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
254 if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
264 if (type == "{") return cont(pushlex("}"), pushcontext, block, poplex, popcontext);
255 if (type == "{") return cont(pushlex("}"), pushcontext, block, poplex, popcontext);
265 if (type == ";") return cont();
256 if (type == ";") return cont();
266 if (type == "attribute") return cont(maybeattribute);
257 if (type == "attribute") return cont(maybeattribute);
267 if (type == "function") return cont(functiondef);
258 if (type == "function") return cont(functiondef);
268 if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
259 if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
269 poplex, statement, poplex);
260 poplex, statement, poplex);
270 if (type == "variable") return cont(pushlex("stat"), maybelabel);
261 if (type == "variable") return cont(pushlex("stat"), maybelabel);
271 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
262 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
272 block, poplex, poplex);
263 block, poplex, poplex);
273 if (type == "case") return cont(expression, expect(":"));
264 if (type == "case") return cont(expression, expect(":"));
274 if (type == "default") return cont(expect(":"));
265 if (type == "default") return cont(expect(":"));
275 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
266 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
276 statement, poplex, popcontext);
267 statement, poplex, popcontext);
277 if (type == "import") return cont(importdef, expect(";"));
268 if (type == "import") return cont(importdef, expect(";"));
278 if (type == "typedef") return cont(typedef);
269 if (type == "typedef") return cont(typedef);
279 return pass(pushlex("stat"), expression, expect(";"), poplex);
270 return pass(pushlex("stat"), expression, expect(";"), poplex);
280 }
271 }
281 function expression(type) {
272 function expression(type) {
282 if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
273 if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
274 if (type == "type" ) return cont(maybeoperator);
283 if (type == "function") return cont(functiondef);
275 if (type == "function") return cont(functiondef);
284 if (type == "keyword c") return cont(maybeexpression);
276 if (type == "keyword c") return cont(maybeexpression);
285 if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
277 if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
286 if (type == "operator") return cont(expression);
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 if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
280 if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
289 return cont();
281 return cont();
290 }
282 }
291 function maybeexpression(type) {
283 function maybeexpression(type) {
292 if (type.match(/[;\}\)\],]/)) return pass();
284 if (type.match(/[;\}\)\],]/)) return pass();
293 return pass(expression);
285 return pass(expression);
294 }
286 }
295
287
296 function maybeoperator(type, value) {
288 function maybeoperator(type, value) {
297 if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
289 if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
298 if (type == "operator" || type == ":") return cont(expression);
290 if (type == "operator" || type == ":") return cont(expression);
299 if (type == ";") return;
291 if (type == ";") return;
300 if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
292 if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
301 if (type == ".") return cont(property, maybeoperator);
293 if (type == ".") return cont(property, maybeoperator);
302 if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
294 if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
303 }
295 }
304
296
305 function maybeattribute(type) {
297 function maybeattribute(type) {
306 if (type == "attribute") return cont(maybeattribute);
298 if (type == "attribute") return cont(maybeattribute);
307 if (type == "function") return cont(functiondef);
299 if (type == "function") return cont(functiondef);
308 if (type == "var") return cont(vardef1);
300 if (type == "var") return cont(vardef1);
309 }
301 }
310
302
311 function metadef(type) {
303 function metadef(type) {
312 if(type == ":") return cont(metadef);
304 if(type == ":") return cont(metadef);
313 if(type == "variable") return cont(metadef);
305 if(type == "variable") return cont(metadef);
314 if(type == "(") return cont(pushlex(")"), commasep(metaargs, ")"), poplex, statement);
306 if(type == "(") return cont(pushlex(")"), commasep(metaargs, ")"), poplex, statement);
315 }
307 }
316 function metaargs(type) {
308 function metaargs(type) {
317 if(type == "variable") return cont();
309 if(type == "variable") return cont();
318 }
310 }
319
311
320 function importdef (type, value) {
312 function importdef (type, value) {
321 if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }
313 if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }
322 else if(type == "variable" || type == "property" || type == "." || value == "*") return cont(importdef);
314 else if(type == "variable" || type == "property" || type == "." || value == "*") return cont(importdef);
323 }
315 }
324
316
325 function typedef (type, value)
317 function typedef (type, value)
326 {
318 {
327 if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }
319 if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }
328 else if (type == "type" && /[A-Z]/.test(value.charAt(0))) { return cont(); }
320 else if (type == "type" && /[A-Z]/.test(value.charAt(0))) { return cont(); }
329 }
321 }
330
322
331 function maybelabel(type) {
323 function maybelabel(type) {
332 if (type == ":") return cont(poplex, statement);
324 if (type == ":") return cont(poplex, statement);
333 return pass(maybeoperator, expect(";"), poplex);
325 return pass(maybeoperator, expect(";"), poplex);
334 }
326 }
335 function property(type) {
327 function property(type) {
336 if (type == "variable") {cx.marked = "property"; return cont();}
328 if (type == "variable") {cx.marked = "property"; return cont();}
337 }
329 }
338 function objprop(type) {
330 function objprop(type) {
339 if (type == "variable") cx.marked = "property";
331 if (type == "variable") cx.marked = "property";
340 if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
332 if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
341 }
333 }
342 function commasep(what, end) {
334 function commasep(what, end) {
343 function proceed(type) {
335 function proceed(type) {
344 if (type == ",") return cont(what, proceed);
336 if (type == ",") return cont(what, proceed);
345 if (type == end) return cont();
337 if (type == end) return cont();
346 return cont(expect(end));
338 return cont(expect(end));
347 }
339 }
348 return function(type) {
340 return function(type) {
349 if (type == end) return cont();
341 if (type == end) return cont();
350 else return pass(what, proceed);
342 else return pass(what, proceed);
351 };
343 };
352 }
344 }
353 function block(type) {
345 function block(type) {
354 if (type == "}") return cont();
346 if (type == "}") return cont();
355 return pass(statement, block);
347 return pass(statement, block);
356 }
348 }
357 function vardef1(type, value) {
349 function vardef1(type, value) {
358 if (type == "variable"){register(value); return cont(typeuse, vardef2);}
350 if (type == "variable"){register(value); return cont(typeuse, vardef2);}
359 return cont();
351 return cont();
360 }
352 }
361 function vardef2(type, value) {
353 function vardef2(type, value) {
362 if (value == "=") return cont(expression, vardef2);
354 if (value == "=") return cont(expression, vardef2);
363 if (type == ",") return cont(vardef1);
355 if (type == ",") return cont(vardef1);
364 }
356 }
365 function forspec1(type, value) {
357 function forspec1(type, value) {
366 if (type == "variable") {
358 if (type == "variable") {
367 register(value);
359 register(value);
368 }
360 return cont(forin, expression)
369 return cont(pushlex(")"), pushcontext, forin, expression, poplex, statement, popcontext);
361 } else {
362 return pass()
363 }
370 }
364 }
371 function forin(_type, value) {
365 function forin(_type, value) {
372 if (value == "in") return cont();
366 if (value == "in") return cont();
373 }
367 }
374 function functiondef(type, value) {
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 if (value == "new") return cont(functiondef);
371 if (value == "new") return cont(functiondef);
377 if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, typeuse, statement, popcontext);
372 if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, typeuse, statement, popcontext);
378 }
373 }
379 function typeuse(type) {
374 function typeuse(type) {
380 if(type == ":") return cont(typestring);
375 if(type == ":") return cont(typestring);
381 }
376 }
382 function typestring(type) {
377 function typestring(type) {
383 if(type == "type") return cont();
378 if(type == "type") return cont();
384 if(type == "variable") return cont();
379 if(type == "variable") return cont();
385 if(type == "{") return cont(pushlex("}"), commasep(typeprop, "}"), poplex);
380 if(type == "{") return cont(pushlex("}"), commasep(typeprop, "}"), poplex);
386 }
381 }
387 function typeprop(type) {
382 function typeprop(type) {
388 if(type == "variable") return cont(typeuse);
383 if(type == "variable") return cont(typeuse);
389 }
384 }
390 function funarg(type, value) {
385 function funarg(type, value) {
391 if (type == "variable") {register(value); return cont(typeuse);}
386 if (type == "variable") {register(value); return cont(typeuse);}
392 }
387 }
393
388
394 // Interface
389 // Interface
395
396 return {
390 return {
397 startState: function(basecolumn) {
391 startState: function(basecolumn) {
398 var defaulttypes = ["Int", "Float", "String", "Void", "Std", "Bool", "Dynamic", "Array"];
392 var defaulttypes = ["Int", "Float", "String", "Void", "Std", "Bool", "Dynamic", "Array"];
399 return {
393 var state = {
400 tokenize: haxeTokenBase,
394 tokenize: haxeTokenBase,
401 reAllowed: true,
395 reAllowed: true,
402 kwAllowed: true,
396 kwAllowed: true,
403 cc: [],
397 cc: [],
404 lexical: new HaxeLexical((basecolumn || 0) - indentUnit, 0, "block", false),
398 lexical: new HaxeLexical((basecolumn || 0) - indentUnit, 0, "block", false),
405 localVars: parserConfig.localVars,
399 localVars: parserConfig.localVars,
406 importedtypes: defaulttypes,
400 importedtypes: defaulttypes,
407 context: parserConfig.localVars && {vars: parserConfig.localVars},
401 context: parserConfig.localVars && {vars: parserConfig.localVars},
408 indented: 0
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 token: function(stream, state) {
409 token: function(stream, state) {
413 if (stream.sol()) {
410 if (stream.sol()) {
414 if (!state.lexical.hasOwnProperty("align"))
411 if (!state.lexical.hasOwnProperty("align"))
415 state.lexical.align = false;
412 state.lexical.align = false;
416 state.indented = stream.indentation();
413 state.indented = stream.indentation();
417 }
414 }
418 if (stream.eatSpace()) return null;
415 if (stream.eatSpace()) return null;
419 var style = state.tokenize(stream, state);
416 var style = state.tokenize(stream, state);
420 if (type == "comment") return style;
417 if (type == "comment") return style;
421 state.reAllowed = !!(type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/));
418 state.reAllowed = !!(type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/));
422 state.kwAllowed = type != '.';
419 state.kwAllowed = type != '.';
423 return parseHaxe(state, style, type, content, stream);
420 return parseHaxe(state, style, type, content, stream);
424 },
421 },
425
422
426 indent: function(state, textAfter) {
423 indent: function(state, textAfter) {
427 if (state.tokenize != haxeTokenBase) return 0;
424 if (state.tokenize != haxeTokenBase) return 0;
428 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
425 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
429 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
426 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
430 var type = lexical.type, closing = firstChar == type;
427 var type = lexical.type, closing = firstChar == type;
431 if (type == "vardef") return lexical.indented + 4;
428 if (type == "vardef") return lexical.indented + 4;
432 else if (type == "form" && firstChar == "{") return lexical.indented;
429 else if (type == "form" && firstChar == "{") return lexical.indented;
433 else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
430 else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
434 else if (lexical.info == "switch" && !closing)
431 else if (lexical.info == "switch" && !closing)
435 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
432 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
436 else if (lexical.align) return lexical.column + (closing ? 0 : 1);
433 else if (lexical.align) return lexical.column + (closing ? 0 : 1);
437 else return lexical.indented + (closing ? 0 : indentUnit);
434 else return lexical.indented + (closing ? 0 : indentUnit);
438 },
435 },
439
436
440 electricChars: "{}",
437 electricChars: "{}",
441 blockCommentStart: "/*",
438 blockCommentStart: "/*",
442 blockCommentEnd: "*/",
439 blockCommentEnd: "*/",
443 lineComment: "//"
440 lineComment: "//"
444 };
441 };
445 });
442 });
446
443
447 CodeMirror.defineMIME("text/x-haxe", "haxe");
444 CodeMirror.defineMIME("text/x-haxe", "haxe");
448
445
449 CodeMirror.defineMode("hxml", function () {
446 CodeMirror.defineMode("hxml", function () {
450
447
451 return {
448 return {
452 startState: function () {
449 startState: function () {
453 return {
450 return {
454 define: false,
451 define: false,
455 inString: false
452 inString: false
456 };
453 };
457 },
454 },
458 token: function (stream, state) {
455 token: function (stream, state) {
459 var ch = stream.peek();
456 var ch = stream.peek();
460 var sol = stream.sol();
457 var sol = stream.sol();
461
458
462 ///* comments */
459 ///* comments */
463 if (ch == "#") {
460 if (ch == "#") {
464 stream.skipToEnd();
461 stream.skipToEnd();
465 return "comment";
462 return "comment";
466 }
463 }
467 if (sol && ch == "-") {
464 if (sol && ch == "-") {
468 var style = "variable-2";
465 var style = "variable-2";
469
466
470 stream.eat(/-/);
467 stream.eat(/-/);
471
468
472 if (stream.peek() == "-") {
469 if (stream.peek() == "-") {
473 stream.eat(/-/);
470 stream.eat(/-/);
474 style = "keyword a";
471 style = "keyword a";
475 }
472 }
476
473
477 if (stream.peek() == "D") {
474 if (stream.peek() == "D") {
478 stream.eat(/[D]/);
475 stream.eat(/[D]/);
479 style = "keyword c";
476 style = "keyword c";
480 state.define = true;
477 state.define = true;
481 }
478 }
482
479
483 stream.eatWhile(/[A-Z]/i);
480 stream.eatWhile(/[A-Z]/i);
484 return style;
481 return style;
485 }
482 }
486
483
487 var ch = stream.peek();
484 var ch = stream.peek();
488
485
489 if (state.inString == false && ch == "'") {
486 if (state.inString == false && ch == "'") {
490 state.inString = true;
487 state.inString = true;
491 ch = stream.next();
488 ch = stream.next();
492 }
489 }
493
490
494 if (state.inString == true) {
491 if (state.inString == true) {
495 if (stream.skipTo("'")) {
492 if (stream.skipTo("'")) {
496
493
497 } else {
494 } else {
498 stream.skipToEnd();
495 stream.skipToEnd();
499 }
496 }
500
497
501 if (stream.peek() == "'") {
498 if (stream.peek() == "'") {
502 stream.next();
499 stream.next();
503 state.inString = false;
500 state.inString = false;
504 }
501 }
505
502
506 return "string";
503 return "string";
507 }
504 }
508
505
509 stream.next();
506 stream.next();
510 return null;
507 return null;
511 },
508 },
512 lineComment: "#"
509 lineComment: "#"
513 };
510 };
514 });
511 });
515
512
516 CodeMirror.defineMIME("text/x-hxml", "hxml");
513 CodeMirror.defineMIME("text/x-hxml", "hxml");
517
514
518 });
515 });
@@ -1,121 +1,150 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
6 mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
8 define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
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")});
30
13
31 function html(stream, state) {
14 var defaultTags = {
32 var tagName = state.htmlState.tagName;
15 script: [
33 if (tagName) tagName = tagName.toLowerCase();
16 ["lang", /(javascript|babel)/i, "javascript"],
34 var style = htmlMode.token(stream, state.htmlState);
17 ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, "javascript"],
35 if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
18 ["type", /./, "text/plain"],
36 // Script block: mode to change to depends on type attribute
19 [null, null, "javascript"]
37 var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
20 ],
38 scriptType = scriptType ? scriptType[1] : "";
21 style: [
39 if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
22 ["lang", /^css$/i, "css"],
40 for (var i = 0; i < scriptTypes.length; ++i) {
23 ["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"],
41 var tp = scriptTypes[i];
24 ["type", /./, "text/plain"],
42 if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
25 [null, null, "css"]
43 if (tp.mode) {
26 ]
44 state.token = script;
27 };
45 state.localMode = tp.mode;
28
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 function maybeBackup(stream, pat, style) {
29 function maybeBackup(stream, pat, style) {
59 var cur = stream.current();
30 var cur = stream.current(), close = cur.search(pat);
60 var close = cur.search(pat);
31 if (close > -1) {
61 if (close > -1) stream.backUp(cur.length - close);
32 stream.backUp(cur.length - close);
62 else if (cur.match(/<\/?$/)) {
33 } else if (cur.match(/<\/?$/)) {
63 stream.backUp(cur.length);
34 stream.backUp(cur.length);
64 if (!stream.match(pat, false)) stream.match(cur);
35 if (!stream.match(pat, false)) stream.match(cur);
65 }
36 }
66 return style;
37 return style;
67 }
38 }
68 function script(stream, state) {
39
69 if (stream.match(/^<\/\s*script\s*>/i, false)) {
40 var attrRegexpCache = {};
70 state.token = html;
41 function getAttrRegexp(attr) {
71 state.localState = state.localMode = null;
42 var regexp = attrRegexpCache[attr];
72 return null;
43 if (regexp) return regexp;
73 }
44 return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*");
74 return maybeBackup(stream, /<\/\s*script\s*>/,
45 }
75 state.localMode.token(stream, state.localState));
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 "";
76 }
54 }
77 function css(stream, state) {
55
78 if (stream.match(/^<\/\s*style\s*>/i, false)) {
56 function getTagRegexp(tagName, anchored) {
79 state.token = html;
57 return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i");
80 state.localState = state.localMode = null;
58 }
81 return null;
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])
82 }
66 }
83 return maybeBackup(stream, /<\/\s*style\s*>/,
67 }
84 cssMode.token(stream, state.localState));
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 }
85 }
74 }
86
75
87 return {
76 CodeMirror.defineMode("htmlmixed", function (config, parserConfig) {
88 startState: function() {
77 var htmlMode = CodeMirror.getMode(config, {
89 var state = htmlMode.startState();
78 name: "xml",
90 return {token: html, localMode: null, localState: null, htmlState: state};
79 htmlMode: true,
91 },
80 multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
81 multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag
82 });
92
83
93 copyState: function(state) {
84 var tags = {};
94 if (state.localState)
85 var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes;
95 var local = CodeMirror.copyState(state.localMode, state.localState);
86 addTags(defaultTags, tags);
96 return {token: state.token, localMode: state.localMode, localState: local,
87 if (configTags) addTags(configTags, tags);
97 htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
88 if (configScript) for (var i = configScript.length - 1; i >= 0; i--)
98 },
89 tags.script.unshift(["type", configScript[i].matches, configScript[i].mode])
99
90
100 token: function(stream, state) {
91 function html(stream, state) {
101 return state.token(stream, state);
92 var tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase();
102 },
93 var tagInfo = tagName && tags.hasOwnProperty(tagName) && tags[tagName];
94
95 var style = htmlMode.token(stream, state.htmlState), modeSpec;
103
96
104 indent: function(state, textAfter) {
97 if (tagInfo && /\btag\b/.test(style) && stream.current() === ">" &&
105 if (!state.localMode || /^\s*<\//.test(textAfter))
98 (modeSpec = findMatchingMode(tagInfo, stream))) {
106 return htmlMode.indent(state.htmlState, textAfter);
99 var mode = CodeMirror.getMode(config, modeSpec);
107 else if (state.localMode.indent)
100 var endTagA = getTagRegexp(tagName, true), endTag = getTagRegexp(tagName, false);
108 return state.localMode.indent(state.localState, textAfter);
101 state.token = function (stream, state) {
109 else
102 if (stream.match(endTagA, false)) {
110 return CodeMirror.Pass;
103 state.token = html;
111 },
104 state.localState = state.localMode = null;
105 return null;
106 }
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, ""));
111 }
112 return style;
113 };
114
115 return {
116 startState: function () {
117 var state = htmlMode.startState();
118 return {token: html, localMode: null, localState: null, htmlState: state};
119 },
112
120
113 innerMode: function(state) {
121 copyState: function (state) {
114 return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
122 var local;
115 }
123 if (state.localState) {
116 };
124 local = CodeMirror.copyState(state.localMode, state.localState);
117 }, "xml", "javascript", "css");
125 }
126 return {token: state.token, localMode: state.localMode, localState: local,
127 htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
128 },
129
130 token: function (stream, state) {
131 return state.token(stream, state);
132 },
118
133
119 CodeMirror.defineMIME("text/html", "htmlmixed");
134 indent: function (state, textAfter) {
135 if (!state.localMode || /^\s*<\//.test(textAfter))
136 return htmlMode.indent(state.htmlState, textAfter);
137 else if (state.localMode.indent)
138 return state.localMode.indent(state.localState, textAfter);
139 else
140 return CodeMirror.Pass;
141 },
120
142
143 innerMode: function (state) {
144 return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
145 }
146 };
147 }, "xml", "javascript", "css");
148
149 CodeMirror.defineMIME("text/html", "htmlmixed");
121 });
150 });
@@ -1,590 +1,590 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../javascript/javascript"), require("../css/css"), require("../htmlmixed/htmlmixed"));
6 mod(require("../../lib/codemirror"), require("../javascript/javascript"), require("../css/css"), require("../htmlmixed/htmlmixed"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../javascript/javascript", "../css/css", "../htmlmixed/htmlmixed"], mod);
8 define(["../../lib/codemirror", "../javascript/javascript", "../css/css", "../htmlmixed/htmlmixed"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode('jade', function (config) {
14 CodeMirror.defineMode('jade', function (config) {
15 // token types
15 // token types
16 var KEYWORD = 'keyword';
16 var KEYWORD = 'keyword';
17 var DOCTYPE = 'meta';
17 var DOCTYPE = 'meta';
18 var ID = 'builtin';
18 var ID = 'builtin';
19 var CLASS = 'qualifier';
19 var CLASS = 'qualifier';
20
20
21 var ATTRS_NEST = {
21 var ATTRS_NEST = {
22 '{': '}',
22 '{': '}',
23 '(': ')',
23 '(': ')',
24 '[': ']'
24 '[': ']'
25 };
25 };
26
26
27 var jsMode = CodeMirror.getMode(config, 'javascript');
27 var jsMode = CodeMirror.getMode(config, 'javascript');
28
28
29 function State() {
29 function State() {
30 this.javaScriptLine = false;
30 this.javaScriptLine = false;
31 this.javaScriptLineExcludesColon = false;
31 this.javaScriptLineExcludesColon = false;
32
32
33 this.javaScriptArguments = false;
33 this.javaScriptArguments = false;
34 this.javaScriptArgumentsDepth = 0;
34 this.javaScriptArgumentsDepth = 0;
35
35
36 this.isInterpolating = false;
36 this.isInterpolating = false;
37 this.interpolationNesting = 0;
37 this.interpolationNesting = 0;
38
38
39 this.jsState = jsMode.startState();
39 this.jsState = jsMode.startState();
40
40
41 this.restOfLine = '';
41 this.restOfLine = '';
42
42
43 this.isIncludeFiltered = false;
43 this.isIncludeFiltered = false;
44 this.isEach = false;
44 this.isEach = false;
45
45
46 this.lastTag = '';
46 this.lastTag = '';
47 this.scriptType = '';
47 this.scriptType = '';
48
48
49 // Attributes Mode
49 // Attributes Mode
50 this.isAttrs = false;
50 this.isAttrs = false;
51 this.attrsNest = [];
51 this.attrsNest = [];
52 this.inAttributeName = true;
52 this.inAttributeName = true;
53 this.attributeIsType = false;
53 this.attributeIsType = false;
54 this.attrValue = '';
54 this.attrValue = '';
55
55
56 // Indented Mode
56 // Indented Mode
57 this.indentOf = Infinity;
57 this.indentOf = Infinity;
58 this.indentToken = '';
58 this.indentToken = '';
59
59
60 this.innerMode = null;
60 this.innerMode = null;
61 this.innerState = null;
61 this.innerState = null;
62
62
63 this.innerModeForLine = false;
63 this.innerModeForLine = false;
64 }
64 }
65 /**
65 /**
66 * Safely copy a state
66 * Safely copy a state
67 *
67 *
68 * @return {State}
68 * @return {State}
69 */
69 */
70 State.prototype.copy = function () {
70 State.prototype.copy = function () {
71 var res = new State();
71 var res = new State();
72 res.javaScriptLine = this.javaScriptLine;
72 res.javaScriptLine = this.javaScriptLine;
73 res.javaScriptLineExcludesColon = this.javaScriptLineExcludesColon;
73 res.javaScriptLineExcludesColon = this.javaScriptLineExcludesColon;
74 res.javaScriptArguments = this.javaScriptArguments;
74 res.javaScriptArguments = this.javaScriptArguments;
75 res.javaScriptArgumentsDepth = this.javaScriptArgumentsDepth;
75 res.javaScriptArgumentsDepth = this.javaScriptArgumentsDepth;
76 res.isInterpolating = this.isInterpolating;
76 res.isInterpolating = this.isInterpolating;
77 res.interpolationNesting = this.intpolationNesting;
77 res.interpolationNesting = this.interpolationNesting;
78
78
79 res.jsState = CodeMirror.copyState(jsMode, this.jsState);
79 res.jsState = CodeMirror.copyState(jsMode, this.jsState);
80
80
81 res.innerMode = this.innerMode;
81 res.innerMode = this.innerMode;
82 if (this.innerMode && this.innerState) {
82 if (this.innerMode && this.innerState) {
83 res.innerState = CodeMirror.copyState(this.innerMode, this.innerState);
83 res.innerState = CodeMirror.copyState(this.innerMode, this.innerState);
84 }
84 }
85
85
86 res.restOfLine = this.restOfLine;
86 res.restOfLine = this.restOfLine;
87
87
88 res.isIncludeFiltered = this.isIncludeFiltered;
88 res.isIncludeFiltered = this.isIncludeFiltered;
89 res.isEach = this.isEach;
89 res.isEach = this.isEach;
90 res.lastTag = this.lastTag;
90 res.lastTag = this.lastTag;
91 res.scriptType = this.scriptType;
91 res.scriptType = this.scriptType;
92 res.isAttrs = this.isAttrs;
92 res.isAttrs = this.isAttrs;
93 res.attrsNest = this.attrsNest.slice();
93 res.attrsNest = this.attrsNest.slice();
94 res.inAttributeName = this.inAttributeName;
94 res.inAttributeName = this.inAttributeName;
95 res.attributeIsType = this.attributeIsType;
95 res.attributeIsType = this.attributeIsType;
96 res.attrValue = this.attrValue;
96 res.attrValue = this.attrValue;
97 res.indentOf = this.indentOf;
97 res.indentOf = this.indentOf;
98 res.indentToken = this.indentToken;
98 res.indentToken = this.indentToken;
99
99
100 res.innerModeForLine = this.innerModeForLine;
100 res.innerModeForLine = this.innerModeForLine;
101
101
102 return res;
102 return res;
103 };
103 };
104
104
105 function javaScript(stream, state) {
105 function javaScript(stream, state) {
106 if (stream.sol()) {
106 if (stream.sol()) {
107 // if javaScriptLine was set at end of line, ignore it
107 // if javaScriptLine was set at end of line, ignore it
108 state.javaScriptLine = false;
108 state.javaScriptLine = false;
109 state.javaScriptLineExcludesColon = false;
109 state.javaScriptLineExcludesColon = false;
110 }
110 }
111 if (state.javaScriptLine) {
111 if (state.javaScriptLine) {
112 if (state.javaScriptLineExcludesColon && stream.peek() === ':') {
112 if (state.javaScriptLineExcludesColon && stream.peek() === ':') {
113 state.javaScriptLine = false;
113 state.javaScriptLine = false;
114 state.javaScriptLineExcludesColon = false;
114 state.javaScriptLineExcludesColon = false;
115 return;
115 return;
116 }
116 }
117 var tok = jsMode.token(stream, state.jsState);
117 var tok = jsMode.token(stream, state.jsState);
118 if (stream.eol()) state.javaScriptLine = false;
118 if (stream.eol()) state.javaScriptLine = false;
119 return tok || true;
119 return tok || true;
120 }
120 }
121 }
121 }
122 function javaScriptArguments(stream, state) {
122 function javaScriptArguments(stream, state) {
123 if (state.javaScriptArguments) {
123 if (state.javaScriptArguments) {
124 if (state.javaScriptArgumentsDepth === 0 && stream.peek() !== '(') {
124 if (state.javaScriptArgumentsDepth === 0 && stream.peek() !== '(') {
125 state.javaScriptArguments = false;
125 state.javaScriptArguments = false;
126 return;
126 return;
127 }
127 }
128 if (stream.peek() === '(') {
128 if (stream.peek() === '(') {
129 state.javaScriptArgumentsDepth++;
129 state.javaScriptArgumentsDepth++;
130 } else if (stream.peek() === ')') {
130 } else if (stream.peek() === ')') {
131 state.javaScriptArgumentsDepth--;
131 state.javaScriptArgumentsDepth--;
132 }
132 }
133 if (state.javaScriptArgumentsDepth === 0) {
133 if (state.javaScriptArgumentsDepth === 0) {
134 state.javaScriptArguments = false;
134 state.javaScriptArguments = false;
135 return;
135 return;
136 }
136 }
137
137
138 var tok = jsMode.token(stream, state.jsState);
138 var tok = jsMode.token(stream, state.jsState);
139 return tok || true;
139 return tok || true;
140 }
140 }
141 }
141 }
142
142
143 function yieldStatement(stream) {
143 function yieldStatement(stream) {
144 if (stream.match(/^yield\b/)) {
144 if (stream.match(/^yield\b/)) {
145 return 'keyword';
145 return 'keyword';
146 }
146 }
147 }
147 }
148
148
149 function doctype(stream) {
149 function doctype(stream) {
150 if (stream.match(/^(?:doctype) *([^\n]+)?/)) {
150 if (stream.match(/^(?:doctype) *([^\n]+)?/)) {
151 return DOCTYPE;
151 return DOCTYPE;
152 }
152 }
153 }
153 }
154
154
155 function interpolation(stream, state) {
155 function interpolation(stream, state) {
156 if (stream.match('#{')) {
156 if (stream.match('#{')) {
157 state.isInterpolating = true;
157 state.isInterpolating = true;
158 state.interpolationNesting = 0;
158 state.interpolationNesting = 0;
159 return 'punctuation';
159 return 'punctuation';
160 }
160 }
161 }
161 }
162
162
163 function interpolationContinued(stream, state) {
163 function interpolationContinued(stream, state) {
164 if (state.isInterpolating) {
164 if (state.isInterpolating) {
165 if (stream.peek() === '}') {
165 if (stream.peek() === '}') {
166 state.interpolationNesting--;
166 state.interpolationNesting--;
167 if (state.interpolationNesting < 0) {
167 if (state.interpolationNesting < 0) {
168 stream.next();
168 stream.next();
169 state.isInterpolating = false;
169 state.isInterpolating = false;
170 return 'puncutation';
170 return 'punctuation';
171 }
171 }
172 } else if (stream.peek() === '{') {
172 } else if (stream.peek() === '{') {
173 state.interpolationNesting++;
173 state.interpolationNesting++;
174 }
174 }
175 return jsMode.token(stream, state.jsState) || true;
175 return jsMode.token(stream, state.jsState) || true;
176 }
176 }
177 }
177 }
178
178
179 function caseStatement(stream, state) {
179 function caseStatement(stream, state) {
180 if (stream.match(/^case\b/)) {
180 if (stream.match(/^case\b/)) {
181 state.javaScriptLine = true;
181 state.javaScriptLine = true;
182 return KEYWORD;
182 return KEYWORD;
183 }
183 }
184 }
184 }
185
185
186 function when(stream, state) {
186 function when(stream, state) {
187 if (stream.match(/^when\b/)) {
187 if (stream.match(/^when\b/)) {
188 state.javaScriptLine = true;
188 state.javaScriptLine = true;
189 state.javaScriptLineExcludesColon = true;
189 state.javaScriptLineExcludesColon = true;
190 return KEYWORD;
190 return KEYWORD;
191 }
191 }
192 }
192 }
193
193
194 function defaultStatement(stream) {
194 function defaultStatement(stream) {
195 if (stream.match(/^default\b/)) {
195 if (stream.match(/^default\b/)) {
196 return KEYWORD;
196 return KEYWORD;
197 }
197 }
198 }
198 }
199
199
200 function extendsStatement(stream, state) {
200 function extendsStatement(stream, state) {
201 if (stream.match(/^extends?\b/)) {
201 if (stream.match(/^extends?\b/)) {
202 state.restOfLine = 'string';
202 state.restOfLine = 'string';
203 return KEYWORD;
203 return KEYWORD;
204 }
204 }
205 }
205 }
206
206
207 function append(stream, state) {
207 function append(stream, state) {
208 if (stream.match(/^append\b/)) {
208 if (stream.match(/^append\b/)) {
209 state.restOfLine = 'variable';
209 state.restOfLine = 'variable';
210 return KEYWORD;
210 return KEYWORD;
211 }
211 }
212 }
212 }
213 function prepend(stream, state) {
213 function prepend(stream, state) {
214 if (stream.match(/^prepend\b/)) {
214 if (stream.match(/^prepend\b/)) {
215 state.restOfLine = 'variable';
215 state.restOfLine = 'variable';
216 return KEYWORD;
216 return KEYWORD;
217 }
217 }
218 }
218 }
219 function block(stream, state) {
219 function block(stream, state) {
220 if (stream.match(/^block\b *(?:(prepend|append)\b)?/)) {
220 if (stream.match(/^block\b *(?:(prepend|append)\b)?/)) {
221 state.restOfLine = 'variable';
221 state.restOfLine = 'variable';
222 return KEYWORD;
222 return KEYWORD;
223 }
223 }
224 }
224 }
225
225
226 function include(stream, state) {
226 function include(stream, state) {
227 if (stream.match(/^include\b/)) {
227 if (stream.match(/^include\b/)) {
228 state.restOfLine = 'string';
228 state.restOfLine = 'string';
229 return KEYWORD;
229 return KEYWORD;
230 }
230 }
231 }
231 }
232
232
233 function includeFiltered(stream, state) {
233 function includeFiltered(stream, state) {
234 if (stream.match(/^include:([a-zA-Z0-9\-]+)/, false) && stream.match('include')) {
234 if (stream.match(/^include:([a-zA-Z0-9\-]+)/, false) && stream.match('include')) {
235 state.isIncludeFiltered = true;
235 state.isIncludeFiltered = true;
236 return KEYWORD;
236 return KEYWORD;
237 }
237 }
238 }
238 }
239
239
240 function includeFilteredContinued(stream, state) {
240 function includeFilteredContinued(stream, state) {
241 if (state.isIncludeFiltered) {
241 if (state.isIncludeFiltered) {
242 var tok = filter(stream, state);
242 var tok = filter(stream, state);
243 state.isIncludeFiltered = false;
243 state.isIncludeFiltered = false;
244 state.restOfLine = 'string';
244 state.restOfLine = 'string';
245 return tok;
245 return tok;
246 }
246 }
247 }
247 }
248
248
249 function mixin(stream, state) {
249 function mixin(stream, state) {
250 if (stream.match(/^mixin\b/)) {
250 if (stream.match(/^mixin\b/)) {
251 state.javaScriptLine = true;
251 state.javaScriptLine = true;
252 return KEYWORD;
252 return KEYWORD;
253 }
253 }
254 }
254 }
255
255
256 function call(stream, state) {
256 function call(stream, state) {
257 if (stream.match(/^\+([-\w]+)/)) {
257 if (stream.match(/^\+([-\w]+)/)) {
258 if (!stream.match(/^\( *[-\w]+ *=/, false)) {
258 if (!stream.match(/^\( *[-\w]+ *=/, false)) {
259 state.javaScriptArguments = true;
259 state.javaScriptArguments = true;
260 state.javaScriptArgumentsDepth = 0;
260 state.javaScriptArgumentsDepth = 0;
261 }
261 }
262 return 'variable';
262 return 'variable';
263 }
263 }
264 if (stream.match(/^\+#{/, false)) {
264 if (stream.match(/^\+#{/, false)) {
265 stream.next();
265 stream.next();
266 state.mixinCallAfter = true;
266 state.mixinCallAfter = true;
267 return interpolation(stream, state);
267 return interpolation(stream, state);
268 }
268 }
269 }
269 }
270 function callArguments(stream, state) {
270 function callArguments(stream, state) {
271 if (state.mixinCallAfter) {
271 if (state.mixinCallAfter) {
272 state.mixinCallAfter = false;
272 state.mixinCallAfter = false;
273 if (!stream.match(/^\( *[-\w]+ *=/, false)) {
273 if (!stream.match(/^\( *[-\w]+ *=/, false)) {
274 state.javaScriptArguments = true;
274 state.javaScriptArguments = true;
275 state.javaScriptArgumentsDepth = 0;
275 state.javaScriptArgumentsDepth = 0;
276 }
276 }
277 return true;
277 return true;
278 }
278 }
279 }
279 }
280
280
281 function conditional(stream, state) {
281 function conditional(stream, state) {
282 if (stream.match(/^(if|unless|else if|else)\b/)) {
282 if (stream.match(/^(if|unless|else if|else)\b/)) {
283 state.javaScriptLine = true;
283 state.javaScriptLine = true;
284 return KEYWORD;
284 return KEYWORD;
285 }
285 }
286 }
286 }
287
287
288 function each(stream, state) {
288 function each(stream, state) {
289 if (stream.match(/^(- *)?(each|for)\b/)) {
289 if (stream.match(/^(- *)?(each|for)\b/)) {
290 state.isEach = true;
290 state.isEach = true;
291 return KEYWORD;
291 return KEYWORD;
292 }
292 }
293 }
293 }
294 function eachContinued(stream, state) {
294 function eachContinued(stream, state) {
295 if (state.isEach) {
295 if (state.isEach) {
296 if (stream.match(/^ in\b/)) {
296 if (stream.match(/^ in\b/)) {
297 state.javaScriptLine = true;
297 state.javaScriptLine = true;
298 state.isEach = false;
298 state.isEach = false;
299 return KEYWORD;
299 return KEYWORD;
300 } else if (stream.sol() || stream.eol()) {
300 } else if (stream.sol() || stream.eol()) {
301 state.isEach = false;
301 state.isEach = false;
302 } else if (stream.next()) {
302 } else if (stream.next()) {
303 while (!stream.match(/^ in\b/, false) && stream.next());
303 while (!stream.match(/^ in\b/, false) && stream.next());
304 return 'variable';
304 return 'variable';
305 }
305 }
306 }
306 }
307 }
307 }
308
308
309 function whileStatement(stream, state) {
309 function whileStatement(stream, state) {
310 if (stream.match(/^while\b/)) {
310 if (stream.match(/^while\b/)) {
311 state.javaScriptLine = true;
311 state.javaScriptLine = true;
312 return KEYWORD;
312 return KEYWORD;
313 }
313 }
314 }
314 }
315
315
316 function tag(stream, state) {
316 function tag(stream, state) {
317 var captures;
317 var captures;
318 if (captures = stream.match(/^(\w(?:[-:\w]*\w)?)\/?/)) {
318 if (captures = stream.match(/^(\w(?:[-:\w]*\w)?)\/?/)) {
319 state.lastTag = captures[1].toLowerCase();
319 state.lastTag = captures[1].toLowerCase();
320 if (state.lastTag === 'script') {
320 if (state.lastTag === 'script') {
321 state.scriptType = 'application/javascript';
321 state.scriptType = 'application/javascript';
322 }
322 }
323 return 'tag';
323 return 'tag';
324 }
324 }
325 }
325 }
326
326
327 function filter(stream, state) {
327 function filter(stream, state) {
328 if (stream.match(/^:([\w\-]+)/)) {
328 if (stream.match(/^:([\w\-]+)/)) {
329 var innerMode;
329 var innerMode;
330 if (config && config.innerModes) {
330 if (config && config.innerModes) {
331 innerMode = config.innerModes(stream.current().substring(1));
331 innerMode = config.innerModes(stream.current().substring(1));
332 }
332 }
333 if (!innerMode) {
333 if (!innerMode) {
334 innerMode = stream.current().substring(1);
334 innerMode = stream.current().substring(1);
335 }
335 }
336 if (typeof innerMode === 'string') {
336 if (typeof innerMode === 'string') {
337 innerMode = CodeMirror.getMode(config, innerMode);
337 innerMode = CodeMirror.getMode(config, innerMode);
338 }
338 }
339 setInnerMode(stream, state, innerMode);
339 setInnerMode(stream, state, innerMode);
340 return 'atom';
340 return 'atom';
341 }
341 }
342 }
342 }
343
343
344 function code(stream, state) {
344 function code(stream, state) {
345 if (stream.match(/^(!?=|-)/)) {
345 if (stream.match(/^(!?=|-)/)) {
346 state.javaScriptLine = true;
346 state.javaScriptLine = true;
347 return 'punctuation';
347 return 'punctuation';
348 }
348 }
349 }
349 }
350
350
351 function id(stream) {
351 function id(stream) {
352 if (stream.match(/^#([\w-]+)/)) {
352 if (stream.match(/^#([\w-]+)/)) {
353 return ID;
353 return ID;
354 }
354 }
355 }
355 }
356
356
357 function className(stream) {
357 function className(stream) {
358 if (stream.match(/^\.([\w-]+)/)) {
358 if (stream.match(/^\.([\w-]+)/)) {
359 return CLASS;
359 return CLASS;
360 }
360 }
361 }
361 }
362
362
363 function attrs(stream, state) {
363 function attrs(stream, state) {
364 if (stream.peek() == '(') {
364 if (stream.peek() == '(') {
365 stream.next();
365 stream.next();
366 state.isAttrs = true;
366 state.isAttrs = true;
367 state.attrsNest = [];
367 state.attrsNest = [];
368 state.inAttributeName = true;
368 state.inAttributeName = true;
369 state.attrValue = '';
369 state.attrValue = '';
370 state.attributeIsType = false;
370 state.attributeIsType = false;
371 return 'punctuation';
371 return 'punctuation';
372 }
372 }
373 }
373 }
374
374
375 function attrsContinued(stream, state) {
375 function attrsContinued(stream, state) {
376 if (state.isAttrs) {
376 if (state.isAttrs) {
377 if (ATTRS_NEST[stream.peek()]) {
377 if (ATTRS_NEST[stream.peek()]) {
378 state.attrsNest.push(ATTRS_NEST[stream.peek()]);
378 state.attrsNest.push(ATTRS_NEST[stream.peek()]);
379 }
379 }
380 if (state.attrsNest[state.attrsNest.length - 1] === stream.peek()) {
380 if (state.attrsNest[state.attrsNest.length - 1] === stream.peek()) {
381 state.attrsNest.pop();
381 state.attrsNest.pop();
382 } else if (stream.eat(')')) {
382 } else if (stream.eat(')')) {
383 state.isAttrs = false;
383 state.isAttrs = false;
384 return 'punctuation';
384 return 'punctuation';
385 }
385 }
386 if (state.inAttributeName && stream.match(/^[^=,\)!]+/)) {
386 if (state.inAttributeName && stream.match(/^[^=,\)!]+/)) {
387 if (stream.peek() === '=' || stream.peek() === '!') {
387 if (stream.peek() === '=' || stream.peek() === '!') {
388 state.inAttributeName = false;
388 state.inAttributeName = false;
389 state.jsState = jsMode.startState();
389 state.jsState = jsMode.startState();
390 if (state.lastTag === 'script' && stream.current().trim().toLowerCase() === 'type') {
390 if (state.lastTag === 'script' && stream.current().trim().toLowerCase() === 'type') {
391 state.attributeIsType = true;
391 state.attributeIsType = true;
392 } else {
392 } else {
393 state.attributeIsType = false;
393 state.attributeIsType = false;
394 }
394 }
395 }
395 }
396 return 'attribute';
396 return 'attribute';
397 }
397 }
398
398
399 var tok = jsMode.token(stream, state.jsState);
399 var tok = jsMode.token(stream, state.jsState);
400 if (state.attributeIsType && tok === 'string') {
400 if (state.attributeIsType && tok === 'string') {
401 state.scriptType = stream.current().toString();
401 state.scriptType = stream.current().toString();
402 }
402 }
403 if (state.attrsNest.length === 0 && (tok === 'string' || tok === 'variable' || tok === 'keyword')) {
403 if (state.attrsNest.length === 0 && (tok === 'string' || tok === 'variable' || tok === 'keyword')) {
404 try {
404 try {
405 Function('', 'var x ' + state.attrValue.replace(/,\s*$/, '').replace(/^!/, ''));
405 Function('', 'var x ' + state.attrValue.replace(/,\s*$/, '').replace(/^!/, ''));
406 state.inAttributeName = true;
406 state.inAttributeName = true;
407 state.attrValue = '';
407 state.attrValue = '';
408 stream.backUp(stream.current().length);
408 stream.backUp(stream.current().length);
409 return attrsContinued(stream, state);
409 return attrsContinued(stream, state);
410 } catch (ex) {
410 } catch (ex) {
411 //not the end of an attribute
411 //not the end of an attribute
412 }
412 }
413 }
413 }
414 state.attrValue += stream.current();
414 state.attrValue += stream.current();
415 return tok || true;
415 return tok || true;
416 }
416 }
417 }
417 }
418
418
419 function attributesBlock(stream, state) {
419 function attributesBlock(stream, state) {
420 if (stream.match(/^&attributes\b/)) {
420 if (stream.match(/^&attributes\b/)) {
421 state.javaScriptArguments = true;
421 state.javaScriptArguments = true;
422 state.javaScriptArgumentsDepth = 0;
422 state.javaScriptArgumentsDepth = 0;
423 return 'keyword';
423 return 'keyword';
424 }
424 }
425 }
425 }
426
426
427 function indent(stream) {
427 function indent(stream) {
428 if (stream.sol() && stream.eatSpace()) {
428 if (stream.sol() && stream.eatSpace()) {
429 return 'indent';
429 return 'indent';
430 }
430 }
431 }
431 }
432
432
433 function comment(stream, state) {
433 function comment(stream, state) {
434 if (stream.match(/^ *\/\/(-)?([^\n]*)/)) {
434 if (stream.match(/^ *\/\/(-)?([^\n]*)/)) {
435 state.indentOf = stream.indentation();
435 state.indentOf = stream.indentation();
436 state.indentToken = 'comment';
436 state.indentToken = 'comment';
437 return 'comment';
437 return 'comment';
438 }
438 }
439 }
439 }
440
440
441 function colon(stream) {
441 function colon(stream) {
442 if (stream.match(/^: */)) {
442 if (stream.match(/^: */)) {
443 return 'colon';
443 return 'colon';
444 }
444 }
445 }
445 }
446
446
447 function text(stream, state) {
447 function text(stream, state) {
448 if (stream.match(/^(?:\| ?| )([^\n]+)/)) {
448 if (stream.match(/^(?:\| ?| )([^\n]+)/)) {
449 return 'string';
449 return 'string';
450 }
450 }
451 if (stream.match(/^(<[^\n]*)/, false)) {
451 if (stream.match(/^(<[^\n]*)/, false)) {
452 // html string
452 // html string
453 setInnerMode(stream, state, 'htmlmixed');
453 setInnerMode(stream, state, 'htmlmixed');
454 state.innerModeForLine = true;
454 state.innerModeForLine = true;
455 return innerMode(stream, state, true);
455 return innerMode(stream, state, true);
456 }
456 }
457 }
457 }
458
458
459 function dot(stream, state) {
459 function dot(stream, state) {
460 if (stream.eat('.')) {
460 if (stream.eat('.')) {
461 var innerMode = null;
461 var innerMode = null;
462 if (state.lastTag === 'script' && state.scriptType.toLowerCase().indexOf('javascript') != -1) {
462 if (state.lastTag === 'script' && state.scriptType.toLowerCase().indexOf('javascript') != -1) {
463 innerMode = state.scriptType.toLowerCase().replace(/"|'/g, '');
463 innerMode = state.scriptType.toLowerCase().replace(/"|'/g, '');
464 } else if (state.lastTag === 'style') {
464 } else if (state.lastTag === 'style') {
465 innerMode = 'css';
465 innerMode = 'css';
466 }
466 }
467 setInnerMode(stream, state, innerMode);
467 setInnerMode(stream, state, innerMode);
468 return 'dot';
468 return 'dot';
469 }
469 }
470 }
470 }
471
471
472 function fail(stream) {
472 function fail(stream) {
473 stream.next();
473 stream.next();
474 return null;
474 return null;
475 }
475 }
476
476
477
477
478 function setInnerMode(stream, state, mode) {
478 function setInnerMode(stream, state, mode) {
479 mode = CodeMirror.mimeModes[mode] || mode;
479 mode = CodeMirror.mimeModes[mode] || mode;
480 mode = config.innerModes ? config.innerModes(mode) || mode : mode;
480 mode = config.innerModes ? config.innerModes(mode) || mode : mode;
481 mode = CodeMirror.mimeModes[mode] || mode;
481 mode = CodeMirror.mimeModes[mode] || mode;
482 mode = CodeMirror.getMode(config, mode);
482 mode = CodeMirror.getMode(config, mode);
483 state.indentOf = stream.indentation();
483 state.indentOf = stream.indentation();
484
484
485 if (mode && mode.name !== 'null') {
485 if (mode && mode.name !== 'null') {
486 state.innerMode = mode;
486 state.innerMode = mode;
487 } else {
487 } else {
488 state.indentToken = 'string';
488 state.indentToken = 'string';
489 }
489 }
490 }
490 }
491 function innerMode(stream, state, force) {
491 function innerMode(stream, state, force) {
492 if (stream.indentation() > state.indentOf || (state.innerModeForLine && !stream.sol()) || force) {
492 if (stream.indentation() > state.indentOf || (state.innerModeForLine && !stream.sol()) || force) {
493 if (state.innerMode) {
493 if (state.innerMode) {
494 if (!state.innerState) {
494 if (!state.innerState) {
495 state.innerState = state.innerMode.startState ? state.innerMode.startState(stream.indentation()) : {};
495 state.innerState = state.innerMode.startState ? state.innerMode.startState(stream.indentation()) : {};
496 }
496 }
497 return stream.hideFirstChars(state.indentOf + 2, function () {
497 return stream.hideFirstChars(state.indentOf + 2, function () {
498 return state.innerMode.token(stream, state.innerState) || true;
498 return state.innerMode.token(stream, state.innerState) || true;
499 });
499 });
500 } else {
500 } else {
501 stream.skipToEnd();
501 stream.skipToEnd();
502 return state.indentToken;
502 return state.indentToken;
503 }
503 }
504 } else if (stream.sol()) {
504 } else if (stream.sol()) {
505 state.indentOf = Infinity;
505 state.indentOf = Infinity;
506 state.indentToken = null;
506 state.indentToken = null;
507 state.innerMode = null;
507 state.innerMode = null;
508 state.innerState = null;
508 state.innerState = null;
509 }
509 }
510 }
510 }
511 function restOfLine(stream, state) {
511 function restOfLine(stream, state) {
512 if (stream.sol()) {
512 if (stream.sol()) {
513 // if restOfLine was set at end of line, ignore it
513 // if restOfLine was set at end of line, ignore it
514 state.restOfLine = '';
514 state.restOfLine = '';
515 }
515 }
516 if (state.restOfLine) {
516 if (state.restOfLine) {
517 stream.skipToEnd();
517 stream.skipToEnd();
518 var tok = state.restOfLine;
518 var tok = state.restOfLine;
519 state.restOfLine = '';
519 state.restOfLine = '';
520 return tok;
520 return tok;
521 }
521 }
522 }
522 }
523
523
524
524
525 function startState() {
525 function startState() {
526 return new State();
526 return new State();
527 }
527 }
528 function copyState(state) {
528 function copyState(state) {
529 return state.copy();
529 return state.copy();
530 }
530 }
531 /**
531 /**
532 * Get the next token in the stream
532 * Get the next token in the stream
533 *
533 *
534 * @param {Stream} stream
534 * @param {Stream} stream
535 * @param {State} state
535 * @param {State} state
536 */
536 */
537 function nextToken(stream, state) {
537 function nextToken(stream, state) {
538 var tok = innerMode(stream, state)
538 var tok = innerMode(stream, state)
539 || restOfLine(stream, state)
539 || restOfLine(stream, state)
540 || interpolationContinued(stream, state)
540 || interpolationContinued(stream, state)
541 || includeFilteredContinued(stream, state)
541 || includeFilteredContinued(stream, state)
542 || eachContinued(stream, state)
542 || eachContinued(stream, state)
543 || attrsContinued(stream, state)
543 || attrsContinued(stream, state)
544 || javaScript(stream, state)
544 || javaScript(stream, state)
545 || javaScriptArguments(stream, state)
545 || javaScriptArguments(stream, state)
546 || callArguments(stream, state)
546 || callArguments(stream, state)
547
547
548 || yieldStatement(stream, state)
548 || yieldStatement(stream, state)
549 || doctype(stream, state)
549 || doctype(stream, state)
550 || interpolation(stream, state)
550 || interpolation(stream, state)
551 || caseStatement(stream, state)
551 || caseStatement(stream, state)
552 || when(stream, state)
552 || when(stream, state)
553 || defaultStatement(stream, state)
553 || defaultStatement(stream, state)
554 || extendsStatement(stream, state)
554 || extendsStatement(stream, state)
555 || append(stream, state)
555 || append(stream, state)
556 || prepend(stream, state)
556 || prepend(stream, state)
557 || block(stream, state)
557 || block(stream, state)
558 || include(stream, state)
558 || include(stream, state)
559 || includeFiltered(stream, state)
559 || includeFiltered(stream, state)
560 || mixin(stream, state)
560 || mixin(stream, state)
561 || call(stream, state)
561 || call(stream, state)
562 || conditional(stream, state)
562 || conditional(stream, state)
563 || each(stream, state)
563 || each(stream, state)
564 || whileStatement(stream, state)
564 || whileStatement(stream, state)
565 || tag(stream, state)
565 || tag(stream, state)
566 || filter(stream, state)
566 || filter(stream, state)
567 || code(stream, state)
567 || code(stream, state)
568 || id(stream, state)
568 || id(stream, state)
569 || className(stream, state)
569 || className(stream, state)
570 || attrs(stream, state)
570 || attrs(stream, state)
571 || attributesBlock(stream, state)
571 || attributesBlock(stream, state)
572 || indent(stream, state)
572 || indent(stream, state)
573 || text(stream, state)
573 || text(stream, state)
574 || comment(stream, state)
574 || comment(stream, state)
575 || colon(stream, state)
575 || colon(stream, state)
576 || dot(stream, state)
576 || dot(stream, state)
577 || fail(stream, state);
577 || fail(stream, state);
578
578
579 return tok === true ? null : tok;
579 return tok === true ? null : tok;
580 }
580 }
581 return {
581 return {
582 startState: startState,
582 startState: startState,
583 copyState: copyState,
583 copyState: copyState,
584 token: nextToken
584 token: nextToken
585 };
585 };
586 });
586 }, 'javascript', 'css', 'htmlmixed');
587
587
588 CodeMirror.defineMIME('text/x-jade', 'jade');
588 CodeMirror.defineMIME('text/x-jade', 'jade');
589
589
590 });
590 });
@@ -1,704 +1,742 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 // TODO actually recognize syntax of TypeScript constructs
4 // TODO actually recognize syntax of TypeScript constructs
5
5
6 (function(mod) {
6 (function(mod) {
7 if (typeof exports == "object" && typeof module == "object") // CommonJS
7 if (typeof exports == "object" && typeof module == "object") // CommonJS
8 mod(require("../../lib/codemirror"));
8 mod(require("../../lib/codemirror"));
9 else if (typeof define == "function" && define.amd) // AMD
9 else if (typeof define == "function" && define.amd) // AMD
10 define(["../../lib/codemirror"], mod);
10 define(["../../lib/codemirror"], mod);
11 else // Plain browser env
11 else // Plain browser env
12 mod(CodeMirror);
12 mod(CodeMirror);
13 })(function(CodeMirror) {
13 })(function(CodeMirror) {
14 "use strict";
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 CodeMirror.defineMode("javascript", function(config, parserConfig) {
21 CodeMirror.defineMode("javascript", function(config, parserConfig) {
17 var indentUnit = config.indentUnit;
22 var indentUnit = config.indentUnit;
18 var statementIndent = parserConfig.statementIndent;
23 var statementIndent = parserConfig.statementIndent;
19 var jsonldMode = parserConfig.jsonld;
24 var jsonldMode = parserConfig.jsonld;
20 var jsonMode = parserConfig.json || jsonldMode;
25 var jsonMode = parserConfig.json || jsonldMode;
21 var isTS = parserConfig.typescript;
26 var isTS = parserConfig.typescript;
22 var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
27 var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
23
28
24 // Tokenizer
29 // Tokenizer
25
30
26 var keywords = function(){
31 var keywords = function(){
27 function kw(type) {return {type: type, style: "keyword"};}
32 function kw(type) {return {type: type, style: "keyword"};}
28 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
33 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
29 var operator = kw("operator"), atom = {type: "atom", style: "atom"};
34 var operator = kw("operator"), atom = {type: "atom", style: "atom"};
30
35
31 var jsKeywords = {
36 var jsKeywords = {
32 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
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 "var": kw("var"), "const": kw("var"), "let": kw("var"),
39 "var": kw("var"), "const": kw("var"), "let": kw("var"),
35 "function": kw("function"), "catch": kw("catch"),
40 "function": kw("function"), "catch": kw("catch"),
36 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
41 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
37 "in": operator, "typeof": operator, "instanceof": operator,
42 "in": operator, "typeof": operator, "instanceof": operator,
38 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
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 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
45 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
41 };
46 };
42
47
43 // Extend the 'normal' keywords with the TypeScript language extensions
48 // Extend the 'normal' keywords with the TypeScript language extensions
44 if (isTS) {
49 if (isTS) {
45 var type = {type: "variable", style: "variable-3"};
50 var type = {type: "variable", style: "variable-3"};
46 var tsKeywords = {
51 var tsKeywords = {
47 // object-like things
52 // object-like things
48 "interface": kw("interface"),
53 "interface": kw("class"),
49 "extends": kw("extends"),
54 "implements": C,
50 "constructor": kw("constructor"),
55 "namespace": C,
56 "module": kw("module"),
57 "enum": kw("module"),
51
58
52 // scope modifiers
59 // scope modifiers
53 "public": kw("public"),
60 "public": kw("modifier"),
54 "private": kw("private"),
61 "private": kw("modifier"),
55 "protected": kw("protected"),
62 "protected": kw("modifier"),
56 "static": kw("static"),
63 "abstract": kw("modifier"),
64
65 // operators
66 "as": operator,
57
67
58 // types
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 for (var attr in tsKeywords) {
72 for (var attr in tsKeywords) {
63 jsKeywords[attr] = tsKeywords[attr];
73 jsKeywords[attr] = tsKeywords[attr];
64 }
74 }
65 }
75 }
66
76
67 return jsKeywords;
77 return jsKeywords;
68 }();
78 }();
69
79
70 var isOperatorChar = /[+\-*&%=<>!?|~^]/;
80 var isOperatorChar = /[+\-*&%=<>!?|~^]/;
71 var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
81 var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
72
82
73 function readRegexp(stream) {
83 function readRegexp(stream) {
74 var escaped = false, next, inSet = false;
84 var escaped = false, next, inSet = false;
75 while ((next = stream.next()) != null) {
85 while ((next = stream.next()) != null) {
76 if (!escaped) {
86 if (!escaped) {
77 if (next == "/" && !inSet) return;
87 if (next == "/" && !inSet) return;
78 if (next == "[") inSet = true;
88 if (next == "[") inSet = true;
79 else if (inSet && next == "]") inSet = false;
89 else if (inSet && next == "]") inSet = false;
80 }
90 }
81 escaped = !escaped && next == "\\";
91 escaped = !escaped && next == "\\";
82 }
92 }
83 }
93 }
84
94
85 // Used as scratch variables to communicate multiple values without
95 // Used as scratch variables to communicate multiple values without
86 // consing up tons of objects.
96 // consing up tons of objects.
87 var type, content;
97 var type, content;
88 function ret(tp, style, cont) {
98 function ret(tp, style, cont) {
89 type = tp; content = cont;
99 type = tp; content = cont;
90 return style;
100 return style;
91 }
101 }
92 function tokenBase(stream, state) {
102 function tokenBase(stream, state) {
93 var ch = stream.next();
103 var ch = stream.next();
94 if (ch == '"' || ch == "'") {
104 if (ch == '"' || ch == "'") {
95 state.tokenize = tokenString(ch);
105 state.tokenize = tokenString(ch);
96 return state.tokenize(stream, state);
106 return state.tokenize(stream, state);
97 } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
107 } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
98 return ret("number", "number");
108 return ret("number", "number");
99 } else if (ch == "." && stream.match("..")) {
109 } else if (ch == "." && stream.match("..")) {
100 return ret("spread", "meta");
110 return ret("spread", "meta");
101 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
111 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
102 return ret(ch);
112 return ret(ch);
103 } else if (ch == "=" && stream.eat(">")) {
113 } else if (ch == "=" && stream.eat(">")) {
104 return ret("=>", "operator");
114 return ret("=>", "operator");
105 } else if (ch == "0" && stream.eat(/x/i)) {
115 } else if (ch == "0" && stream.eat(/x/i)) {
106 stream.eatWhile(/[\da-f]/i);
116 stream.eatWhile(/[\da-f]/i);
107 return ret("number", "number");
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 } else if (/\d/.test(ch)) {
124 } else if (/\d/.test(ch)) {
109 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
125 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
110 return ret("number", "number");
126 return ret("number", "number");
111 } else if (ch == "/") {
127 } else if (ch == "/") {
112 if (stream.eat("*")) {
128 if (stream.eat("*")) {
113 state.tokenize = tokenComment;
129 state.tokenize = tokenComment;
114 return tokenComment(stream, state);
130 return tokenComment(stream, state);
115 } else if (stream.eat("/")) {
131 } else if (stream.eat("/")) {
116 stream.skipToEnd();
132 stream.skipToEnd();
117 return ret("comment", "comment");
133 return ret("comment", "comment");
118 } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
134 } else if (expressionAllowed(stream, state, 1)) {
119 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
120 readRegexp(stream);
135 readRegexp(stream);
121 stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
136 stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
122 return ret("regexp", "string-2");
137 return ret("regexp", "string-2");
123 } else {
138 } else {
124 stream.eatWhile(isOperatorChar);
139 stream.eatWhile(isOperatorChar);
125 return ret("operator", "operator", stream.current());
140 return ret("operator", "operator", stream.current());
126 }
141 }
127 } else if (ch == "`") {
142 } else if (ch == "`") {
128 state.tokenize = tokenQuasi;
143 state.tokenize = tokenQuasi;
129 return tokenQuasi(stream, state);
144 return tokenQuasi(stream, state);
130 } else if (ch == "#") {
145 } else if (ch == "#") {
131 stream.skipToEnd();
146 stream.skipToEnd();
132 return ret("error", "error");
147 return ret("error", "error");
133 } else if (isOperatorChar.test(ch)) {
148 } else if (isOperatorChar.test(ch)) {
134 stream.eatWhile(isOperatorChar);
149 stream.eatWhile(isOperatorChar);
135 return ret("operator", "operator", stream.current());
150 return ret("operator", "operator", stream.current());
136 } else if (wordRE.test(ch)) {
151 } else if (wordRE.test(ch)) {
137 stream.eatWhile(wordRE);
152 stream.eatWhile(wordRE);
138 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
153 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
139 return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
154 return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
140 ret("variable", "variable", word);
155 ret("variable", "variable", word);
141 }
156 }
142 }
157 }
143
158
144 function tokenString(quote) {
159 function tokenString(quote) {
145 return function(stream, state) {
160 return function(stream, state) {
146 var escaped = false, next;
161 var escaped = false, next;
147 if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
162 if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
148 state.tokenize = tokenBase;
163 state.tokenize = tokenBase;
149 return ret("jsonld-keyword", "meta");
164 return ret("jsonld-keyword", "meta");
150 }
165 }
151 while ((next = stream.next()) != null) {
166 while ((next = stream.next()) != null) {
152 if (next == quote && !escaped) break;
167 if (next == quote && !escaped) break;
153 escaped = !escaped && next == "\\";
168 escaped = !escaped && next == "\\";
154 }
169 }
155 if (!escaped) state.tokenize = tokenBase;
170 if (!escaped) state.tokenize = tokenBase;
156 return ret("string", "string");
171 return ret("string", "string");
157 };
172 };
158 }
173 }
159
174
160 function tokenComment(stream, state) {
175 function tokenComment(stream, state) {
161 var maybeEnd = false, ch;
176 var maybeEnd = false, ch;
162 while (ch = stream.next()) {
177 while (ch = stream.next()) {
163 if (ch == "/" && maybeEnd) {
178 if (ch == "/" && maybeEnd) {
164 state.tokenize = tokenBase;
179 state.tokenize = tokenBase;
165 break;
180 break;
166 }
181 }
167 maybeEnd = (ch == "*");
182 maybeEnd = (ch == "*");
168 }
183 }
169 return ret("comment", "comment");
184 return ret("comment", "comment");
170 }
185 }
171
186
172 function tokenQuasi(stream, state) {
187 function tokenQuasi(stream, state) {
173 var escaped = false, next;
188 var escaped = false, next;
174 while ((next = stream.next()) != null) {
189 while ((next = stream.next()) != null) {
175 if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
190 if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
176 state.tokenize = tokenBase;
191 state.tokenize = tokenBase;
177 break;
192 break;
178 }
193 }
179 escaped = !escaped && next == "\\";
194 escaped = !escaped && next == "\\";
180 }
195 }
181 return ret("quasi", "string-2", stream.current());
196 return ret("quasi", "string-2", stream.current());
182 }
197 }
183
198
184 var brackets = "([{}])";
199 var brackets = "([{}])";
185 // This is a crude lookahead trick to try and notice that we're
200 // This is a crude lookahead trick to try and notice that we're
186 // parsing the argument patterns for a fat-arrow function before we
201 // parsing the argument patterns for a fat-arrow function before we
187 // actually hit the arrow token. It only works if the arrow is on
202 // actually hit the arrow token. It only works if the arrow is on
188 // the same line as the arguments and there's no strange noise
203 // the same line as the arguments and there's no strange noise
189 // (comments) in between. Fallback is to only notice when we hit the
204 // (comments) in between. Fallback is to only notice when we hit the
190 // arrow, and not declare the arguments as locals for the arrow
205 // arrow, and not declare the arguments as locals for the arrow
191 // body.
206 // body.
192 function findFatArrow(stream, state) {
207 function findFatArrow(stream, state) {
193 if (state.fatArrowAt) state.fatArrowAt = null;
208 if (state.fatArrowAt) state.fatArrowAt = null;
194 var arrow = stream.string.indexOf("=>", stream.start);
209 var arrow = stream.string.indexOf("=>", stream.start);
195 if (arrow < 0) return;
210 if (arrow < 0) return;
196
211
197 var depth = 0, sawSomething = false;
212 var depth = 0, sawSomething = false;
198 for (var pos = arrow - 1; pos >= 0; --pos) {
213 for (var pos = arrow - 1; pos >= 0; --pos) {
199 var ch = stream.string.charAt(pos);
214 var ch = stream.string.charAt(pos);
200 var bracket = brackets.indexOf(ch);
215 var bracket = brackets.indexOf(ch);
201 if (bracket >= 0 && bracket < 3) {
216 if (bracket >= 0 && bracket < 3) {
202 if (!depth) { ++pos; break; }
217 if (!depth) { ++pos; break; }
203 if (--depth == 0) break;
218 if (--depth == 0) break;
204 } else if (bracket >= 3 && bracket < 6) {
219 } else if (bracket >= 3 && bracket < 6) {
205 ++depth;
220 ++depth;
206 } else if (wordRE.test(ch)) {
221 } else if (wordRE.test(ch)) {
207 sawSomething = true;
222 sawSomething = true;
208 } else if (/["'\/]/.test(ch)) {
223 } else if (/["'\/]/.test(ch)) {
209 return;
224 return;
210 } else if (sawSomething && !depth) {
225 } else if (sawSomething && !depth) {
211 ++pos;
226 ++pos;
212 break;
227 break;
213 }
228 }
214 }
229 }
215 if (sawSomething && !depth) state.fatArrowAt = pos;
230 if (sawSomething && !depth) state.fatArrowAt = pos;
216 }
231 }
217
232
218 // Parser
233 // Parser
219
234
220 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
235 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
221
236
222 function JSLexical(indented, column, type, align, prev, info) {
237 function JSLexical(indented, column, type, align, prev, info) {
223 this.indented = indented;
238 this.indented = indented;
224 this.column = column;
239 this.column = column;
225 this.type = type;
240 this.type = type;
226 this.prev = prev;
241 this.prev = prev;
227 this.info = info;
242 this.info = info;
228 if (align != null) this.align = align;
243 if (align != null) this.align = align;
229 }
244 }
230
245
231 function inScope(state, varname) {
246 function inScope(state, varname) {
232 for (var v = state.localVars; v; v = v.next)
247 for (var v = state.localVars; v; v = v.next)
233 if (v.name == varname) return true;
248 if (v.name == varname) return true;
234 for (var cx = state.context; cx; cx = cx.prev) {
249 for (var cx = state.context; cx; cx = cx.prev) {
235 for (var v = cx.vars; v; v = v.next)
250 for (var v = cx.vars; v; v = v.next)
236 if (v.name == varname) return true;
251 if (v.name == varname) return true;
237 }
252 }
238 }
253 }
239
254
240 function parseJS(state, style, type, content, stream) {
255 function parseJS(state, style, type, content, stream) {
241 var cc = state.cc;
256 var cc = state.cc;
242 // Communicate our context to the combinators.
257 // Communicate our context to the combinators.
243 // (Less wasteful than consing up a hundred closures on every call.)
258 // (Less wasteful than consing up a hundred closures on every call.)
244 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
259 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
245
260
246 if (!state.lexical.hasOwnProperty("align"))
261 if (!state.lexical.hasOwnProperty("align"))
247 state.lexical.align = true;
262 state.lexical.align = true;
248
263
249 while(true) {
264 while(true) {
250 var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
265 var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
251 if (combinator(type, content)) {
266 if (combinator(type, content)) {
252 while(cc.length && cc[cc.length - 1].lex)
267 while(cc.length && cc[cc.length - 1].lex)
253 cc.pop()();
268 cc.pop()();
254 if (cx.marked) return cx.marked;
269 if (cx.marked) return cx.marked;
255 if (type == "variable" && inScope(state, content)) return "variable-2";
270 if (type == "variable" && inScope(state, content)) return "variable-2";
256 return style;
271 return style;
257 }
272 }
258 }
273 }
259 }
274 }
260
275
261 // Combinator utils
276 // Combinator utils
262
277
263 var cx = {state: null, column: null, marked: null, cc: null};
278 var cx = {state: null, column: null, marked: null, cc: null};
264 function pass() {
279 function pass() {
265 for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
280 for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
266 }
281 }
267 function cont() {
282 function cont() {
268 pass.apply(null, arguments);
283 pass.apply(null, arguments);
269 return true;
284 return true;
270 }
285 }
271 function register(varname) {
286 function register(varname) {
272 function inList(list) {
287 function inList(list) {
273 for (var v = list; v; v = v.next)
288 for (var v = list; v; v = v.next)
274 if (v.name == varname) return true;
289 if (v.name == varname) return true;
275 return false;
290 return false;
276 }
291 }
277 var state = cx.state;
292 var state = cx.state;
293 cx.marked = "def";
278 if (state.context) {
294 if (state.context) {
279 cx.marked = "def";
280 if (inList(state.localVars)) return;
295 if (inList(state.localVars)) return;
281 state.localVars = {name: varname, next: state.localVars};
296 state.localVars = {name: varname, next: state.localVars};
282 } else {
297 } else {
283 if (inList(state.globalVars)) return;
298 if (inList(state.globalVars)) return;
284 if (parserConfig.globalVars)
299 if (parserConfig.globalVars)
285 state.globalVars = {name: varname, next: state.globalVars};
300 state.globalVars = {name: varname, next: state.globalVars};
286 }
301 }
287 }
302 }
288
303
289 // Combinators
304 // Combinators
290
305
291 var defaultVars = {name: "this", next: {name: "arguments"}};
306 var defaultVars = {name: "this", next: {name: "arguments"}};
292 function pushcontext() {
307 function pushcontext() {
293 cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
308 cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
294 cx.state.localVars = defaultVars;
309 cx.state.localVars = defaultVars;
295 }
310 }
296 function popcontext() {
311 function popcontext() {
297 cx.state.localVars = cx.state.context.vars;
312 cx.state.localVars = cx.state.context.vars;
298 cx.state.context = cx.state.context.prev;
313 cx.state.context = cx.state.context.prev;
299 }
314 }
300 function pushlex(type, info) {
315 function pushlex(type, info) {
301 var result = function() {
316 var result = function() {
302 var state = cx.state, indent = state.indented;
317 var state = cx.state, indent = state.indented;
303 if (state.lexical.type == "stat") indent = state.lexical.indented;
318 if (state.lexical.type == "stat") indent = state.lexical.indented;
304 else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
319 else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
305 indent = outer.indented;
320 indent = outer.indented;
306 state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
321 state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
307 };
322 };
308 result.lex = true;
323 result.lex = true;
309 return result;
324 return result;
310 }
325 }
311 function poplex() {
326 function poplex() {
312 var state = cx.state;
327 var state = cx.state;
313 if (state.lexical.prev) {
328 if (state.lexical.prev) {
314 if (state.lexical.type == ")")
329 if (state.lexical.type == ")")
315 state.indented = state.lexical.indented;
330 state.indented = state.lexical.indented;
316 state.lexical = state.lexical.prev;
331 state.lexical = state.lexical.prev;
317 }
332 }
318 }
333 }
319 poplex.lex = true;
334 poplex.lex = true;
320
335
321 function expect(wanted) {
336 function expect(wanted) {
322 function exp(type) {
337 function exp(type) {
323 if (type == wanted) return cont();
338 if (type == wanted) return cont();
324 else if (wanted == ";") return pass();
339 else if (wanted == ";") return pass();
325 else return cont(exp);
340 else return cont(exp);
326 };
341 };
327 return exp;
342 return exp;
328 }
343 }
329
344
330 function statement(type, value) {
345 function statement(type, value) {
331 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
346 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
332 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
347 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
333 if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
348 if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
334 if (type == "{") return cont(pushlex("}"), block, poplex);
349 if (type == "{") return cont(pushlex("}"), block, poplex);
335 if (type == ";") return cont();
350 if (type == ";") return cont();
336 if (type == "if") {
351 if (type == "if") {
337 if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
352 if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
338 cx.state.cc.pop()();
353 cx.state.cc.pop()();
339 return cont(pushlex("form"), expression, statement, poplex, maybeelse);
354 return cont(pushlex("form"), expression, statement, poplex, maybeelse);
340 }
355 }
341 if (type == "function") return cont(functiondef);
356 if (type == "function") return cont(functiondef);
342 if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
357 if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
343 if (type == "variable") return cont(pushlex("stat"), maybelabel);
358 if (type == "variable") return cont(pushlex("stat"), maybelabel);
344 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
359 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
345 block, poplex, poplex);
360 block, poplex, poplex);
346 if (type == "case") return cont(expression, expect(":"));
361 if (type == "case") return cont(expression, expect(":"));
347 if (type == "default") return cont(expect(":"));
362 if (type == "default") return cont(expect(":"));
348 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
363 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
349 statement, poplex, popcontext);
364 statement, poplex, popcontext);
350 if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
351 if (type == "class") return cont(pushlex("form"), className, poplex);
365 if (type == "class") return cont(pushlex("form"), className, poplex);
352 if (type == "export") return cont(pushlex("form"), afterExport, poplex);
366 if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
353 if (type == "import") return cont(pushlex("form"), afterImport, 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 return pass(pushlex("stat"), expression, expect(";"), poplex);
369 return pass(pushlex("stat"), expression, expect(";"), poplex);
355 }
370 }
356 function expression(type) {
371 function expression(type) {
357 return expressionInner(type, false);
372 return expressionInner(type, false);
358 }
373 }
359 function expressionNoComma(type) {
374 function expressionNoComma(type) {
360 return expressionInner(type, true);
375 return expressionInner(type, true);
361 }
376 }
362 function expressionInner(type, noComma) {
377 function expressionInner(type, noComma) {
363 if (cx.state.fatArrowAt == cx.stream.start) {
378 if (cx.state.fatArrowAt == cx.stream.start) {
364 var body = noComma ? arrowBodyNoComma : arrowBody;
379 var body = noComma ? arrowBodyNoComma : arrowBody;
365 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
380 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
366 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
381 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
367 }
382 }
368
383
369 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
384 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
370 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
385 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
371 if (type == "function") return cont(functiondef, maybeop);
386 if (type == "function") return cont(functiondef, maybeop);
372 if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
387 if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
373 if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
388 if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
374 if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
389 if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
375 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
390 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
376 if (type == "{") return contCommasep(objprop, "}", null, maybeop);
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 return cont();
394 return cont();
379 }
395 }
380 function maybeexpression(type) {
396 function maybeexpression(type) {
381 if (type.match(/[;\}\)\],]/)) return pass();
397 if (type.match(/[;\}\)\],]/)) return pass();
382 return pass(expression);
398 return pass(expression);
383 }
399 }
384 function maybeexpressionNoComma(type) {
400 function maybeexpressionNoComma(type) {
385 if (type.match(/[;\}\)\],]/)) return pass();
401 if (type.match(/[;\}\)\],]/)) return pass();
386 return pass(expressionNoComma);
402 return pass(expressionNoComma);
387 }
403 }
388
404
389 function maybeoperatorComma(type, value) {
405 function maybeoperatorComma(type, value) {
390 if (type == ",") return cont(expression);
406 if (type == ",") return cont(expression);
391 return maybeoperatorNoComma(type, value, false);
407 return maybeoperatorNoComma(type, value, false);
392 }
408 }
393 function maybeoperatorNoComma(type, value, noComma) {
409 function maybeoperatorNoComma(type, value, noComma) {
394 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
410 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
395 var expr = noComma == false ? expression : expressionNoComma;
411 var expr = noComma == false ? expression : expressionNoComma;
396 if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
412 if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
397 if (type == "operator") {
413 if (type == "operator") {
398 if (/\+\+|--/.test(value)) return cont(me);
414 if (/\+\+|--/.test(value)) return cont(me);
399 if (value == "?") return cont(expression, expect(":"), expr);
415 if (value == "?") return cont(expression, expect(":"), expr);
400 return cont(expr);
416 return cont(expr);
401 }
417 }
402 if (type == "quasi") { return pass(quasi, me); }
418 if (type == "quasi") { return pass(quasi, me); }
403 if (type == ";") return;
419 if (type == ";") return;
404 if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
420 if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
405 if (type == ".") return cont(property, me);
421 if (type == ".") return cont(property, me);
406 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
422 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
407 }
423 }
408 function quasi(type, value) {
424 function quasi(type, value) {
409 if (type != "quasi") return pass();
425 if (type != "quasi") return pass();
410 if (value.slice(value.length - 2) != "${") return cont(quasi);
426 if (value.slice(value.length - 2) != "${") return cont(quasi);
411 return cont(expression, continueQuasi);
427 return cont(expression, continueQuasi);
412 }
428 }
413 function continueQuasi(type) {
429 function continueQuasi(type) {
414 if (type == "}") {
430 if (type == "}") {
415 cx.marked = "string-2";
431 cx.marked = "string-2";
416 cx.state.tokenize = tokenQuasi;
432 cx.state.tokenize = tokenQuasi;
417 return cont(quasi);
433 return cont(quasi);
418 }
434 }
419 }
435 }
420 function arrowBody(type) {
436 function arrowBody(type) {
421 findFatArrow(cx.stream, cx.state);
437 findFatArrow(cx.stream, cx.state);
422 return pass(type == "{" ? statement : expression);
438 return pass(type == "{" ? statement : expression);
423 }
439 }
424 function arrowBodyNoComma(type) {
440 function arrowBodyNoComma(type) {
425 findFatArrow(cx.stream, cx.state);
441 findFatArrow(cx.stream, cx.state);
426 return pass(type == "{" ? statement : expressionNoComma);
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 function maybelabel(type) {
456 function maybelabel(type) {
429 if (type == ":") return cont(poplex, statement);
457 if (type == ":") return cont(poplex, statement);
430 return pass(maybeoperatorComma, expect(";"), poplex);
458 return pass(maybeoperatorComma, expect(";"), poplex);
431 }
459 }
432 function property(type) {
460 function property(type) {
433 if (type == "variable") {cx.marked = "property"; return cont();}
461 if (type == "variable") {cx.marked = "property"; return cont();}
434 }
462 }
435 function objprop(type, value) {
463 function objprop(type, value) {
436 if (type == "variable" || cx.style == "keyword") {
464 if (type == "variable" || cx.style == "keyword") {
437 cx.marked = "property";
465 cx.marked = "property";
438 if (value == "get" || value == "set") return cont(getterSetter);
466 if (value == "get" || value == "set") return cont(getterSetter);
439 return cont(afterprop);
467 return cont(afterprop);
440 } else if (type == "number" || type == "string") {
468 } else if (type == "number" || type == "string") {
441 cx.marked = jsonldMode ? "property" : (cx.style + " property");
469 cx.marked = jsonldMode ? "property" : (cx.style + " property");
442 return cont(afterprop);
470 return cont(afterprop);
443 } else if (type == "jsonld-keyword") {
471 } else if (type == "jsonld-keyword") {
444 return cont(afterprop);
472 return cont(afterprop);
473 } else if (type == "modifier") {
474 return cont(objprop)
445 } else if (type == "[") {
475 } else if (type == "[") {
446 return cont(expression, expect("]"), afterprop);
476 return cont(expression, expect("]"), afterprop);
477 } else if (type == "spread") {
478 return cont(expression);
447 }
479 }
448 }
480 }
449 function getterSetter(type) {
481 function getterSetter(type) {
450 if (type != "variable") return pass(afterprop);
482 if (type != "variable") return pass(afterprop);
451 cx.marked = "property";
483 cx.marked = "property";
452 return cont(functiondef);
484 return cont(functiondef);
453 }
485 }
454 function afterprop(type) {
486 function afterprop(type) {
455 if (type == ":") return cont(expressionNoComma);
487 if (type == ":") return cont(expressionNoComma);
456 if (type == "(") return pass(functiondef);
488 if (type == "(") return pass(functiondef);
457 }
489 }
458 function commasep(what, end) {
490 function commasep(what, end) {
459 function proceed(type) {
491 function proceed(type) {
460 if (type == ",") {
492 if (type == ",") {
461 var lex = cx.state.lexical;
493 var lex = cx.state.lexical;
462 if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
494 if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
463 return cont(what, proceed);
495 return cont(what, proceed);
464 }
496 }
465 if (type == end) return cont();
497 if (type == end) return cont();
466 return cont(expect(end));
498 return cont(expect(end));
467 }
499 }
468 return function(type) {
500 return function(type) {
469 if (type == end) return cont();
501 if (type == end) return cont();
470 return pass(what, proceed);
502 return pass(what, proceed);
471 };
503 };
472 }
504 }
473 function contCommasep(what, end, info) {
505 function contCommasep(what, end, info) {
474 for (var i = 3; i < arguments.length; i++)
506 for (var i = 3; i < arguments.length; i++)
475 cx.cc.push(arguments[i]);
507 cx.cc.push(arguments[i]);
476 return cont(pushlex(end, info), commasep(what, end), poplex);
508 return cont(pushlex(end, info), commasep(what, end), poplex);
477 }
509 }
478 function block(type) {
510 function block(type) {
479 if (type == "}") return cont();
511 if (type == "}") return cont();
480 return pass(statement, block);
512 return pass(statement, block);
481 }
513 }
482 function maybetype(type) {
514 function maybetype(type) {
483 if (isTS && type == ":") return cont(typedef);
515 if (isTS && type == ":") return cont(typedef);
484 }
516 }
485 function maybedefault(_, value) {
517 function maybedefault(_, value) {
486 if (value == "=") return cont(expressionNoComma);
518 if (value == "=") return cont(expressionNoComma);
487 }
519 }
488 function typedef(type) {
520 function typedef(type) {
489 if (type == "variable") {cx.marked = "variable-3"; return cont();}
521 if (type == "variable") {cx.marked = "variable-3"; return cont();}
490 }
522 }
491 function vardef() {
523 function vardef() {
492 return pass(pattern, maybetype, maybeAssign, vardefCont);
524 return pass(pattern, maybetype, maybeAssign, vardefCont);
493 }
525 }
494 function pattern(type, value) {
526 function pattern(type, value) {
527 if (type == "modifier") return cont(pattern)
495 if (type == "variable") { register(value); return cont(); }
528 if (type == "variable") { register(value); return cont(); }
529 if (type == "spread") return cont(pattern);
496 if (type == "[") return contCommasep(pattern, "]");
530 if (type == "[") return contCommasep(pattern, "]");
497 if (type == "{") return contCommasep(proppattern, "}");
531 if (type == "{") return contCommasep(proppattern, "}");
498 }
532 }
499 function proppattern(type, value) {
533 function proppattern(type, value) {
500 if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
534 if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
501 register(value);
535 register(value);
502 return cont(maybeAssign);
536 return cont(maybeAssign);
503 }
537 }
504 if (type == "variable") cx.marked = "property";
538 if (type == "variable") cx.marked = "property";
539 if (type == "spread") return cont(pattern);
540 if (type == "}") return pass();
505 return cont(expect(":"), pattern, maybeAssign);
541 return cont(expect(":"), pattern, maybeAssign);
506 }
542 }
507 function maybeAssign(_type, value) {
543 function maybeAssign(_type, value) {
508 if (value == "=") return cont(expressionNoComma);
544 if (value == "=") return cont(expressionNoComma);
509 }
545 }
510 function vardefCont(type) {
546 function vardefCont(type) {
511 if (type == ",") return cont(vardef);
547 if (type == ",") return cont(vardef);
512 }
548 }
513 function maybeelse(type, value) {
549 function maybeelse(type, value) {
514 if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
550 if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
515 }
551 }
516 function forspec(type) {
552 function forspec(type) {
517 if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
553 if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
518 }
554 }
519 function forspec1(type) {
555 function forspec1(type) {
520 if (type == "var") return cont(vardef, expect(";"), forspec2);
556 if (type == "var") return cont(vardef, expect(";"), forspec2);
521 if (type == ";") return cont(forspec2);
557 if (type == ";") return cont(forspec2);
522 if (type == "variable") return cont(formaybeinof);
558 if (type == "variable") return cont(formaybeinof);
523 return pass(expression, expect(";"), forspec2);
559 return pass(expression, expect(";"), forspec2);
524 }
560 }
525 function formaybeinof(_type, value) {
561 function formaybeinof(_type, value) {
526 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
562 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
527 return cont(maybeoperatorComma, forspec2);
563 return cont(maybeoperatorComma, forspec2);
528 }
564 }
529 function forspec2(type, value) {
565 function forspec2(type, value) {
530 if (type == ";") return cont(forspec3);
566 if (type == ";") return cont(forspec3);
531 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
567 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
532 return pass(expression, expect(";"), forspec3);
568 return pass(expression, expect(";"), forspec3);
533 }
569 }
534 function forspec3(type) {
570 function forspec3(type) {
535 if (type != ")") cont(expression);
571 if (type != ")") cont(expression);
536 }
572 }
537 function functiondef(type, value) {
573 function functiondef(type, value) {
538 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
574 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
539 if (type == "variable") {register(value); return cont(functiondef);}
575 if (type == "variable") {register(value); return cont(functiondef);}
540 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
576 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
541 }
577 }
542 function funarg(type) {
578 function funarg(type) {
543 if (type == "spread") return cont(funarg);
579 if (type == "spread") return cont(funarg);
544 return pass(pattern, maybetype, maybedefault);
580 return pass(pattern, maybetype, maybedefault);
545 }
581 }
546 function className(type, value) {
582 function className(type, value) {
547 if (type == "variable") {register(value); return cont(classNameAfter);}
583 if (type == "variable") {register(value); return cont(classNameAfter);}
548 }
584 }
549 function classNameAfter(type, value) {
585 function classNameAfter(type, value) {
550 if (value == "extends") return cont(expression, classNameAfter);
586 if (value == "extends") return cont(expression, classNameAfter);
551 if (type == "{") return cont(pushlex("}"), classBody, poplex);
587 if (type == "{") return cont(pushlex("}"), classBody, poplex);
552 }
588 }
553 function classBody(type, value) {
589 function classBody(type, value) {
554 if (type == "variable" || cx.style == "keyword") {
590 if (type == "variable" || cx.style == "keyword") {
555 if (value == "static") {
591 if (value == "static") {
556 cx.marked = "keyword";
592 cx.marked = "keyword";
557 return cont(classBody);
593 return cont(classBody);
558 }
594 }
559 cx.marked = "property";
595 cx.marked = "property";
560 if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
596 if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
561 return cont(functiondef, classBody);
597 return cont(functiondef, classBody);
562 }
598 }
563 if (value == "*") {
599 if (value == "*") {
564 cx.marked = "keyword";
600 cx.marked = "keyword";
565 return cont(classBody);
601 return cont(classBody);
566 }
602 }
567 if (type == ";") return cont(classBody);
603 if (type == ";") return cont(classBody);
568 if (type == "}") return cont();
604 if (type == "}") return cont();
569 }
605 }
570 function classGetterSetter(type) {
606 function classGetterSetter(type) {
571 if (type != "variable") return pass();
607 if (type != "variable") return pass();
572 cx.marked = "property";
608 cx.marked = "property";
573 return cont();
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 function afterExport(_type, value) {
611 function afterExport(_type, value) {
580 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
612 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
581 if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
613 if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
582 return pass(statement);
614 return pass(statement);
583 }
615 }
584 function afterImport(type) {
616 function afterImport(type) {
585 if (type == "string") return cont();
617 if (type == "string") return cont();
586 return pass(importSpec, maybeFrom);
618 return pass(importSpec, maybeFrom);
587 }
619 }
588 function importSpec(type, value) {
620 function importSpec(type, value) {
589 if (type == "{") return contCommasep(importSpec, "}");
621 if (type == "{") return contCommasep(importSpec, "}");
590 if (type == "variable") register(value);
622 if (type == "variable") register(value);
591 if (value == "*") cx.marked = "keyword";
623 if (value == "*") cx.marked = "keyword";
592 return cont(maybeAs);
624 return cont(maybeAs);
593 }
625 }
594 function maybeAs(_type, value) {
626 function maybeAs(_type, value) {
595 if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
627 if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
596 }
628 }
597 function maybeFrom(_type, value) {
629 function maybeFrom(_type, value) {
598 if (value == "from") { cx.marked = "keyword"; return cont(expression); }
630 if (value == "from") { cx.marked = "keyword"; return cont(expression); }
599 }
631 }
600 function arrayLiteral(type) {
632 function arrayLiteral(type) {
601 if (type == "]") return cont();
633 if (type == "]") return cont();
602 return pass(expressionNoComma, maybeArrayComprehension);
634 return pass(expressionNoComma, maybeArrayComprehension);
603 }
635 }
604 function maybeArrayComprehension(type) {
636 function maybeArrayComprehension(type) {
605 if (type == "for") return pass(comprehension, expect("]"));
637 if (type == "for") return pass(comprehension, expect("]"));
606 if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
638 if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
607 return pass(commasep(expressionNoComma, "]"));
639 return pass(commasep(expressionNoComma, "]"));
608 }
640 }
609 function comprehension(type) {
641 function comprehension(type) {
610 if (type == "for") return cont(forspec, comprehension);
642 if (type == "for") return cont(forspec, comprehension);
611 if (type == "if") return cont(expression, comprehension);
643 if (type == "if") return cont(expression, comprehension);
612 }
644 }
613
645
614 function isContinuedStatement(state, textAfter) {
646 function isContinuedStatement(state, textAfter) {
615 return state.lastType == "operator" || state.lastType == "," ||
647 return state.lastType == "operator" || state.lastType == "," ||
616 isOperatorChar.test(textAfter.charAt(0)) ||
648 isOperatorChar.test(textAfter.charAt(0)) ||
617 /[,.]/.test(textAfter.charAt(0));
649 /[,.]/.test(textAfter.charAt(0));
618 }
650 }
619
651
620 // Interface
652 // Interface
621
653
622 return {
654 return {
623 startState: function(basecolumn) {
655 startState: function(basecolumn) {
624 var state = {
656 var state = {
625 tokenize: tokenBase,
657 tokenize: tokenBase,
626 lastType: "sof",
658 lastType: "sof",
627 cc: [],
659 cc: [],
628 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
660 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
629 localVars: parserConfig.localVars,
661 localVars: parserConfig.localVars,
630 context: parserConfig.localVars && {vars: parserConfig.localVars},
662 context: parserConfig.localVars && {vars: parserConfig.localVars},
631 indented: 0
663 indented: basecolumn || 0
632 };
664 };
633 if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
665 if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
634 state.globalVars = parserConfig.globalVars;
666 state.globalVars = parserConfig.globalVars;
635 return state;
667 return state;
636 },
668 },
637
669
638 token: function(stream, state) {
670 token: function(stream, state) {
639 if (stream.sol()) {
671 if (stream.sol()) {
640 if (!state.lexical.hasOwnProperty("align"))
672 if (!state.lexical.hasOwnProperty("align"))
641 state.lexical.align = false;
673 state.lexical.align = false;
642 state.indented = stream.indentation();
674 state.indented = stream.indentation();
643 findFatArrow(stream, state);
675 findFatArrow(stream, state);
644 }
676 }
645 if (state.tokenize != tokenComment && stream.eatSpace()) return null;
677 if (state.tokenize != tokenComment && stream.eatSpace()) return null;
646 var style = state.tokenize(stream, state);
678 var style = state.tokenize(stream, state);
647 if (type == "comment") return style;
679 if (type == "comment") return style;
648 state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
680 state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
649 return parseJS(state, style, type, content, stream);
681 return parseJS(state, style, type, content, stream);
650 },
682 },
651
683
652 indent: function(state, textAfter) {
684 indent: function(state, textAfter) {
653 if (state.tokenize == tokenComment) return CodeMirror.Pass;
685 if (state.tokenize == tokenComment) return CodeMirror.Pass;
654 if (state.tokenize != tokenBase) return 0;
686 if (state.tokenize != tokenBase) return 0;
655 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
687 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
656 // Kludge to prevent 'maybelse' from blocking lexical scope pops
688 // Kludge to prevent 'maybelse' from blocking lexical scope pops
657 if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
689 if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
658 var c = state.cc[i];
690 var c = state.cc[i];
659 if (c == poplex) lexical = lexical.prev;
691 if (c == poplex) lexical = lexical.prev;
660 else if (c != maybeelse) break;
692 else if (c != maybeelse) break;
661 }
693 }
662 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
694 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
663 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
695 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
664 lexical = lexical.prev;
696 lexical = lexical.prev;
665 var type = lexical.type, closing = firstChar == type;
697 var type = lexical.type, closing = firstChar == type;
666
698
667 if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
699 if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
668 else if (type == "form" && firstChar == "{") return lexical.indented;
700 else if (type == "form" && firstChar == "{") return lexical.indented;
669 else if (type == "form") return lexical.indented + indentUnit;
701 else if (type == "form") return lexical.indented + indentUnit;
670 else if (type == "stat")
702 else if (type == "stat")
671 return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
703 return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
672 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
704 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
673 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
705 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
674 else if (lexical.align) return lexical.column + (closing ? 0 : 1);
706 else if (lexical.align) return lexical.column + (closing ? 0 : 1);
675 else return lexical.indented + (closing ? 0 : indentUnit);
707 else return lexical.indented + (closing ? 0 : indentUnit);
676 },
708 },
677
709
678 electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
710 electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
679 blockCommentStart: jsonMode ? null : "/*",
711 blockCommentStart: jsonMode ? null : "/*",
680 blockCommentEnd: jsonMode ? null : "*/",
712 blockCommentEnd: jsonMode ? null : "*/",
681 lineComment: jsonMode ? null : "//",
713 lineComment: jsonMode ? null : "//",
682 fold: "brace",
714 fold: "brace",
683 closeBrackets: "()[]{}''\"\"``",
715 closeBrackets: "()[]{}''\"\"``",
684
716
685 helperType: jsonMode ? "json" : "javascript",
717 helperType: jsonMode ? "json" : "javascript",
686 jsonldMode: jsonldMode,
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 CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
729 CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
692
730
693 CodeMirror.defineMIME("text/javascript", "javascript");
731 CodeMirror.defineMIME("text/javascript", "javascript");
694 CodeMirror.defineMIME("text/ecmascript", "javascript");
732 CodeMirror.defineMIME("text/ecmascript", "javascript");
695 CodeMirror.defineMIME("application/javascript", "javascript");
733 CodeMirror.defineMIME("application/javascript", "javascript");
696 CodeMirror.defineMIME("application/x-javascript", "javascript");
734 CodeMirror.defineMIME("application/x-javascript", "javascript");
697 CodeMirror.defineMIME("application/ecmascript", "javascript");
735 CodeMirror.defineMIME("application/ecmascript", "javascript");
698 CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
736 CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
699 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
737 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
700 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
738 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
701 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
739 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
702 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
740 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
703
741
704 });
742 });
@@ -1,299 +1,364 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("julia", function(_conf, parserConf) {
14 CodeMirror.defineMode("julia", function(_conf, parserConf) {
15 var ERRORCLASS = 'error';
15 var ERRORCLASS = 'error';
16
16
17 function wordRegexp(words) {
17 function wordRegexp(words) {
18 return new RegExp("^((" + words.join(")|(") + "))\\b");
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 var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
22 var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
23 var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*!*/;
23 var identifiers = parserConf.identifiers || /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*!*/;
24 var blockOpeners = ["begin", "function", "type", "immutable", "let", "macro", "for", "while", "quote", "if", "else", "elseif", "try", "finally", "catch", "do"];
24 var blockOpeners = ["begin", "function", "type", "immutable", "let", "macro", "for", "while", "quote", "if", "else", "elseif", "try", "finally", "catch", "do"];
25 var blockClosers = ["end", "else", "elseif", "catch", "finally"];
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'];
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', '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'];
27 var builtinList = ['true', 'false', 'nothing', 'NaN', 'Inf'];
28
28
29 //var stringPrefixes = new RegExp("^[br]?('|\")")
29 //var stringPrefixes = new RegExp("^[br]?('|\")")
30 var stringPrefixes = /^(`|'|"{3}|([br]?"))/;
30 var stringPrefixes = /^(`|'|"{3}|([brv]?"))/;
31 var keywords = wordRegexp(keywordList);
31 var keywords = wordRegexp(keywordList);
32 var builtins = wordRegexp(builtinList);
32 var builtins = wordRegexp(builtinList);
33 var openers = wordRegexp(blockOpeners);
33 var openers = wordRegexp(blockOpeners);
34 var closers = wordRegexp(blockClosers);
34 var closers = wordRegexp(blockClosers);
35 var macro = /^@[_A-Za-z][_A-Za-z0-9]*/;
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 function inArray(state) {
39 var ch = cur_scope(state);
40 var ch = currentScope(state);
40 if(ch=="[" || ch=="{") {
41 if (ch == '[') {
41 return true;
42 return true;
42 }
43 }
43 else {
44 return false;
44 return false;
45 }
46 }
45 }
47
46
48 function cur_scope(state) {
47 function currentScope(state) {
49 if(state.scopes.length==0) {
48 if (state.scopes.length == 0) {
50 return null;
49 return null;
51 }
50 }
52 return state.scopes[state.scopes.length - 1];
51 return state.scopes[state.scopes.length - 1];
53 }
52 }
54
53
55 // tokenizers
54 // tokenizers
56 function tokenBase(stream, state) {
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 // Handle scope changes
71 // Handle scope changes
58 var leaving_expr = state.leaving_expr;
72 var leavingExpr = state.leavingExpr;
59 if(stream.sol()) {
73 if (stream.sol()) {
60 leaving_expr = false;
74 leavingExpr = false;
61 }
75 }
62 state.leaving_expr = false;
76 state.leavingExpr = false;
63 if(leaving_expr) {
77 if (leavingExpr) {
64 if(stream.match(/^'+/)) {
78 if (stream.match(/^'+/)) {
65 return 'operator';
79 return 'operator';
66 }
80 }
67
68 }
81 }
69
82
70 if(stream.match(/^\.{2,3}/)) {
83 if (stream.match(/^\.{2,3}/)) {
71 return 'operator';
84 return 'operator';
72 }
85 }
73
86
74 if (stream.eatSpace()) {
87 if (stream.eatSpace()) {
75 return null;
88 return null;
76 }
89 }
77
90
78 var ch = stream.peek();
91 var ch = stream.peek();
79 // Handle Comments
92
93 // Handle single line comments
80 if (ch === '#') {
94 if (ch === '#') {
81 stream.skipToEnd();
95 stream.skipToEnd();
82 return 'comment';
96 return 'comment';
83 }
84 if(ch==='[') {
85 state.scopes.push("[");
86 }
97 }
87
98
88 if(ch==='{') {
99 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 state.scopes.pop();
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 state.scopes.pop();
111 state.scopes.pop();
101 state.leaving_expr=true;
112 state.leavingExpr = true;
102 }
103
104 if(ch===')') {
105 state.leaving_expr = true;
106 }
113 }
107
114
108 var match;
115 var match;
109 if(!in_array(state) && (match=stream.match(openers, false))) {
116 if (!inArray(state) && (match=stream.match(openers, false))) {
110 state.scopes.push(match);
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 state.scopes.pop();
121 state.scopes.pop();
115 }
122 }
116
123
117 if(in_array(state)) {
124 if (inArray(state)) {
118 if(stream.match(/^end/)) {
125 if (state.lastToken == 'end' && stream.match(/^:/)) {
126 return 'operator';
127 }
128 if (stream.match(/^end/)) {
119 return 'number';
129 return 'number';
120 }
130 }
121
122 }
131 }
123
132
124 if(stream.match(/^=>/)) {
133 if (stream.match(/^=>/)) {
125 return 'operator';
134 return 'operator';
126 }
135 }
127
136
128
129 // Handle Number Literals
137 // Handle Number Literals
130 if (stream.match(/^[0-9\.]/, false)) {
138 if (stream.match(/^[0-9\.]/, false)) {
131 var imMatcher = RegExp(/^im\b/);
139 var imMatcher = RegExp(/^im\b/);
132 var floatLiteral = false;
140 var floatLiteral = false;
133 // Floats
141 // Floats
134 if (stream.match(/^\d*\.(?!\.)\d+([ef][\+\-]?\d+)?/i)) { floatLiteral = true; }
142 if (stream.match(/^\d*\.(?!\.)\d+([ef][\+\-]?\d+)?/i)) { floatLiteral = true; }
135 if (stream.match(/^\d+\.(?!\.)\d*/)) { floatLiteral = true; }
143 if (stream.match(/^\d+\.(?!\.)\d*/)) { floatLiteral = true; }
136 if (stream.match(/^\.\d+/)) { floatLiteral = true; }
144 if (stream.match(/^\.\d+/)) { floatLiteral = true; }
145 if (stream.match(/^0x\.[0-9a-f]+p[\+\-]?\d+/i)) { floatLiteral = true; }
137 if (floatLiteral) {
146 if (floatLiteral) {
138 // Float literals may be "imaginary"
147 // Float literals may be "imaginary"
139 stream.match(imMatcher);
148 stream.match(imMatcher);
140 state.leaving_expr = true;
149 state.leavingExpr = true;
141 return 'number';
150 return 'number';
142 }
151 }
143 // Integers
152 // Integers
144 var intLiteral = false;
153 var intLiteral = false;
145 // Hex
154 // Hex
146 if (stream.match(/^0x[0-9a-f]+/i)) { intLiteral = true; }
155 if (stream.match(/^0x[0-9a-f]+/i)) { intLiteral = true; }
147 // Binary
156 // Binary
148 if (stream.match(/^0b[01]+/i)) { intLiteral = true; }
157 if (stream.match(/^0b[01]+/i)) { intLiteral = true; }
149 // Octal
158 // Octal
150 if (stream.match(/^0o[0-7]+/i)) { intLiteral = true; }
159 if (stream.match(/^0o[0-7]+/i)) { intLiteral = true; }
151 // Decimal
160 // Decimal
152 if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
161 if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
153 intLiteral = true;
162 intLiteral = true;
154 }
163 }
155 // Zero by itself with no other piece of number.
164 // Zero by itself with no other piece of number.
156 if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
165 if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
157 if (intLiteral) {
166 if (intLiteral) {
158 // Integer literals may be "long"
167 // Integer literals may be "long"
159 stream.match(imMatcher);
168 stream.match(imMatcher);
160 state.leaving_expr = true;
169 state.leavingExpr = true;
161 return 'number';
170 return 'number';
162 }
171 }
163 }
172 }
164
173
165 if(stream.match(/^(::)|(<:)/)) {
174 if (stream.match(/^<:/)) {
166 return 'operator';
175 return 'operator';
167 }
176 }
168
177
178 if (stream.match(typeAnnotation)) {
179 return 'builtin';
180 }
181
169 // Handle symbols
182 // Handle symbols
170 if(!leaving_expr && stream.match(symbol)) {
183 if (!leavingExpr && stream.match(symbol) || stream.match(/:\./)) {
171 return 'string';
184 return 'builtin';
185 }
186
187 // Handle parametric types
188 if (stream.match(/^{[^}]*}(?=\()/)) {
189 return 'builtin';
172 }
190 }
173
191
174 // Handle operators and Delimiters
192 // Handle operators and Delimiters
175 if (stream.match(operators)) {
193 if (stream.match(operators)) {
176 return 'operator';
194 return 'operator';
177 }
195 }
178
196
179
180 // Handle Strings
197 // Handle Strings
181 if (stream.match(stringPrefixes)) {
198 if (stream.match(stringPrefixes)) {
182 state.tokenize = tokenStringFactory(stream.current());
199 state.tokenize = tokenStringFactory(stream.current());
183 return state.tokenize(stream, state);
200 return state.tokenize(stream, state);
184 }
201 }
185
202
186 if (stream.match(macro)) {
203 if (stream.match(macro)) {
187 return 'meta';
204 return 'meta';
188 }
205 }
189
206
190
191 if (stream.match(delimiters)) {
207 if (stream.match(delimiters)) {
192 return null;
208 return null;
193 }
209 }
194
210
195 if (stream.match(keywords)) {
211 if (stream.match(keywords)) {
196 return 'keyword';
212 return 'keyword';
197 }
213 }
198
214
199 if (stream.match(builtins)) {
215 if (stream.match(builtins)) {
200 return 'builtin';
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 if (stream.match(identifiers)) {
225 if (stream.match(identifiers)) {
205 state.leaving_expr=true;
226 if (isDefinition) {
227 if (stream.peek() === '.') {
228 state.isDefinition = true;
229 return 'variable';
230 }
231 state.isDefinition = false;
232 return 'def';
233 }
234 if (stream.match(/^({[^}]*})*\(/, false)) {
235 return callOrDef(stream, state);
236 }
237 state.leavingExpr = true;
206 return 'variable';
238 return 'variable';
207 }
239 }
240
208 // Handle non-detected items
241 // Handle non-detected items
209 stream.next();
242 stream.next();
210 return ERRORCLASS;
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 function tokenStringFactory(delimiter) {
282 function tokenStringFactory(delimiter) {
214 while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
283 while ('bruv'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
215 delimiter = delimiter.substr(1);
284 delimiter = delimiter.substr(1);
216 }
285 }
217 var singleline = delimiter.length == 1;
286 var singleline = delimiter == "'";
218 var OUTCLASS = 'string';
287 var OUTCLASS = 'string';
219
288
220 function tokenString(stream, state) {
289 function tokenString(stream, state) {
221 while (!stream.eol()) {
290 while (!stream.eol()) {
222 stream.eatWhile(/[^'"\\]/);
291 stream.eatWhile(/[^'"\\]/);
223 if (stream.eat('\\')) {
292 if (stream.eat('\\')) {
224 stream.next();
293 stream.next();
225 if (singleline && stream.eol()) {
294 if (singleline && stream.eol()) {
226 return OUTCLASS;
295 return OUTCLASS;
227 }
296 }
228 } else if (stream.match(delimiter)) {
297 } else if (stream.match(delimiter)) {
229 state.tokenize = tokenBase;
298 state.tokenize = tokenBase;
230 return OUTCLASS;
299 return OUTCLASS;
231 } else {
300 } else {
232 stream.eat(/['"]/);
301 stream.eat(/['"]/);
233 }
302 }
234 }
303 }
235 if (singleline) {
304 if (singleline) {
236 if (parserConf.singleLineStringErrors) {
305 if (parserConf.singleLineStringErrors) {
237 return ERRORCLASS;
306 return ERRORCLASS;
238 } else {
307 } else {
239 state.tokenize = tokenBase;
308 state.tokenize = tokenBase;
240 }
309 }
241 }
310 }
242 return OUTCLASS;
311 return OUTCLASS;
243 }
312 }
244 tokenString.isString = true;
313 tokenString.isString = true;
245 return tokenString;
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 var external = {
317 var external = {
267 startState: function() {
318 startState: function() {
268 return {
319 return {
269 tokenize: tokenBase,
320 tokenize: tokenBase,
270 scopes: [],
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 token: function(stream, state) {
330 token: function(stream, state) {
276 var style = tokenLexer(stream, state);
331 var style = state.tokenize(stream, state);
277 state.lastStyle = style;
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 return style;
343 return style;
279 },
344 },
280
345
281 indent: function(state, textAfter) {
346 indent: function(state, textAfter) {
282 var delta = 0;
347 var delta = 0;
283 if(textAfter=="end" || textAfter=="]" || textAfter=="}" || textAfter=="else" || textAfter=="elseif" || textAfter=="catch" || textAfter=="finally") {
348 if (textAfter == "end" || textAfter == "]" || textAfter == "}" || textAfter == "else" || textAfter == "elseif" || textAfter == "catch" || textAfter == "finally") {
284 delta = -1;
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 lineComment: "#",
354 lineComment: "#",
290 fold: "indent",
355 fold: "indent",
291 electricChars: "edlsifyh]}"
356 electricChars: "edlsifyh]}"
292 };
357 };
293 return external;
358 return external;
294 });
359 });
295
360
296
361
297 CodeMirror.defineMIME("text/x-julia", "julia");
362 CodeMirror.defineMIME("text/x-julia", "julia");
298
363
299 });
364 });
@@ -1,781 +1,803 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta"));
6 mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../xml/xml", "../meta"], mod);
8 define(["../../lib/codemirror", "../xml/xml", "../meta"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
14 CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
15
15
16 var htmlFound = CodeMirror.modes.hasOwnProperty("xml");
16 var htmlFound = CodeMirror.modes.hasOwnProperty("xml");
17 var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? {name: "xml", htmlMode: true} : "text/plain");
17 var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? {name: "xml", htmlMode: true} : "text/plain");
18
18
19 function getMode(name) {
19 function getMode(name) {
20 if (CodeMirror.findModeByName) {
20 if (CodeMirror.findModeByName) {
21 var found = CodeMirror.findModeByName(name);
21 var found = CodeMirror.findModeByName(name);
22 if (found) name = found.mime || found.mimes[0];
22 if (found) name = found.mime || found.mimes[0];
23 }
23 }
24 var mode = CodeMirror.getMode(cmCfg, name);
24 var mode = CodeMirror.getMode(cmCfg, name);
25 return mode.name == "null" ? null : mode;
25 return mode.name == "null" ? null : mode;
26 }
26 }
27
27
28 // Should characters that affect highlighting be highlighted separate?
28 // Should characters that affect highlighting be highlighted separate?
29 // Does not include characters that will be output (such as `1.` and `-` for lists)
29 // Does not include characters that will be output (such as `1.` and `-` for lists)
30 if (modeCfg.highlightFormatting === undefined)
30 if (modeCfg.highlightFormatting === undefined)
31 modeCfg.highlightFormatting = false;
31 modeCfg.highlightFormatting = false;
32
32
33 // Maximum number of nested blockquotes. Set to 0 for infinite nesting.
33 // Maximum number of nested blockquotes. Set to 0 for infinite nesting.
34 // Excess `>` will emit `error` token.
34 // Excess `>` will emit `error` token.
35 if (modeCfg.maxBlockquoteDepth === undefined)
35 if (modeCfg.maxBlockquoteDepth === undefined)
36 modeCfg.maxBlockquoteDepth = 0;
36 modeCfg.maxBlockquoteDepth = 0;
37
37
38 // Should underscores in words open/close em/strong?
38 // Should underscores in words open/close em/strong?
39 if (modeCfg.underscoresBreakWords === undefined)
39 if (modeCfg.underscoresBreakWords === undefined)
40 modeCfg.underscoresBreakWords = true;
40 modeCfg.underscoresBreakWords = true;
41
41
42 // Turn on fenced code blocks? ("```" to start/end)
42 // Use `fencedCodeBlocks` to configure fenced code blocks. false to
43 if (modeCfg.fencedCodeBlocks === undefined) modeCfg.fencedCodeBlocks = false;
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 // Turn on task lists? ("- [ ] " and "- [x] ")
47 // Turn on task lists? ("- [ ] " and "- [x] ")
46 if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
48 if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
47
49
48 // Turn on strikethrough syntax
50 // Turn on strikethrough syntax
49 if (modeCfg.strikethrough === undefined)
51 if (modeCfg.strikethrough === undefined)
50 modeCfg.strikethrough = false;
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 var codeDepth = 0;
58 var codeDepth = 0;
53
59
54 var header = 'header'
60 var tokenTypes = {
55 , code = 'comment'
61 header: "header",
56 , quote = 'quote'
62 code: "comment",
57 , list1 = 'variable-2'
63 quote: "quote",
58 , list2 = 'variable-3'
64 list1: "variable-2",
59 , list3 = 'keyword'
65 list2: "variable-3",
60 , hr = 'hr'
66 list3: "keyword",
61 , image = 'tag'
67 hr: "hr",
62 , formatting = 'formatting'
68 image: "tag",
63 , linkinline = 'link'
69 formatting: "formatting",
64 , linkemail = 'link'
70 linkInline: "link",
65 , linktext = 'link'
71 linkEmail: "link",
66 , linkhref = 'string'
72 linkText: "link",
67 , em = 'em'
73 linkHref: "string",
68 , strong = 'strong'
74 em: "em",
69 , strikethrough = 'strikethrough';
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 var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
85 var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
72 , ulRE = /^[*\-+]\s+/
86 , ulRE = /^[*\-+]\s+/
73 , olRE = /^[0-9]+([.)])\s+/
87 , olRE = /^[0-9]+([.)])\s+/
74 , taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
88 , taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
75 , atxHeaderRE = /^(#+)(?: |$)/
89 , atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
76 , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
90 , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
77 , textRE = /^[^#!\[\]*_\\<>` "'(~]+/;
91 , textRE = /^[^#!\[\]*_\\<>` "'(~]+/
92 , fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
93 ")[ \\t]*([\\w+#]*)");
78
94
79 function switchInline(stream, state, f) {
95 function switchInline(stream, state, f) {
80 state.f = state.inline = f;
96 state.f = state.inline = f;
81 return f(stream, state);
97 return f(stream, state);
82 }
98 }
83
99
84 function switchBlock(stream, state, f) {
100 function switchBlock(stream, state, f) {
85 state.f = state.block = f;
101 state.f = state.block = f;
86 return f(stream, state);
102 return f(stream, state);
87 }
103 }
88
104
105 function lineIsEmpty(line) {
106 return !line || !/\S/.test(line.string)
107 }
89
108
90 // Blocks
109 // Blocks
91
110
92 function blankLine(state) {
111 function blankLine(state) {
93 // Reset linkTitle state
112 // Reset linkTitle state
94 state.linkTitle = false;
113 state.linkTitle = false;
95 // Reset EM state
114 // Reset EM state
96 state.em = false;
115 state.em = false;
97 // Reset STRONG state
116 // Reset STRONG state
98 state.strong = false;
117 state.strong = false;
99 // Reset strikethrough state
118 // Reset strikethrough state
100 state.strikethrough = false;
119 state.strikethrough = false;
101 // Reset state.quote
120 // Reset state.quote
102 state.quote = 0;
121 state.quote = 0;
103 // Reset state.indentedCode
122 // Reset state.indentedCode
104 state.indentedCode = false;
123 state.indentedCode = false;
105 if (!htmlFound && state.f == htmlBlock) {
124 if (!htmlFound && state.f == htmlBlock) {
106 state.f = inlineNormal;
125 state.f = inlineNormal;
107 state.block = blockNormal;
126 state.block = blockNormal;
108 }
127 }
109 // Reset state.trailingSpace
128 // Reset state.trailingSpace
110 state.trailingSpace = 0;
129 state.trailingSpace = 0;
111 state.trailingSpaceNewLine = false;
130 state.trailingSpaceNewLine = false;
112 // Mark this line as blank
131 // Mark this line as blank
113 state.thisLineHasContent = false;
132 state.prevLine = state.thisLine
133 state.thisLine = null
114 return null;
134 return null;
115 }
135 }
116
136
117 function blockNormal(stream, state) {
137 function blockNormal(stream, state) {
118
138
119 var sol = stream.sol();
139 var sol = stream.sol();
120
140
121 var prevLineIsList = state.list !== false,
141 var prevLineIsList = state.list !== false,
122 prevLineIsIndentedCode = state.indentedCode;
142 prevLineIsIndentedCode = state.indentedCode;
123
143
124 state.indentedCode = false;
144 state.indentedCode = false;
125
145
126 if (prevLineIsList) {
146 if (prevLineIsList) {
127 if (state.indentationDiff >= 0) { // Continued list
147 if (state.indentationDiff >= 0) { // Continued list
128 if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
148 if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
129 state.indentation -= state.indentationDiff;
149 state.indentation -= state.indentationDiff;
130 }
150 }
131 state.list = null;
151 state.list = null;
132 } else if (state.indentation > 0) {
152 } else if (state.indentation > 0) {
133 state.list = null;
153 state.list = null;
134 state.listDepth = Math.floor(state.indentation / 4);
154 state.listDepth = Math.floor(state.indentation / 4);
135 } else { // No longer a list
155 } else { // No longer a list
136 state.list = false;
156 state.list = false;
137 state.listDepth = 0;
157 state.listDepth = 0;
138 }
158 }
139 }
159 }
140
160
141 var match = null;
161 var match = null;
142 if (state.indentationDiff >= 4) {
162 if (state.indentationDiff >= 4) {
143 stream.skipToEnd();
163 stream.skipToEnd();
144 if (prevLineIsIndentedCode || !state.prevLineHasContent) {
164 if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) {
145 state.indentation -= 4;
165 state.indentation -= 4;
146 state.indentedCode = true;
166 state.indentedCode = true;
147 return code;
167 return tokenTypes.code;
148 } else {
168 } else {
149 return null;
169 return null;
150 }
170 }
151 } else if (stream.eatSpace()) {
171 } else if (stream.eatSpace()) {
152 return null;
172 return null;
153 } else if ((match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
173 } else if ((match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
154 state.header = match[1].length;
174 state.header = match[1].length;
155 if (modeCfg.highlightFormatting) state.formatting = "header";
175 if (modeCfg.highlightFormatting) state.formatting = "header";
156 state.f = state.inline;
176 state.f = state.inline;
157 return getType(state);
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 state.header = match[0].charAt(0) == '=' ? 1 : 2;
180 state.header = match[0].charAt(0) == '=' ? 1 : 2;
160 if (modeCfg.highlightFormatting) state.formatting = "header";
181 if (modeCfg.highlightFormatting) state.formatting = "header";
161 state.f = state.inline;
182 state.f = state.inline;
162 return getType(state);
183 return getType(state);
163 } else if (stream.eat('>')) {
184 } else if (stream.eat('>')) {
164 state.quote = sol ? 1 : state.quote + 1;
185 state.quote = sol ? 1 : state.quote + 1;
165 if (modeCfg.highlightFormatting) state.formatting = "quote";
186 if (modeCfg.highlightFormatting) state.formatting = "quote";
166 stream.eatSpace();
187 stream.eatSpace();
167 return getType(state);
188 return getType(state);
168 } else if (stream.peek() === '[') {
189 } else if (stream.peek() === '[') {
169 return switchInline(stream, state, footnoteLink);
190 return switchInline(stream, state, footnoteLink);
170 } else if (stream.match(hrRE, true)) {
191 } else if (stream.match(hrRE, true)) {
171 state.hr = true;
192 state.hr = true;
172 return hr;
193 return tokenTypes.hr;
173 } else if ((!state.prevLineHasContent || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
194 } else if ((lineIsEmpty(state.prevLine) || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
174 var listType = null;
195 var listType = null;
175 if (stream.match(ulRE, true)) {
196 if (stream.match(ulRE, true)) {
176 listType = 'ul';
197 listType = 'ul';
177 } else {
198 } else {
178 stream.match(olRE, true);
199 stream.match(olRE, true);
179 listType = 'ol';
200 listType = 'ol';
180 }
201 }
181 state.indentation += 4;
202 state.indentation = stream.column() + stream.current().length;
182 state.list = true;
203 state.list = true;
183 state.listDepth++;
204 state.listDepth++;
184 if (modeCfg.taskLists && stream.match(taskListRE, false)) {
205 if (modeCfg.taskLists && stream.match(taskListRE, false)) {
185 state.taskList = true;
206 state.taskList = true;
186 }
207 }
187 state.f = state.inline;
208 state.f = state.inline;
188 if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
209 if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
189 return getType(state);
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 // try switching mode
213 // try switching mode
192 state.localMode = getMode(RegExp.$1);
214 state.localMode = getMode(match[2]);
193 if (state.localMode) state.localState = state.localMode.startState();
215 if (state.localMode) state.localState = state.localMode.startState();
194 state.f = state.block = local;
216 state.f = state.block = local;
195 if (modeCfg.highlightFormatting) state.formatting = "code-block";
217 if (modeCfg.highlightFormatting) state.formatting = "code-block";
196 state.code = true;
218 state.code = true;
197 return getType(state);
219 return getType(state);
198 }
220 }
199
221
200 return switchInline(stream, state, state.inline);
222 return switchInline(stream, state, state.inline);
201 }
223 }
202
224
203 function htmlBlock(stream, state) {
225 function htmlBlock(stream, state) {
204 var style = htmlMode.token(stream, state.htmlState);
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 (state.md_inside && stream.current().indexOf(">") > -1)) {
229 (state.md_inside && stream.current().indexOf(">") > -1)) {
207 state.f = inlineNormal;
230 state.f = inlineNormal;
208 state.block = blockNormal;
231 state.block = blockNormal;
209 state.htmlState = null;
232 state.htmlState = null;
210 }
233 }
211 return style;
234 return style;
212 }
235 }
213
236
214 function local(stream, state) {
237 function local(stream, state) {
215 if (stream.sol() && stream.match("```", false)) {
238 if (state.fencedChars && stream.match(state.fencedChars, false)) {
216 state.localMode = state.localState = null;
239 state.localMode = state.localState = null;
217 state.f = state.block = leavingLocal;
240 state.f = state.block = leavingLocal;
218 return null;
241 return null;
219 } else if (state.localMode) {
242 } else if (state.localMode) {
220 return state.localMode.token(stream, state.localState);
243 return state.localMode.token(stream, state.localState);
221 } else {
244 } else {
222 stream.skipToEnd();
245 stream.skipToEnd();
223 return code;
246 return tokenTypes.code;
224 }
247 }
225 }
248 }
226
249
227 function leavingLocal(stream, state) {
250 function leavingLocal(stream, state) {
228 stream.match("```");
251 stream.match(state.fencedChars);
229 state.block = blockNormal;
252 state.block = blockNormal;
230 state.f = inlineNormal;
253 state.f = inlineNormal;
254 state.fencedChars = null;
231 if (modeCfg.highlightFormatting) state.formatting = "code-block";
255 if (modeCfg.highlightFormatting) state.formatting = "code-block";
232 state.code = true;
256 state.code = true;
233 var returnType = getType(state);
257 var returnType = getType(state);
234 state.code = false;
258 state.code = false;
235 return returnType;
259 return returnType;
236 }
260 }
237
261
238 // Inline
262 // Inline
239 function getType(state) {
263 function getType(state) {
240 var styles = [];
264 var styles = [];
241
265
242 if (state.formatting) {
266 if (state.formatting) {
243 styles.push(formatting);
267 styles.push(tokenTypes.formatting);
244
268
245 if (typeof state.formatting === "string") state.formatting = [state.formatting];
269 if (typeof state.formatting === "string") state.formatting = [state.formatting];
246
270
247 for (var i = 0; i < state.formatting.length; i++) {
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 if (state.formatting[i] === "header") {
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 // Add `formatting-quote` and `formatting-quote-#` for blockquotes
278 // Add `formatting-quote` and `formatting-quote-#` for blockquotes
255 // Add `error` instead if the maximum blockquote nesting depth is passed
279 // Add `error` instead if the maximum blockquote nesting depth is passed
256 if (state.formatting[i] === "quote") {
280 if (state.formatting[i] === "quote") {
257 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
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 } else {
283 } else {
260 styles.push("error");
284 styles.push("error");
261 }
285 }
262 }
286 }
263 }
287 }
264 }
288 }
265
289
266 if (state.taskOpen) {
290 if (state.taskOpen) {
267 styles.push("meta");
291 styles.push("meta");
268 return styles.length ? styles.join(' ') : null;
292 return styles.length ? styles.join(' ') : null;
269 }
293 }
270 if (state.taskClosed) {
294 if (state.taskClosed) {
271 styles.push("property");
295 styles.push("property");
272 return styles.length ? styles.join(' ') : null;
296 return styles.length ? styles.join(' ') : null;
273 }
297 }
274
298
275 if (state.linkHref) {
299 if (state.linkHref) {
276 styles.push(linkhref, "url");
300 styles.push(tokenTypes.linkHref, "url");
277 } else { // Only apply inline styles to non-url text
301 } else { // Only apply inline styles to non-url text
278 if (state.strong) { styles.push(strong); }
302 if (state.strong) { styles.push(tokenTypes.strong); }
279 if (state.em) { styles.push(em); }
303 if (state.em) { styles.push(tokenTypes.em); }
280 if (state.strikethrough) { styles.push(strikethrough); }
304 if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
281
305 if (state.linkText) { styles.push(tokenTypes.linkText); }
282 if (state.linkText) { styles.push(linktext); }
306 if (state.code) { styles.push(tokenTypes.code); }
283
284 if (state.code) { styles.push(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 if (state.quote) {
311 if (state.quote) {
290 styles.push(quote);
312 styles.push(tokenTypes.quote);
291
313
292 // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
314 // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
293 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
315 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
294 styles.push(quote + "-" + state.quote);
316 styles.push(tokenTypes.quote + "-" + state.quote);
295 } else {
317 } else {
296 styles.push(quote + "-" + modeCfg.maxBlockquoteDepth);
318 styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth);
297 }
319 }
298 }
320 }
299
321
300 if (state.list !== false) {
322 if (state.list !== false) {
301 var listMod = (state.listDepth - 1) % 3;
323 var listMod = (state.listDepth - 1) % 3;
302 if (!listMod) {
324 if (!listMod) {
303 styles.push(list1);
325 styles.push(tokenTypes.list1);
304 } else if (listMod === 1) {
326 } else if (listMod === 1) {
305 styles.push(list2);
327 styles.push(tokenTypes.list2);
306 } else {
328 } else {
307 styles.push(list3);
329 styles.push(tokenTypes.list3);
308 }
330 }
309 }
331 }
310
332
311 if (state.trailingSpaceNewLine) {
333 if (state.trailingSpaceNewLine) {
312 styles.push("trailing-space-new-line");
334 styles.push("trailing-space-new-line");
313 } else if (state.trailingSpace) {
335 } else if (state.trailingSpace) {
314 styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
336 styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
315 }
337 }
316
338
317 return styles.length ? styles.join(' ') : null;
339 return styles.length ? styles.join(' ') : null;
318 }
340 }
319
341
320 function handleText(stream, state) {
342 function handleText(stream, state) {
321 if (stream.match(textRE, true)) {
343 if (stream.match(textRE, true)) {
322 return getType(state);
344 return getType(state);
323 }
345 }
324 return undefined;
346 return undefined;
325 }
347 }
326
348
327 function inlineNormal(stream, state) {
349 function inlineNormal(stream, state) {
328 var style = state.text(stream, state);
350 var style = state.text(stream, state);
329 if (typeof style !== 'undefined')
351 if (typeof style !== 'undefined')
330 return style;
352 return style;
331
353
332 if (state.list) { // List marker (*, +, -, 1., etc)
354 if (state.list) { // List marker (*, +, -, 1., etc)
333 state.list = null;
355 state.list = null;
334 return getType(state);
356 return getType(state);
335 }
357 }
336
358
337 if (state.taskList) {
359 if (state.taskList) {
338 var taskOpen = stream.match(taskListRE, true)[1] !== "x";
360 var taskOpen = stream.match(taskListRE, true)[1] !== "x";
339 if (taskOpen) state.taskOpen = true;
361 if (taskOpen) state.taskOpen = true;
340 else state.taskClosed = true;
362 else state.taskClosed = true;
341 if (modeCfg.highlightFormatting) state.formatting = "task";
363 if (modeCfg.highlightFormatting) state.formatting = "task";
342 state.taskList = false;
364 state.taskList = false;
343 return getType(state);
365 return getType(state);
344 }
366 }
345
367
346 state.taskOpen = false;
368 state.taskOpen = false;
347 state.taskClosed = false;
369 state.taskClosed = false;
348
370
349 if (state.header && stream.match(/^#+$/, true)) {
371 if (state.header && stream.match(/^#+$/, true)) {
350 if (modeCfg.highlightFormatting) state.formatting = "header";
372 if (modeCfg.highlightFormatting) state.formatting = "header";
351 return getType(state);
373 return getType(state);
352 }
374 }
353
375
354 // Get sol() value now, before character is consumed
376 // Get sol() value now, before character is consumed
355 var sol = stream.sol();
377 var sol = stream.sol();
356
378
357 var ch = stream.next();
379 var ch = stream.next();
358
380
359 if (ch === '\\') {
381 if (ch === '\\') {
360 stream.next();
382 stream.next();
361 if (modeCfg.highlightFormatting) {
383 if (modeCfg.highlightFormatting) {
362 var type = getType(state);
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 // Matches link titles present on next line
390 // Matches link titles present on next line
368 if (state.linkTitle) {
391 if (state.linkTitle) {
369 state.linkTitle = false;
392 state.linkTitle = false;
370 var matchCh = ch;
393 var matchCh = ch;
371 if (ch === '(') {
394 if (ch === '(') {
372 matchCh = ')';
395 matchCh = ')';
373 }
396 }
374 matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
397 matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
375 var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
398 var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
376 if (stream.match(new RegExp(regex), true)) {
399 if (stream.match(new RegExp(regex), true)) {
377 return linkhref;
400 return tokenTypes.linkHref;
378 }
401 }
379 }
402 }
380
403
381 // If this block is changed, it may need to be updated in GFM mode
404 // If this block is changed, it may need to be updated in GFM mode
382 if (ch === '`') {
405 if (ch === '`') {
383 var previousFormatting = state.formatting;
406 var previousFormatting = state.formatting;
384 if (modeCfg.highlightFormatting) state.formatting = "code";
407 if (modeCfg.highlightFormatting) state.formatting = "code";
385 var t = getType(state);
408 var t = getType(state);
386 var before = stream.pos;
409 var before = stream.pos;
387 stream.eatWhile('`');
410 stream.eatWhile('`');
388 var difference = 1 + stream.pos - before;
411 var difference = 1 + stream.pos - before;
389 if (!state.code) {
412 if (!state.code) {
390 codeDepth = difference;
413 codeDepth = difference;
391 state.code = true;
414 state.code = true;
392 return getType(state);
415 return getType(state);
393 } else {
416 } else {
394 if (difference === codeDepth) { // Must be exact
417 if (difference === codeDepth) { // Must be exact
395 state.code = false;
418 state.code = false;
396 return t;
419 return t;
397 }
420 }
398 state.formatting = previousFormatting;
421 state.formatting = previousFormatting;
399 return getType(state);
422 return getType(state);
400 }
423 }
401 } else if (state.code) {
424 } else if (state.code) {
402 return getType(state);
425 return getType(state);
403 }
426 }
404
427
405 if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
428 if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
406 stream.match(/\[[^\]]*\]/);
429 stream.match(/\[[^\]]*\]/);
407 state.inline = state.f = linkHref;
430 state.inline = state.f = linkHref;
408 return image;
431 return tokenTypes.image;
409 }
432 }
410
433
411 if (ch === '[' && stream.match(/.*\](\(.*\)| ?\[.*\])/, false)) {
434 if (ch === '[' && stream.match(/.*\](\(.*\)| ?\[.*\])/, false)) {
412 state.linkText = true;
435 state.linkText = true;
413 if (modeCfg.highlightFormatting) state.formatting = "link";
436 if (modeCfg.highlightFormatting) state.formatting = "link";
414 return getType(state);
437 return getType(state);
415 }
438 }
416
439
417 if (ch === ']' && state.linkText && stream.match(/\(.*\)| ?\[.*\]/, false)) {
440 if (ch === ']' && state.linkText && stream.match(/\(.*\)| ?\[.*\]/, false)) {
418 if (modeCfg.highlightFormatting) state.formatting = "link";
441 if (modeCfg.highlightFormatting) state.formatting = "link";
419 var type = getType(state);
442 var type = getType(state);
420 state.linkText = false;
443 state.linkText = false;
421 state.inline = state.f = linkHref;
444 state.inline = state.f = linkHref;
422 return type;
445 return type;
423 }
446 }
424
447
425 if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
448 if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
426 state.f = state.inline = linkInline;
449 state.f = state.inline = linkInline;
427 if (modeCfg.highlightFormatting) state.formatting = "link";
450 if (modeCfg.highlightFormatting) state.formatting = "link";
428 var type = getType(state);
451 var type = getType(state);
429 if (type){
452 if (type){
430 type += " ";
453 type += " ";
431 } else {
454 } else {
432 type = "";
455 type = "";
433 }
456 }
434 return type + linkinline;
457 return type + tokenTypes.linkInline;
435 }
458 }
436
459
437 if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
460 if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
438 state.f = state.inline = linkInline;
461 state.f = state.inline = linkInline;
439 if (modeCfg.highlightFormatting) state.formatting = "link";
462 if (modeCfg.highlightFormatting) state.formatting = "link";
440 var type = getType(state);
463 var type = getType(state);
441 if (type){
464 if (type){
442 type += " ";
465 type += " ";
443 } else {
466 } else {
444 type = "";
467 type = "";
445 }
468 }
446 return type + linkemail;
469 return type + tokenTypes.linkEmail;
447 }
470 }
448
471
449 if (ch === '<' && stream.match(/^\w/, false)) {
472 if (ch === '<' && stream.match(/^(!--|\w)/, false)) {
450 if (stream.string.indexOf(">") != -1) {
473 var end = stream.string.indexOf(">", stream.pos);
451 var atts = stream.string.substring(1,stream.string.indexOf(">"));
474 if (end != -1) {
452 if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) {
475 var atts = stream.string.substring(stream.start, end);
453 state.md_inside = true;
476 if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true;
454 }
455 }
477 }
456 stream.backUp(1);
478 stream.backUp(1);
457 state.htmlState = CodeMirror.startState(htmlMode);
479 state.htmlState = CodeMirror.startState(htmlMode);
458 return switchBlock(stream, state, htmlBlock);
480 return switchBlock(stream, state, htmlBlock);
459 }
481 }
460
482
461 if (ch === '<' && stream.match(/^\/\w*?>/)) {
483 if (ch === '<' && stream.match(/^\/\w*?>/)) {
462 state.md_inside = false;
484 state.md_inside = false;
463 return "tag";
485 return "tag";
464 }
486 }
465
487
466 var ignoreUnderscore = false;
488 var ignoreUnderscore = false;
467 if (!modeCfg.underscoresBreakWords) {
489 if (!modeCfg.underscoresBreakWords) {
468 if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
490 if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
469 var prevPos = stream.pos - 2;
491 var prevPos = stream.pos - 2;
470 if (prevPos >= 0) {
492 if (prevPos >= 0) {
471 var prevCh = stream.string.charAt(prevPos);
493 var prevCh = stream.string.charAt(prevPos);
472 if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
494 if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
473 ignoreUnderscore = true;
495 ignoreUnderscore = true;
474 }
496 }
475 }
497 }
476 }
498 }
477 }
499 }
478 if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
500 if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
479 if (sol && stream.peek() === ' ') {
501 if (sol && stream.peek() === ' ') {
480 // Do nothing, surrounded by newline and space
502 // Do nothing, surrounded by newline and space
481 } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
503 } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
482 if (modeCfg.highlightFormatting) state.formatting = "strong";
504 if (modeCfg.highlightFormatting) state.formatting = "strong";
483 var t = getType(state);
505 var t = getType(state);
484 state.strong = false;
506 state.strong = false;
485 return t;
507 return t;
486 } else if (!state.strong && stream.eat(ch)) { // Add STRONG
508 } else if (!state.strong && stream.eat(ch)) { // Add STRONG
487 state.strong = ch;
509 state.strong = ch;
488 if (modeCfg.highlightFormatting) state.formatting = "strong";
510 if (modeCfg.highlightFormatting) state.formatting = "strong";
489 return getType(state);
511 return getType(state);
490 } else if (state.em === ch) { // Remove EM
512 } else if (state.em === ch) { // Remove EM
491 if (modeCfg.highlightFormatting) state.formatting = "em";
513 if (modeCfg.highlightFormatting) state.formatting = "em";
492 var t = getType(state);
514 var t = getType(state);
493 state.em = false;
515 state.em = false;
494 return t;
516 return t;
495 } else if (!state.em) { // Add EM
517 } else if (!state.em) { // Add EM
496 state.em = ch;
518 state.em = ch;
497 if (modeCfg.highlightFormatting) state.formatting = "em";
519 if (modeCfg.highlightFormatting) state.formatting = "em";
498 return getType(state);
520 return getType(state);
499 }
521 }
500 } else if (ch === ' ') {
522 } else if (ch === ' ') {
501 if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
523 if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
502 if (stream.peek() === ' ') { // Surrounded by spaces, ignore
524 if (stream.peek() === ' ') { // Surrounded by spaces, ignore
503 return getType(state);
525 return getType(state);
504 } else { // Not surrounded by spaces, back up pointer
526 } else { // Not surrounded by spaces, back up pointer
505 stream.backUp(1);
527 stream.backUp(1);
506 }
528 }
507 }
529 }
508 }
530 }
509
531
510 if (modeCfg.strikethrough) {
532 if (modeCfg.strikethrough) {
511 if (ch === '~' && stream.eatWhile(ch)) {
533 if (ch === '~' && stream.eatWhile(ch)) {
512 if (state.strikethrough) {// Remove strikethrough
534 if (state.strikethrough) {// Remove strikethrough
513 if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
535 if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
514 var t = getType(state);
536 var t = getType(state);
515 state.strikethrough = false;
537 state.strikethrough = false;
516 return t;
538 return t;
517 } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough
539 } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough
518 state.strikethrough = true;
540 state.strikethrough = true;
519 if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
541 if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
520 return getType(state);
542 return getType(state);
521 }
543 }
522 } else if (ch === ' ') {
544 } else if (ch === ' ') {
523 if (stream.match(/^~~/, true)) { // Probably surrounded by space
545 if (stream.match(/^~~/, true)) { // Probably surrounded by space
524 if (stream.peek() === ' ') { // Surrounded by spaces, ignore
546 if (stream.peek() === ' ') { // Surrounded by spaces, ignore
525 return getType(state);
547 return getType(state);
526 } else { // Not surrounded by spaces, back up pointer
548 } else { // Not surrounded by spaces, back up pointer
527 stream.backUp(2);
549 stream.backUp(2);
528 }
550 }
529 }
551 }
530 }
552 }
531 }
553 }
532
554
533 if (ch === ' ') {
555 if (ch === ' ') {
534 if (stream.match(/ +$/, false)) {
556 if (stream.match(/ +$/, false)) {
535 state.trailingSpace++;
557 state.trailingSpace++;
536 } else if (state.trailingSpace) {
558 } else if (state.trailingSpace) {
537 state.trailingSpaceNewLine = true;
559 state.trailingSpaceNewLine = true;
538 }
560 }
539 }
561 }
540
562
541 return getType(state);
563 return getType(state);
542 }
564 }
543
565
544 function linkInline(stream, state) {
566 function linkInline(stream, state) {
545 var ch = stream.next();
567 var ch = stream.next();
546
568
547 if (ch === ">") {
569 if (ch === ">") {
548 state.f = state.inline = inlineNormal;
570 state.f = state.inline = inlineNormal;
549 if (modeCfg.highlightFormatting) state.formatting = "link";
571 if (modeCfg.highlightFormatting) state.formatting = "link";
550 var type = getType(state);
572 var type = getType(state);
551 if (type){
573 if (type){
552 type += " ";
574 type += " ";
553 } else {
575 } else {
554 type = "";
576 type = "";
555 }
577 }
556 return type + linkinline;
578 return type + tokenTypes.linkInline;
557 }
579 }
558
580
559 stream.match(/^[^>]+/, true);
581 stream.match(/^[^>]+/, true);
560
582
561 return linkinline;
583 return tokenTypes.linkInline;
562 }
584 }
563
585
564 function linkHref(stream, state) {
586 function linkHref(stream, state) {
565 // Check if space, and return NULL if so (to avoid marking the space)
587 // Check if space, and return NULL if so (to avoid marking the space)
566 if(stream.eatSpace()){
588 if(stream.eatSpace()){
567 return null;
589 return null;
568 }
590 }
569 var ch = stream.next();
591 var ch = stream.next();
570 if (ch === '(' || ch === '[') {
592 if (ch === '(' || ch === '[') {
571 state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
593 state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
572 if (modeCfg.highlightFormatting) state.formatting = "link-string";
594 if (modeCfg.highlightFormatting) state.formatting = "link-string";
573 state.linkHref = true;
595 state.linkHref = true;
574 return getType(state);
596 return getType(state);
575 }
597 }
576 return 'error';
598 return 'error';
577 }
599 }
578
600
579 function getLinkHrefInside(endChar) {
601 function getLinkHrefInside(endChar) {
580 return function(stream, state) {
602 return function(stream, state) {
581 var ch = stream.next();
603 var ch = stream.next();
582
604
583 if (ch === endChar) {
605 if (ch === endChar) {
584 state.f = state.inline = inlineNormal;
606 state.f = state.inline = inlineNormal;
585 if (modeCfg.highlightFormatting) state.formatting = "link-string";
607 if (modeCfg.highlightFormatting) state.formatting = "link-string";
586 var returnState = getType(state);
608 var returnState = getType(state);
587 state.linkHref = false;
609 state.linkHref = false;
588 return returnState;
610 return returnState;
589 }
611 }
590
612
591 if (stream.match(inlineRE(endChar), true)) {
613 if (stream.match(inlineRE(endChar), true)) {
592 stream.backUp(1);
614 stream.backUp(1);
593 }
615 }
594
616
595 state.linkHref = true;
617 state.linkHref = true;
596 return getType(state);
618 return getType(state);
597 };
619 };
598 }
620 }
599
621
600 function footnoteLink(stream, state) {
622 function footnoteLink(stream, state) {
601 if (stream.match(/^[^\]]*\]:/, false)) {
623 if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) {
602 state.f = footnoteLinkInside;
624 state.f = footnoteLinkInside;
603 stream.next(); // Consume [
625 stream.next(); // Consume [
604 if (modeCfg.highlightFormatting) state.formatting = "link";
626 if (modeCfg.highlightFormatting) state.formatting = "link";
605 state.linkText = true;
627 state.linkText = true;
606 return getType(state);
628 return getType(state);
607 }
629 }
608 return switchInline(stream, state, inlineNormal);
630 return switchInline(stream, state, inlineNormal);
609 }
631 }
610
632
611 function footnoteLinkInside(stream, state) {
633 function footnoteLinkInside(stream, state) {
612 if (stream.match(/^\]:/, true)) {
634 if (stream.match(/^\]:/, true)) {
613 state.f = state.inline = footnoteUrl;
635 state.f = state.inline = footnoteUrl;
614 if (modeCfg.highlightFormatting) state.formatting = "link";
636 if (modeCfg.highlightFormatting) state.formatting = "link";
615 var returnType = getType(state);
637 var returnType = getType(state);
616 state.linkText = false;
638 state.linkText = false;
617 return returnType;
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 function footnoteUrl(stream, state) {
647 function footnoteUrl(stream, state) {
626 // Check if space, and return NULL if so (to avoid marking the space)
648 // Check if space, and return NULL if so (to avoid marking the space)
627 if(stream.eatSpace()){
649 if(stream.eatSpace()){
628 return null;
650 return null;
629 }
651 }
630 // Match URL
652 // Match URL
631 stream.match(/^[^\s]+/, true);
653 stream.match(/^[^\s]+/, true);
632 // Check for link title
654 // Check for link title
633 if (stream.peek() === undefined) { // End of line, set flag to check next line
655 if (stream.peek() === undefined) { // End of line, set flag to check next line
634 state.linkTitle = true;
656 state.linkTitle = true;
635 } else { // More content on line, check if link title
657 } else { // More content on line, check if link title
636 stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
658 stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
637 }
659 }
638 state.f = state.inline = inlineNormal;
660 state.f = state.inline = inlineNormal;
639 return linkhref + " url";
661 return tokenTypes.linkHref + " url";
640 }
662 }
641
663
642 var savedInlineRE = [];
664 var savedInlineRE = [];
643 function inlineRE(endChar) {
665 function inlineRE(endChar) {
644 if (!savedInlineRE[endChar]) {
666 if (!savedInlineRE[endChar]) {
645 // Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741)
667 // Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741)
646 endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
668 endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
647 // Match any non-endChar, escaped character, as well as the closing
669 // Match any non-endChar, escaped character, as well as the closing
648 // endChar.
670 // endChar.
649 savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')');
671 savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')');
650 }
672 }
651 return savedInlineRE[endChar];
673 return savedInlineRE[endChar];
652 }
674 }
653
675
654 var mode = {
676 var mode = {
655 startState: function() {
677 startState: function() {
656 return {
678 return {
657 f: blockNormal,
679 f: blockNormal,
658
680
659 prevLineHasContent: false,
681 prevLine: null,
660 thisLineHasContent: false,
682 thisLine: null,
661
683
662 block: blockNormal,
684 block: blockNormal,
663 htmlState: null,
685 htmlState: null,
664 indentation: 0,
686 indentation: 0,
665
687
666 inline: inlineNormal,
688 inline: inlineNormal,
667 text: handleText,
689 text: handleText,
668
690
669 formatting: false,
691 formatting: false,
670 linkText: false,
692 linkText: false,
671 linkHref: false,
693 linkHref: false,
672 linkTitle: false,
694 linkTitle: false,
673 em: false,
695 em: false,
674 strong: false,
696 strong: false,
675 header: 0,
697 header: 0,
676 hr: false,
698 hr: false,
677 taskList: false,
699 taskList: false,
678 list: false,
700 list: false,
679 listDepth: 0,
701 listDepth: 0,
680 quote: 0,
702 quote: 0,
681 trailingSpace: 0,
703 trailingSpace: 0,
682 trailingSpaceNewLine: false,
704 trailingSpaceNewLine: false,
683 strikethrough: false
705 strikethrough: false,
706 fencedChars: null
684 };
707 };
685 },
708 },
686
709
687 copyState: function(s) {
710 copyState: function(s) {
688 return {
711 return {
689 f: s.f,
712 f: s.f,
690
713
691 prevLineHasContent: s.prevLineHasContent,
714 prevLine: s.prevLine,
692 thisLineHasContent: s.thisLineHasContent,
715 thisLine: s.thisLine,
693
716
694 block: s.block,
717 block: s.block,
695 htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
718 htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
696 indentation: s.indentation,
719 indentation: s.indentation,
697
720
698 localMode: s.localMode,
721 localMode: s.localMode,
699 localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
722 localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
700
723
701 inline: s.inline,
724 inline: s.inline,
702 text: s.text,
725 text: s.text,
703 formatting: false,
726 formatting: false,
704 linkTitle: s.linkTitle,
727 linkTitle: s.linkTitle,
728 code: s.code,
705 em: s.em,
729 em: s.em,
706 strong: s.strong,
730 strong: s.strong,
707 strikethrough: s.strikethrough,
731 strikethrough: s.strikethrough,
708 header: s.header,
732 header: s.header,
709 hr: s.hr,
733 hr: s.hr,
710 taskList: s.taskList,
734 taskList: s.taskList,
711 list: s.list,
735 list: s.list,
712 listDepth: s.listDepth,
736 listDepth: s.listDepth,
713 quote: s.quote,
737 quote: s.quote,
714 indentedCode: s.indentedCode,
738 indentedCode: s.indentedCode,
715 trailingSpace: s.trailingSpace,
739 trailingSpace: s.trailingSpace,
716 trailingSpaceNewLine: s.trailingSpaceNewLine,
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 token: function(stream, state) {
746 token: function(stream, state) {
722
747
723 // Reset state.formatting
748 // Reset state.formatting
724 state.formatting = false;
749 state.formatting = false;
725
750
726 if (stream.sol()) {
751 if (stream != state.thisLine) {
727 var forceBlankLine = !!state.header || state.hr;
752 var forceBlankLine = state.header || state.hr;
728
753
729 // Reset state.header and state.hr
754 // Reset state.header and state.hr
730 state.header = 0;
755 state.header = 0;
731 state.hr = false;
756 state.hr = false;
732
757
733 if (stream.match(/^\s*$/, true) || forceBlankLine) {
758 if (stream.match(/^\s*$/, true) || forceBlankLine) {
734 state.prevLineHasContent = false;
735 blankLine(state);
759 blankLine(state);
736 return forceBlankLine ? this.token(stream, state) : null;
760 if (!forceBlankLine) return null
737 } else {
761 state.prevLine = null
738 state.prevLineHasContent = state.thisLineHasContent;
739 state.thisLineHasContent = true;
740 }
762 }
741
763
764 state.prevLine = state.thisLine
765 state.thisLine = stream
766
742 // Reset state.taskList
767 // Reset state.taskList
743 state.taskList = false;
768 state.taskList = false;
744
769
745 // Reset state.code
746 state.code = false;
747
748 // Reset state.trailingSpace
770 // Reset state.trailingSpace
749 state.trailingSpace = 0;
771 state.trailingSpace = 0;
750 state.trailingSpaceNewLine = false;
772 state.trailingSpaceNewLine = false;
751
773
752 state.f = state.block;
774 state.f = state.block;
753 var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
775 var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
754 var difference = Math.floor((indentation - state.indentation) / 4) * 4;
776 var difference = Math.floor((indentation - state.indentation) / 4) * 4;
755 if (difference > 4) difference = 4;
777 if (difference > 4) difference = 4;
756 var adjustedIndentation = state.indentation + difference;
778 var adjustedIndentation = state.indentation + difference;
757 state.indentationDiff = adjustedIndentation - state.indentation;
779 state.indentationDiff = adjustedIndentation - state.indentation;
758 state.indentation = adjustedIndentation;
780 state.indentation = adjustedIndentation;
759 if (indentation > 0) return null;
781 if (indentation > 0) return null;
760 }
782 }
761 return state.f(stream, state);
783 return state.f(stream, state);
762 },
784 },
763
785
764 innerMode: function(state) {
786 innerMode: function(state) {
765 if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
787 if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
766 if (state.localState) return {state: state.localState, mode: state.localMode};
788 if (state.localState) return {state: state.localState, mode: state.localMode};
767 return {state: state, mode: mode};
789 return {state: state, mode: mode};
768 },
790 },
769
791
770 blankLine: blankLine,
792 blankLine: blankLine,
771
793
772 getType: getType,
794 getType: getType,
773
795
774 fold: "markdown"
796 fold: "markdown"
775 };
797 };
776 return mode;
798 return mode;
777 }, "xml");
799 }, "xml");
778
800
779 CodeMirror.defineMIME("text/x-markdown", "markdown");
801 CodeMirror.defineMIME("text/x-markdown", "markdown");
780
802
781 });
803 });
@@ -1,188 +1,201 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../lib/codemirror"));
6 mod(require("../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../lib/codemirror"], mod);
8 define(["../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.modeInfo = [
14 CodeMirror.modeInfo = [
15 {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]},
15 {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]},
16 {name: "PGP", mimes: ["application/pgp", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["pgp"]},
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 {name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i},
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 {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h"]},
20 {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h"]},
20 {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]},
21 {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]},
21 {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]},
22 {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]},
22 {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp"]},
23 {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp"]},
23 {name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj"]},
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 {name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/},
27 {name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/},
25 {name: "CoffeeScript", mime: "text/x-coffeescript", mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]},
28 {name: "CoffeeScript", mime: "text/x-coffeescript", mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]},
26 {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]},
29 {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]},
27 {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]},
30 {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]},
28 {name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]},
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 {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]},
33 {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]},
30 {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]},
34 {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]},
31 {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]},
35 {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]},
32 {name: "Dart", mimes: ["application/dart", "text/x-dart"], mode: "dart", ext: ["dart"]},
36 {name: "Dart", mimes: ["application/dart", "text/x-dart"], mode: "dart", ext: ["dart"]},
33 {name: "diff", mime: "text/x-diff", mode: "diff", ext: ["diff", "patch"]},
37 {name: "diff", mime: "text/x-diff", mode: "diff", ext: ["diff", "patch"]},
34 {name: "Django", mime: "text/x-django", mode: "django"},
38 {name: "Django", mime: "text/x-django", mode: "django"},
35 {name: "Dockerfile", mime: "text/x-dockerfile", mode: "dockerfile", file: /^Dockerfile$/},
39 {name: "Dockerfile", mime: "text/x-dockerfile", mode: "dockerfile", file: /^Dockerfile$/},
36 {name: "DTD", mime: "application/xml-dtd", mode: "dtd", ext: ["dtd"]},
40 {name: "DTD", mime: "application/xml-dtd", mode: "dtd", ext: ["dtd"]},
37 {name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]},
41 {name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]},
38 {name: "EBNF", mime: "text/x-ebnf", mode: "ebnf"},
42 {name: "EBNF", mime: "text/x-ebnf", mode: "ebnf"},
39 {name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]},
43 {name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]},
40 {name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]},
44 {name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]},
41 {name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]},
45 {name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]},
42 {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]},
46 {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]},
43 {name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]},
47 {name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]},
44 {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]},
48 {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]},
45 {name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]},
49 {name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]},
46 {name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]},
50 {name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]},
47 {name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90"]},
51 {name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90"]},
48 {name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]},
52 {name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]},
49 {name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]},
53 {name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]},
50 {name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]},
54 {name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]},
51 {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history).md$/i},
55 {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history).md$/i},
52 {name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]},
56 {name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]},
53 {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy"]},
57 {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy"]},
54 {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]},
58 {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]},
55 {name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]},
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 {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]},
61 {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]},
57 {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]},
62 {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]},
58 {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]},
63 {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]},
59 {name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm"], alias: ["xhtml"]},
64 {name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm"], alias: ["xhtml"]},
60 {name: "HTTP", mime: "message/http", mode: "http"},
65 {name: "HTTP", mime: "message/http", mode: "http"},
61 {name: "IDL", mime: "text/x-idl", mode: "idl", ext: ["pro"]},
66 {name: "IDL", mime: "text/x-idl", mode: "idl", ext: ["pro"]},
62 {name: "Jade", mime: "text/x-jade", mode: "jade", ext: ["jade"]},
67 {name: "Jade", mime: "text/x-jade", mode: "jade", ext: ["jade"]},
63 {name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]},
68 {name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]},
64 {name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"], alias: ["jsp"]},
69 {name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"], alias: ["jsp"]},
65 {name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"],
70 {name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"],
66 mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]},
71 mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]},
67 {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]},
72 {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]},
68 {name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]},
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 {name: "Jinja2", mime: "null", mode: "jinja2"},
75 {name: "Jinja2", mime: "null", mode: "jinja2"},
70 {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]},
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 {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]},
78 {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]},
73 {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]},
79 {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]},
74 {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]},
80 {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]},
75 {name: "Markdown", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]},
81 {name: "Markdown", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]},
76 {name: "mIRC", mime: "text/mirc", mode: "mirc"},
82 {name: "mIRC", mime: "text/mirc", mode: "mirc"},
77 {name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"},
83 {name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"},
78 {name: "Mathematica", mime: "text/x-mathematica", mode: "mathematica", ext: ["m", "nb"]},
84 {name: "Mathematica", mime: "text/x-mathematica", mode: "mathematica", ext: ["m", "nb"]},
79 {name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]},
85 {name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]},
80 {name: "MUMPS", mime: "text/x-mumps", mode: "mumps"},
86 {name: "MUMPS", mime: "text/x-mumps", mode: "mumps"},
81 {name: "MS SQL", mime: "text/x-mssql", mode: "sql"},
87 {name: "MS SQL", mime: "text/x-mssql", mode: "sql"},
82 {name: "MySQL", mime: "text/x-mysql", mode: "sql"},
88 {name: "MySQL", mime: "text/x-mysql", mode: "sql"},
83 {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i},
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 {name: "NTriples", mime: "text/n-triples", mode: "ntriples", ext: ["nt"]},
91 {name: "NTriples", mime: "text/n-triples", mode: "ntriples", ext: ["nt"]},
85 {name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"]},
92 {name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"]},
86 {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]},
93 {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]},
87 {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]},
94 {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]},
95 {name: "Oz", mime: "text/x-oz", mode: "oz", ext: ["oz"]},
88 {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]},
96 {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]},
89 {name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]},
97 {name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]},
90 {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]},
98 {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]},
91 {name: "PHP", mime: "application/x-httpd-php", mode: "php", ext: ["php", "php3", "php4", "php5", "phtml"]},
99 {name: "PHP", mime: "application/x-httpd-php", mode: "php", ext: ["php", "php3", "php4", "php5", "phtml"]},
92 {name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]},
100 {name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]},
93 {name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]},
101 {name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]},
94 {name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]},
102 {name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]},
95 {name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"], alias: ["ini", "properties"]},
103 {name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"], alias: ["ini", "properties"]},
96 {name: "Python", mime: "text/x-python", mode: "python", ext: ["py", "pyw"]},
104 {name: "Python", mime: "text/x-python", mode: "python", ext: ["py", "pyw"]},
97 {name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]},
105 {name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]},
98 {name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]},
106 {name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]},
99 {name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r"], alias: ["rscript"]},
107 {name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r"], alias: ["rscript"]},
100 {name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"], alias: ["rst"]},
108 {name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"], alias: ["rst"]},
101 {name: "RPM Changes", mime: "text/x-rpm-changes", mode: "rpm"},
109 {name: "RPM Changes", mime: "text/x-rpm-changes", mode: "rpm"},
102 {name: "RPM Spec", mime: "text/x-rpm-spec", mode: "rpm", ext: ["spec"]},
110 {name: "RPM Spec", mime: "text/x-rpm-spec", mode: "rpm", ext: ["spec"]},
103 {name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"], alias: ["jruby", "macruby", "rake", "rb", "rbx"]},
111 {name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"], alias: ["jruby", "macruby", "rake", "rb", "rbx"]},
104 {name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]},
112 {name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]},
105 {name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]},
113 {name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]},
106 {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]},
114 {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]},
107 {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]},
115 {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]},
108 {name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]},
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 {name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]},
118 {name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]},
111 {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]},
119 {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]},
112 {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]},
120 {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]},
113 {name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]},
121 {name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]},
114 {name: "Solr", mime: "text/x-solr", mode: "solr"},
122 {name: "Solr", mime: "text/x-solr", mode: "solr"},
115 {name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]},
123 {name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]},
116 {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]},
124 {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]},
117 {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]},
125 {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]},
118 {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]},
126 {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]},
127 {name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]},
119 {name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]},
128 {name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]},
120 {name: "MariaDB", mime: "text/x-mariadb", mode: "sql"},
129 {name: "MariaDB", mime: "text/x-mariadb", mode: "sql"},
121 {name: "sTeX", mime: "text/x-stex", mode: "stex"},
130 {name: "sTeX", mime: "text/x-stex", mode: "stex"},
122 {name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx"], alias: ["tex"]},
131 {name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx"], alias: ["tex"]},
123 {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v"]},
132 {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v"]},
124 {name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]},
133 {name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]},
125 {name: "Textile", mime: "text/x-textile", mode: "textile", ext: ["textile"]},
134 {name: "Textile", mime: "text/x-textile", mode: "textile", ext: ["textile"]},
126 {name: "TiddlyWiki ", mime: "text/x-tiddlywiki", mode: "tiddlywiki"},
135 {name: "TiddlyWiki ", mime: "text/x-tiddlywiki", mode: "tiddlywiki"},
127 {name: "Tiki wiki", mime: "text/tiki", mode: "tiki"},
136 {name: "Tiki wiki", mime: "text/tiki", mode: "tiki"},
128 {name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]},
137 {name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]},
129 {name: "Tornado", mime: "text/x-tornado", mode: "tornado"},
138 {name: "Tornado", mime: "text/x-tornado", mode: "tornado"},
130 {name: "troff", mime: "troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]},
139 {name: "troff", mime: "troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]},
131 {name: "TTCN", mime: "text/x-ttcn", mode: "ttcn", ext: ["ttcn", "ttcn3", "ttcnpp"]},
140 {name: "TTCN", mime: "text/x-ttcn", mode: "ttcn", ext: ["ttcn", "ttcn3", "ttcnpp"]},
132 {name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]},
141 {name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]},
133 {name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]},
142 {name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]},
134 {name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]},
143 {name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]},
135 {name: "Twig", mime: "text/x-twig", mode: "twig"},
144 {name: "Twig", mime: "text/x-twig", mode: "twig"},
136 {name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]},
145 {name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]},
137 {name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]},
146 {name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]},
138 {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]},
147 {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]},
139 {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]},
148 {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]},
149 {name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]},
140 {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd"], alias: ["rss", "wsdl", "xsd"]},
150 {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd"], alias: ["rss", "wsdl", "xsd"]},
141 {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]},
151 {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]},
142 {name: "YAML", mime: "text/x-yaml", mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]},
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 // Ensure all modes have a mime property for backwards compatibility
158 // Ensure all modes have a mime property for backwards compatibility
146 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
159 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
147 var info = CodeMirror.modeInfo[i];
160 var info = CodeMirror.modeInfo[i];
148 if (info.mimes) info.mime = info.mimes[0];
161 if (info.mimes) info.mime = info.mimes[0];
149 }
162 }
150
163
151 CodeMirror.findModeByMIME = function(mime) {
164 CodeMirror.findModeByMIME = function(mime) {
152 mime = mime.toLowerCase();
165 mime = mime.toLowerCase();
153 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
166 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
154 var info = CodeMirror.modeInfo[i];
167 var info = CodeMirror.modeInfo[i];
155 if (info.mime == mime) return info;
168 if (info.mime == mime) return info;
156 if (info.mimes) for (var j = 0; j < info.mimes.length; j++)
169 if (info.mimes) for (var j = 0; j < info.mimes.length; j++)
157 if (info.mimes[j] == mime) return info;
170 if (info.mimes[j] == mime) return info;
158 }
171 }
159 };
172 };
160
173
161 CodeMirror.findModeByExtension = function(ext) {
174 CodeMirror.findModeByExtension = function(ext) {
162 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
175 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
163 var info = CodeMirror.modeInfo[i];
176 var info = CodeMirror.modeInfo[i];
164 if (info.ext) for (var j = 0; j < info.ext.length; j++)
177 if (info.ext) for (var j = 0; j < info.ext.length; j++)
165 if (info.ext[j] == ext) return info;
178 if (info.ext[j] == ext) return info;
166 }
179 }
167 };
180 };
168
181
169 CodeMirror.findModeByFileName = function(filename) {
182 CodeMirror.findModeByFileName = function(filename) {
170 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
183 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
171 var info = CodeMirror.modeInfo[i];
184 var info = CodeMirror.modeInfo[i];
172 if (info.file && info.file.test(filename)) return info;
185 if (info.file && info.file.test(filename)) return info;
173 }
186 }
174 var dot = filename.lastIndexOf(".");
187 var dot = filename.lastIndexOf(".");
175 var ext = dot > -1 && filename.substring(dot + 1, filename.length);
188 var ext = dot > -1 && filename.substring(dot + 1, filename.length);
176 if (ext) return CodeMirror.findModeByExtension(ext);
189 if (ext) return CodeMirror.findModeByExtension(ext);
177 };
190 };
178
191
179 CodeMirror.findModeByName = function(name) {
192 CodeMirror.findModeByName = function(name) {
180 name = name.toLowerCase();
193 name = name.toLowerCase();
181 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
194 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
182 var info = CodeMirror.modeInfo[i];
195 var info = CodeMirror.modeInfo[i];
183 if (info.name.toLowerCase() == name) return info;
196 if (info.name.toLowerCase() == name) return info;
184 if (info.alias) for (var j = 0; j < info.alias.length; j++)
197 if (info.alias) for (var j = 0; j < info.alias.length; j++)
185 if (info.alias[j].toLowerCase() == name) return info;
198 if (info.alias[j].toLowerCase() == name) return info;
186 }
199 }
187 };
200 };
188 });
201 });
@@ -1,336 +1,336 b''
1 var _EMPTY_EXT = {'exts': [], 'mode': 'plain'};
1 var _EMPTY_EXT = {'exts': [], 'mode': 'plain'};
2
2
3 MIME_TO_EXT = {
3 MIME_TO_EXT = {
4 "application/json": {"exts": ["*.json","*.map"], "mode": "javascript"},
4 "application/json": {"exts": ["*.json","*.map"], "mode": "javascript"},
5 "application/postscript": {"exts": ["*.ps","*.eps"], "mode": ""},
5 "application/postscript": {"exts": ["*.ps","*.eps"], "mode": ""},
6 "application/sieve": {"exts": ["*.siv","*.sieve"], "mode": "sieve"},
6 "application/sieve": {"exts": ["*.siv","*.sieve"], "mode": "sieve"},
7 "application/typescript": {"exts": ["*.ts"], "mode": "javascript"},
7 "application/typescript": {"exts": ["*.ts"], "mode": "javascript"},
8 "application/x-actionscript": {"exts": ["*.as"], "mode": ""},
8 "application/x-actionscript": {"exts": ["*.as"], "mode": ""},
9 "application/x-actionscript3": {"exts": ["*.as"], "mode": ""},
9 "application/x-actionscript3": {"exts": ["*.as"], "mode": ""},
10 "application/x-aspx": {"exts": ["*.aspx"], "mode": "htmlembedded"},
10 "application/x-aspx": {"exts": ["*.aspx"], "mode": "htmlembedded"},
11 "application/x-awk": {"exts": ["*.awk"], "mode": ""},
11 "application/x-awk": {"exts": ["*.awk"], "mode": ""},
12 "application/x-befunge": {"exts": ["*.befunge"], "mode": ""},
12 "application/x-befunge": {"exts": ["*.befunge"], "mode": ""},
13 "application/x-brainfuck": {"exts": ["*.bf","*.b"], "mode": ""},
13 "application/x-brainfuck": {"exts": ["*.bf","*.b"], "mode": ""},
14 "application/x-cheetah": {"exts": ["*.tmpl","*.spt"], "mode": ""},
14 "application/x-cheetah": {"exts": ["*.tmpl","*.spt"], "mode": ""},
15 "application/x-coldfusion": {"exts": ["*.cfm","*.cfml","*.cfc"], "mode": ""},
15 "application/x-coldfusion": {"exts": ["*.cfm","*.cfml","*.cfc"], "mode": ""},
16 "application/x-csh": {"exts": ["*.tcsh","*.csh"], "mode": ""},
16 "application/x-csh": {"exts": ["*.tcsh","*.csh"], "mode": ""},
17 "application/x-dos-batch": {"exts": ["*.bat","*.cmd"], "mode": ""},
17 "application/x-dos-batch": {"exts": ["*.bat","*.cmd"], "mode": ""},
18 "application/x-ecl": {"exts": ["*.ecl"], "mode": ""},
18 "application/x-ecl": {"exts": ["*.ecl"], "mode": ""},
19 "application/x-ejs": {"exts": ["*.ejs"], "mode": "htmlembedded"},
19 "application/x-ejs": {"exts": ["*.ejs"], "mode": "htmlembedded"},
20 "application/x-evoque": {"exts": ["*.evoque"], "mode": ""},
20 "application/x-evoque": {"exts": ["*.evoque"], "mode": ""},
21 "application/x-fantom": {"exts": ["*.fan"], "mode": ""},
21 "application/x-fantom": {"exts": ["*.fan"], "mode": ""},
22 "application/x-genshi": {"exts": ["*.kid"], "mode": ""},
22 "application/x-genshi": {"exts": ["*.kid"], "mode": ""},
23 "application/x-gettext": {"exts": ["*.pot","*.po"], "mode": ""},
23 "application/x-gettext": {"exts": ["*.pot","*.po"], "mode": ""},
24 "application/x-json": {"exts": ["*.json"], "mode": ""},
24 "application/x-json": {"exts": ["*.json"], "mode": ""},
25 "application/x-jsp": {"exts": ["*.jsp"], "mode": "htmlembedded"},
25 "application/x-jsp": {"exts": ["*.jsp"], "mode": "htmlembedded"},
26 "application/x-mako": {"exts": ["*.mako"], "mode": ""},
26 "application/x-mako": {"exts": ["*.mako"], "mode": ""},
27 "application/x-mason": {"exts": ["*.m","*.mhtml","*.mc","*.mi","autohandler","dhandler"], "mode": ""},
27 "application/x-mason": {"exts": ["*.m","*.mhtml","*.mc","*.mi","autohandler","dhandler"], "mode": ""},
28 "application/x-myghty": {"exts": ["*.myt","autodelegate"], "mode": ""},
28 "application/x-myghty": {"exts": ["*.myt","autodelegate"], "mode": ""},
29 "application/x-php": {"exts": ["*.phtml"], "mode": ""},
29 "application/x-php": {"exts": ["*.phtml"], "mode": ""},
30 "application/x-pypylog": {"exts": ["*.pypylog"], "mode": ""},
30 "application/x-pypylog": {"exts": ["*.pypylog"], "mode": ""},
31 "application/x-qml": {"exts": ["*.qml"], "mode": ""},
31 "application/x-qml": {"exts": ["*.qml"], "mode": ""},
32 "application/x-sh-session": {"exts": ["*.shell-session"], "mode": ""},
32 "application/x-sh-session": {"exts": ["*.shell-session"], "mode": ""},
33 "application/x-shell-session": {"exts": ["*.sh-session"], "mode": ""},
33 "application/x-shell-session": {"exts": ["*.sh-session"], "mode": ""},
34 "application/x-smarty": {"exts": ["*.tpl"], "mode": ""},
34 "application/x-smarty": {"exts": ["*.tpl"], "mode": ""},
35 "application/x-sparql-query": {"exts": [], "mode": "sparql"},
35 "application/x-sparql-query": {"exts": [], "mode": "sparql"},
36 "application/x-ssp": {"exts": ["*.ssp"], "mode": ""},
36 "application/x-ssp": {"exts": ["*.ssp"], "mode": ""},
37 "application/x-troff": {"exts": ["*.[1234567]","*.man"], "mode": ""},
37 "application/x-troff": {"exts": ["*.[1234567]","*.man"], "mode": ""},
38 "application/x-urbiscript": {"exts": ["*.u"], "mode": ""},
38 "application/x-urbiscript": {"exts": ["*.u"], "mode": ""},
39 "application/xml": {"exts": ["*.xml","*.xsl","*.rss","*.xslt","*.xsd","*.wsdl"], "mode": "xml"},
39 "application/xml": {"exts": ["*.xml","*.xsl","*.rss","*.xslt","*.xsd","*.wsdl"], "mode": "xml"},
40 "application/xml+evoque": {"exts": ["*.xml"], "mode": ""},
40 "application/xml+evoque": {"exts": ["*.xml"], "mode": ""},
41 "application/xml-dtd": {"exts": ["*.dtd"], "mode": "dtd"},
41 "application/xml-dtd": {"exts": ["*.dtd"], "mode": "dtd"},
42 "application/xquery": {"exts": ["*.xqy","*.xquery","*.xq","*.xql","*.xqm","*.xy"], "mode": "xquery"},
42 "application/xquery": {"exts": ["*.xqy","*.xquery","*.xq","*.xql","*.xqm","*.xy"], "mode": "xquery"},
43 "application/xsl+xml": {"exts": ["*.xsl","*.xslt","*.xpl"], "mode": ""},
43 "application/xsl+xml": {"exts": ["*.xsl","*.xslt","*.xpl"], "mode": ""},
44 "jinja2": {"exts": [".jinja2"], "mode": "jinja2"},
44 "jinja2": {"exts": [".jinja2"], "mode": "jinja2"},
45 "message/http": {"exts": [], "mode": "http"},
45 "message/http": {"exts": [], "mode": "http"},
46 "text/S-plus": {"exts": ["*.S","*.R",".Rhistory",".Rprofile"], "mode": ""},
46 "text/S-plus": {"exts": ["*.S","*.R",".Rhistory",".Rprofile"], "mode": ""},
47 "text/apl": {"exts": ["*.dyalog","*.pgp","*.apl"], "mode": "apl"},
47 "text/apl": {"exts": ["*.dyalog","*.pgp","*.apl"], "mode": "apl"},
48 "text/coffeescript": {"exts": ["*.coffee"], "mode": ""},
48 "text/coffeescript": {"exts": ["*.coffee"], "mode": ""},
49 "text/css": {"exts": ["*.css"], "mode": "css"},
49 "text/css": {"exts": ["*.css"], "mode": "css"},
50 "text/haxe": {"exts": ["*.hx"], "mode": ""},
50 "text/haxe": {"exts": ["*.hx"], "mode": ""},
51 "text/html": {"exts": ["*.html","*.htm","*.xhtml","*.xslt"], "mode": "htmlmixed"},
51 "text/html": {"exts": ["*.html","*.htm","*.xhtml","*.xslt"], "mode": "htmlmixed"},
52 "text/html+evoque": {"exts": ["*.html"], "mode": ""},
52 "text/html+evoque": {"exts": ["*.html"], "mode": ""},
53 "text/html+ruby": {"exts": ["*.rhtml"], "mode": ""},
53 "text/html+ruby": {"exts": ["*.rhtml"], "mode": ""},
54 "text/idl": {"exts": ["*.pro"], "mode": ""},
54 "text/idl": {"exts": ["*.pro"], "mode": ""},
55 "text/javascript": {"exts": ["*.js"], "mode": "javascript"},
55 "text/javascript": {"exts": ["*.js"], "mode": "javascript"},
56 "text/livescript": {"exts": ["*.ls"], "mode": ""},
56 "text/livescript": {"exts": ["*.ls"], "mode": ""},
57 "text/matlab": {"exts": ["*.m"], "mode": ""},
57 "text/matlab": {"exts": ["*.m"], "mode": ""},
58 "text/mirc": {"exts": [], "mode": "mirc"},
58 "text/mirc": {"exts": [], "mode": "mirc"},
59 "text/n-triples": {"exts": ["*.nt"], "mode": "ntriples"},
59 "text/n-triples": {"exts": ["*.nt"], "mode": "ntriples"},
60 "text/octave": {"exts": ["*.m"], "mode": ""},
60 "text/octave": {"exts": ["*.m"], "mode": ""},
61 "text/plain": {"exts": ["*.txt","*.text","*.conf","*.def","*.list","*.log"], "mode": "null"},
61 "text/plain": {"exts": ["*.txt","*.text","*.conf","*.def","*.list","*.log"], "mode": "null"},
62 "text/scilab": {"exts": ["*.sci","*.sce","*.tst"], "mode": ""},
62 "text/scilab": {"exts": ["*.sci","*.sce","*.tst"], "mode": ""},
63 "text/smali": {"exts": ["*.smali"], "mode": ""},
63 "text/smali": {"exts": ["*.smali"], "mode": ""},
64 "text/tiki": {"exts": [], "mode": "tiki"},
64 "text/tiki": {"exts": [], "mode": "tiki"},
65 "text/vbscript": {"exts": ["*.vb","*.vbs"], "mode": "vbscript"},
65 "text/vbscript": {"exts": ["*.vb","*.vbs"], "mode": "vbscript"},
66 "text/velocity": {"exts": ["*.vtl"], "mode": "velocity"},
66 "text/velocity": {"exts": ["*.vtl"], "mode": "velocity"},
67 "text/x-abap": {"exts": ["*.abap"], "mode": ""},
67 "text/x-abap": {"exts": ["*.abap"], "mode": ""},
68 "text/x-ada": {"exts": ["*.adb","*.ads","*.ada"], "mode": ""},
68 "text/x-ada": {"exts": ["*.adb","*.ads","*.ada"], "mode": ""},
69 "text/x-apacheconf": {"exts": [".htaccess","apache.conf","apache2.conf"], "mode": ""},
69 "text/x-apacheconf": {"exts": [".htaccess","apache.conf","apache2.conf"], "mode": ""},
70 "text/x-aspectj": {"exts": ["*.aj"], "mode": ""},
70 "text/x-aspectj": {"exts": ["*.aj"], "mode": ""},
71 "text/x-asterisk": {"exts": [], "mode": "asterisk"},
71 "text/x-asterisk": {"exts": [], "mode": "asterisk"},
72 "text/x-asymptote": {"exts": ["*.asy"], "mode": ""},
72 "text/x-asymptote": {"exts": ["*.asy"], "mode": ""},
73 "text/x-autohotkey": {"exts": ["*.ahk","*.ahkl"], "mode": ""},
73 "text/x-autohotkey": {"exts": ["*.ahk","*.ahkl"], "mode": ""},
74 "text/x-autoit": {"exts": ["*.au3"], "mode": ""},
74 "text/x-autoit": {"exts": ["*.au3"], "mode": ""},
75 "text/x-bmx": {"exts": ["*.bmx"], "mode": ""},
75 "text/x-bmx": {"exts": ["*.bmx"], "mode": ""},
76 "text/x-boo": {"exts": ["*.boo"], "mode": ""},
76 "text/x-boo": {"exts": ["*.boo"], "mode": ""},
77 "text/x-c": {"exts": ["*.c"], "mode": "clike"},
77 "text/x-c": {"exts": ["*.c"], "mode": "clike"},
78 "text/x-c++hdr": {"exts": ["*.cpp","*.hpp","*.c++","*.h++","*.cc","*.hh","*.cxx","*.hxx","*.C","*.H","*.cp","*.CPP"], "mode": "clike"},
78 "text/x-c++hdr": {"exts": ["*.cpp","*.hpp","*.c++","*.h++","*.cc","*.hh","*.cxx","*.hxx","*.C","*.H","*.cp","*.CPP"], "mode": "clike"},
79 "text/x-c++src": {"exts": ["*.cpp","*.c++","*.cc","*.cxx","*.hpp","*.h++","*.hh","*.hxx"], "mode": "clike"},
79 "text/x-c++src": {"exts": ["*.cpp","*.c++","*.cc","*.cxx","*.hpp","*.h++","*.hh","*.hxx"], "mode": "clike"},
80 "text/x-c-objdump": {"exts": ["*.c-objdump"], "mode": ""},
80 "text/x-c-objdump": {"exts": ["*.c-objdump"], "mode": ""},
81 "text/x-ceylon": {"exts": ["*.ceylon"], "mode": ""},
81 "text/x-ceylon": {"exts": ["*.ceylon"], "mode": ""},
82 "text/x-chdr": {"exts": ["*.c","*.h","*.idc"], "mode": "clike"},
82 "text/x-chdr": {"exts": ["*.c","*.h","*.idc"], "mode": "clike"},
83 "text/x-clojure": {"exts": ["*.clj"], "mode": "clojure"},
83 "text/x-clojure": {"exts": ["*.clj"], "mode": "clojure"},
84 "text/x-cmake": {"exts": ["*.cmake","CMakeLists.txt","*.cmake.in"], "mode": "cmake"},
84 "text/x-cmake": {"exts": ["*.cmake","CMakeLists.txt","*.cmake.in"], "mode": "cmake"},
85 "text/x-cobol": {"exts": ["*.cob","*.COB","*.cpy","*.CPY"], "mode": "cobol"},
85 "text/x-cobol": {"exts": ["*.cob","*.COB","*.cpy","*.CPY"], "mode": "cobol"},
86 "text/x-coffeescript": {"exts": ["*.coffee"], "mode": "coffeescript"},
86 "text/x-coffeescript": {"exts": ["*.coffee"], "mode": "coffeescript"},
87 "text/x-common-lisp": {"exts": ["*.cl","*.lisp","*.el"], "mode": "commonlisp"},
87 "text/x-common-lisp": {"exts": ["*.cl","*.lisp","*.el"], "mode": "commonlisp"},
88 "text/x-coq": {"exts": ["*.v"], "mode": ""},
88 "text/x-coq": {"exts": ["*.v"], "mode": ""},
89 "text/x-cpp-objdump": {"exts": ["*.cpp-objdump","*.c++-objdump","*.cxx-objdump"], "mode": ""},
89 "text/x-cpp-objdump": {"exts": ["*.cpp-objdump","*.c++-objdump","*.cxx-objdump"], "mode": ""},
90 "text/x-crocsrc": {"exts": ["*.croc"], "mode": ""},
90 "text/x-crocsrc": {"exts": ["*.croc"], "mode": ""},
91 "text/x-csharp": {"exts": ["*.cs"], "mode": "clike"},
91 "text/x-csharp": {"exts": ["*.cs"], "mode": "clike"},
92 "text/x-csrc": {"exts": ["*.c","*.h"], "mode": "clike"},
92 "text/x-csrc": {"exts": ["*.c","*.h"], "mode": "clike"},
93 "text/x-cuda": {"exts": ["*.cu","*.cuh"], "mode": ""},
93 "text/x-cuda": {"exts": ["*.cu","*.cuh"], "mode": ""},
94 "text/x-cython": {"exts": ["*.pyx","*.pxd","*.pxi"], "mode": "python"},
94 "text/x-cython": {"exts": ["*.pyx","*.pxd","*.pxi"], "mode": "python"},
95 "text/x-d": {"exts": ["*.d"], "mode": "d"},
95 "text/x-d": {"exts": ["*.d"], "mode": "d"},
96 "text/x-d-objdump": {"exts": ["*.d-objdump"], "mode": ""},
96 "text/x-d-objdump": {"exts": ["*.d-objdump"], "mode": ""},
97 "text/x-dart": {"exts": ["*.dart"], "mode": ""},
97 "text/x-dart": {"exts": ["*.dart"], "mode": ""},
98 "text/x-dg": {"exts": ["*.dg"], "mode": ""},
98 "text/x-dg": {"exts": ["*.dg"], "mode": ""},
99 "text/x-diff": {"exts": ["*.diff","*.patch"], "mode": "diff"},
99 "text/x-diff": {"exts": ["*.diff","*.patch"], "mode": "diff"},
100 "text/x-dsrc": {"exts": ["*.d","*.di"], "mode": ""},
100 "text/x-dsrc": {"exts": ["*.d","*.di"], "mode": ""},
101 "text/x-duel": {"exts": ["*.duel","*.jbst"], "mode": ""},
101 "text/x-duel": {"exts": ["*.duel","*.jbst"], "mode": ""},
102 "text/x-dylan": {"exts": ["*.dylan","*.dyl","*.intr"], "mode": "dylan"},
102 "text/x-dylan": {"exts": ["*.dylan","*.dyl","*.intr"], "mode": "dylan"},
103 "text/x-dylan-console": {"exts": ["*.dylan-console"], "mode": ""},
103 "text/x-dylan-console": {"exts": ["*.dylan-console"], "mode": ""},
104 "text/x-dylan-lid": {"exts": ["*.lid","*.hdp"], "mode": ""},
104 "text/x-dylan-lid": {"exts": ["*.lid","*.hdp"], "mode": ""},
105 "text/x-echdr": {"exts": ["*.ec","*.eh"], "mode": ""},
105 "text/x-echdr": {"exts": ["*.ec","*.eh"], "mode": ""},
106 "text/x-ecl": {"exts": ["*.ecl"], "mode": "ecl"},
106 "text/x-ecl": {"exts": ["*.ecl"], "mode": "ecl"},
107 "text/x-elixir": {"exts": ["*.ex","*.exs"], "mode": ""},
107 "text/x-elixir": {"exts": ["*.ex","*.exs"], "mode": ""},
108 "text/x-erl-shellsession": {"exts": ["*.erl-sh"], "mode": ""},
108 "text/x-erl-shellsession": {"exts": ["*.erl-sh"], "mode": ""},
109 "text/x-erlang": {"exts": ["*.erl","*.hrl","*.es","*.escript"], "mode": "erlang"},
109 "text/x-erlang": {"exts": ["*.erl","*.hrl","*.es","*.escript"], "mode": "erlang"},
110 "text/x-factor": {"exts": ["*.factor"], "mode": "factor"},
110 "text/x-factor": {"exts": ["*.factor"], "mode": "factor"},
111 "text/x-fancysrc": {"exts": ["*.fy","*.fancypack"], "mode": ""},
111 "text/x-fancysrc": {"exts": ["*.fy","*.fancypack"], "mode": ""},
112 "text/x-felix": {"exts": ["*.flx","*.flxh"], "mode": ""},
112 "text/x-felix": {"exts": ["*.flx","*.flxh"], "mode": ""},
113 "text/x-fortran": {"exts": ["*.f","*.f90","*.F","*.F90","*.for","*.f77"], "mode": "fortran"},
113 "text/x-fortran": {"exts": ["*.f","*.f90","*.F","*.F90","*.for","*.f77"], "mode": "fortran"},
114 "text/x-fsharp": {"exts": ["*.fs","*.fsi"], "mode": "mllike"},
114 "text/x-fsharp": {"exts": ["*.fs","*.fsi"], "mode": "mllike"},
115 "text/x-gas": {"exts": ["*.s","*.S"], "mode": "gas"},
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 "text/x-gherkin": {"exts": ["*.feature"], "mode": ""},
117 "text/x-gherkin": {"exts": ["*.feature"], "mode": ""},
118 "text/x-glslsrc": {"exts": ["*.vert","*.frag","*.geo"], "mode": ""},
118 "text/x-glslsrc": {"exts": ["*.vert","*.frag","*.geo"], "mode": ""},
119 "text/x-gnuplot": {"exts": ["*.plot","*.plt"], "mode": ""},
119 "text/x-gnuplot": {"exts": ["*.plot","*.plt"], "mode": ""},
120 "text/x-go": {"exts": ["*.go"], "mode": "go"},
120 "text/x-go": {"exts": ["*.go"], "mode": "go"},
121 "text/x-gooddata-cl": {"exts": ["*.gdc"], "mode": ""},
121 "text/x-gooddata-cl": {"exts": ["*.gdc"], "mode": ""},
122 "text/x-gooddata-maql": {"exts": ["*.maql"], "mode": ""},
122 "text/x-gooddata-maql": {"exts": ["*.maql"], "mode": ""},
123 "text/x-gosrc": {"exts": ["*.go"], "mode": ""},
123 "text/x-gosrc": {"exts": ["*.go"], "mode": ""},
124 "text/x-gosu": {"exts": ["*.gs","*.gsx","*.gsp","*.vark"], "mode": ""},
124 "text/x-gosu": {"exts": ["*.gs","*.gsx","*.gsp","*.vark"], "mode": ""},
125 "text/x-gosu-template": {"exts": ["*.gst"], "mode": ""},
125 "text/x-gosu-template": {"exts": ["*.gst"], "mode": ""},
126 "text/x-groovy": {"exts": ["*.groovy"], "mode": "groovy"},
126 "text/x-groovy": {"exts": ["*.groovy"], "mode": "groovy"},
127 "text/x-haml": {"exts": ["*.haml"], "mode": "haml"},
127 "text/x-haml": {"exts": ["*.haml"], "mode": "haml"},
128 "text/x-haskell": {"exts": ["*.hs"], "mode": "haskell"},
128 "text/x-haskell": {"exts": ["*.hs"], "mode": "haskell"},
129 "text/x-haxe": {"exts": ["*.hx"], "mode": "haxe"},
129 "text/x-haxe": {"exts": ["*.hx"], "mode": "haxe"},
130 "text/x-hybris": {"exts": ["*.hy","*.hyb"], "mode": ""},
130 "text/x-hybris": {"exts": ["*.hy","*.hyb"], "mode": ""},
131 "text/x-ini": {"exts": ["*.ini","*.cfg"], "mode": ""},
131 "text/x-ini": {"exts": ["*.ini","*.cfg"], "mode": ""},
132 "text/x-iokesrc": {"exts": ["*.ik"], "mode": ""},
132 "text/x-iokesrc": {"exts": ["*.ik"], "mode": ""},
133 "text/x-iosrc": {"exts": ["*.io"], "mode": ""},
133 "text/x-iosrc": {"exts": ["*.io"], "mode": ""},
134 "text/x-irclog": {"exts": ["*.weechatlog"], "mode": ""},
134 "text/x-irclog": {"exts": ["*.weechatlog"], "mode": ""},
135 "text/x-jade": {"exts": ["*.jade"], "mode": "jade"},
135 "text/x-jade": {"exts": ["*.jade"], "mode": "jade"},
136 "text/x-java": {"exts": ["*.java"], "mode": "clike"},
136 "text/x-java": {"exts": ["*.java"], "mode": "clike"},
137 "text/x-julia": {"exts": ["*.jl"], "mode": "julia"},
137 "text/x-julia": {"exts": ["*.jl"], "mode": "julia"},
138 "text/x-kconfig": {"exts": ["Kconfig","*Config.in*","external.in*","standard-modules.in"], "mode": ""},
138 "text/x-kconfig": {"exts": ["Kconfig","*Config.in*","external.in*","standard-modules.in"], "mode": ""},
139 "text/x-koka": {"exts": ["*.kk","*.kki"], "mode": ""},
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 "text/x-lasso": {"exts": ["*.lasso","*.lasso[89]"], "mode": ""},
141 "text/x-lasso": {"exts": ["*.lasso","*.lasso[89]"], "mode": ""},
142 "text/x-latex": {"exts": ["*.ltx","*.text"], "mode": "stex"},
142 "text/x-latex": {"exts": ["*.ltx","*.text"], "mode": "stex"},
143 "text/x-less": {"exts": ["*.less"], "mode": "css"},
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 "text/x-livescript": {"exts": ["*.ls"], "mode": "livescript"},
145 "text/x-livescript": {"exts": ["*.ls"], "mode": "livescript"},
146 "text/x-llvm": {"exts": ["*.ll"], "mode": ""},
146 "text/x-llvm": {"exts": ["*.ll"], "mode": ""},
147 "text/x-logos": {"exts": ["*.x","*.xi","*.xm","*.xmi"], "mode": ""},
147 "text/x-logos": {"exts": ["*.x","*.xi","*.xm","*.xmi"], "mode": ""},
148 "text/x-logtalk": {"exts": ["*.lgt"], "mode": ""},
148 "text/x-logtalk": {"exts": ["*.lgt"], "mode": ""},
149 "text/x-lua": {"exts": ["*.lua","*.wlua"], "mode": "lua"},
149 "text/x-lua": {"exts": ["*.lua","*.wlua"], "mode": "lua"},
150 "text/x-makefile": {"exts": ["*.mak","Makefile","makefile","Makefile.*","GNUmakefile"], "mode": ""},
150 "text/x-makefile": {"exts": ["*.mak","Makefile","makefile","Makefile.*","GNUmakefile"], "mode": ""},
151 "text/x-mariadb": {"exts": ["*.sql"], "mode": "sql"},
151 "text/x-mariadb": {"exts": ["*.sql"], "mode": "sql"},
152 "text/x-markdown": {"exts": ["*.md","*.markdown","*.mdown","*.mkd"], "mode": "gfm"},
152 "text/x-markdown": {"exts": ["*.md","*.markdown","*.mdown","*.mkd"], "mode": "gfm"},
153 "text/x-minidsrc": {"exts": ["*.md"], "mode": "gfm"},
153 "text/x-minidsrc": {"exts": ["*.md"], "mode": "gfm"},
154 "text/x-modelica": {"exts": ["*.mo"], "mode": "modelica"},
154 "text/x-modelica": {"exts": ["*.mo"], "mode": "modelica"},
155 "text/x-modula2": {"exts": ["*.def","*.mod"], "mode": ""},
155 "text/x-modula2": {"exts": ["*.def","*.mod"], "mode": ""},
156 "text/x-monkey": {"exts": ["*.monkey"], "mode": ""},
156 "text/x-monkey": {"exts": ["*.monkey"], "mode": ""},
157 "text/x-moocode": {"exts": ["*.moo"], "mode": ""},
157 "text/x-moocode": {"exts": ["*.moo"], "mode": ""},
158 "text/x-moonscript": {"exts": ["*.moon"], "mode": ""},
158 "text/x-moonscript": {"exts": ["*.moon"], "mode": ""},
159 "text/x-nasm": {"exts": ["*.asm","*.ASM"], "mode": ""},
159 "text/x-nasm": {"exts": ["*.asm","*.ASM"], "mode": ""},
160 "text/x-nemerle": {"exts": ["*.n"], "mode": ""},
160 "text/x-nemerle": {"exts": ["*.n"], "mode": ""},
161 "text/x-newlisp": {"exts": ["*.lsp","*.nl"], "mode": ""},
161 "text/x-newlisp": {"exts": ["*.lsp","*.nl"], "mode": ""},
162 "text/x-newspeak": {"exts": ["*.ns2"], "mode": ""},
162 "text/x-newspeak": {"exts": ["*.ns2"], "mode": ""},
163 "text/x-nginx-conf": {"exts": ["*.conf"], "mode": "nginx"},
163 "text/x-nginx-conf": {"exts": ["*.conf"], "mode": "nginx"},
164 "text/x-nimrod": {"exts": ["*.nim","*.nimrod"], "mode": ""},
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 "text/x-objdump": {"exts": ["*.objdump"], "mode": ""},
166 "text/x-objdump": {"exts": ["*.objdump"], "mode": ""},
167 "text/x-objective-c": {"exts": ["*.m","*.h"], "mode": ""},
167 "text/x-objective-c": {"exts": ["*.m","*.h"], "mode": ""},
168 "text/x-objective-c++": {"exts": ["*.mm","*.hh"], "mode": ""},
168 "text/x-objective-c++": {"exts": ["*.mm","*.hh"], "mode": ""},
169 "text/x-objective-j": {"exts": ["*.j"], "mode": ""},
169 "text/x-objective-j": {"exts": ["*.j"], "mode": ""},
170 "text/x-ocaml": {"exts": ["*.ml","*.mli","*.mll","*.mly"], "mode": "mllike"},
170 "text/x-ocaml": {"exts": ["*.ml","*.mli","*.mll","*.mly"], "mode": "mllike"},
171 "text/x-ooc": {"exts": ["*.ooc"], "mode": ""},
171 "text/x-ooc": {"exts": ["*.ooc"], "mode": ""},
172 "text/x-opa": {"exts": ["*.opa"], "mode": ""},
172 "text/x-opa": {"exts": ["*.opa"], "mode": ""},
173 "text/x-openedge": {"exts": ["*.p","*.cls"], "mode": ""},
173 "text/x-openedge": {"exts": ["*.p","*.cls"], "mode": ""},
174 "text/x-pascal": {"exts": ["*.pas","*.p"], "mode": "pascal"},
174 "text/x-pascal": {"exts": ["*.pas","*.p"], "mode": "pascal"},
175 "text/x-perl": {"exts": ["*.pl","*.pm"], "mode": "perl"},
175 "text/x-perl": {"exts": ["*.pl","*.pm"], "mode": "perl"},
176 "text/x-php": {"exts": ["*.php","*.php[345]","*.inc"], "mode": "php"},
176 "text/x-php": {"exts": ["*.php","*.php[345]","*.inc"], "mode": "php"},
177 "text/x-pig": {"exts": ["*.pig"], "mode": "pig"},
177 "text/x-pig": {"exts": ["*.pig"], "mode": "pig"},
178 "text/x-povray": {"exts": ["*.pov","*.inc"], "mode": ""},
178 "text/x-povray": {"exts": ["*.pov","*.inc"], "mode": ""},
179 "text/x-powershell": {"exts": ["*.ps1"], "mode": ""},
179 "text/x-powershell": {"exts": ["*.ps1"], "mode": ""},
180 "text/x-prolog": {"exts": ["*.prolog","*.pro","*.pl"], "mode": ""},
180 "text/x-prolog": {"exts": ["*.prolog","*.pro","*.pl"], "mode": ""},
181 "text/x-properties": {"exts": ["*.properties","*.ini","*.in"], "mode": "properties"},
181 "text/x-properties": {"exts": ["*.properties","*.ini","*.in"], "mode": "properties"},
182 "text/x-python": {"exts": ["*.py","*.pyw","*.sc","SConstruct","SConscript","*.tac","*.sage"], "mode": "python"},
182 "text/x-python": {"exts": ["*.py","*.pyw","*.sc","SConstruct","SConscript","*.tac","*.sage"], "mode": "python"},
183 "text/x-python-traceback": {"exts": ["*.pytb"], "mode": ""},
183 "text/x-python-traceback": {"exts": ["*.pytb"], "mode": ""},
184 "text/x-python3-traceback": {"exts": ["*.py3tb"], "mode": ""},
184 "text/x-python3-traceback": {"exts": ["*.py3tb"], "mode": ""},
185 "text/x-r-doc": {"exts": ["*.Rd"], "mode": ""},
185 "text/x-r-doc": {"exts": ["*.Rd"], "mode": ""},
186 "text/x-racket": {"exts": ["*.rkt","*.rktl"], "mode": ""},
186 "text/x-racket": {"exts": ["*.rkt","*.rktl"], "mode": ""},
187 "text/x-rebol": {"exts": ["*.r","*.r3"], "mode": ""},
187 "text/x-rebol": {"exts": ["*.r","*.r3"], "mode": ""},
188 "text/x-robotframework": {"exts": ["*.txt","*.robot"], "mode": ""},
188 "text/x-robotframework": {"exts": ["*.txt","*.robot"], "mode": ""},
189 "text/x-rpm-spec": {"exts": ["*.spec"], "mode": "rpm"},
189 "text/x-rpm-spec": {"exts": ["*.spec"], "mode": "rpm"},
190 "text/x-rsrc": {"exts": ["*.r"], "mode": "r"},
190 "text/x-rsrc": {"exts": ["*.r"], "mode": "r"},
191 "text/x-rst": {"exts": ["*.rst","*.rest"], "mode": "rst"},
191 "text/x-rst": {"exts": ["*.rst","*.rest"], "mode": "rst"},
192 "text/x-ruby": {"exts": ["*.rb","*.rbw","Rakefile","*.rake","*.gemspec","*.rbx","*.duby"], "mode": "ruby"},
192 "text/x-ruby": {"exts": ["*.rb","*.rbw","Rakefile","*.rake","*.gemspec","*.rbx","*.duby"], "mode": "ruby"},
193 "text/x-rustsrc": {"exts": ["*.rs","*.rc"], "mode": "rust"},
193 "text/x-rustsrc": {"exts": ["*.rs","*.rc"], "mode": "rust"},
194 "text/x-sass": {"exts": ["*.sass"], "mode": "sass"},
194 "text/x-sass": {"exts": ["*.sass"], "mode": "sass"},
195 "text/x-scala": {"exts": ["*.scala"], "mode": "clike"},
195 "text/x-scala": {"exts": ["*.scala"], "mode": "clike"},
196 "text/x-scaml": {"exts": ["*.scaml"], "mode": ""},
196 "text/x-scaml": {"exts": ["*.scaml"], "mode": ""},
197 "text/x-scheme": {"exts": ["*.scm","*.ss"], "mode": "scheme"},
197 "text/x-scheme": {"exts": ["*.scm","*.ss"], "mode": "scheme"},
198 "text/x-scss": {"exts": ["*.scss"], "mode": "css"},
198 "text/x-scss": {"exts": ["*.scss"], "mode": "css"},
199 "text/x-sh": {"exts": ["*.sh","*.ksh","*.bash","*.ebuild","*.eclass",".bashrc","bashrc",".bash_*","bash_*"], "mode": "shell"},
199 "text/x-sh": {"exts": ["*.sh","*.ksh","*.bash","*.ebuild","*.eclass",".bashrc","bashrc",".bash_*","bash_*"], "mode": "shell"},
200 "text/x-smalltalk": {"exts": ["*.st"], "mode": ""},
200 "text/x-smalltalk": {"exts": ["*.st"], "mode": ""},
201 "text/x-smarty": {"exts": ["*.tpl"], "mode": "smarty"},
201 "text/x-smarty": {"exts": ["*.tpl"], "mode": "smarty"},
202 "text/x-snobol": {"exts": ["*.snobol"], "mode": ""},
202 "text/x-snobol": {"exts": ["*.snobol"], "mode": ""},
203 "text/x-sourcepawn": {"exts": ["*.sp"], "mode": ""},
203 "text/x-sourcepawn": {"exts": ["*.sp"], "mode": ""},
204 "text/x-sql": {"exts": ["*.sql"], "mode": "sql"},
204 "text/x-sql": {"exts": ["*.sql"], "mode": "sql"},
205 "text/x-sqlite3-console": {"exts": ["*.sqlite3-console"], "mode": ""},
205 "text/x-sqlite3-console": {"exts": ["*.sqlite3-console"], "mode": ""},
206 "text/x-squidconf": {"exts": ["squid.conf"], "mode": ""},
206 "text/x-squidconf": {"exts": ["squid.conf"], "mode": ""},
207 "text/x-standardml": {"exts": ["*.sml","*.sig","*.fun"], "mode": ""},
207 "text/x-standardml": {"exts": ["*.sml","*.sig","*.fun"], "mode": ""},
208 "text/x-stex": {"exts": [], "mode": "stex"},
208 "text/x-stex": {"exts": [], "mode": "stex"},
209 "text/x-stsrc": {"exts": ["*.rs","*.rc","*.st"], "mode": "smalltalk"},
209 "text/x-stsrc": {"exts": ["*.rs","*.rc","*.st"], "mode": "smalltalk"},
210 "text/x-systemverilog": {"exts": ["*.sv","*.svh","*.v"], "mode": "verilog"},
210 "text/x-systemverilog": {"exts": ["*.sv","*.svh","*.v"], "mode": "verilog"},
211 "text/x-tcl": {"exts": ["*.tcl"], "mode": "tcl"},
211 "text/x-tcl": {"exts": ["*.tcl"], "mode": "tcl"},
212 "text/x-tea": {"exts": ["*.tea"], "mode": ""},
212 "text/x-tea": {"exts": ["*.tea"], "mode": ""},
213 "text/x-tex": {"exts": ["*.tex","*.aux","*.toc"], "mode": ""},
213 "text/x-tex": {"exts": ["*.tex","*.aux","*.toc"], "mode": ""},
214 "text/x-tiddlywiki": {"exts": [], "mode": "tiddlywiki"},
214 "text/x-tiddlywiki": {"exts": [], "mode": "tiddlywiki"},
215 "text/x-typescript": {"exts": ["*.ts"], "mode": ""},
215 "text/x-typescript": {"exts": ["*.ts"], "mode": ""},
216 "text/x-vala": {"exts": ["*.vala","*.vapi"], "mode": ""},
216 "text/x-vala": {"exts": ["*.vala","*.vapi"], "mode": ""},
217 "text/x-vb": {"exts": ["*.vb"], "mode": "vb"},
217 "text/x-vb": {"exts": ["*.vb"], "mode": "vb"},
218 "text/x-vbnet": {"exts": ["*.vb","*.bas"], "mode": ""},
218 "text/x-vbnet": {"exts": ["*.vb","*.bas"], "mode": ""},
219 "text/x-verilog": {"exts": ["*.v"], "mode": "verilog"},
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 "text/x-vim": {"exts": ["*.vim",".vimrc",".exrc",".gvimrc","_vimrc","_exrc","_gvimrc","vimrc","gvimrc"], "mode": ""},
221 "text/x-vim": {"exts": ["*.vim",".vimrc",".exrc",".gvimrc","_vimrc","_exrc","_gvimrc","vimrc","gvimrc"], "mode": ""},
222 "text/x-windows-registry": {"exts": ["*.reg"], "mode": ""},
222 "text/x-windows-registry": {"exts": ["*.reg"], "mode": ""},
223 "text/x-xtend": {"exts": ["*.xtend"], "mode": ""},
223 "text/x-xtend": {"exts": ["*.xtend"], "mode": ""},
224 "text/x-yaml": {"exts": ["*.yaml","*.yml"], "mode": "yaml"},
224 "text/x-yaml": {"exts": ["*.yaml","*.yml"], "mode": "yaml"},
225 "text/x-z80": {"exts": ["*.z80"], "mode": "z80"},
225 "text/x-z80": {"exts": ["*.z80"], "mode": "z80"},
226 "text/xml": {"exts": ["*.xml","*.xsl","*.rss","*.xslt","*.xsd","*.wsdl"], "mode": ""},
226 "text/xml": {"exts": ["*.xml","*.xsl","*.rss","*.xslt","*.xsd","*.wsdl"], "mode": ""},
227 "text/xquery": {"exts": ["*.xqy","*.xquery","*.xq","*.xql","*.xqm"], "mode": ""}
227 "text/xquery": {"exts": ["*.xqy","*.xquery","*.xq","*.xql","*.xqm"], "mode": ""}
228 };
228 };
229
229
230 /* Special case for overriding mode by file extensions
230 /* Special case for overriding mode by file extensions
231 * key is extensions, value is codemirror mode
231 * key is extensions, value is codemirror mode
232 * */
232 * */
233 _SPECIAL_CASES = {
233 _SPECIAL_CASES = {
234 "md": "markdown",
234 "md": "markdown",
235 "markdown": "markdown"
235 "markdown": "markdown"
236 };
236 };
237
237
238 /**
238 /**
239 * Get's proposed extension based on given mimetype
239 * Get's proposed extension based on given mimetype
240 *
240 *
241 * @param mimetype
241 * @param mimetype
242 * @returns extensions (default .txt)
242 * @returns extensions (default .txt)
243 */
243 */
244 var getExtFromMimeType = function(mimetype){
244 var getExtFromMimeType = function(mimetype){
245
245
246 var proposed_exts = MIME_TO_EXT[mimetype] || _EMPTY_EXT;
246 var proposed_exts = MIME_TO_EXT[mimetype] || _EMPTY_EXT;
247 if(proposed_exts.exts.length < 1){
247 if(proposed_exts.exts.length < 1){
248 //fallback to text/plain
248 //fallback to text/plain
249 proposed_exts = {'exts': ['*.txt'], 'mode': '' }
249 proposed_exts = {'exts': ['*.txt'], 'mode': '' }
250 }
250 }
251 // get the first
251 // get the first
252 var ext = proposed_exts.exts[0];
252 var ext = proposed_exts.exts[0];
253 if(ext[0] == '*'){
253 if(ext[0] == '*'){
254 ext = ext.substr(1)
254 ext = ext.substr(1)
255 }
255 }
256
256
257 return ext
257 return ext
258 };
258 };
259
259
260 var getMimeTypeFromExt = function(ext, multiple){
260 var getMimeTypeFromExt = function(ext, multiple){
261 mimetypes = [];
261 mimetypes = [];
262 for (k in MIME_TO_EXT){
262 for (k in MIME_TO_EXT){
263 var mode = MIME_TO_EXT[k];
263 var mode = MIME_TO_EXT[k];
264 if ($.inArray("*."+ext, mode.exts) != -1){
264 if ($.inArray("*."+ext, mode.exts) != -1){
265 mimetypes.push(k)
265 mimetypes.push(k)
266 }
266 }
267 }
267 }
268 if(multiple){
268 if(multiple){
269 return mimetypes
269 return mimetypes
270 }
270 }
271 if(mimetypes.length > 0){
271 if(mimetypes.length > 0){
272 return mimetypes[0]
272 return mimetypes[0]
273 }
273 }
274
274
275 };
275 };
276
276
277 var getFilenameAndExt = function(filename){
277 var getFilenameAndExt = function(filename){
278 var parts = filename.split('.');
278 var parts = filename.split('.');
279 var ext = null;
279 var ext = null;
280 var filename = null;
280 var filename = null;
281
281
282 if (parts.length > 1){
282 if (parts.length > 1){
283 var ext = parts.pop();
283 var ext = parts.pop();
284 var filename = parts.join("");
284 var filename = parts.join("");
285 }
285 }
286 return {"filename": filename, "ext": ext}
286 return {"filename": filename, "ext": ext}
287 }
287 }
288
288
289 /**
289 /**
290 * Detect mode from extension, this is mostly used to override the
290 * Detect mode from extension, this is mostly used to override the
291 * detection by mimetype
291 * detection by mimetype
292 *
292 *
293 * @param filename
293 * @param filename
294 */
294 */
295 var detectCodeMirrorModeFromExt = function(filename, fallback){
295 var detectCodeMirrorModeFromExt = function(filename, fallback){
296 var ext = filename.split('.');
296 var ext = filename.split('.');
297 if (ext){
297 if (ext){
298 var ext = ext[ext.length-1];
298 var ext = ext[ext.length-1];
299 }
299 }
300 // try to do a lookup by extension
300 // try to do a lookup by extension
301 var _special_mode = _SPECIAL_CASES[ext];
301 var _special_mode = _SPECIAL_CASES[ext];
302 if (_special_mode){
302 if (_special_mode){
303 return _special_mode
303 return _special_mode
304 }
304 }
305 if(fallback !== undefined && fallback === true){
305 if(fallback !== undefined && fallback === true){
306 var mimetype = getMimeTypeFromExt(ext);
306 var mimetype = getMimeTypeFromExt(ext);
307 if(mimetype){
307 if(mimetype){
308 return MIME_TO_EXT[mimetype].mode;
308 return MIME_TO_EXT[mimetype].mode;
309 }
309 }
310
310
311 }
311 }
312 }
312 }
313
313
314
314
315 /**
315 /**
316 * Try to detect a codemirror mode based on a filename and mimetype
316 * Try to detect a codemirror mode based on a filename and mimetype
317 *
317 *
318 * @param filename
318 * @param filename
319 * @param mimetype
319 * @param mimetype
320 * @returns mode or undefined
320 * @returns mode or undefined
321 */
321 */
322 var detectCodeMirrorMode = function(filename, mimetype, fallback){
322 var detectCodeMirrorMode = function(filename, mimetype, fallback){
323 // just use _SPECIAL_CASES for detection here, as we usually got mimetype
323 // just use _SPECIAL_CASES for detection here, as we usually got mimetype
324 // and it's faster to lookup by mimetype.
324 // and it's faster to lookup by mimetype.
325 var do_fallback = fallback || false;
325 var do_fallback = fallback || false;
326 var _mode_from_ext = detectCodeMirrorModeFromExt(filename, do_fallback);
326 var _mode_from_ext = detectCodeMirrorModeFromExt(filename, do_fallback);
327 if(_mode_from_ext){
327 if(_mode_from_ext){
328 return _mode_from_ext
328 return _mode_from_ext
329 }
329 }
330
330
331 // first try to match by exact mimetype
331 // first try to match by exact mimetype
332 var mode = MIME_TO_EXT[mimetype];
332 var mode = MIME_TO_EXT[mimetype];
333 if(mode && mode.mode){
333 if(mode && mode.mode){
334 return mode.mode;
334 return mode.mode;
335 }
335 }
336 }
336 }
@@ -1,178 +1,178 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("nginx", function(config) {
14 CodeMirror.defineMode("nginx", function(config) {
15
15
16 function words(str) {
16 function words(str) {
17 var obj = {}, words = str.split(" ");
17 var obj = {}, words = str.split(" ");
18 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
18 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
19 return obj;
19 return obj;
20 }
20 }
21
21
22 var keywords = words(
22 var keywords = words(
23 /* ngxDirectiveControl */ "break return rewrite set" +
23 /* ngxDirectiveControl */ "break return rewrite set" +
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"
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 var keywords_block = words(
27 var keywords_block = words(
28 /* ngxDirectiveBlock */ "http mail events server types location upstream charset_map limit_except if geo map"
28 /* ngxDirectiveBlock */ "http mail events server types location upstream charset_map limit_except if geo map"
29 );
29 );
30
30
31 var keywords_important = words(
31 var keywords_important = words(
32 /* ngxDirectiveImportant */ "include root server server_name listen internal proxy_pass memcached_pass fastcgi_pass try_files"
32 /* ngxDirectiveImportant */ "include root server server_name listen internal proxy_pass memcached_pass fastcgi_pass try_files"
33 );
33 );
34
34
35 var indentUnit = config.indentUnit, type;
35 var indentUnit = config.indentUnit, type;
36 function ret(style, tp) {type = tp; return style;}
36 function ret(style, tp) {type = tp; return style;}
37
37
38 function tokenBase(stream, state) {
38 function tokenBase(stream, state) {
39
39
40
40
41 stream.eatWhile(/[\w\$_]/);
41 stream.eatWhile(/[\w\$_]/);
42
42
43 var cur = stream.current();
43 var cur = stream.current();
44
44
45
45
46 if (keywords.propertyIsEnumerable(cur)) {
46 if (keywords.propertyIsEnumerable(cur)) {
47 return "keyword";
47 return "keyword";
48 }
48 }
49 else if (keywords_block.propertyIsEnumerable(cur)) {
49 else if (keywords_block.propertyIsEnumerable(cur)) {
50 return "variable-2";
50 return "variable-2";
51 }
51 }
52 else if (keywords_important.propertyIsEnumerable(cur)) {
52 else if (keywords_important.propertyIsEnumerable(cur)) {
53 return "string-2";
53 return "string-2";
54 }
54 }
55 /**/
55 /**/
56
56
57 var ch = stream.next();
57 var ch = stream.next();
58 if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
58 if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
59 else if (ch == "/" && stream.eat("*")) {
59 else if (ch == "/" && stream.eat("*")) {
60 state.tokenize = tokenCComment;
60 state.tokenize = tokenCComment;
61 return tokenCComment(stream, state);
61 return tokenCComment(stream, state);
62 }
62 }
63 else if (ch == "<" && stream.eat("!")) {
63 else if (ch == "<" && stream.eat("!")) {
64 state.tokenize = tokenSGMLComment;
64 state.tokenize = tokenSGMLComment;
65 return tokenSGMLComment(stream, state);
65 return tokenSGMLComment(stream, state);
66 }
66 }
67 else if (ch == "=") ret(null, "compare");
67 else if (ch == "=") ret(null, "compare");
68 else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
68 else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
69 else if (ch == "\"" || ch == "'") {
69 else if (ch == "\"" || ch == "'") {
70 state.tokenize = tokenString(ch);
70 state.tokenize = tokenString(ch);
71 return state.tokenize(stream, state);
71 return state.tokenize(stream, state);
72 }
72 }
73 else if (ch == "#") {
73 else if (ch == "#") {
74 stream.skipToEnd();
74 stream.skipToEnd();
75 return ret("comment", "comment");
75 return ret("comment", "comment");
76 }
76 }
77 else if (ch == "!") {
77 else if (ch == "!") {
78 stream.match(/^\s*\w*/);
78 stream.match(/^\s*\w*/);
79 return ret("keyword", "important");
79 return ret("keyword", "important");
80 }
80 }
81 else if (/\d/.test(ch)) {
81 else if (/\d/.test(ch)) {
82 stream.eatWhile(/[\w.%]/);
82 stream.eatWhile(/[\w.%]/);
83 return ret("number", "unit");
83 return ret("number", "unit");
84 }
84 }
85 else if (/[,.+>*\/]/.test(ch)) {
85 else if (/[,.+>*\/]/.test(ch)) {
86 return ret(null, "select-op");
86 return ret(null, "select-op");
87 }
87 }
88 else if (/[;{}:\[\]]/.test(ch)) {
88 else if (/[;{}:\[\]]/.test(ch)) {
89 return ret(null, ch);
89 return ret(null, ch);
90 }
90 }
91 else {
91 else {
92 stream.eatWhile(/[\w\\\-]/);
92 stream.eatWhile(/[\w\\\-]/);
93 return ret("variable", "variable");
93 return ret("variable", "variable");
94 }
94 }
95 }
95 }
96
96
97 function tokenCComment(stream, state) {
97 function tokenCComment(stream, state) {
98 var maybeEnd = false, ch;
98 var maybeEnd = false, ch;
99 while ((ch = stream.next()) != null) {
99 while ((ch = stream.next()) != null) {
100 if (maybeEnd && ch == "/") {
100 if (maybeEnd && ch == "/") {
101 state.tokenize = tokenBase;
101 state.tokenize = tokenBase;
102 break;
102 break;
103 }
103 }
104 maybeEnd = (ch == "*");
104 maybeEnd = (ch == "*");
105 }
105 }
106 return ret("comment", "comment");
106 return ret("comment", "comment");
107 }
107 }
108
108
109 function tokenSGMLComment(stream, state) {
109 function tokenSGMLComment(stream, state) {
110 var dashes = 0, ch;
110 var dashes = 0, ch;
111 while ((ch = stream.next()) != null) {
111 while ((ch = stream.next()) != null) {
112 if (dashes >= 2 && ch == ">") {
112 if (dashes >= 2 && ch == ">") {
113 state.tokenize = tokenBase;
113 state.tokenize = tokenBase;
114 break;
114 break;
115 }
115 }
116 dashes = (ch == "-") ? dashes + 1 : 0;
116 dashes = (ch == "-") ? dashes + 1 : 0;
117 }
117 }
118 return ret("comment", "comment");
118 return ret("comment", "comment");
119 }
119 }
120
120
121 function tokenString(quote) {
121 function tokenString(quote) {
122 return function(stream, state) {
122 return function(stream, state) {
123 var escaped = false, ch;
123 var escaped = false, ch;
124 while ((ch = stream.next()) != null) {
124 while ((ch = stream.next()) != null) {
125 if (ch == quote && !escaped)
125 if (ch == quote && !escaped)
126 break;
126 break;
127 escaped = !escaped && ch == "\\";
127 escaped = !escaped && ch == "\\";
128 }
128 }
129 if (!escaped) state.tokenize = tokenBase;
129 if (!escaped) state.tokenize = tokenBase;
130 return ret("string", "string");
130 return ret("string", "string");
131 };
131 };
132 }
132 }
133
133
134 return {
134 return {
135 startState: function(base) {
135 startState: function(base) {
136 return {tokenize: tokenBase,
136 return {tokenize: tokenBase,
137 baseIndent: base || 0,
137 baseIndent: base || 0,
138 stack: []};
138 stack: []};
139 },
139 },
140
140
141 token: function(stream, state) {
141 token: function(stream, state) {
142 if (stream.eatSpace()) return null;
142 if (stream.eatSpace()) return null;
143 type = null;
143 type = null;
144 var style = state.tokenize(stream, state);
144 var style = state.tokenize(stream, state);
145
145
146 var context = state.stack[state.stack.length-1];
146 var context = state.stack[state.stack.length-1];
147 if (type == "hash" && context == "rule") style = "atom";
147 if (type == "hash" && context == "rule") style = "atom";
148 else if (style == "variable") {
148 else if (style == "variable") {
149 if (context == "rule") style = "number";
149 if (context == "rule") style = "number";
150 else if (!context || context == "@media{") style = "tag";
150 else if (!context || context == "@media{") style = "tag";
151 }
151 }
152
152
153 if (context == "rule" && /^[\{\};]$/.test(type))
153 if (context == "rule" && /^[\{\};]$/.test(type))
154 state.stack.pop();
154 state.stack.pop();
155 if (type == "{") {
155 if (type == "{") {
156 if (context == "@media") state.stack[state.stack.length-1] = "@media{";
156 if (context == "@media") state.stack[state.stack.length-1] = "@media{";
157 else state.stack.push("{");
157 else state.stack.push("{");
158 }
158 }
159 else if (type == "}") state.stack.pop();
159 else if (type == "}") state.stack.pop();
160 else if (type == "@media") state.stack.push("@media");
160 else if (type == "@media") state.stack.push("@media");
161 else if (context == "{" && type != "comment") state.stack.push("rule");
161 else if (context == "{" && type != "comment") state.stack.push("rule");
162 return style;
162 return style;
163 },
163 },
164
164
165 indent: function(state, textAfter) {
165 indent: function(state, textAfter) {
166 var n = state.stack.length;
166 var n = state.stack.length;
167 if (/^\}/.test(textAfter))
167 if (/^\}/.test(textAfter))
168 n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
168 n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
169 return state.baseIndent + n * indentUnit;
169 return state.baseIndent + n * indentUnit;
170 },
170 },
171
171
172 electricChars: "}"
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 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../clike/clike"));
6 mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../clike/clike"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../clike/clike"], mod);
8 define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../clike/clike"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 function keywords(str) {
14 function keywords(str) {
15 var obj = {}, words = str.split(" ");
15 var obj = {}, words = str.split(" ");
16 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
16 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
17 return obj;
17 return obj;
18 }
18 }
19
19
20 // Helper for phpString
20 // Helper for phpString
21 function matchSequence(list, end, escapes) {
21 function matchSequence(list, end, escapes) {
22 if (list.length == 0) return phpString(end);
22 if (list.length == 0) return phpString(end);
23 return function (stream, state) {
23 return function (stream, state) {
24 var patterns = list[0];
24 var patterns = list[0];
25 for (var i = 0; i < patterns.length; i++) if (stream.match(patterns[i][0])) {
25 for (var i = 0; i < patterns.length; i++) if (stream.match(patterns[i][0])) {
26 state.tokenize = matchSequence(list.slice(1), end);
26 state.tokenize = matchSequence(list.slice(1), end);
27 return patterns[i][1];
27 return patterns[i][1];
28 }
28 }
29 state.tokenize = phpString(end, escapes);
29 state.tokenize = phpString(end, escapes);
30 return "string";
30 return "string";
31 };
31 };
32 }
32 }
33 function phpString(closing, escapes) {
33 function phpString(closing, escapes) {
34 return function(stream, state) { return phpString_(stream, state, closing, escapes); };
34 return function(stream, state) { return phpString_(stream, state, closing, escapes); };
35 }
35 }
36 function phpString_(stream, state, closing, escapes) {
36 function phpString_(stream, state, closing, escapes) {
37 // "Complex" syntax
37 // "Complex" syntax
38 if (escapes !== false && stream.match("${", false) || stream.match("{$", false)) {
38 if (escapes !== false && stream.match("${", false) || stream.match("{$", false)) {
39 state.tokenize = null;
39 state.tokenize = null;
40 return "string";
40 return "string";
41 }
41 }
42
42
43 // Simple syntax
43 // Simple syntax
44 if (escapes !== false && stream.match(/^\$[a-zA-Z_][a-zA-Z0-9_]*/)) {
44 if (escapes !== false && stream.match(/^\$[a-zA-Z_][a-zA-Z0-9_]*/)) {
45 // After the variable name there may appear array or object operator.
45 // After the variable name there may appear array or object operator.
46 if (stream.match("[", false)) {
46 if (stream.match("[", false)) {
47 // Match array operator
47 // Match array operator
48 state.tokenize = matchSequence([
48 state.tokenize = matchSequence([
49 [["[", null]],
49 [["[", null]],
50 [[/\d[\w\.]*/, "number"],
50 [[/\d[\w\.]*/, "number"],
51 [/\$[a-zA-Z_][a-zA-Z0-9_]*/, "variable-2"],
51 [/\$[a-zA-Z_][a-zA-Z0-9_]*/, "variable-2"],
52 [/[\w\$]+/, "variable"]],
52 [/[\w\$]+/, "variable"]],
53 [["]", null]]
53 [["]", null]]
54 ], closing, escapes);
54 ], closing, escapes);
55 }
55 }
56 if (stream.match(/\-\>\w/, false)) {
56 if (stream.match(/\-\>\w/, false)) {
57 // Match object operator
57 // Match object operator
58 state.tokenize = matchSequence([
58 state.tokenize = matchSequence([
59 [["->", null]],
59 [["->", null]],
60 [[/[\w]+/, "variable"]]
60 [[/[\w]+/, "variable"]]
61 ], closing, escapes);
61 ], closing, escapes);
62 }
62 }
63 return "variable-2";
63 return "variable-2";
64 }
64 }
65
65
66 var escaped = false;
66 var escaped = false;
67 // Normal string
67 // Normal string
68 while (!stream.eol() &&
68 while (!stream.eol() &&
69 (escaped || escapes === false ||
69 (escaped || escapes === false ||
70 (!stream.match("{$", false) &&
70 (!stream.match("{$", false) &&
71 !stream.match(/^(\$[a-zA-Z_][a-zA-Z0-9_]*|\$\{)/, false)))) {
71 !stream.match(/^(\$[a-zA-Z_][a-zA-Z0-9_]*|\$\{)/, false)))) {
72 if (!escaped && stream.match(closing)) {
72 if (!escaped && stream.match(closing)) {
73 state.tokenize = null;
73 state.tokenize = null;
74 state.tokStack.pop(); state.tokStack.pop();
74 state.tokStack.pop(); state.tokStack.pop();
75 break;
75 break;
76 }
76 }
77 escaped = stream.next() == "\\" && !escaped;
77 escaped = stream.next() == "\\" && !escaped;
78 }
78 }
79 return "string";
79 return "string";
80 }
80 }
81
81
82 var phpKeywords = "abstract and array as break case catch class clone const continue declare default " +
82 var phpKeywords = "abstract and array as break case catch class clone const continue declare default " +
83 "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
83 "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
84 "for foreach function global goto if implements interface instanceof namespace " +
84 "for foreach function global goto if implements interface instanceof namespace " +
85 "new or private protected public static switch throw trait try use var while xor " +
85 "new or private protected public static switch throw trait try use var while xor " +
86 "die echo empty exit eval include include_once isset list require require_once return " +
86 "die echo empty exit eval include include_once isset list require require_once return " +
87 "print unset __halt_compiler self static parent yield insteadof finally";
87 "print unset __halt_compiler self static parent yield insteadof finally";
88 var phpAtoms = "true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__";
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 CodeMirror.registerHelper("hintWords", "php", [phpKeywords, phpAtoms, phpBuiltin].join(" ").split(" "));
90 CodeMirror.registerHelper("hintWords", "php", [phpKeywords, phpAtoms, phpBuiltin].join(" ").split(" "));
91 CodeMirror.registerHelper("wordChars", "php", /[\w$]/);
91 CodeMirror.registerHelper("wordChars", "php", /[\w$]/);
92
92
93 var phpConfig = {
93 var phpConfig = {
94 name: "clike",
94 name: "clike",
95 helperType: "php",
95 helperType: "php",
96 keywords: keywords(phpKeywords),
96 keywords: keywords(phpKeywords),
97 blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"),
97 blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"),
98 defKeywords: keywords("class function interface namespace trait"),
98 defKeywords: keywords("class function interface namespace trait"),
99 atoms: keywords(phpAtoms),
99 atoms: keywords(phpAtoms),
100 builtin: keywords(phpBuiltin),
100 builtin: keywords(phpBuiltin),
101 multiLineStrings: true,
101 multiLineStrings: true,
102 hooks: {
102 hooks: {
103 "$": function(stream) {
103 "$": function(stream) {
104 stream.eatWhile(/[\w\$_]/);
104 stream.eatWhile(/[\w\$_]/);
105 return "variable-2";
105 return "variable-2";
106 },
106 },
107 "<": function(stream, state) {
107 "<": function(stream, state) {
108 if (stream.match(/<</)) {
108 var before;
109 var nowDoc = stream.eat("'");
109 if (before = stream.match(/<<\s*/)) {
110 var quoted = stream.eat(/['"]/);
110 stream.eatWhile(/[\w\.]/);
111 stream.eatWhile(/[\w\.]/);
111 var delim = stream.current().slice(3 + (nowDoc ? 1 : 0));
112 var delim = stream.current().slice(before[0].length + (quoted ? 2 : 1));
112 if (nowDoc) stream.eat("'");
113 if (quoted) stream.eat(quoted);
113 if (delim) {
114 if (delim) {
114 (state.tokStack || (state.tokStack = [])).push(delim, 0);
115 (state.tokStack || (state.tokStack = [])).push(delim, 0);
115 state.tokenize = phpString(delim, nowDoc ? false : true);
116 state.tokenize = phpString(delim, quoted != "'");
116 return "string";
117 return "string";
117 }
118 }
118 }
119 }
119 return false;
120 return false;
120 },
121 },
121 "#": function(stream) {
122 "#": function(stream) {
122 while (!stream.eol() && !stream.match("?>", false)) stream.next();
123 while (!stream.eol() && !stream.match("?>", false)) stream.next();
123 return "comment";
124 return "comment";
124 },
125 },
125 "/": function(stream) {
126 "/": function(stream) {
126 if (stream.eat("/")) {
127 if (stream.eat("/")) {
127 while (!stream.eol() && !stream.match("?>", false)) stream.next();
128 while (!stream.eol() && !stream.match("?>", false)) stream.next();
128 return "comment";
129 return "comment";
129 }
130 }
130 return false;
131 return false;
131 },
132 },
132 '"': function(_stream, state) {
133 '"': function(_stream, state) {
133 (state.tokStack || (state.tokStack = [])).push('"', 0);
134 (state.tokStack || (state.tokStack = [])).push('"', 0);
134 state.tokenize = phpString('"');
135 state.tokenize = phpString('"');
135 return "string";
136 return "string";
136 },
137 },
137 "{": function(_stream, state) {
138 "{": function(_stream, state) {
138 if (state.tokStack && state.tokStack.length)
139 if (state.tokStack && state.tokStack.length)
139 state.tokStack[state.tokStack.length - 1]++;
140 state.tokStack[state.tokStack.length - 1]++;
140 return false;
141 return false;
141 },
142 },
142 "}": function(_stream, state) {
143 "}": function(_stream, state) {
143 if (state.tokStack && state.tokStack.length > 0 &&
144 if (state.tokStack && state.tokStack.length > 0 &&
144 !--state.tokStack[state.tokStack.length - 1]) {
145 !--state.tokStack[state.tokStack.length - 1]) {
145 state.tokenize = phpString(state.tokStack[state.tokStack.length - 2]);
146 state.tokenize = phpString(state.tokStack[state.tokStack.length - 2]);
146 }
147 }
147 return false;
148 return false;
148 }
149 }
149 }
150 }
150 };
151 };
151
152
152 CodeMirror.defineMode("php", function(config, parserConfig) {
153 CodeMirror.defineMode("php", function(config, parserConfig) {
153 var htmlMode = CodeMirror.getMode(config, "text/html");
154 var htmlMode = CodeMirror.getMode(config, "text/html");
154 var phpMode = CodeMirror.getMode(config, phpConfig);
155 var phpMode = CodeMirror.getMode(config, phpConfig);
155
156
156 function dispatch(stream, state) {
157 function dispatch(stream, state) {
157 var isPHP = state.curMode == phpMode;
158 var isPHP = state.curMode == phpMode;
158 if (stream.sol() && state.pending && state.pending != '"' && state.pending != "'") state.pending = null;
159 if (stream.sol() && state.pending && state.pending != '"' && state.pending != "'") state.pending = null;
159 if (!isPHP) {
160 if (!isPHP) {
160 if (stream.match(/^<\?\w*/)) {
161 if (stream.match(/^<\?\w*/)) {
161 state.curMode = phpMode;
162 state.curMode = phpMode;
163 if (!state.php) state.php = CodeMirror.startState(phpMode, htmlMode.indent(state.html, ""))
162 state.curState = state.php;
164 state.curState = state.php;
163 return "meta";
165 return "meta";
164 }
166 }
165 if (state.pending == '"' || state.pending == "'") {
167 if (state.pending == '"' || state.pending == "'") {
166 while (!stream.eol() && stream.next() != state.pending) {}
168 while (!stream.eol() && stream.next() != state.pending) {}
167 var style = "string";
169 var style = "string";
168 } else if (state.pending && stream.pos < state.pending.end) {
170 } else if (state.pending && stream.pos < state.pending.end) {
169 stream.pos = state.pending.end;
171 stream.pos = state.pending.end;
170 var style = state.pending.style;
172 var style = state.pending.style;
171 } else {
173 } else {
172 var style = htmlMode.token(stream, state.curState);
174 var style = htmlMode.token(stream, state.curState);
173 }
175 }
174 if (state.pending) state.pending = null;
176 if (state.pending) state.pending = null;
175 var cur = stream.current(), openPHP = cur.search(/<\?/), m;
177 var cur = stream.current(), openPHP = cur.search(/<\?/), m;
176 if (openPHP != -1) {
178 if (openPHP != -1) {
177 if (style == "string" && (m = cur.match(/[\'\"]$/)) && !/\?>/.test(cur)) state.pending = m[0];
179 if (style == "string" && (m = cur.match(/[\'\"]$/)) && !/\?>/.test(cur)) state.pending = m[0];
178 else state.pending = {end: stream.pos, style: style};
180 else state.pending = {end: stream.pos, style: style};
179 stream.backUp(cur.length - openPHP);
181 stream.backUp(cur.length - openPHP);
180 }
182 }
181 return style;
183 return style;
182 } else if (isPHP && state.php.tokenize == null && stream.match("?>")) {
184 } else if (isPHP && state.php.tokenize == null && stream.match("?>")) {
183 state.curMode = htmlMode;
185 state.curMode = htmlMode;
184 state.curState = state.html;
186 state.curState = state.html;
187 if (!state.php.context.prev) state.php = null;
185 return "meta";
188 return "meta";
186 } else {
189 } else {
187 return phpMode.token(stream, state.curState);
190 return phpMode.token(stream, state.curState);
188 }
191 }
189 }
192 }
190
193
191 return {
194 return {
192 startState: function() {
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 return {html: html,
198 return {html: html,
195 php: php,
199 php: php,
196 curMode: parserConfig.startOpen ? phpMode : htmlMode,
200 curMode: parserConfig.startOpen ? phpMode : htmlMode,
197 curState: parserConfig.startOpen ? php : html,
201 curState: parserConfig.startOpen ? php : html,
198 pending: null};
202 pending: null};
199 },
203 },
200
204
201 copyState: function(state) {
205 copyState: function(state) {
202 var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
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 if (state.curMode == htmlMode) cur = htmlNew;
208 if (state.curMode == htmlMode) cur = htmlNew;
205 else cur = phpNew;
209 else cur = phpNew;
206 return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
210 return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
207 pending: state.pending};
211 pending: state.pending};
208 },
212 },
209
213
210 token: dispatch,
214 token: dispatch,
211
215
212 indent: function(state, textAfter) {
216 indent: function(state, textAfter) {
213 if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) ||
217 if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) ||
214 (state.curMode == phpMode && /^\?>/.test(textAfter)))
218 (state.curMode == phpMode && /^\?>/.test(textAfter)))
215 return htmlMode.indent(state.html, textAfter);
219 return htmlMode.indent(state.html, textAfter);
216 return state.curMode.indent(state.curState, textAfter);
220 return state.curMode.indent(state.curState, textAfter);
217 },
221 },
218
222
219 blockCommentStart: "/*",
223 blockCommentStart: "/*",
220 blockCommentEnd: "*/",
224 blockCommentEnd: "*/",
221 lineComment: "//",
225 lineComment: "//",
222
226
223 innerMode: function(state) { return {state: state.curState, mode: state.curMode}; }
227 innerMode: function(state) { return {state: state.curState, mode: state.curMode}; }
224 };
228 };
225 }, "htmlmixed", "clike");
229 }, "htmlmixed", "clike");
226
230
227 CodeMirror.defineMIME("application/x-httpd-php", "php");
231 CodeMirror.defineMIME("application/x-httpd-php", "php");
228 CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
232 CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
229 CodeMirror.defineMIME("text/x-php", phpConfig);
233 CodeMirror.defineMIME("text/x-php", phpConfig);
230 });
234 });
@@ -1,358 +1,347 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 function wordRegexp(words) {
14 function wordRegexp(words) {
15 return new RegExp("^((" + words.join(")|(") + "))\\b");
15 return new RegExp("^((" + words.join(")|(") + "))\\b");
16 }
16 }
17
17
18 var wordOperators = wordRegexp(["and", "or", "not", "is"]);
18 var wordOperators = wordRegexp(["and", "or", "not", "is"]);
19 var commonKeywords = ["as", "assert", "break", "class", "continue",
19 var commonKeywords = ["as", "assert", "break", "class", "continue",
20 "def", "del", "elif", "else", "except", "finally",
20 "def", "del", "elif", "else", "except", "finally",
21 "for", "from", "global", "if", "import",
21 "for", "from", "global", "if", "import",
22 "lambda", "pass", "raise", "return",
22 "lambda", "pass", "raise", "return",
23 "try", "while", "with", "yield", "in"];
23 "try", "while", "with", "yield", "in"];
24 var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr",
24 var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr",
25 "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
25 "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
26 "enumerate", "eval", "filter", "float", "format", "frozenset",
26 "enumerate", "eval", "filter", "float", "format", "frozenset",
27 "getattr", "globals", "hasattr", "hash", "help", "hex", "id",
27 "getattr", "globals", "hasattr", "hash", "help", "hex", "id",
28 "input", "int", "isinstance", "issubclass", "iter", "len",
28 "input", "int", "isinstance", "issubclass", "iter", "len",
29 "list", "locals", "map", "max", "memoryview", "min", "next",
29 "list", "locals", "map", "max", "memoryview", "min", "next",
30 "object", "oct", "open", "ord", "pow", "property", "range",
30 "object", "oct", "open", "ord", "pow", "property", "range",
31 "repr", "reversed", "round", "set", "setattr", "slice",
31 "repr", "reversed", "round", "set", "setattr", "slice",
32 "sorted", "staticmethod", "str", "sum", "super", "tuple",
32 "sorted", "staticmethod", "str", "sum", "super", "tuple",
33 "type", "vars", "zip", "__import__", "NotImplemented",
33 "type", "vars", "zip", "__import__", "NotImplemented",
34 "Ellipsis", "__debug__"];
34 "Ellipsis", "__debug__"];
35 var py2 = {builtins: ["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
35 var py2 = {builtins: ["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
36 "file", "intern", "long", "raw_input", "reduce", "reload",
36 "file", "intern", "long", "raw_input", "reduce", "reload",
37 "unichr", "unicode", "xrange", "False", "True", "None"],
37 "unichr", "unicode", "xrange", "False", "True", "None"],
38 keywords: ["exec", "print"]};
38 keywords: ["exec", "print"]};
39 var py3 = {builtins: ["ascii", "bytes", "exec", "print"],
39 var py3 = {builtins: ["ascii", "bytes", "exec", "print"],
40 keywords: ["nonlocal", "False", "True", "None", "async", "await"]};
40 keywords: ["nonlocal", "False", "True", "None", "async", "await"]};
41
41
42 CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonBuiltins));
42 CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonBuiltins));
43
43
44 function top(state) {
44 function top(state) {
45 return state.scopes[state.scopes.length - 1];
45 return state.scopes[state.scopes.length - 1];
46 }
46 }
47
47
48 CodeMirror.defineMode("python", function(conf, parserConf) {
48 CodeMirror.defineMode("python", function(conf, parserConf) {
49 var ERRORCLASS = "error";
49 var ERRORCLASS = "error";
50
50
51 var singleDelimiters = parserConf.singleDelimiters || new RegExp("^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]");
51 var singleDelimiters = parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/;
52 var doubleOperators = parserConf.doubleOperators || new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
52 var doubleOperators = parserConf.doubleOperators || /^([!<>]==|<>|<<|>>|\/\/|\*\*)/;
53 var doubleDelimiters = parserConf.doubleDelimiters || new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
53 var doubleDelimiters = parserConf.doubleDelimiters || /^(\+=|\-=|\*=|%=|\/=|&=|\|=|\^=)/;
54 var tripleDelimiters = parserConf.tripleDelimiters || new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
54 var tripleDelimiters = parserConf.tripleDelimiters || /^(\/\/=|>>=|<<=|\*\*=)/;
55
55
56 if (parserConf.version && parseInt(parserConf.version, 10) == 3){
56 if (parserConf.version && parseInt(parserConf.version, 10) == 3){
57 // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
57 // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
58 var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!@]");
58 var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!@]/;
59 var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*");
59 var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
60 } else {
60 } else {
61 var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
61 var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!]/;
62 var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
62 var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
63 }
63 }
64
64
65 var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
65 var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
66
66
67 var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
67 var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
68 if(parserConf.extra_keywords != undefined){
68 if(parserConf.extra_keywords != undefined){
69 myKeywords = myKeywords.concat(parserConf.extra_keywords);
69 myKeywords = myKeywords.concat(parserConf.extra_keywords);
70 }
70 }
71 if(parserConf.extra_builtins != undefined){
71 if(parserConf.extra_builtins != undefined){
72 myBuiltins = myBuiltins.concat(parserConf.extra_builtins);
72 myBuiltins = myBuiltins.concat(parserConf.extra_builtins);
73 }
73 }
74 if (parserConf.version && parseInt(parserConf.version, 10) == 3) {
74 if (parserConf.version && parseInt(parserConf.version, 10) == 3) {
75 myKeywords = myKeywords.concat(py3.keywords);
75 myKeywords = myKeywords.concat(py3.keywords);
76 myBuiltins = myBuiltins.concat(py3.builtins);
76 myBuiltins = myBuiltins.concat(py3.builtins);
77 var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i");
77 var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i");
78 } else {
78 } else {
79 myKeywords = myKeywords.concat(py2.keywords);
79 myKeywords = myKeywords.concat(py2.keywords);
80 myBuiltins = myBuiltins.concat(py2.builtins);
80 myBuiltins = myBuiltins.concat(py2.builtins);
81 var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
81 var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
82 }
82 }
83 var keywords = wordRegexp(myKeywords);
83 var keywords = wordRegexp(myKeywords);
84 var builtins = wordRegexp(myBuiltins);
84 var builtins = wordRegexp(myBuiltins);
85
85
86 // tokenizers
86 // tokenizers
87 function tokenBase(stream, state) {
87 function tokenBase(stream, state) {
88 // Handle scope changes
88 // Handle scope changes
89 if (stream.sol() && top(state).type == "py") {
89 if (stream.sol() && top(state).type == "py") {
90 var scopeOffset = top(state).offset;
90 var scopeOffset = top(state).offset;
91 if (stream.eatSpace()) {
91 if (stream.eatSpace()) {
92 var lineOffset = stream.indentation();
92 var lineOffset = stream.indentation();
93 if (lineOffset > scopeOffset)
93 if (lineOffset > scopeOffset)
94 pushScope(stream, state, "py");
94 pushScope(stream, state, "py");
95 else if (lineOffset < scopeOffset && dedent(stream, state))
95 else if (lineOffset < scopeOffset && dedent(stream, state))
96 state.errorToken = true;
96 state.errorToken = true;
97 return null;
97 return null;
98 } else {
98 } else {
99 var style = tokenBaseInner(stream, state);
99 var style = tokenBaseInner(stream, state);
100 if (scopeOffset > 0 && dedent(stream, state))
100 if (scopeOffset > 0 && dedent(stream, state))
101 style += " " + ERRORCLASS;
101 style += " " + ERRORCLASS;
102 return style;
102 return style;
103 }
103 }
104 }
104 }
105 return tokenBaseInner(stream, state);
105 return tokenBaseInner(stream, state);
106 }
106 }
107
107
108 function tokenBaseInner(stream, state) {
108 function tokenBaseInner(stream, state) {
109 if (stream.eatSpace()) return null;
109 if (stream.eatSpace()) return null;
110
110
111 var ch = stream.peek();
111 var ch = stream.peek();
112
112
113 // Handle Comments
113 // Handle Comments
114 if (ch == "#") {
114 if (ch == "#") {
115 stream.skipToEnd();
115 stream.skipToEnd();
116 return "comment";
116 return "comment";
117 }
117 }
118
118
119 // Handle Number Literals
119 // Handle Number Literals
120 if (stream.match(/^[0-9\.]/, false)) {
120 if (stream.match(/^[0-9\.]/, false)) {
121 var floatLiteral = false;
121 var floatLiteral = false;
122 // Floats
122 // Floats
123 if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
123 if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
124 if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
124 if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
125 if (stream.match(/^\.\d+/)) { floatLiteral = true; }
125 if (stream.match(/^\.\d+/)) { floatLiteral = true; }
126 if (floatLiteral) {
126 if (floatLiteral) {
127 // Float literals may be "imaginary"
127 // Float literals may be "imaginary"
128 stream.eat(/J/i);
128 stream.eat(/J/i);
129 return "number";
129 return "number";
130 }
130 }
131 // Integers
131 // Integers
132 var intLiteral = false;
132 var intLiteral = false;
133 // Hex
133 // Hex
134 if (stream.match(/^0x[0-9a-f]+/i)) intLiteral = true;
134 if (stream.match(/^0x[0-9a-f]+/i)) intLiteral = true;
135 // Binary
135 // Binary
136 if (stream.match(/^0b[01]+/i)) intLiteral = true;
136 if (stream.match(/^0b[01]+/i)) intLiteral = true;
137 // Octal
137 // Octal
138 if (stream.match(/^0o[0-7]+/i)) intLiteral = true;
138 if (stream.match(/^0o[0-7]+/i)) intLiteral = true;
139 // Decimal
139 // Decimal
140 if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
140 if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) {
141 // Decimal literals may be "imaginary"
141 // Decimal literals may be "imaginary"
142 stream.eat(/J/i);
142 stream.eat(/J/i);
143 // TODO - Can you have imaginary longs?
143 // TODO - Can you have imaginary longs?
144 intLiteral = true;
144 intLiteral = true;
145 }
145 }
146 // Zero by itself with no other piece of number.
146 // Zero by itself with no other piece of number.
147 if (stream.match(/^0(?![\dx])/i)) intLiteral = true;
147 if (stream.match(/^0(?![\dx])/i)) intLiteral = true;
148 if (intLiteral) {
148 if (intLiteral) {
149 // Integer literals may be "long"
149 // Integer literals may be "long"
150 stream.eat(/L/i);
150 stream.eat(/L/i);
151 return "number";
151 return "number";
152 }
152 }
153 }
153 }
154
154
155 // Handle Strings
155 // Handle Strings
156 if (stream.match(stringPrefixes)) {
156 if (stream.match(stringPrefixes)) {
157 state.tokenize = tokenStringFactory(stream.current());
157 state.tokenize = tokenStringFactory(stream.current());
158 return state.tokenize(stream, state);
158 return state.tokenize(stream, state);
159 }
159 }
160
160
161 // Handle operators and Delimiters
161 // Handle operators and Delimiters
162 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
162 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
163 return null;
163 return "punctuation";
164
164
165 if (stream.match(doubleOperators) || stream.match(singleOperators))
165 if (stream.match(doubleOperators) || stream.match(singleOperators))
166 return "operator";
166 return "operator";
167
167
168 if (stream.match(singleDelimiters))
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 if (stream.match(keywords) || stream.match(wordOperators))
174 if (stream.match(keywords) || stream.match(wordOperators))
172 return "keyword";
175 return "keyword";
173
176
174 if (stream.match(builtins))
177 if (stream.match(builtins))
175 return "builtin";
178 return "builtin";
176
179
177 if (stream.match(/^(self|cls)\b/))
180 if (stream.match(/^(self|cls)\b/))
178 return "variable-2";
181 return "variable-2";
179
182
180 if (stream.match(identifiers)) {
183 if (stream.match(identifiers)) {
181 if (state.lastToken == "def" || state.lastToken == "class")
184 if (state.lastToken == "def" || state.lastToken == "class")
182 return "def";
185 return "def";
183 return "variable";
186 return "variable";
184 }
187 }
185
188
186 // Handle non-detected items
189 // Handle non-detected items
187 stream.next();
190 stream.next();
188 return ERRORCLASS;
191 return ERRORCLASS;
189 }
192 }
190
193
191 function tokenStringFactory(delimiter) {
194 function tokenStringFactory(delimiter) {
192 while ("rub".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
195 while ("rub".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
193 delimiter = delimiter.substr(1);
196 delimiter = delimiter.substr(1);
194
197
195 var singleline = delimiter.length == 1;
198 var singleline = delimiter.length == 1;
196 var OUTCLASS = "string";
199 var OUTCLASS = "string";
197
200
198 function tokenString(stream, state) {
201 function tokenString(stream, state) {
199 while (!stream.eol()) {
202 while (!stream.eol()) {
200 stream.eatWhile(/[^'"\\]/);
203 stream.eatWhile(/[^'"\\]/);
201 if (stream.eat("\\")) {
204 if (stream.eat("\\")) {
202 stream.next();
205 stream.next();
203 if (singleline && stream.eol())
206 if (singleline && stream.eol())
204 return OUTCLASS;
207 return OUTCLASS;
205 } else if (stream.match(delimiter)) {
208 } else if (stream.match(delimiter)) {
206 state.tokenize = tokenBase;
209 state.tokenize = tokenBase;
207 return OUTCLASS;
210 return OUTCLASS;
208 } else {
211 } else {
209 stream.eat(/['"]/);
212 stream.eat(/['"]/);
210 }
213 }
211 }
214 }
212 if (singleline) {
215 if (singleline) {
213 if (parserConf.singleLineStringErrors)
216 if (parserConf.singleLineStringErrors)
214 return ERRORCLASS;
217 return ERRORCLASS;
215 else
218 else
216 state.tokenize = tokenBase;
219 state.tokenize = tokenBase;
217 }
220 }
218 return OUTCLASS;
221 return OUTCLASS;
219 }
222 }
220 tokenString.isString = true;
223 tokenString.isString = true;
221 return tokenString;
224 return tokenString;
222 }
225 }
223
226
224 function pushScope(stream, state, type) {
227 function pushScope(stream, state, type) {
225 var offset = 0, align = null;
228 var offset = 0, align = null;
226 if (type == "py") {
229 if (type == "py") {
227 while (top(state).type != "py")
230 while (top(state).type != "py")
228 state.scopes.pop();
231 state.scopes.pop();
229 }
232 }
230 offset = top(state).offset + (type == "py" ? conf.indentUnit : hangingIndent);
233 offset = top(state).offset + (type == "py" ? conf.indentUnit : hangingIndent);
231 if (type != "py" && !stream.match(/^(\s|#.*)*$/, false))
234 if (type != "py" && !stream.match(/^(\s|#.*)*$/, false))
232 align = stream.column() + 1;
235 align = stream.column() + 1;
233 state.scopes.push({offset: offset, type: type, align: align});
236 state.scopes.push({offset: offset, type: type, align: align});
234 }
237 }
235
238
236 function dedent(stream, state) {
239 function dedent(stream, state) {
237 var indented = stream.indentation();
240 var indented = stream.indentation();
238 while (top(state).offset > indented) {
241 while (top(state).offset > indented) {
239 if (top(state).type != "py") return true;
242 if (top(state).type != "py") return true;
240 state.scopes.pop();
243 state.scopes.pop();
241 }
244 }
242 return top(state).offset != indented;
245 return top(state).offset != indented;
243 }
246 }
244
247
245 function tokenLexer(stream, state) {
248 function tokenLexer(stream, state) {
246 var style = state.tokenize(stream, state);
249 var style = state.tokenize(stream, state);
247 var current = stream.current();
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 // Handle decorators
252 // Handle decorators
261 if (current == "@"){
253 if (current == "@"){
262 if(parserConf.version && parseInt(parserConf.version, 10) == 3){
254 if(parserConf.version && parseInt(parserConf.version, 10) == 3){
263 return stream.match(identifiers, false) ? "meta" : "operator";
255 return stream.match(identifiers, false) ? "meta" : "operator";
264 } else {
256 } else {
265 return stream.match(identifiers, false) ? "meta" : ERRORCLASS;
257 return stream.match(identifiers, false) ? "meta" : ERRORCLASS;
266 }
258 }
267 }
259 }
268
260
269 if ((style == "variable" || style == "builtin")
261 if ((style == "variable" || style == "builtin")
270 && state.lastStyle == "meta")
262 && state.lastToken == "meta")
271 style = "meta";
263 style = "meta";
272
264
273 // Handle scope changes.
265 // Handle scope changes.
274 if (current == "pass" || current == "return")
266 if (current == "pass" || current == "return")
275 state.dedent += 1;
267 state.dedent += 1;
276
268
277 if (current == "lambda") state.lambda = true;
269 if (current == "lambda") state.lambda = true;
278 if (current == ":" && !state.lambda && top(state).type == "py")
270 if (current == ":" && !state.lambda && top(state).type == "py")
279 pushScope(stream, state, "py");
271 pushScope(stream, state, "py");
280
272
281 var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1;
273 var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1;
282 if (delimiter_index != -1)
274 if (delimiter_index != -1)
283 pushScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
275 pushScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
284
276
285 delimiter_index = "])}".indexOf(current);
277 delimiter_index = "])}".indexOf(current);
286 if (delimiter_index != -1) {
278 if (delimiter_index != -1) {
287 if (top(state).type == current) state.scopes.pop();
279 if (top(state).type == current) state.scopes.pop();
288 else return ERRORCLASS;
280 else return ERRORCLASS;
289 }
281 }
290 if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
282 if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
291 if (state.scopes.length > 1) state.scopes.pop();
283 if (state.scopes.length > 1) state.scopes.pop();
292 state.dedent -= 1;
284 state.dedent -= 1;
293 }
285 }
294
286
295 return style;
287 return style;
296 }
288 }
297
289
298 var external = {
290 var external = {
299 startState: function(basecolumn) {
291 startState: function(basecolumn) {
300 return {
292 return {
301 tokenize: tokenBase,
293 tokenize: tokenBase,
302 scopes: [{offset: basecolumn || 0, type: "py", align: null}],
294 scopes: [{offset: basecolumn || 0, type: "py", align: null}],
303 lastStyle: null,
304 lastToken: null,
295 lastToken: null,
305 lambda: false,
296 lambda: false,
306 dedent: 0
297 dedent: 0
307 };
298 };
308 },
299 },
309
300
310 token: function(stream, state) {
301 token: function(stream, state) {
311 var addErr = state.errorToken;
302 var addErr = state.errorToken;
312 if (addErr) state.errorToken = false;
303 if (addErr) state.errorToken = false;
313 var style = tokenLexer(stream, state);
304 var style = tokenLexer(stream, state);
314
305
315 state.lastStyle = style;
306 if (style && style != "comment")
316
307 state.lastToken = (style == "keyword" || style == "punctuation") ? stream.current() : style;
317 var current = stream.current();
308 if (style == "punctuation") style = null;
318 if (current && style)
319 state.lastToken = current;
320
309
321 if (stream.eol() && state.lambda)
310 if (stream.eol() && state.lambda)
322 state.lambda = false;
311 state.lambda = false;
323 return addErr ? style + " " + ERRORCLASS : style;
312 return addErr ? style + " " + ERRORCLASS : style;
324 },
313 },
325
314
326 indent: function(state, textAfter) {
315 indent: function(state, textAfter) {
327 if (state.tokenize != tokenBase)
316 if (state.tokenize != tokenBase)
328 return state.tokenize.isString ? CodeMirror.Pass : 0;
317 return state.tokenize.isString ? CodeMirror.Pass : 0;
329
318
330 var scope = top(state);
319 var scope = top(state);
331 var closing = textAfter && textAfter.charAt(0) == scope.type;
320 var closing = textAfter && textAfter.charAt(0) == scope.type;
332 if (scope.align != null)
321 if (scope.align != null)
333 return scope.align - (closing ? 1 : 0);
322 return scope.align - (closing ? 1 : 0);
334 else if (closing && state.scopes.length > 1)
323 else if (closing && state.scopes.length > 1)
335 return state.scopes[state.scopes.length - 2].offset;
324 return state.scopes[state.scopes.length - 2].offset;
336 else
325 else
337 return scope.offset;
326 return scope.offset;
338 },
327 },
339
328
340 closeBrackets: {triples: "'\""},
329 closeBrackets: {triples: "'\""},
341 lineComment: "#",
330 lineComment: "#",
342 fold: "indent"
331 fold: "indent"
343 };
332 };
344 return external;
333 return external;
345 });
334 });
346
335
347 CodeMirror.defineMIME("text/x-python", "python");
336 CodeMirror.defineMIME("text/x-python", "python");
348
337
349 var words = function(str) { return str.split(" "); };
338 var words = function(str) { return str.split(" "); };
350
339
351 CodeMirror.defineMIME("text/x-cython", {
340 CodeMirror.defineMIME("text/x-cython", {
352 name: "python",
341 name: "python",
353 extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
342 extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
354 "extern gil include nogil property public"+
343 "extern gil include nogil property public"+
355 "readonly struct union DEF IF ELIF ELSE")
344 "readonly struct union DEF IF ELIF ELSE")
356 });
345 });
357
346
358 });
347 });
@@ -1,101 +1,109 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("rpm-changes", function() {
14 CodeMirror.defineMode("rpm-changes", function() {
15 var headerSeperator = /^-+$/;
15 var headerSeperator = /^-+$/;
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} - /;
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 var simpleEmail = /^[\w+.-]+@[\w.-]+/;
17 var simpleEmail = /^[\w+.-]+@[\w.-]+/;
18
18
19 return {
19 return {
20 token: function(stream) {
20 token: function(stream) {
21 if (stream.sol()) {
21 if (stream.sol()) {
22 if (stream.match(headerSeperator)) { return 'tag'; }
22 if (stream.match(headerSeperator)) { return 'tag'; }
23 if (stream.match(headerLine)) { return 'tag'; }
23 if (stream.match(headerLine)) { return 'tag'; }
24 }
24 }
25 if (stream.match(simpleEmail)) { return 'string'; }
25 if (stream.match(simpleEmail)) { return 'string'; }
26 stream.next();
26 stream.next();
27 return null;
27 return null;
28 }
28 }
29 };
29 };
30 });
30 });
31
31
32 CodeMirror.defineMIME("text/x-rpm-changes", "rpm-changes");
32 CodeMirror.defineMIME("text/x-rpm-changes", "rpm-changes");
33
33
34 // Quick and dirty spec file highlighting
34 // Quick and dirty spec file highlighting
35
35
36 CodeMirror.defineMode("rpm-spec", function() {
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):/;
39 var preamble = /^[a-zA-Z0-9()]+:/;
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)/;
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 var control_flow_complex = /^%(ifnarch|ifarch|if)/; // rpm control flow macros
41 var control_flow_complex = /^%(ifnarch|ifarch|if)/; // rpm control flow macros
42 var control_flow_simple = /^%(else|endif)/; // rpm control flow macros
42 var control_flow_simple = /^%(else|endif)/; // rpm control flow macros
43 var operators = /^(\!|\?|\<\=|\<|\>\=|\>|\=\=|\&\&|\|\|)/; // operators in control flow macros
43 var operators = /^(\!|\?|\<\=|\<|\>\=|\>|\=\=|\&\&|\|\|)/; // operators in control flow macros
44
44
45 return {
45 return {
46 startState: function () {
46 startState: function () {
47 return {
47 return {
48 controlFlow: false,
48 controlFlow: false,
49 macroParameters: false,
49 macroParameters: false,
50 section: false
50 section: false
51 };
51 };
52 },
52 },
53 token: function (stream, state) {
53 token: function (stream, state) {
54 var ch = stream.peek();
54 var ch = stream.peek();
55 if (ch == "#") { stream.skipToEnd(); return "comment"; }
55 if (ch == "#") { stream.skipToEnd(); return "comment"; }
56
56
57 if (stream.sol()) {
57 if (stream.sol()) {
58 if (stream.match(preamble)) { return "preamble"; }
58 if (stream.match(preamble)) { return "header"; }
59 if (stream.match(section)) { return "section"; }
59 if (stream.match(section)) { return "atom"; }
60 }
60 }
61
61
62 if (stream.match(/^\$\w+/)) { return "def"; } // Variables like '$RPM_BUILD_ROOT'
62 if (stream.match(/^\$\w+/)) { return "def"; } // Variables like '$RPM_BUILD_ROOT'
63 if (stream.match(/^\$\{\w+\}/)) { return "def"; } // Variables like '${RPM_BUILD_ROOT}'
63 if (stream.match(/^\$\{\w+\}/)) { return "def"; } // Variables like '${RPM_BUILD_ROOT}'
64
64
65 if (stream.match(control_flow_simple)) { return "keyword"; }
65 if (stream.match(control_flow_simple)) { return "keyword"; }
66 if (stream.match(control_flow_complex)) {
66 if (stream.match(control_flow_complex)) {
67 state.controlFlow = true;
67 state.controlFlow = true;
68 return "keyword";
68 return "keyword";
69 }
69 }
70 if (state.controlFlow) {
70 if (state.controlFlow) {
71 if (stream.match(operators)) { return "operator"; }
71 if (stream.match(operators)) { return "operator"; }
72 if (stream.match(/^(\d+)/)) { return "number"; }
72 if (stream.match(/^(\d+)/)) { return "number"; }
73 if (stream.eol()) { state.controlFlow = false; }
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 // Macros like '%make_install' or '%attr(0775,root,root)'
81 // Macros like '%make_install' or '%attr(0775,root,root)'
79 if (stream.match(/^%[\w]+/)) {
82 if (stream.match(/^%[\w]+/)) {
80 if (stream.match(/^\(/)) { state.macroParameters = true; }
83 if (stream.match(/^\(/)) { state.macroParameters = true; }
81 return "macro";
84 return "keyword";
82 }
85 }
83 if (state.macroParameters) {
86 if (state.macroParameters) {
84 if (stream.match(/^\d+/)) { return "number";}
87 if (stream.match(/^\d+/)) { return "number";}
85 if (stream.match(/^\)/)) {
88 if (stream.match(/^\)/)) {
86 state.macroParameters = false;
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 //TODO: Include bash script sub-parser (CodeMirror supports that)
100 //TODO: Include bash script sub-parser (CodeMirror supports that)
93 stream.next();
101 stream.next();
94 return null;
102 return null;
95 }
103 }
96 };
104 };
97 });
105 });
98
106
99 CodeMirror.defineMIME("text/x-rpm-spec", "rpm-spec");
107 CodeMirror.defineMIME("text/x-rpm-spec", "rpm-spec");
100
108
101 });
109 });
@@ -1,285 +1,285 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("ruby", function(config) {
14 CodeMirror.defineMode("ruby", function(config) {
15 function wordObj(words) {
15 function wordObj(words) {
16 var o = {};
16 var o = {};
17 for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
17 for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
18 return o;
18 return o;
19 }
19 }
20 var keywords = wordObj([
20 var keywords = wordObj([
21 "alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else",
21 "alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else",
22 "elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or",
22 "elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or",
23 "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
23 "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
24 "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
24 "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
25 "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
25 "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
26 "require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
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 "catch", "loop", "proc", "begin"]);
29 "catch", "loop", "proc", "begin"]);
30 var dedentWords = wordObj(["end", "until"]);
30 var dedentWords = wordObj(["end", "until"]);
31 var matching = {"[": "]", "{": "}", "(": ")"};
31 var matching = {"[": "]", "{": "}", "(": ")"};
32 var curPunc;
32 var curPunc;
33
33
34 function chain(newtok, stream, state) {
34 function chain(newtok, stream, state) {
35 state.tokenize.push(newtok);
35 state.tokenize.push(newtok);
36 return newtok(stream, state);
36 return newtok(stream, state);
37 }
37 }
38
38
39 function tokenBase(stream, state) {
39 function tokenBase(stream, state) {
40 curPunc = null;
41 if (stream.sol() && stream.match("=begin") && stream.eol()) {
40 if (stream.sol() && stream.match("=begin") && stream.eol()) {
42 state.tokenize.push(readBlockComment);
41 state.tokenize.push(readBlockComment);
43 return "comment";
42 return "comment";
44 }
43 }
45 if (stream.eatSpace()) return null;
44 if (stream.eatSpace()) return null;
46 var ch = stream.next(), m;
45 var ch = stream.next(), m;
47 if (ch == "`" || ch == "'" || ch == '"') {
46 if (ch == "`" || ch == "'" || ch == '"') {
48 return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
47 return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
49 } else if (ch == "/") {
48 } else if (ch == "/") {
50 var currentIndex = stream.current().length;
49 var currentIndex = stream.current().length;
51 if (stream.skipTo("/")) {
50 if (stream.skipTo("/")) {
52 var search_till = stream.current().length;
51 var search_till = stream.current().length;
53 stream.backUp(stream.current().length - currentIndex);
52 stream.backUp(stream.current().length - currentIndex);
54 var balance = 0; // balance brackets
53 var balance = 0; // balance brackets
55 while (stream.current().length < search_till) {
54 while (stream.current().length < search_till) {
56 var chchr = stream.next();
55 var chchr = stream.next();
57 if (chchr == "(") balance += 1;
56 if (chchr == "(") balance += 1;
58 else if (chchr == ")") balance -= 1;
57 else if (chchr == ")") balance -= 1;
59 if (balance < 0) break;
58 if (balance < 0) break;
60 }
59 }
61 stream.backUp(stream.current().length - currentIndex);
60 stream.backUp(stream.current().length - currentIndex);
62 if (balance == 0)
61 if (balance == 0)
63 return chain(readQuoted(ch, "string-2", true), stream, state);
62 return chain(readQuoted(ch, "string-2", true), stream, state);
64 }
63 }
65 return "operator";
64 return "operator";
66 } else if (ch == "%") {
65 } else if (ch == "%") {
67 var style = "string", embed = true;
66 var style = "string", embed = true;
68 if (stream.eat("s")) style = "atom";
67 if (stream.eat("s")) style = "atom";
69 else if (stream.eat(/[WQ]/)) style = "string";
68 else if (stream.eat(/[WQ]/)) style = "string";
70 else if (stream.eat(/[r]/)) style = "string-2";
69 else if (stream.eat(/[r]/)) style = "string-2";
71 else if (stream.eat(/[wxq]/)) { style = "string"; embed = false; }
70 else if (stream.eat(/[wxq]/)) { style = "string"; embed = false; }
72 var delim = stream.eat(/[^\w\s=]/);
71 var delim = stream.eat(/[^\w\s=]/);
73 if (!delim) return "operator";
72 if (!delim) return "operator";
74 if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
73 if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
75 return chain(readQuoted(delim, style, embed, true), stream, state);
74 return chain(readQuoted(delim, style, embed, true), stream, state);
76 } else if (ch == "#") {
75 } else if (ch == "#") {
77 stream.skipToEnd();
76 stream.skipToEnd();
78 return "comment";
77 return "comment";
79 } else if (ch == "<" && (m = stream.match(/^<-?[\`\"\']?([a-zA-Z_?]\w*)[\`\"\']?(?:;|$)/))) {
78 } else if (ch == "<" && (m = stream.match(/^<-?[\`\"\']?([a-zA-Z_?]\w*)[\`\"\']?(?:;|$)/))) {
80 return chain(readHereDoc(m[1]), stream, state);
79 return chain(readHereDoc(m[1]), stream, state);
81 } else if (ch == "0") {
80 } else if (ch == "0") {
82 if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/);
81 if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/);
83 else if (stream.eat("b")) stream.eatWhile(/[01]/);
82 else if (stream.eat("b")) stream.eatWhile(/[01]/);
84 else stream.eatWhile(/[0-7]/);
83 else stream.eatWhile(/[0-7]/);
85 return "number";
84 return "number";
86 } else if (/\d/.test(ch)) {
85 } else if (/\d/.test(ch)) {
87 stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/);
86 stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/);
88 return "number";
87 return "number";
89 } else if (ch == "?") {
88 } else if (ch == "?") {
90 while (stream.match(/^\\[CM]-/)) {}
89 while (stream.match(/^\\[CM]-/)) {}
91 if (stream.eat("\\")) stream.eatWhile(/\w/);
90 if (stream.eat("\\")) stream.eatWhile(/\w/);
92 else stream.next();
91 else stream.next();
93 return "string";
92 return "string";
94 } else if (ch == ":") {
93 } else if (ch == ":") {
95 if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
94 if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
96 if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
95 if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
97
96
98 // :> :>> :< :<< are valid symbols
97 // :> :>> :< :<< are valid symbols
99 if (stream.eat(/[\<\>]/)) {
98 if (stream.eat(/[\<\>]/)) {
100 stream.eat(/[\<\>]/);
99 stream.eat(/[\<\>]/);
101 return "atom";
100 return "atom";
102 }
101 }
103
102
104 // :+ :- :/ :* :| :& :! are valid symbols
103 // :+ :- :/ :* :| :& :! are valid symbols
105 if (stream.eat(/[\+\-\*\/\&\|\:\!]/)) {
104 if (stream.eat(/[\+\-\*\/\&\|\:\!]/)) {
106 return "atom";
105 return "atom";
107 }
106 }
108
107
109 // Symbols can't start by a digit
108 // Symbols can't start by a digit
110 if (stream.eat(/[a-zA-Z$@_\xa1-\uffff]/)) {
109 if (stream.eat(/[a-zA-Z$@_\xa1-\uffff]/)) {
111 stream.eatWhile(/[\w$\xa1-\uffff]/);
110 stream.eatWhile(/[\w$\xa1-\uffff]/);
112 // Only one ? ! = is allowed and only as the last character
111 // Only one ? ! = is allowed and only as the last character
113 stream.eat(/[\?\!\=]/);
112 stream.eat(/[\?\!\=]/);
114 return "atom";
113 return "atom";
115 }
114 }
116 return "operator";
115 return "operator";
117 } else if (ch == "@" && stream.match(/^@?[a-zA-Z_\xa1-\uffff]/)) {
116 } else if (ch == "@" && stream.match(/^@?[a-zA-Z_\xa1-\uffff]/)) {
118 stream.eat("@");
117 stream.eat("@");
119 stream.eatWhile(/[\w\xa1-\uffff]/);
118 stream.eatWhile(/[\w\xa1-\uffff]/);
120 return "variable-2";
119 return "variable-2";
121 } else if (ch == "$") {
120 } else if (ch == "$") {
122 if (stream.eat(/[a-zA-Z_]/)) {
121 if (stream.eat(/[a-zA-Z_]/)) {
123 stream.eatWhile(/[\w]/);
122 stream.eatWhile(/[\w]/);
124 } else if (stream.eat(/\d/)) {
123 } else if (stream.eat(/\d/)) {
125 stream.eat(/\d/);
124 stream.eat(/\d/);
126 } else {
125 } else {
127 stream.next(); // Must be a special global like $: or $!
126 stream.next(); // Must be a special global like $: or $!
128 }
127 }
129 return "variable-3";
128 return "variable-3";
130 } else if (/[a-zA-Z_\xa1-\uffff]/.test(ch)) {
129 } else if (/[a-zA-Z_\xa1-\uffff]/.test(ch)) {
131 stream.eatWhile(/[\w\xa1-\uffff]/);
130 stream.eatWhile(/[\w\xa1-\uffff]/);
132 stream.eat(/[\?\!]/);
131 stream.eat(/[\?\!]/);
133 if (stream.eat(":")) return "atom";
132 if (stream.eat(":")) return "atom";
134 return "ident";
133 return "ident";
135 } else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
134 } else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
136 curPunc = "|";
135 curPunc = "|";
137 return null;
136 return null;
138 } else if (/[\(\)\[\]{}\\;]/.test(ch)) {
137 } else if (/[\(\)\[\]{}\\;]/.test(ch)) {
139 curPunc = ch;
138 curPunc = ch;
140 return null;
139 return null;
141 } else if (ch == "-" && stream.eat(">")) {
140 } else if (ch == "-" && stream.eat(">")) {
142 return "arrow";
141 return "arrow";
143 } else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) {
142 } else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) {
144 var more = stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
143 var more = stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
145 if (ch == "." && !more) curPunc = ".";
144 if (ch == "." && !more) curPunc = ".";
146 return "operator";
145 return "operator";
147 } else {
146 } else {
148 return null;
147 return null;
149 }
148 }
150 }
149 }
151
150
152 function tokenBaseUntilBrace(depth) {
151 function tokenBaseUntilBrace(depth) {
153 if (!depth) depth = 1;
152 if (!depth) depth = 1;
154 return function(stream, state) {
153 return function(stream, state) {
155 if (stream.peek() == "}") {
154 if (stream.peek() == "}") {
156 if (depth == 1) {
155 if (depth == 1) {
157 state.tokenize.pop();
156 state.tokenize.pop();
158 return state.tokenize[state.tokenize.length-1](stream, state);
157 return state.tokenize[state.tokenize.length-1](stream, state);
159 } else {
158 } else {
160 state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth - 1);
159 state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth - 1);
161 }
160 }
162 } else if (stream.peek() == "{") {
161 } else if (stream.peek() == "{") {
163 state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth + 1);
162 state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth + 1);
164 }
163 }
165 return tokenBase(stream, state);
164 return tokenBase(stream, state);
166 };
165 };
167 }
166 }
168 function tokenBaseOnce() {
167 function tokenBaseOnce() {
169 var alreadyCalled = false;
168 var alreadyCalled = false;
170 return function(stream, state) {
169 return function(stream, state) {
171 if (alreadyCalled) {
170 if (alreadyCalled) {
172 state.tokenize.pop();
171 state.tokenize.pop();
173 return state.tokenize[state.tokenize.length-1](stream, state);
172 return state.tokenize[state.tokenize.length-1](stream, state);
174 }
173 }
175 alreadyCalled = true;
174 alreadyCalled = true;
176 return tokenBase(stream, state);
175 return tokenBase(stream, state);
177 };
176 };
178 }
177 }
179 function readQuoted(quote, style, embed, unescaped) {
178 function readQuoted(quote, style, embed, unescaped) {
180 return function(stream, state) {
179 return function(stream, state) {
181 var escaped = false, ch;
180 var escaped = false, ch;
182
181
183 if (state.context.type === 'read-quoted-paused') {
182 if (state.context.type === 'read-quoted-paused') {
184 state.context = state.context.prev;
183 state.context = state.context.prev;
185 stream.eat("}");
184 stream.eat("}");
186 }
185 }
187
186
188 while ((ch = stream.next()) != null) {
187 while ((ch = stream.next()) != null) {
189 if (ch == quote && (unescaped || !escaped)) {
188 if (ch == quote && (unescaped || !escaped)) {
190 state.tokenize.pop();
189 state.tokenize.pop();
191 break;
190 break;
192 }
191 }
193 if (embed && ch == "#" && !escaped) {
192 if (embed && ch == "#" && !escaped) {
194 if (stream.eat("{")) {
193 if (stream.eat("{")) {
195 if (quote == "}") {
194 if (quote == "}") {
196 state.context = {prev: state.context, type: 'read-quoted-paused'};
195 state.context = {prev: state.context, type: 'read-quoted-paused'};
197 }
196 }
198 state.tokenize.push(tokenBaseUntilBrace());
197 state.tokenize.push(tokenBaseUntilBrace());
199 break;
198 break;
200 } else if (/[@\$]/.test(stream.peek())) {
199 } else if (/[@\$]/.test(stream.peek())) {
201 state.tokenize.push(tokenBaseOnce());
200 state.tokenize.push(tokenBaseOnce());
202 break;
201 break;
203 }
202 }
204 }
203 }
205 escaped = !escaped && ch == "\\";
204 escaped = !escaped && ch == "\\";
206 }
205 }
207 return style;
206 return style;
208 };
207 };
209 }
208 }
210 function readHereDoc(phrase) {
209 function readHereDoc(phrase) {
211 return function(stream, state) {
210 return function(stream, state) {
212 if (stream.match(phrase)) state.tokenize.pop();
211 if (stream.match(phrase)) state.tokenize.pop();
213 else stream.skipToEnd();
212 else stream.skipToEnd();
214 return "string";
213 return "string";
215 };
214 };
216 }
215 }
217 function readBlockComment(stream, state) {
216 function readBlockComment(stream, state) {
218 if (stream.sol() && stream.match("=end") && stream.eol())
217 if (stream.sol() && stream.match("=end") && stream.eol())
219 state.tokenize.pop();
218 state.tokenize.pop();
220 stream.skipToEnd();
219 stream.skipToEnd();
221 return "comment";
220 return "comment";
222 }
221 }
223
222
224 return {
223 return {
225 startState: function() {
224 startState: function() {
226 return {tokenize: [tokenBase],
225 return {tokenize: [tokenBase],
227 indented: 0,
226 indented: 0,
228 context: {type: "top", indented: -config.indentUnit},
227 context: {type: "top", indented: -config.indentUnit},
229 continuedLine: false,
228 continuedLine: false,
230 lastTok: null,
229 lastTok: null,
231 varList: false};
230 varList: false};
232 },
231 },
233
232
234 token: function(stream, state) {
233 token: function(stream, state) {
234 curPunc = null;
235 if (stream.sol()) state.indented = stream.indentation();
235 if (stream.sol()) state.indented = stream.indentation();
236 var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
236 var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
237 var thisTok = curPunc;
237 var thisTok = curPunc;
238 if (style == "ident") {
238 if (style == "ident") {
239 var word = stream.current();
239 var word = stream.current();
240 style = state.lastTok == "." ? "property"
240 style = state.lastTok == "." ? "property"
241 : keywords.propertyIsEnumerable(stream.current()) ? "keyword"
241 : keywords.propertyIsEnumerable(stream.current()) ? "keyword"
242 : /^[A-Z]/.test(word) ? "tag"
242 : /^[A-Z]/.test(word) ? "tag"
243 : (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def"
243 : (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def"
244 : "variable";
244 : "variable";
245 if (style == "keyword") {
245 if (style == "keyword") {
246 thisTok = word;
246 thisTok = word;
247 if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
247 if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
248 else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
248 else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
249 else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
249 else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
250 kwtype = "indent";
250 kwtype = "indent";
251 else if (word == "do" && state.context.indented < state.indented)
251 else if (word == "do" && state.context.indented < state.indented)
252 kwtype = "indent";
252 kwtype = "indent";
253 }
253 }
254 }
254 }
255 if (curPunc || (style && style != "comment")) state.lastTok = thisTok;
255 if (curPunc || (style && style != "comment")) state.lastTok = thisTok;
256 if (curPunc == "|") state.varList = !state.varList;
256 if (curPunc == "|") state.varList = !state.varList;
257
257
258 if (kwtype == "indent" || /[\(\[\{]/.test(curPunc))
258 if (kwtype == "indent" || /[\(\[\{]/.test(curPunc))
259 state.context = {prev: state.context, type: curPunc || style, indented: state.indented};
259 state.context = {prev: state.context, type: curPunc || style, indented: state.indented};
260 else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev)
260 else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev)
261 state.context = state.context.prev;
261 state.context = state.context.prev;
262
262
263 if (stream.eol())
263 if (stream.eol())
264 state.continuedLine = (curPunc == "\\" || style == "operator");
264 state.continuedLine = (curPunc == "\\" || style == "operator");
265 return style;
265 return style;
266 },
266 },
267
267
268 indent: function(state, textAfter) {
268 indent: function(state, textAfter) {
269 if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0;
269 if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0;
270 var firstChar = textAfter && textAfter.charAt(0);
270 var firstChar = textAfter && textAfter.charAt(0);
271 var ct = state.context;
271 var ct = state.context;
272 var closing = ct.type == matching[firstChar] ||
272 var closing = ct.type == matching[firstChar] ||
273 ct.type == "keyword" && /^(?:end|until|else|elsif|when|rescue)\b/.test(textAfter);
273 ct.type == "keyword" && /^(?:end|until|else|elsif|when|rescue)\b/.test(textAfter);
274 return ct.indented + (closing ? 0 : config.indentUnit) +
274 return ct.indented + (closing ? 0 : config.indentUnit) +
275 (state.continuedLine ? config.indentUnit : 0);
275 (state.continuedLine ? config.indentUnit : 0);
276 },
276 },
277
277
278 electricChars: "}de", // enD and rescuE
278 electricInput: /^\s*(?:end|rescue|\})$/,
279 lineComment: "#"
279 lineComment: "#"
280 };
280 };
281 });
281 });
282
282
283 CodeMirror.defineMIME("text/x-ruby", "ruby");
283 CodeMirror.defineMIME("text/x-ruby", "ruby");
284
284
285 });
285 });
@@ -1,451 +1,71 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("rust", function() {
14 CodeMirror.defineSimpleMode("rust",{
15 var indentUnit = 4, altIndentUnit = 2;
15 start: [
16 var valKeywords = {
16 // string and byte string
17 "if": "if-style", "while": "if-style", "loop": "else-style", "else": "else-style",
17 {regex: /b?"/, token: "string", next: "string"},
18 "do": "else-style", "ret": "else-style", "fail": "else-style",
18 // raw string and raw byte string
19 "break": "atom", "cont": "atom", "const": "let", "resource": "fn",
19 {regex: /b?r"/, token: "string", next: "string_raw"},
20 "let": "let", "fn": "fn", "for": "for", "alt": "alt", "iface": "iface",
20 {regex: /b?r#+"/, token: "string", next: "string_raw_hash"},
21 "impl": "impl", "type": "type", "enum": "enum", "mod": "mod",
21 // character
22 "as": "op", "true": "atom", "false": "atom", "assert": "op", "check": "op",
22 {regex: /'(?:[^'\\]|\\(?:[nrt0'"]|x[\da-fA-F]{2}|u\{[\da-fA-F]{6}\}))'/, token: "string-2"},
23 "claim": "op", "native": "ignore", "unsafe": "ignore", "import": "else-style",
23 // byte
24 "export": "else-style", "copy": "op", "log": "op", "log_err": "op",
24 {regex: /b'(?:[^']|\\(?:['\\nrt0]|x[\da-fA-F]{2}))'/, token: "string-2"},
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 }
184
25
185 function stat_of(comb, tag) {
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)?/,
186 return cont(pushlex("stat", tag), comb, poplex, block);
27 token: "number"},
187 }
28 {regex: /(let(?:\s+mut)?|fn|enum|mod|struct|type)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/, token: ["keyword", null, "def"]},
188 function block(type) {
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"},
189 if (type == "}") return cont();
30 {regex: /\b(?:Self|isize|usize|char|bool|u8|u16|u32|u64|f16|f32|f64|i8|i16|i32|i64|str|Option)\b/, token: "atom"},
190 if (type == "let") return stat_of(letdef1, "let");
31 {regex: /\b(?:true|false|Some|None|Ok|Err)\b/, token: "builtin"},
191 if (type == "fn") return stat_of(fndef);
32 {regex: /\b(fn)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/,
192 if (type == "type") return cont(pushlex("stat"), tydef, endstatement, poplex, block);
33 token: ["keyword", null ,"def"]},
193 if (type == "enum") return stat_of(enumdef);
34 {regex: /#!?\[.*\]/, token: "meta"},
194 if (type == "mod") return stat_of(mod);
35 {regex: /\/\/.*/, token: "comment"},
195 if (type == "iface") return stat_of(iface);
36 {regex: /\/\*/, token: "comment", next: "comment"},
196 if (type == "impl") return stat_of(impl);
37 {regex: /[-+\/*=<>!]+/, token: "operator"},
197 if (type == "open-attr") return cont(pushlex("]"), commasep(expression, "]"), poplex);
38 {regex: /[a-zA-Z_]\w*!/,token: "variable-3"},
198 if (type == "ignore" || type.match(/[\]\);,]/)) return cont(block);
39 {regex: /[a-zA-Z_]\w*/, token: "variable"},
199 return pass(pushlex("stat"), expression, poplex, endstatement, block);
40 {regex: /[\{\[\(]/, indent: true},
200 }
41 {regex: /[\}\]\)]/, dedent: true}
201 function endstatement(type) {
42 ],
202 if (type == ";") return cont();
43 string: [
203 return pass();
44 {regex: /"/, token: "string", next: "start"},
204 }
45 {regex: /(?:[^\\"]|\\(?:.|$))*/, token: "string"}
205 function expression(type) {
46 ],
206 if (type == "atom" || type == "name") return cont(maybeop);
47 string_raw: [
207 if (type == "{") return cont(pushlex("}"), exprbrace, poplex);
48 {regex: /"/, token: "string", next: "start"},
208 if (type.match(/[\[\(]/)) return matchBrackets(type, expression);
49 {regex: /[^"]*/, token: "string"}
209 if (type.match(/[\]\)\};,]/)) return pass();
50 ],
210 if (type == "if-style") return cont(expression, expression);
51 string_raw_hash: [
211 if (type == "else-style" || type == "op") return cont(expression);
52 {regex: /"#+/, token: "string", next: "start"},
212 if (type == "for") return cont(pattern, maybetype, inop, expression, expression);
53 {regex: /(?:[^"]|"(?!#))*/, token: "string"}
213 if (type == "alt") return cont(expression, altbody);
54 ],
214 if (type == "fn") return cont(fndef);
55 comment: [
215 if (type == "macro") return cont(macro);
56 {regex: /.*?\*\//, token: "comment", next: "start"},
216 return cont();
57 {regex: /.*/, token: "comment"}
217 }
58 ],
218 function maybeop(type) {
59 meta: {
219 if (content == ".") return cont(maybeprop);
60 dontIndentStates: ["comment"],
220 if (content == "::<"){return cont(typarams, maybeop);}
61 electricInput: /^\s*\}$/,
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: "{}",
442 blockCommentStart: "/*",
62 blockCommentStart: "/*",
443 blockCommentEnd: "*/",
63 blockCommentEnd: "*/",
444 lineComment: "//",
64 lineComment: "//",
445 fold: "brace"
65 fold: "brace"
446 };
66 }
447 });
67 });
448
68
69
449 CodeMirror.defineMIME("text/x-rustsrc", "rust");
70 CodeMirror.defineMIME("text/x-rustsrc", "rust");
450
451 });
71 });
@@ -1,174 +1,176 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("sparql", function(config) {
14 CodeMirror.defineMode("sparql", function(config) {
15 var indentUnit = config.indentUnit;
15 var indentUnit = config.indentUnit;
16 var curPunc;
16 var curPunc;
17
17
18 function wordRegexp(words) {
18 function wordRegexp(words) {
19 return new RegExp("^(?:" + words.join("|") + ")$", "i");
19 return new RegExp("^(?:" + words.join("|") + ")$", "i");
20 }
20 }
21 var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
21 var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
22 "iri", "uri", "bnode", "count", "sum", "min", "max", "avg", "sample",
22 "iri", "uri", "bnode", "count", "sum", "min", "max", "avg", "sample",
23 "group_concat", "rand", "abs", "ceil", "floor", "round", "concat", "substr", "strlen",
23 "group_concat", "rand", "abs", "ceil", "floor", "round", "concat", "substr", "strlen",
24 "replace", "ucase", "lcase", "encode_for_uri", "contains", "strstarts", "strends",
24 "replace", "ucase", "lcase", "encode_for_uri", "contains", "strstarts", "strends",
25 "strbefore", "strafter", "year", "month", "day", "hours", "minutes", "seconds",
25 "strbefore", "strafter", "year", "month", "day", "hours", "minutes", "seconds",
26 "timezone", "tz", "now", "uuid", "struuid", "md5", "sha1", "sha256", "sha384",
26 "timezone", "tz", "now", "uuid", "struuid", "md5", "sha1", "sha256", "sha384",
27 "sha512", "coalesce", "if", "strlang", "strdt", "isnumeric", "regex", "exists",
27 "sha512", "coalesce", "if", "strlang", "strdt", "isnumeric", "regex", "exists",
28 "isblank", "isliteral", "a"]);
28 "isblank", "isliteral", "a"]);
29 var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
29 var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
30 "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
30 "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
31 "graph", "by", "asc", "desc", "as", "having", "undef", "values", "group",
31 "graph", "by", "asc", "desc", "as", "having", "undef", "values", "group",
32 "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union",
32 "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union",
33 "true", "false", "with",
33 "true", "false", "with",
34 "data", "copy", "to", "move", "add", "create", "drop", "clear", "load"]);
34 "data", "copy", "to", "move", "add", "create", "drop", "clear", "load"]);
35 var operatorChars = /[*+\-<>=&|\^\/!\?]/;
35 var operatorChars = /[*+\-<>=&|\^\/!\?]/;
36
36
37 function tokenBase(stream, state) {
37 function tokenBase(stream, state) {
38 var ch = stream.next();
38 var ch = stream.next();
39 curPunc = null;
39 curPunc = null;
40 if (ch == "$" || ch == "?") {
40 if (ch == "$" || ch == "?") {
41 if(ch == "?" && stream.match(/\s/, false)){
41 if(ch == "?" && stream.match(/\s/, false)){
42 return "operator";
42 return "operator";
43 }
43 }
44 stream.match(/^[\w\d]*/);
44 stream.match(/^[\w\d]*/);
45 return "variable-2";
45 return "variable-2";
46 }
46 }
47 else if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) {
47 else if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) {
48 stream.match(/^[^\s\u00a0>]*>?/);
48 stream.match(/^[^\s\u00a0>]*>?/);
49 return "atom";
49 return "atom";
50 }
50 }
51 else if (ch == "\"" || ch == "'") {
51 else if (ch == "\"" || ch == "'") {
52 state.tokenize = tokenLiteral(ch);
52 state.tokenize = tokenLiteral(ch);
53 return state.tokenize(stream, state);
53 return state.tokenize(stream, state);
54 }
54 }
55 else if (/[{}\(\),\.;\[\]]/.test(ch)) {
55 else if (/[{}\(\),\.;\[\]]/.test(ch)) {
56 curPunc = ch;
56 curPunc = ch;
57 return "bracket";
57 return "bracket";
58 }
58 }
59 else if (ch == "#") {
59 else if (ch == "#") {
60 stream.skipToEnd();
60 stream.skipToEnd();
61 return "comment";
61 return "comment";
62 }
62 }
63 else if (operatorChars.test(ch)) {
63 else if (operatorChars.test(ch)) {
64 stream.eatWhile(operatorChars);
64 stream.eatWhile(operatorChars);
65 return "operator";
65 return "operator";
66 }
66 }
67 else if (ch == ":") {
67 else if (ch == ":") {
68 stream.eatWhile(/[\w\d\._\-]/);
68 stream.eatWhile(/[\w\d\._\-]/);
69 return "atom";
69 return "atom";
70 }
70 }
71 else if (ch == "@") {
71 else if (ch == "@") {
72 stream.eatWhile(/[a-z\d\-]/i);
72 stream.eatWhile(/[a-z\d\-]/i);
73 return "meta";
73 return "meta";
74 }
74 }
75 else {
75 else {
76 stream.eatWhile(/[_\w\d]/);
76 stream.eatWhile(/[_\w\d]/);
77 if (stream.eat(":")) {
77 if (stream.eat(":")) {
78 stream.eatWhile(/[\w\d_\-]/);
78 stream.eatWhile(/[\w\d_\-]/);
79 return "atom";
79 return "atom";
80 }
80 }
81 var word = stream.current();
81 var word = stream.current();
82 if (ops.test(word))
82 if (ops.test(word))
83 return "builtin";
83 return "builtin";
84 else if (keywords.test(word))
84 else if (keywords.test(word))
85 return "keyword";
85 return "keyword";
86 else
86 else
87 return "variable";
87 return "variable";
88 }
88 }
89 }
89 }
90
90
91 function tokenLiteral(quote) {
91 function tokenLiteral(quote) {
92 return function(stream, state) {
92 return function(stream, state) {
93 var escaped = false, ch;
93 var escaped = false, ch;
94 while ((ch = stream.next()) != null) {
94 while ((ch = stream.next()) != null) {
95 if (ch == quote && !escaped) {
95 if (ch == quote && !escaped) {
96 state.tokenize = tokenBase;
96 state.tokenize = tokenBase;
97 break;
97 break;
98 }
98 }
99 escaped = !escaped && ch == "\\";
99 escaped = !escaped && ch == "\\";
100 }
100 }
101 return "string";
101 return "string";
102 };
102 };
103 }
103 }
104
104
105 function pushContext(state, type, col) {
105 function pushContext(state, type, col) {
106 state.context = {prev: state.context, indent: state.indent, col: col, type: type};
106 state.context = {prev: state.context, indent: state.indent, col: col, type: type};
107 }
107 }
108 function popContext(state) {
108 function popContext(state) {
109 state.indent = state.context.indent;
109 state.indent = state.context.indent;
110 state.context = state.context.prev;
110 state.context = state.context.prev;
111 }
111 }
112
112
113 return {
113 return {
114 startState: function() {
114 startState: function() {
115 return {tokenize: tokenBase,
115 return {tokenize: tokenBase,
116 context: null,
116 context: null,
117 indent: 0,
117 indent: 0,
118 col: 0};
118 col: 0};
119 },
119 },
120
120
121 token: function(stream, state) {
121 token: function(stream, state) {
122 if (stream.sol()) {
122 if (stream.sol()) {
123 if (state.context && state.context.align == null) state.context.align = false;
123 if (state.context && state.context.align == null) state.context.align = false;
124 state.indent = stream.indentation();
124 state.indent = stream.indentation();
125 }
125 }
126 if (stream.eatSpace()) return null;
126 if (stream.eatSpace()) return null;
127 var style = state.tokenize(stream, state);
127 var style = state.tokenize(stream, state);
128
128
129 if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") {
129 if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") {
130 state.context.align = true;
130 state.context.align = true;
131 }
131 }
132
132
133 if (curPunc == "(") pushContext(state, ")", stream.column());
133 if (curPunc == "(") pushContext(state, ")", stream.column());
134 else if (curPunc == "[") pushContext(state, "]", stream.column());
134 else if (curPunc == "[") pushContext(state, "]", stream.column());
135 else if (curPunc == "{") pushContext(state, "}", stream.column());
135 else if (curPunc == "{") pushContext(state, "}", stream.column());
136 else if (/[\]\}\)]/.test(curPunc)) {
136 else if (/[\]\}\)]/.test(curPunc)) {
137 while (state.context && state.context.type == "pattern") popContext(state);
137 while (state.context && state.context.type == "pattern") popContext(state);
138 if (state.context && curPunc == state.context.type) popContext(state);
138 if (state.context && curPunc == state.context.type) popContext(state);
139 }
139 }
140 else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state);
140 else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state);
141 else if (/atom|string|variable/.test(style) && state.context) {
141 else if (/atom|string|variable/.test(style) && state.context) {
142 if (/[\}\]]/.test(state.context.type))
142 if (/[\}\]]/.test(state.context.type))
143 pushContext(state, "pattern", stream.column());
143 pushContext(state, "pattern", stream.column());
144 else if (state.context.type == "pattern" && !state.context.align) {
144 else if (state.context.type == "pattern" && !state.context.align) {
145 state.context.align = true;
145 state.context.align = true;
146 state.context.col = stream.column();
146 state.context.col = stream.column();
147 }
147 }
148 }
148 }
149
149
150 return style;
150 return style;
151 },
151 },
152
152
153 indent: function(state, textAfter) {
153 indent: function(state, textAfter) {
154 var firstChar = textAfter && textAfter.charAt(0);
154 var firstChar = textAfter && textAfter.charAt(0);
155 var context = state.context;
155 var context = state.context;
156 if (/[\]\}]/.test(firstChar))
156 if (/[\]\}]/.test(firstChar))
157 while (context && context.type == "pattern") context = context.prev;
157 while (context && context.type == "pattern") context = context.prev;
158
158
159 var closing = context && firstChar == context.type;
159 var closing = context && firstChar == context.type;
160 if (!context)
160 if (!context)
161 return 0;
161 return 0;
162 else if (context.type == "pattern")
162 else if (context.type == "pattern")
163 return context.col;
163 return context.col;
164 else if (context.align)
164 else if (context.align)
165 return context.col + (closing ? 0 : 1);
165 return context.col + (closing ? 0 : 1);
166 else
166 else
167 return context.indent + (closing ? 0 : indentUnit);
167 return context.indent + (closing ? 0 : indentUnit);
168 }
168 },
169
170 lineComment: "#"
169 };
171 };
170 });
172 });
171
173
172 CodeMirror.defineMIME("application/sparql-query", "sparql");
174 CodeMirror.defineMIME("application/sparql-query", "sparql");
173
175
174 });
176 });
@@ -1,391 +1,391 b''
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("sql", function(config, parserConfig) {
14 CodeMirror.defineMode("sql", function(config, parserConfig) {
15 "use strict";
15 "use strict";
16
16
17 var client = parserConfig.client || {},
17 var client = parserConfig.client || {},
18 atoms = parserConfig.atoms || {"false": true, "true": true, "null": true},
18 atoms = parserConfig.atoms || {"false": true, "true": true, "null": true},
19 builtin = parserConfig.builtin || {},
19 builtin = parserConfig.builtin || {},
20 keywords = parserConfig.keywords || {},
20 keywords = parserConfig.keywords || {},
21 operatorChars = parserConfig.operatorChars || /^[*+\-%<>!=&|~^]/,
21 operatorChars = parserConfig.operatorChars || /^[*+\-%<>!=&|~^]/,
22 support = parserConfig.support || {},
22 support = parserConfig.support || {},
23 hooks = parserConfig.hooks || {},
23 hooks = parserConfig.hooks || {},
24 dateSQL = parserConfig.dateSQL || {"date" : true, "time" : true, "timestamp" : true};
24 dateSQL = parserConfig.dateSQL || {"date" : true, "time" : true, "timestamp" : true};
25
25
26 function tokenBase(stream, state) {
26 function tokenBase(stream, state) {
27 var ch = stream.next();
27 var ch = stream.next();
28
28
29 // call hooks from the mime type
29 // call hooks from the mime type
30 if (hooks[ch]) {
30 if (hooks[ch]) {
31 var result = hooks[ch](stream, state);
31 var result = hooks[ch](stream, state);
32 if (result !== false) return result;
32 if (result !== false) return result;
33 }
33 }
34
34
35 if (support.hexNumber == true &&
35 if (support.hexNumber == true &&
36 ((ch == "0" && stream.match(/^[xX][0-9a-fA-F]+/))
36 ((ch == "0" && stream.match(/^[xX][0-9a-fA-F]+/))
37 || (ch == "x" || ch == "X") && stream.match(/^'[0-9a-fA-F]+'/))) {
37 || (ch == "x" || ch == "X") && stream.match(/^'[0-9a-fA-F]+'/))) {
38 // hex
38 // hex
39 // ref: http://dev.mysql.com/doc/refman/5.5/en/hexadecimal-literals.html
39 // ref: http://dev.mysql.com/doc/refman/5.5/en/hexadecimal-literals.html
40 return "number";
40 return "number";
41 } else if (support.binaryNumber == true &&
41 } else if (support.binaryNumber == true &&
42 (((ch == "b" || ch == "B") && stream.match(/^'[01]+'/))
42 (((ch == "b" || ch == "B") && stream.match(/^'[01]+'/))
43 || (ch == "0" && stream.match(/^b[01]+/)))) {
43 || (ch == "0" && stream.match(/^b[01]+/)))) {
44 // bitstring
44 // bitstring
45 // ref: http://dev.mysql.com/doc/refman/5.5/en/bit-field-literals.html
45 // ref: http://dev.mysql.com/doc/refman/5.5/en/bit-field-literals.html
46 return "number";
46 return "number";
47 } else if (ch.charCodeAt(0) > 47 && ch.charCodeAt(0) < 58) {
47 } else if (ch.charCodeAt(0) > 47 && ch.charCodeAt(0) < 58) {
48 // numbers
48 // numbers
49 // ref: http://dev.mysql.com/doc/refman/5.5/en/number-literals.html
49 // ref: http://dev.mysql.com/doc/refman/5.5/en/number-literals.html
50 stream.match(/^[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/);
50 stream.match(/^[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/);
51 support.decimallessFloat == true && stream.eat('.');
51 support.decimallessFloat == true && stream.eat('.');
52 return "number";
52 return "number";
53 } else if (ch == "?" && (stream.eatSpace() || stream.eol() || stream.eat(";"))) {
53 } else if (ch == "?" && (stream.eatSpace() || stream.eol() || stream.eat(";"))) {
54 // placeholders
54 // placeholders
55 return "variable-3";
55 return "variable-3";
56 } else if (ch == "'" || (ch == '"' && support.doubleQuote)) {
56 } else if (ch == "'" || (ch == '"' && support.doubleQuote)) {
57 // strings
57 // strings
58 // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
58 // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
59 state.tokenize = tokenLiteral(ch);
59 state.tokenize = tokenLiteral(ch);
60 return state.tokenize(stream, state);
60 return state.tokenize(stream, state);
61 } else if ((((support.nCharCast == true && (ch == "n" || ch == "N"))
61 } else if ((((support.nCharCast == true && (ch == "n" || ch == "N"))
62 || (support.charsetCast == true && ch == "_" && stream.match(/[a-z][a-z0-9]*/i)))
62 || (support.charsetCast == true && ch == "_" && stream.match(/[a-z][a-z0-9]*/i)))
63 && (stream.peek() == "'" || stream.peek() == '"'))) {
63 && (stream.peek() == "'" || stream.peek() == '"'))) {
64 // charset casting: _utf8'str', N'str', n'str'
64 // charset casting: _utf8'str', N'str', n'str'
65 // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
65 // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
66 return "keyword";
66 return "keyword";
67 } else if (/^[\(\),\;\[\]]/.test(ch)) {
67 } else if (/^[\(\),\;\[\]]/.test(ch)) {
68 // no highlightning
68 // no highlightning
69 return null;
69 return null;
70 } else if (support.commentSlashSlash && ch == "/" && stream.eat("/")) {
70 } else if (support.commentSlashSlash && ch == "/" && stream.eat("/")) {
71 // 1-line comment
71 // 1-line comment
72 stream.skipToEnd();
72 stream.skipToEnd();
73 return "comment";
73 return "comment";
74 } else if ((support.commentHash && ch == "#")
74 } else if ((support.commentHash && ch == "#")
75 || (ch == "-" && stream.eat("-") && (!support.commentSpaceRequired || stream.eat(" ")))) {
75 || (ch == "-" && stream.eat("-") && (!support.commentSpaceRequired || stream.eat(" ")))) {
76 // 1-line comments
76 // 1-line comments
77 // ref: https://kb.askmonty.org/en/comment-syntax/
77 // ref: https://kb.askmonty.org/en/comment-syntax/
78 stream.skipToEnd();
78 stream.skipToEnd();
79 return "comment";
79 return "comment";
80 } else if (ch == "/" && stream.eat("*")) {
80 } else if (ch == "/" && stream.eat("*")) {
81 // multi-line comments
81 // multi-line comments
82 // ref: https://kb.askmonty.org/en/comment-syntax/
82 // ref: https://kb.askmonty.org/en/comment-syntax/
83 state.tokenize = tokenComment;
83 state.tokenize = tokenComment;
84 return state.tokenize(stream, state);
84 return state.tokenize(stream, state);
85 } else if (ch == ".") {
85 } else if (ch == ".") {
86 // .1 for 0.1
86 // .1 for 0.1
87 if (support.zerolessFloat == true && stream.match(/^(?:\d+(?:e[+-]?\d+)?)/i)) {
87 if (support.zerolessFloat == true && stream.match(/^(?:\d+(?:e[+-]?\d+)?)/i)) {
88 return "number";
88 return "number";
89 }
89 }
90 // .table_name (ODBC)
90 // .table_name (ODBC)
91 // // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
91 // // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
92 if (support.ODBCdotTable == true && stream.match(/^[a-zA-Z_]+/)) {
92 if (support.ODBCdotTable == true && stream.match(/^[a-zA-Z_]+/)) {
93 return "variable-2";
93 return "variable-2";
94 }
94 }
95 } else if (operatorChars.test(ch)) {
95 } else if (operatorChars.test(ch)) {
96 // operators
96 // operators
97 stream.eatWhile(operatorChars);
97 stream.eatWhile(operatorChars);
98 return null;
98 return null;
99 } else if (ch == '{' &&
99 } else if (ch == '{' &&
100 (stream.match(/^( )*(d|D|t|T|ts|TS)( )*'[^']*'( )*}/) || stream.match(/^( )*(d|D|t|T|ts|TS)( )*"[^"]*"( )*}/))) {
100 (stream.match(/^( )*(d|D|t|T|ts|TS)( )*'[^']*'( )*}/) || stream.match(/^( )*(d|D|t|T|ts|TS)( )*"[^"]*"( )*}/))) {
101 // dates (weird ODBC syntax)
101 // dates (weird ODBC syntax)
102 // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
102 // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
103 return "number";
103 return "number";
104 } else {
104 } else {
105 stream.eatWhile(/^[_\w\d]/);
105 stream.eatWhile(/^[_\w\d]/);
106 var word = stream.current().toLowerCase();
106 var word = stream.current().toLowerCase();
107 // dates (standard SQL syntax)
107 // dates (standard SQL syntax)
108 // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
108 // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
109 if (dateSQL.hasOwnProperty(word) && (stream.match(/^( )+'[^']*'/) || stream.match(/^( )+"[^"]*"/)))
109 if (dateSQL.hasOwnProperty(word) && (stream.match(/^( )+'[^']*'/) || stream.match(/^( )+"[^"]*"/)))
110 return "number";
110 return "number";
111 if (atoms.hasOwnProperty(word)) return "atom";
111 if (atoms.hasOwnProperty(word)) return "atom";
112 if (builtin.hasOwnProperty(word)) return "builtin";
112 if (builtin.hasOwnProperty(word)) return "builtin";
113 if (keywords.hasOwnProperty(word)) return "keyword";
113 if (keywords.hasOwnProperty(word)) return "keyword";
114 if (client.hasOwnProperty(word)) return "string-2";
114 if (client.hasOwnProperty(word)) return "string-2";
115 return null;
115 return null;
116 }
116 }
117 }
117 }
118
118
119 // 'string', with char specified in quote escaped by '\'
119 // 'string', with char specified in quote escaped by '\'
120 function tokenLiteral(quote) {
120 function tokenLiteral(quote) {
121 return function(stream, state) {
121 return function(stream, state) {
122 var escaped = false, ch;
122 var escaped = false, ch;
123 while ((ch = stream.next()) != null) {
123 while ((ch = stream.next()) != null) {
124 if (ch == quote && !escaped) {
124 if (ch == quote && !escaped) {
125 state.tokenize = tokenBase;
125 state.tokenize = tokenBase;
126 break;
126 break;
127 }
127 }
128 escaped = !escaped && ch == "\\";
128 escaped = !escaped && ch == "\\";
129 }
129 }
130 return "string";
130 return "string";
131 };
131 };
132 }
132 }
133 function tokenComment(stream, state) {
133 function tokenComment(stream, state) {
134 while (true) {
134 while (true) {
135 if (stream.skipTo("*")) {
135 if (stream.skipTo("*")) {
136 stream.next();
136 stream.next();
137 if (stream.eat("/")) {
137 if (stream.eat("/")) {
138 state.tokenize = tokenBase;
138 state.tokenize = tokenBase;
139 break;
139 break;
140 }
140 }
141 } else {
141 } else {
142 stream.skipToEnd();
142 stream.skipToEnd();
143 break;
143 break;
144 }
144 }
145 }
145 }
146 return "comment";
146 return "comment";
147 }
147 }
148
148
149 function pushContext(stream, state, type) {
149 function pushContext(stream, state, type) {
150 state.context = {
150 state.context = {
151 prev: state.context,
151 prev: state.context,
152 indent: stream.indentation(),
152 indent: stream.indentation(),
153 col: stream.column(),
153 col: stream.column(),
154 type: type
154 type: type
155 };
155 };
156 }
156 }
157
157
158 function popContext(state) {
158 function popContext(state) {
159 state.indent = state.context.indent;
159 state.indent = state.context.indent;
160 state.context = state.context.prev;
160 state.context = state.context.prev;
161 }
161 }
162
162
163 return {
163 return {
164 startState: function() {
164 startState: function() {
165 return {tokenize: tokenBase, context: null};
165 return {tokenize: tokenBase, context: null};
166 },
166 },
167
167
168 token: function(stream, state) {
168 token: function(stream, state) {
169 if (stream.sol()) {
169 if (stream.sol()) {
170 if (state.context && state.context.align == null)
170 if (state.context && state.context.align == null)
171 state.context.align = false;
171 state.context.align = false;
172 }
172 }
173 if (stream.eatSpace()) return null;
173 if (stream.eatSpace()) return null;
174
174
175 var style = state.tokenize(stream, state);
175 var style = state.tokenize(stream, state);
176 if (style == "comment") return style;
176 if (style == "comment") return style;
177
177
178 if (state.context && state.context.align == null)
178 if (state.context && state.context.align == null)
179 state.context.align = true;
179 state.context.align = true;
180
180
181 var tok = stream.current();
181 var tok = stream.current();
182 if (tok == "(")
182 if (tok == "(")
183 pushContext(stream, state, ")");
183 pushContext(stream, state, ")");
184 else if (tok == "[")
184 else if (tok == "[")
185 pushContext(stream, state, "]");
185 pushContext(stream, state, "]");
186 else if (state.context && state.context.type == tok)
186 else if (state.context && state.context.type == tok)
187 popContext(state);
187 popContext(state);
188 return style;
188 return style;
189 },
189 },
190
190
191 indent: function(state, textAfter) {
191 indent: function(state, textAfter) {
192 var cx = state.context;
192 var cx = state.context;
193 if (!cx) return CodeMirror.Pass;
193 if (!cx) return CodeMirror.Pass;
194 var closing = textAfter.charAt(0) == cx.type;
194 var closing = textAfter.charAt(0) == cx.type;
195 if (cx.align) return cx.col + (closing ? 0 : 1);
195 if (cx.align) return cx.col + (closing ? 0 : 1);
196 else return cx.indent + (closing ? 0 : config.indentUnit);
196 else return cx.indent + (closing ? 0 : config.indentUnit);
197 },
197 },
198
198
199 blockCommentStart: "/*",
199 blockCommentStart: "/*",
200 blockCommentEnd: "*/",
200 blockCommentEnd: "*/",
201 lineComment: support.commentSlashSlash ? "//" : support.commentHash ? "#" : null
201 lineComment: support.commentSlashSlash ? "//" : support.commentHash ? "#" : null
202 };
202 };
203 });
203 });
204
204
205 (function() {
205 (function() {
206 "use strict";
206 "use strict";
207
207
208 // `identifier`
208 // `identifier`
209 function hookIdentifier(stream) {
209 function hookIdentifier(stream) {
210 // MySQL/MariaDB identifiers
210 // MySQL/MariaDB identifiers
211 // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
211 // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
212 var ch;
212 var ch;
213 while ((ch = stream.next()) != null) {
213 while ((ch = stream.next()) != null) {
214 if (ch == "`" && !stream.eat("`")) return "variable-2";
214 if (ch == "`" && !stream.eat("`")) return "variable-2";
215 }
215 }
216 stream.backUp(stream.current().length - 1);
216 stream.backUp(stream.current().length - 1);
217 return stream.eatWhile(/\w/) ? "variable-2" : null;
217 return stream.eatWhile(/\w/) ? "variable-2" : null;
218 }
218 }
219
219
220 // variable token
220 // variable token
221 function hookVar(stream) {
221 function hookVar(stream) {
222 // variables
222 // variables
223 // @@prefix.varName @varName
223 // @@prefix.varName @varName
224 // varName can be quoted with ` or ' or "
224 // varName can be quoted with ` or ' or "
225 // ref: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
225 // ref: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
226 if (stream.eat("@")) {
226 if (stream.eat("@")) {
227 stream.match(/^session\./);
227 stream.match(/^session\./);
228 stream.match(/^local\./);
228 stream.match(/^local\./);
229 stream.match(/^global\./);
229 stream.match(/^global\./);
230 }
230 }
231
231
232 if (stream.eat("'")) {
232 if (stream.eat("'")) {
233 stream.match(/^.*'/);
233 stream.match(/^.*'/);
234 return "variable-2";
234 return "variable-2";
235 } else if (stream.eat('"')) {
235 } else if (stream.eat('"')) {
236 stream.match(/^.*"/);
236 stream.match(/^.*"/);
237 return "variable-2";
237 return "variable-2";
238 } else if (stream.eat("`")) {
238 } else if (stream.eat("`")) {
239 stream.match(/^.*`/);
239 stream.match(/^.*`/);
240 return "variable-2";
240 return "variable-2";
241 } else if (stream.match(/^[0-9a-zA-Z$\.\_]+/)) {
241 } else if (stream.match(/^[0-9a-zA-Z$\.\_]+/)) {
242 return "variable-2";
242 return "variable-2";
243 }
243 }
244 return null;
244 return null;
245 };
245 };
246
246
247 // short client keyword token
247 // short client keyword token
248 function hookClient(stream) {
248 function hookClient(stream) {
249 // \N means NULL
249 // \N means NULL
250 // ref: http://dev.mysql.com/doc/refman/5.5/en/null-values.html
250 // ref: http://dev.mysql.com/doc/refman/5.5/en/null-values.html
251 if (stream.eat("N")) {
251 if (stream.eat("N")) {
252 return "atom";
252 return "atom";
253 }
253 }
254 // \g, etc
254 // \g, etc
255 // ref: http://dev.mysql.com/doc/refman/5.5/en/mysql-commands.html
255 // ref: http://dev.mysql.com/doc/refman/5.5/en/mysql-commands.html
256 return stream.match(/^[a-zA-Z.#!?]/) ? "variable-2" : null;
256 return stream.match(/^[a-zA-Z.#!?]/) ? "variable-2" : null;
257 }
257 }
258
258
259 // these keywords are used by all SQL dialects (however, a mode can still overwrite it)
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 // turn a space-separated list into an array
262 // turn a space-separated list into an array
263 function set(str) {
263 function set(str) {
264 var obj = {}, words = str.split(" ");
264 var obj = {}, words = str.split(" ");
265 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
265 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
266 return obj;
266 return obj;
267 }
267 }
268
268
269 // A generic SQL Mode. It's not a standard, it just try to support what is generally supported
269 // A generic SQL Mode. It's not a standard, it just try to support what is generally supported
270 CodeMirror.defineMIME("text/x-sql", {
270 CodeMirror.defineMIME("text/x-sql", {
271 name: "sql",
271 name: "sql",
272 keywords: set(sqlKeywords + "begin"),
272 keywords: set(sqlKeywords + "begin"),
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"),
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 atoms: set("false true null unknown"),
274 atoms: set("false true null unknown"),
275 operatorChars: /^[*+\-%<>!=]/,
275 operatorChars: /^[*+\-%<>!=]/,
276 dateSQL: set("date time timestamp"),
276 dateSQL: set("date time timestamp"),
277 support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
277 support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
278 });
278 });
279
279
280 CodeMirror.defineMIME("text/x-mssql", {
280 CodeMirror.defineMIME("text/x-mssql", {
281 name: "sql",
281 name: "sql",
282 client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
282 client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
283 keywords: set(sqlKeywords + "begin trigger proc view index for add constraint key primary foreign collate clustered nonclustered declare"),
283 keywords: set(sqlKeywords + "begin trigger proc view index for add constraint key primary foreign collate clustered nonclustered declare"),
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 "),
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 atoms: set("false true null unknown"),
285 atoms: set("false true null unknown"),
286 operatorChars: /^[*+\-%<>!=]/,
286 operatorChars: /^[*+\-%<>!=]/,
287 dateSQL: set("date datetimeoffset datetime2 smalldatetime datetime time"),
287 dateSQL: set("date datetimeoffset datetime2 smalldatetime datetime time"),
288 hooks: {
288 hooks: {
289 "@": hookVar
289 "@": hookVar
290 }
290 }
291 });
291 });
292
292
293 CodeMirror.defineMIME("text/x-mysql", {
293 CodeMirror.defineMIME("text/x-mysql", {
294 name: "sql",
294 name: "sql",
295 client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
295 client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
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"),
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 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"),
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 atoms: set("false true null unknown"),
298 atoms: set("false true null unknown"),
299 operatorChars: /^[*+\-%<>!=&|^]/,
299 operatorChars: /^[*+\-%<>!=&|^]/,
300 dateSQL: set("date time timestamp"),
300 dateSQL: set("date time timestamp"),
301 support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
301 support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
302 hooks: {
302 hooks: {
303 "@": hookVar,
303 "@": hookVar,
304 "`": hookIdentifier,
304 "`": hookIdentifier,
305 "\\": hookClient
305 "\\": hookClient
306 }
306 }
307 });
307 });
308
308
309 CodeMirror.defineMIME("text/x-mariadb", {
309 CodeMirror.defineMIME("text/x-mariadb", {
310 name: "sql",
310 name: "sql",
311 client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
311 client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
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"),
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 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"),
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 atoms: set("false true null unknown"),
314 atoms: set("false true null unknown"),
315 operatorChars: /^[*+\-%<>!=&|^]/,
315 operatorChars: /^[*+\-%<>!=&|^]/,
316 dateSQL: set("date time timestamp"),
316 dateSQL: set("date time timestamp"),
317 support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
317 support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
318 hooks: {
318 hooks: {
319 "@": hookVar,
319 "@": hookVar,
320 "`": hookIdentifier,
320 "`": hookIdentifier,
321 "\\": hookClient
321 "\\": hookClient
322 }
322 }
323 });
323 });
324
324
325 // the query language used by Apache Cassandra is called CQL, but this mime type
325 // the query language used by Apache Cassandra is called CQL, but this mime type
326 // is called Cassandra to avoid confusion with Contextual Query Language
326 // is called Cassandra to avoid confusion with Contextual Query Language
327 CodeMirror.defineMIME("text/x-cassandra", {
327 CodeMirror.defineMIME("text/x-cassandra", {
328 name: "sql",
328 name: "sql",
329 client: { },
329 client: { },
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"),
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 builtin: set("ascii bigint blob boolean counter decimal double float frozen inet int list map static text timestamp timeuuid tuple uuid varchar varint"),
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 atoms: set("false true infinity NaN"),
332 atoms: set("false true infinity NaN"),
333 operatorChars: /^[<>=]/,
333 operatorChars: /^[<>=]/,
334 dateSQL: { },
334 dateSQL: { },
335 support: set("commentSlashSlash decimallessFloat"),
335 support: set("commentSlashSlash decimallessFloat"),
336 hooks: { }
336 hooks: { }
337 });
337 });
338
338
339 // this is based on Peter Raganitsch's 'plsql' mode
339 // this is based on Peter Raganitsch's 'plsql' mode
340 CodeMirror.defineMIME("text/x-plsql", {
340 CodeMirror.defineMIME("text/x-plsql", {
341 name: "sql",
341 name: "sql",
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"),
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 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"),
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 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"),
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 operatorChars: /^[*+\-%<>!=~]/,
345 operatorChars: /^[*+\-%<>!=~]/,
346 dateSQL: set("date time timestamp"),
346 dateSQL: set("date time timestamp"),
347 support: set("doubleQuote nCharCast zerolessFloat binaryNumber hexNumber")
347 support: set("doubleQuote nCharCast zerolessFloat binaryNumber hexNumber")
348 });
348 });
349
349
350 // Created to support specific hive keywords
350 // Created to support specific hive keywords
351 CodeMirror.defineMIME("text/x-hive", {
351 CodeMirror.defineMIME("text/x-hive", {
352 name: "sql",
352 name: "sql",
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"),
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 builtin: set("bool boolean long timestamp tinyint smallint bigint int float double date datetime unsigned string array struct map uniontype"),
354 builtin: set("bool boolean long timestamp tinyint smallint bigint int float double date datetime unsigned string array struct map uniontype"),
355 atoms: set("false true null unknown"),
355 atoms: set("false true null unknown"),
356 operatorChars: /^[*+\-%<>!=]/,
356 operatorChars: /^[*+\-%<>!=]/,
357 dateSQL: set("date timestamp"),
357 dateSQL: set("date timestamp"),
358 support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
358 support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
359 });
359 });
360 }());
360 }());
361
361
362 });
362 });
363
363
364 /*
364 /*
365 How Properties of Mime Types are used by SQL Mode
365 How Properties of Mime Types are used by SQL Mode
366 =================================================
366 =================================================
367
367
368 keywords:
368 keywords:
369 A list of keywords you want to be highlighted.
369 A list of keywords you want to be highlighted.
370 builtin:
370 builtin:
371 A list of builtin types you want to be highlighted (if you want types to be of class "builtin" instead of "keyword").
371 A list of builtin types you want to be highlighted (if you want types to be of class "builtin" instead of "keyword").
372 operatorChars:
372 operatorChars:
373 All characters that must be handled as operators.
373 All characters that must be handled as operators.
374 client:
374 client:
375 Commands parsed and executed by the client (not the server).
375 Commands parsed and executed by the client (not the server).
376 support:
376 support:
377 A list of supported syntaxes which are not common, but are supported by more than 1 DBMS.
377 A list of supported syntaxes which are not common, but are supported by more than 1 DBMS.
378 * ODBCdotTable: .tableName
378 * ODBCdotTable: .tableName
379 * zerolessFloat: .1
379 * zerolessFloat: .1
380 * doubleQuote
380 * doubleQuote
381 * nCharCast: N'string'
381 * nCharCast: N'string'
382 * charsetCast: _utf8'string'
382 * charsetCast: _utf8'string'
383 * commentHash: use # char for comments
383 * commentHash: use # char for comments
384 * commentSlashSlash: use // for comments
384 * commentSlashSlash: use // for comments
385 * commentSpaceRequired: require a space after -- for comments
385 * commentSpaceRequired: require a space after -- for comments
386 atoms:
386 atoms:
387 Keywords that must be highlighted as atoms,. Some DBMS's support more atoms than others:
387 Keywords that must be highlighted as atoms,. Some DBMS's support more atoms than others:
388 UNKNOWN, INFINITY, UNDERFLOW, NaN...
388 UNKNOWN, INFINITY, UNDERFLOW, NaN...
389 dateSQL:
389 dateSQL:
390 Used for date/time SQL standard syntax, because not all DBMS's support same temporal types.
390 Used for date/time SQL standard syntax, because not all DBMS's support same temporal types.
391 */
391 */
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
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
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now